diff --git a/version-rust/Cargo.lock b/version-rust/Cargo.lock index 0abbfde..e16eb1c 100644 --- a/version-rust/Cargo.lock +++ b/version-rust/Cargo.lock @@ -2,6 +2,34 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher 0.4.4", + "cpufeatures 0.2.17", +] + +[[package]] +name = "aes" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35f0f96ce78e38c3dc6d8948aa8163d06385be74000f3c7a95bf1eef35d3ea32" +dependencies = [ + "cipher 0.5.2", + "cpubits", + "cpufeatures 0.3.1", +] + [[package]] name = "aho-corasick" version = "1.1.5" @@ -56,7 +84,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -67,7 +95,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -76,12 +104,51 @@ version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" +[[package]] +name = "arbitrary" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bc62ac97cc33321f50863d514c3bc38a453947a8f9e781137e47c7401020aed" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "async-compression" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee19bd99b43e3691acbad4e840420a4881cea6c0b66a208125a824f8fd53f5a1" +dependencies = [ + "compression-codecs", + "compression-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "bitflags" version = "1.3.2" @@ -94,12 +161,88 @@ version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "block-padding" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "710f1dd022ef4e93f8a438b4ba958de7f64308434fa6a87104481645cc30068b" +dependencies = [ + "hybrid-array", +] + [[package]] name = "bumpalo" version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + +[[package]] +name = "bzip2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" +dependencies = [ + "bzip2-sys", +] + +[[package]] +name = "bzip2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c" +dependencies = [ + "libbz2-rs-sys", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.13+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" +dependencies = [ + "cc", + "pkg-config", +] + +[[package]] +name = "cbc" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce2dc9ee5f88d11e0beb842c88b33c8a5cf0d1329c4b19494af42b07dbfe8896" +dependencies = [ + "cipher 0.5.2", +] + [[package]] name = "cc" version = "1.6.0" @@ -107,6 +250,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f74872d07caf508b30a21f6836e7d7016a2eaf7d9ff4f48deaa58cd8a0407630" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -129,18 +274,212 @@ dependencies = [ "windows-link", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common 0.1.7", + "inout 0.1.4", +] + +[[package]] +name = "cipher" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" +dependencies = [ + "crypto-common 0.2.2", + "inout 0.2.2", +] + +[[package]] +name = "clap" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa8876b300ab35ba921adea3dfd70157a46249b33f95c9084ae5709785478946" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0797fb7aeb1406c84efac526901f7ec3ead2124f946b494e72879d4b54704d" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9c751b79415d4e559e3d1fcf128e09e720eb673a06d26cf6f392d37d75b66e0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "clap_lex" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c133bc6a41be0d194c306b5506d15e6feeea7b1d6604bd3f8310dfb2ca96486" + [[package]] name = "colorchoice" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" +[[package]] +name = "compression-codecs" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98fc98460ba0ad5317075d3632b8dfc45d0be8c4a49347c2a38272019717614a" +dependencies = [ + "compression-core", + "flate2", + "memchr", +] + +[[package]] +name = "compression-core" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e8ccc4ea9f6acc32d102c0f6d471d11d913ad15f20c04de743374861fa1d414" + +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[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" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "core_detect" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f8f80099a98041a3d1622845c271458a2d73e688351bf3cb999266764b81d48" + +[[package]] +name = "cpubits" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" + +[[package]] +name = "crc32fast" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "deflate64" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac6b926516df9c60bfa16e107b21086399f8285a44ca9711344b9e553c5146e2" + [[package]] name = "defmt" version = "1.1.1" @@ -172,6 +511,45 @@ dependencies = [ "thiserror", ] +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" + +[[package]] +name = "derive_arbitrary" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b034bd7d5f032402a2479444dcc6f74e36a03f31854d41680fb240ef682a1ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[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", + "crypto-common 0.1.7", + "subtle", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", + "const-oid", + "crypto-common 0.2.2", +] + [[package]] name = "dirs" version = "6.0.0" @@ -190,7 +568,18 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "displaydoc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", ] [[package]] @@ -198,13 +587,40 @@ name = "dlphelper" version = "0.1.0" dependencies = [ "anyhow", + "base64 0.22.1", "chrono", + "clap", "dirs", "env_logger", + "hex", + "indexmap", "log", + "rand", + "regex", + "reqwest", + "rpassword", "serde", "serde_json", + "sevenz-rust2", + "sha2 0.10.9", "tempfile", + "unrar", + "url", + "zip", +] + +[[package]] +name = "encoding_rs" +version = "0.8.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e985e0451871ad22fb8d2b6b076e2028a502a0d3950998c2c5c0a4f9b5d9679" +dependencies = [ + "cfg-if", + "core_detect", + "multiversion_no_op", + "rustversion", + "scopeguard", + "simdutf8", ] [[package]] @@ -230,6 +646,12 @@ dependencies = [ "log", ] +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "errno" version = "0.3.14" @@ -237,7 +659,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -252,12 +674,75 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aedcfb3409746eddb02b9e19ebda1c3394f759a152e48ee875a0844d1b955484" +[[package]] +name = "flate2" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" +dependencies = [ + "crc32fast", + "miniz_oxide", + "zlib-rs", +] + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", + "futures-sink", +] + [[package]] name = "futures-core" version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-sink" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" + [[package]] name = "futures-task" version = "0.3.34" @@ -271,11 +756,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-core", + "futures-io", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "slab", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi 5.3.0", + "wasip2", + "wasm-bindgen", +] + [[package]] name = "getrandom" version = "0.4.3" @@ -284,7 +807,179 @@ checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 6.0.0", +] + +[[package]] +name = "h2" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d29020232d6aa3fb1daca64c1127cf662cf97f254ae16c18c05b8ab635fc118" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[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 = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hybrid-array" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17" +dependencies = [ + "typenum", +] + +[[package]] +name = "hyper" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3e324da4c95177d6291d4c8730197c0d1822f8a9766814a4a44fa5ab797c9c" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa8e654703247911e29c23fbeaa261834bd9bb74efba2f9acddc37bfb127f53" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddc03d96684f9226b8a787cdb71488417b53ab5ea8fdb1dac946cb9431cc8bff" +dependencies = [ + "base64 0.23.1", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "httparse", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", ] [[package]] @@ -311,6 +1006,147 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" + +[[package]] +name = "icu_properties" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" + +[[package]] +name = "icu_provider" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", + "serde", + "serde_core", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "inout" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" +dependencies = [ + "block-padding", + "hybrid-array", +] + +[[package]] +name = "ipnet" +version = "2.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791930b43c0d5973160d90a8f3894509f2b273430f5c5c73b668636d0287c5c0" + [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -360,6 +1196,16 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + [[package]] name = "js-sys" version = "0.3.106" @@ -371,6 +1217,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "libbz2-rs-sys" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b357333733e8260735ba5894eb928c02ecc69c78715f01a8019e7fa7f2db4c" + [[package]] name = "libc" version = "0.2.190" @@ -392,18 +1244,107 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" +[[package]] +name = "litemap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" + [[package]] name = "log" version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" +[[package]] +name = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +dependencies = [ + "byteorder", + "crc", +] + +[[package]] +name = "lzma-rust2" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde178a3caf126c440fa15628147772d8ee590a39477d711353fbe2e58a73a5b" + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "memchr" version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1788edb87fdc09c7e26304471e2f5be8cdefb1b6930d6e3985fc02ff53bf86ee" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "multiversion_no_op" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743fb55ba31b18fb1ecef6bdc9aa2743314978ac084044301a7eee33fb99a20d" + +[[package]] +name = "native-tls" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + [[package]] name = "num-traits" version = "0.2.19" @@ -425,18 +1366,83 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "openssl" +version = "0.10.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77823a27f0babb03091cb9ed9ef80af3b39dbc82f97e8fa530374b7dafd87a45" +dependencies = [ + "bitflags 2.13.2", + "cfg-if", + "foreign-types", + "libc", + "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.119", +] + +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + +[[package]] +name = "openssl-sys" +version = "0.9.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b47e7e6bb2c38cd930d25a23b40fa52e068c10e85f3e03a7f5ba5aaca5713695" +dependencies = [ + "cc", + "libc", + "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 = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", + "hmac", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + [[package]] name = "pin-project-lite" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + [[package]] name = "portable-atomic" version = "1.15.0" @@ -452,6 +1458,36 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "potential_utf" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6394b9e965e73d0a289ee54f589087e2c676aedf60885baf52c76b771e4958" + +[[package]] +name = "ppmd-rust" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "196a7c80b9a7652aba7cc070827516c2abe4ccdf53d128e1944003cf5726cff1" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + [[package]] name = "proc-macro2" version = "1.0.107" @@ -470,12 +1506,47 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "r-efi" version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +[[package]] +name = "rand" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + [[package]] name = "redox_users" version = "0.5.3" @@ -515,6 +1586,83 @@ version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "js-sys", + "log", + "mime", + "native-tls", + "percent-encoding", + "pin-project-lite", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rpassword" +version = "7.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da316a15f47e3d053de9cb2c439650bd8fa4aaeb9365f2e5f27f492ff73c196" +dependencies = [ + "libc", + "rtoolbox", + "windows-sys 0.61.2", +] + +[[package]] +name = "rtoolbox" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a1efe12a1469752d0e6ff5ebec0b6ef4924cc5c4c71046b0ec730040535819d" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "rustix" version = "1.1.5" @@ -525,7 +1673,40 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d41d731c7d2f962d1ccc364cec258de3c0e93b38c2fb3ba97ac74513048d634" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", ] [[package]] @@ -534,6 +1715,50 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags 2.13.2", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.229" @@ -577,18 +1802,127 @@ dependencies = [ "zmij", ] +[[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 = "sevenz-rust2" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4f883677093690e91fef8ae81fad8bce9e2c3a079b61054f05ce0d3ecf681e" +dependencies = [ + "aes 0.9.3", + "bzip2 0.6.1", + "cbc", + "crc32fast", + "getrandom 0.4.3", + "js-sys", + "lzma-rust2", + "ppmd-rust", + "sha2 0.11.0", + "wasm-bindgen", +] + +[[package]] +name = "sha1" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.1", + "digest 0.11.3", +] + [[package]] name = "shlex" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "slab" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +[[package]] +name = "smallvec" +version = "1.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9395f0f0eee849a9b707b2f06bb92a6a422090e2123bb2ef8e87a0e61892a8e" + +[[package]] +name = "socket2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.119" @@ -611,6 +1945,47 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901704edd0dfe137f1987838ee4f259e4e063c31371bdb423f7ae38ec6f77f02" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.13.2", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tempfile" version = "3.27.0" @@ -618,10 +1993,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom", + "getrandom 0.4.3", "once_cell", "rustix", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -644,18 +2019,259 @@ dependencies = [ "syn 3.0.6", ] +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "tinystr" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e95f91fcc7a621e8b030f6aa23c71fe9838ae2fb4d8118b75602a328f5144044" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys 0.61.2", +] + +[[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.26.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9cc2678c2cdd569ef8215e2afd7954ada2ae20b4fdd2c5fe6139a3b02d105db" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e464cf451ba96ebfc6f9b6542f17ee8b8956e33f1e40d9690624e59d7a7f8a4b" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "libc", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "async-compression", + "bitflags 2.13.2", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "pin-project-lite", + "tokio", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "url", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + [[package]] name = "unicode-ident" version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" +[[package]] +name = "unrar" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ec61343a630d2b50d13216dea5125e157d3fc180a7d3f447d22fe146b648fc" +dependencies = [ + "bitflags 2.13.2", + "regex", + "unrar_sys", + "widestring", +] + +[[package]] +name = "unrar_sys" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b77675b883cfbe6bf41e6b7a5cd6008e0a83ba497de3d96e41a064bbeead765" +dependencies = [ + "cc", + "libc", + "winapi", +] + +[[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.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "want" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec4cdd0dd910afe868b7ef477227d8d538b46b3075031afee8a9f2acb0a2ed0b" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "wasm-bindgen" version = "0.2.129" @@ -669,6 +2285,17 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbab34de2d982e9b48e18d216d04c4a6f641066ff19ffb699980f591ee3610e" +dependencies = [ + "js-sys", + "tokio", + "wasm-bindgen", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.129" @@ -701,6 +2328,44 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "web-sys" +version = "0.3.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88261b9deccee56594c11a3460c462c41f58d148598fe70ad77070126a68aba4" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "widestring" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" + +[[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-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-core" version = "0.62.2" @@ -742,6 +2407,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] + [[package]] name = "windows-result" version = "0.4.1" @@ -760,6 +2436,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.61.2" @@ -769,8 +2454,286 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "writeable" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" + +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + +[[package]] +name = "yoke" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec8ebde2db3681e8c9980cc27822030e68752690ddfa9473e739aeb4dbde6d71" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86502bf56ac7c77571a32e2647bb2a15894565e981fb2a48d7bde2d91c965a9d" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5457206954b06561e2608c7e19cf58b1926586d999c246eebe4502f7e2039d1a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f75b4683f6c7f45248d4d64056a24298c6281e0993356d7d1b4a1a962ef10d4a" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13084392c5e4bc371903e2935a5eaeed24905a7511356b883835e18a78f6879" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zerotrie" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "zip" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" +dependencies = [ + "aes 0.8.4", + "arbitrary", + "bzip2 0.5.2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "deflate64", + "displaydoc", + "flate2", + "getrandom 0.3.4", + "hmac", + "indexmap", + "lzma-rs", + "memchr", + "pbkdf2", + "sha1", + "thiserror", + "time", + "xz2", + "zeroize", + "zopfli", + "zstd", +] + +[[package]] +name = "zlib-rs" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112" + [[package]] name = "zmij" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" + +[[package]] +name = "zopfli" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" +dependencies = [ + "bumpalo", + "crc32fast", + "log", + "simd-adler32", +] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d80649ab6db9d9f6f9c80a40becd948eda4714a0a5ac8c4d157a32231c7882" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.1.0+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef0a8027ec3ee71300ab3bcbcd0393f434aa72b91ca6d635a39941deae8eea0" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/version-rust/Cargo.toml b/version-rust/Cargo.toml index 393b169..7141725 100644 --- a/version-rust/Cargo.toml +++ b/version-rust/Cargo.toml @@ -6,12 +6,25 @@ description = "Torrent-first platform for Warhammer proxy models: Discord channe [dependencies] anyhow = "1" +base64 = "0.22" chrono = "0.4" +clap = { version = "4", features = ["derive"] } dirs = "6" env_logger = "0.11" +hex = "0.4" +indexmap = { version = "2", features = ["serde"] } log = "0.4" +rand = "0.9" +regex = "1" +reqwest = { version = "0.12", features = ["blocking", "gzip", "json"] } +rpassword = "7" serde = { version = "1", features = ["derive"] } serde_json = "1" +sha2 = "0.10" +sevenz-rust2 = "0.23" +unrar = "0.5" +url = "2" +zip = "2" [dev-dependencies] tempfile = "3" diff --git a/version-rust/data/warhammer_data.json b/version-rust/data/warhammer_data.json new file mode 100644 index 0000000..2297f4d --- /dev/null +++ b/version-rust/data/warhammer_data.json @@ -0,0 +1,1522 @@ +{ + "systems": { + "Warhammer 40,000": { + "Space Marines": [ + "space marine", + "astartes", + "primaris", + "intercessor", + "reiver", + "aggressor", + "inceptor", + "hellblaster", + "eradicator", + "bladeguard", + "sternguard", + "devastator", + "tactical squad", + "terminator squad", + "assault marine", + "assault intercessor", + "outrider", + "scout squad", + "vanguard veteran", + "invictor", + "impulsor", + "gladiator", + "land speeder", + "drop pod", + "inner circle", + "honour guard" + ], + "Ultramarines": [ + "ultramarines", + "guilliman", + "calgar" + ], + "Blood Angels": [ + "blood angel", + "sanguinary guard", + "sanguinor", + "death company", + "baal predator", + "mephiston", + "dante", + "astorath", + "flesh tearers", + "lamberto", + "furioso" + ], + "Dark Angels": [ + "dark angel", + "ravenwing", + "deathwing", + "inner circle companions", + "azrael", + "asmodai", + "belial", + "samuel", + "lion el'jonson", + "lion el jonson", + "nephilim jetfighter" + ], + "Space Wolves": [ + "space wolf", + "space wolves", + "wulfen", + "thunderwolf", + "wolf guard", + "rune priest", + "wolf priest", + "wolf lord", + "logan grimnar", + "ragnar blackmane", + "canis wolfborn", + "fenrisian wolf", + "stormfang", + "murderfang", + "lukas the trickster" + ], + "Black Templars": [ + "black templar", + "crusader squad", + "high marshal helbrecht", + "grimaldus", + "the emperor's champion", + "emperors champion", + "castellan", + "land raider crusader" + ], + "Imperial Fists": [ + "imperial fist", + "rogal dorn", + "lupos", + "tor garadon", + "horatius hold", + "dorn's arrow" + ], + "Raven Guard": [ + "raven guard", + "kayvaan shrike", + "corvus", + "sable brand", + "shadow captains" + ], + "Iron Hands": [ + "iron hand", + "iron hands", + "ferrus manus", + "iron father", + "medusan immortals" + ], + "White Scars": [ + "white scar", + "jaghatai khan", + "stormseer", + "korsos" + ], + "Salamanders": [ + "salamander", + "vulkan", + "he'stan", + "adrax agatone", + "drake-scale", + "flamecaster" + ], + "Grey Knights": [ + "grey knight", + "grand master", + "brother-captain", + "nemesis dreadknight", + "draigo", + "castellan crowe", + "sternguard knight" + ], + "Deathwatch": [ + "deathwatch", + "watch captain", + "watch master", + "kill team cassius", + "overkill", + "corvus blackstar" + ], + "Crimson Fists": [ + "crimson fist", + "kantor", + "rynn's world" + ], + "Flesh Tearers": [ + "flesh tearer", + "gabriel seth", + "amissum" + ], + "Astra Militarum": [ + "astra militarum", + "imperial guard", + "cadian", + "catachan", + "krieg", + "death korps", + "tempestus", + "scion", + "valhallan", + "steel legion", + "tallarn", + "vostroyan", + "tanith", + "gaunt's ghosts", + "leman russ", + "chimera", + "basilisk", + "hydra", + "wyvern", + "manticore", + "deathstrike", + "sentinel", + "taurox", + "commissar", + "bullgryn", + "ogryn", + "ratling", + "heavy weapon squad", + "baneblade", + "stormlord", + "shadowsword", + "hellhammer", + "malcador", + "macharius", + "valkyrie", + "vulture", + "primaris psyker", + "astropath", + "priest" + ], + "Adeptus Mechanicus": [ + "adeptus mechanicus", + "mechanicum", + "admech", + "skitarii", + "cult mechanicus", + "sicarian", + "ruststalker", + "infiltrator", + "kataphron", + "kastelan", + "ironstrider", + "sydonian", + "onager", + "dunecrawler", + "maniple", + "archmagos", + "magos", + "dominus", + "manipulus", + "enginseer", + "transuranic", + "tech-priest", + "cybernetica", + "thallax", + "castellax", + "vorax", + "ordinatus", + "belisarius cawl" + ], + "Adepta Sororitas": [ + "adepta sororitas", + "sisters of battle", + "sister of battle", + "battle sister", + "repentia", + "retributor", + "canoness", + "dialogus", + "hospitaller", + "seraphim", + "zephyrim", + "paragon warsuit", + "morvenn vahl", + "junith", + "immersa", + "exorcist", + "immolator" + ], + "Adeptus Custodes": [ + "adeptus custodes", + "custodes", + "custodian", + "allarus", + "vertus praetor", + "venatari", + "aquilon", + "sagittarum", + "hetaeron", + "trajann", + "constantin valdor", + "sisters of silence", + "witchseeker", + "prosecutor", + "vigilator", + "caladius", + "coronus", + "telemon", + "achillus", + "galatus", + "pallas" + ], + "Imperial Knights": [ + "imperial knight", + "knight errant", + "knight paladin", + "knight crusader", + "knight warden", + "knight gallant", + "knight lancer", + "knight acheron", + "knight castellan", + "knight valiant", + "knight preceptor", + "questoris", + "armiger", + "warglaive", + "helverin", + "morialtis", + "canis rex", + "cerastus", + "atropos", + "seneschal" + ], + "Imperial Agents": [ + "inquisition", + "inquisitor", + "astra telepathica", + "witch hunter", + "coteaz", + "eisenhorn", + "ravenor", + "kyria draxus", + "officio assassinorum", + "culexus", + "vindicare", + "callidus", + "eversor", + "saint celestine", + "living saint", + "assassin" + ], + "Chaos Space Marines": [ + "chaos space marine", + "black legion", + "iron warriors", + "word bearers", + "night lords", + "night lord", + "alpha legion", + "chaos terminator", + "chosen", + "havoc", + "raptor", + "warp talon", + "chaos cultist", + "cultist", + "daemon prince", + "chaos lord", + "chaos sorcerer", + "abaddon", + "kharn", + "ahriman", + "typhus", + "fabius bile", + "vashtorr", + "defiler", + "forgefiend", + "maulerfiend", + "helldrake", + "helbrute", + "chaos spawn", + "obliterator", + "chaos rhino", + "chaos vindicator", + "spartan assault", + "mastodon", + "typhon", + "csm" + ], + "Death Guard": [ + "death guard", + "nurgle", + "plague marine", + "deathshroud", + "mortarion", + "plaguecaster", + "poxwalker", + "blightlord", + "foetid bloat-drone", + "plagueburst crawler", + "myphitic blight-hauler", + "blight hauler", + "tallyman", + "foul blightspawn", + "biologus putrifier", + "plague surgeon", + "necrosius" + ], + "Thousand Sons": [ + "thousand sons", + "tzeentch", + "rubric marine", + "rubricae", + "scarab occult", + "magnus the red", + "ahzek ahriman", + "arhiman", + "exalted sorcerer", + "osiron", + "mutalith vortex beast", + "tzaangor", + "prospero" + ], + "Chaos Daemons": [ + "chaos daemon", + "chaos daemons", + "daemonette", + "bloodletter", + "plaguebearer", + "horror", + "screamer", + "flesh hound", + "juggernaut", + "keeper of secrets", + "skarbrand", + "kairos fateweaver", + "rotigus", + "be'lakor", + "great unclean one", + "lord of change", + "soul grinder", + "skull cannon", + "burning chariot", + "exalted flamer", + "fiend of slaanesh", + "plague drone", + "nurgling", + "herald", + "skulltaker", + "khorne", + "slaanesh", + "skull lord", + "shalaxi helbane" + ], + "World Eaters": [ + "world eater", + "angron", + "eightbound", + "exalted eightbound", + "jakhals", + "berserker", + "skull lord" + ], + "Emperor's Children": [ + "emperor's children", + "emperors children", + "fulgrim", + "noise marine", + "lucius the eternal", + "flawless blades" + ], + "Iron Warriors": [ + "iron warrior", + "perturabo" + ], + "Red Corsairs": [ + "red corsair", + "huron blackheart" + ], + "Chaos Knights": [ + "chaos knight", + "knight desecrator", + "knight despoiler", + "knight rampager", + "kharibdyss", + "renegade knight" + ], + "Orks": [ + "ork", + "orks", + "orkz", + "nob", + "boyz", + "grot", + "weirdboy", + "painboy", + "warboss", + "ghazghkull", + "meganob", + "deff dread", + "killa kan", + "deffkopta", + "stormboy", + "kommando", + "burna boy", + "loota", + "trukk", + "battlewagon", + "gorkanaut", + "morkanaut", + "stompa", + "squig", + "zagstruk", + "snikrot", + "speed freek", + "boomdakka", + "flash gitz", + "wazbom blasta", + "dakka jet", + "burna-bomber", + "blitza-bomber", + "da troopz", + "dad and sonz", + "ass sassins", + "abby boi" + ], + "T'au Empire": [ + "tau", + "t'au", + "ta'u", + "kroot", + "vespid", + "battlesuit", + "crisis suit", + "broadside", + "r'varna", + "ghostkeel", + "stormsurge", + "fire warrior", + "pathfinder team", + "devilfish", + "hammerhead", + "sky ray", + "piranha", + "sniper drone team", + "ethereal", + "commander farsight", + "commander shadowsun", + "aun'va", + "darkstrider", + "longstrike", + "mont'ka", + "assorted drones", + "breacher", + "bomber", + "tetra", + "barracuda", + "sun shark", + "razorshark", + "kv128 stormsurge", + "tx4 piranha", + "kv46" + ], + "Tyranids": [ + "tyranid", + "hive tyrant", + "swarmlord", + "carnifex", + "hormagaunt", + "termagant", + "termagaunt", + "genestealer brood", + "zoanthrope", + "venomthrope", + "exocrine", + "haruspex", + "tyranid prime", + "tyranid warrior", + "ravener", + "gargoyle", + "spore mine", + "mawloc", + "trygon", + "harridan", + "harpy", + "crone", + "tervigon", + "barbed hierodule", + "hierodule", + "hierophant", + "neurothrope", + "deathleaper", + "lictor", + "pyrovore", + "biovore", + "broodlord", + "bio-titan", + "dominatrix" + ], + "Genestealer Cults": [ + "genestealer cult", + "genestealer", + "aberrant", + "acolyte", + "neophyte hybrid", + "primus", + "magus", + "patriarch", + "purestrain genestealer", + "sanctus", + "kelermorph", + "goliath truck", + "rockgrinder", + "jackal alcaeus", + "cult limo", + "hijacked" + ], + "Necrons": [ + "necron", + "c'tan", + "canoptek", + "wraith", + "spyder", + "scarab", + "tesseract vault", + "doomsday ark", + "annihilation barge", + "ghost ark", + "monolith", + "doom scythe", + "night scythe", + "imotekh", + "szarekh", + "nemesor zahndrekh", + "vargard obyron", + "lokhrust", + "skorpekh", + "flayed one", + "deathmark", + "lychguard", + "necron warrior", + "necron immortal", + "ovoid", + "dzaan" + ], + "Aeldari": [ + "aeldari", + "eldar", + "craftworld", + "ulthwe", + "biel-tan", + "iyanden", + "alaitoc", + "saim-hann", + "farseer", + "warlock", + "spiritseer", + "autarch", + "asurmen", + "guardian defender", + "ranger", + "wraithguard", + "wraithblades", + "wraithlord", + "wraithknight", + "dire avenger", + "howling banshee", + "striking scorpion", + "swooping hawk", + "warp spider", + "fire dragon", + "dark reaper", + "shining spears", + "windrider", + "vyper", + "wave serpent", + "fire prism", + "night spinner", + "war walker", + "hemlock wraithfighter", + "crimson hunter", + "shade runner", + "skyrunner" + ], + "Drukhari": [ + "drukhari", + "dark eldar", + "kabal", + "wych", + "wrack", + "haemonculus", + "coven", + "reaver jetbike", + "hellion", + "scourge", + "mandrake", + "kabalite warrior", + "raider", + "ravager", + "venom", + "razorwing", + "voidraven", + "grotesque", + "talos", + "cronos", + "beast pack", + "khymera", + "razorwing flock", + "asdrubael vect", + "lilith", + "sathonyx", + "luriel" + ], + "Harlequins": [ + "harlequin", + "death jester", + "shadowseer", + "solitaire", + "troupe", + "starweaver", + "voidweaver" + ], + "Leagues of Votann": [ + "leagues of votann", + "votann", + "hearthkyn", + "ironkin", + "brokhyr", + "kahl", + "cthonian", + "transhyperic", + "thegn" + ] + }, + "Age of Sigmar": { + "Stormcast Eternals": [ + "stormcast", + "eternal", + "liberator", + "sequitor", + "evocator", + "vindictor", + "judicators", + "retributors", + "sacrosanct", + "dracothian", + "lord-arcane", + "knight-questor", + "neave blacktalon", + "stormdrake", + "krondys", + "karazai" + ], + "Seraphon": [ + "seraphon", + "saurus", + "skink", + "slann", + "carnosaur", + "bastiladon", + "stegadon", + "razordon", + "salamander" + ], + "Orruk Warclans": [ + "orruk", + "warclan", + "kruleboyz", + "ironjawz", + "brute", + "gorger", + "weirdnob", + "warchanter" + ], + "Gloomspite Gitz": [ + "gloomspite", + "gitz", + "moonclan", + "spiderfang", + "troggoth", + "loontouched", + "zarbag", + "skragrot" + ], + "Sylvaneth": [ + "sylvaneth", + "treelord", + "dryad", + "branchwraith", + "alarielle", + "kurnothi" + ], + "Ossiarch Bonereapers": [ + "ossiarch", + "bonereaper", + "mortek", + "keldrek", + "katakros" + ], + "Nighthaunt": [ + "nighthaunt", + "grimghast", + "bladegheist", + "chainghast", + "kurdoss", + "lady olynder" + ], + "Lumineth Realm-lords": [ + "lumineth", + "aelf", + "vanari", + "teclis", + "light of eltharion" + ], + "Daughters of Khaine": [ + "daughters of khaine", + "khainite", + "witch aelf", + "morgwaeth", + "morathi" + ], + "Fyreslayers": [ + "fyreslayer", + "vulkite", + "hearthguard", + "auric", + "grimhold" + ], + "Kharadron Overlords": [ + "kharadron", + "skyfarer", + "endofters", + "grundstok", + "arcanaut" + ], + "Idoneth Deepkin": [ + "idoneth", + "deepkin", + "namarti", + "isharann", + "volturnos" + ], + "Blades of Khorne": [ + "blades of khorne", + "khorne", + "skullgrinder", + "blood warrior", + "wrathmonger" + ], + "Maggotkin of Nurgle": [ + "maggotkin", + "nurgle", + "blightking", + "rotmire", + "orghotts" + ], + "Slaves to Darkness": [ + "slaves to darkness", + "chaos warrior", + "chaos knight", + "archaon", + "gaunt summoner", + "everchosen" + ], + "Skaven": [ + "skaven", + "clanrat", + "stormvermin", + "verminlord", + "grey seer", + "warplock", + "ratling gun" + ], + "Soulblight Gravelords": [ + "soulblight", + "gravelord", + "vampire", + "deathrattle", + "koldhunter", + "belladamma" + ], + "Cities of Sigmar": [ + "cities of sigmar", + "freeguild", + "windspeaker", + "callis and toll", + "hammerers" + ] + }, + "The Horus Heresy": { + "Space Marine Legions": [ + "legiones astartes", + "pre-heresy", + "horus heresy", + "justaerin", + "seeker squad", + "suzerain", + "invictarus", + "veteran tactical", + "contemptor", + "leviathan pattern", + "sicaran", + "fellblade", + "kratos", + "fire raptor", + "eisenstein" + ], + "Mechanicum": [ + "mechanicum", + "fulgurite", + "magos", + "thallax" + ] + }, + "Other Games": { + "Kill Team": [ + "kill team", + "killteam", + "killzone", + "operative", + "hand of the archon", + "void-dance troupe", + "veteran guardsmen", + "spector squad", + "wolf scouts", + "scout squad kill" + ], + "Necromunda": [ + "necromunda", + "goliath gang", + "escher", + "orlock", + "cawdor", + "van saar", + "ash wastes", + "underhive", + "sumpkrocs", + "forge boss", + "sumpkroc", + "matriarch", + "phyrr cat" + ], + "Adeptus Titanicus": [ + "adepticus titanicus", + "titan legio", + "reaver titan", + "warhound titan", + "warlord titan", + "imperator titan", + "warmaster titan", + "titanicus" + ], + "Warhammer Underworlds": [ + "warhammer underworlds", + "underworlds", + "warband", + "shadeborn", + "embergard" + ], + "Aeronautica Imperialis": [ + "aeronautica", + "t'au air caste", + "lightning fighter", + "thunderbolt" + ] + }, + "The Old World": { + "Kingdom of Bretonnia": [ + "bretonnia", + "grail knight", + "peasant", + "questing knight", + "perrin" + ], + "Orc and Goblin Tribes": [ + "greenskin", + "goblin", + "night goblin", + "forest goblin", + "black orc" + ], + "Tomb Kings of Khemri": [ + "tomb king", + "khemri", + "necrolith", + "skeleton archer" + ], + "Empire of Man": [ + "empire of man", + "state troop", + "greatsword", + "empire knight" + ], + "Warriors of Chaos": [ + "chaos dwarf", + "dog of war", + "chaos marauder" + ], + "High Elf Realms": [ + "high elf", + "eltharion", + "phoenix guard" + ], + "Wood Elf Realms": [ + "wood elf", + "glade guard", + "waywatcher" + ], + "Beastmen Brayherds": [ + "beastmen", + "brayherd", + "ghorgon", + "cygor" + ], + "Dwarfen Mountain Holds": [ + "dwarf", + "ironbreaker", + "hammerer" + ] + }, + "Middle-Earth": { + "Rivendell": [ + "rivendell", + "elrond", + "elendil", + "isildur", + "gil-galad", + "beorning", + "grimbeorn", + "rumil", + "orophin" + ], + "Minas Tirith": [ + "minas tirith", + "gondor", + "boromir", + "faramir" + ], + "Mordor": [ + "mordor", + "orc", + "orcs", + "nazgul", + "witch-king" + ], + "Iron Hills": [ + "iron hills", + "dwarf", + "mattock", + "dwalin" + ], + "Moria": [ + "moria", + "cave troll", + "balrog" + ] + } + }, + "classes": [ + [ + "Titanic", + [ + "titan", + "stompa", + "gargantuan", + "hierophant", + "harridan", + "hierodule", + "imperator", + "warmaster", + "tesseract vault", + "plaguereaper", + "warhound", + "warlord titan", + "ta'unar", + "spermato", + "titandeath" + ] + ], + [ + "Fortification", + [ + "fortification", + "bunker", + "bastion", + "wall of martyrs" + ] + ], + [ + "Flyer", + [ + "flyer", + "heldrake", + "dakka jet", + "burna-bomber", + "blitza-bomber", + "bomber", + "sky ray", + "stormraven", + "storm talon", + "stormhawk", + "caestus", + "valkyrie", + "vulture", + "thunderbolt", + "lightning", + "marauder", + "razorwing", + "voidraven", + "crimson hunter", + "hemlock", + "doom scythe", + "night scythe", + "harpy", + "crone", + "fire raptor", + "barracuda", + "sun shark", + "razorshark", + "wazbom blasta", + "nephilim jetfighter", + "corvus blackstar" + ] + ], + [ + "Vehicle", + [ + "transport", + "rhino", + "razorback", + "chimera", + "taurox", + "trukk", + "battlewagon", + "devilfish", + "wave serpent", + "ghost ark", + "land raider", + "repulsor", + "drop pod", + "starweaver", + "voidweaver", + "goliath truck", + "rockgrinder", + "cult limo", + "raider", + "venom", + "spartan assault", + "predator", + "vindicator", + "whirlwind", + "basilisk", + "hydra", + "wyvern", + "manticore", + "deathstrike", + "onager dunecrawler", + "kastelan", + "hammerhead", + "broadside", + "stormsurge", + "r'varna", + "soul grinder", + "defiler", + "forgefiend", + "maulerfiend", + "plagueburst crawler", + "annihilation barge", + "doomsday ark", + "fire prism", + "night spinner", + "exorcist", + "immolator", + "caladius", + "coronus grav", + "pallas grav", + "impulsor", + "gladiator", + "baal predator", + "land speeder", + "ironstrider", + "sydonian", + "sentinel", + "taurox", + "kataphron" + ] + ], + [ + "Walker", + [ + "dreadnought", + "redemptor", + "contemptor", + "leviathan pattern", + "brutalis", + "ballistus", + "deredeo", + "wulfen dreadnought", + "killa kan", + "deff dread", + "wraithlord", + "wraithknight", + "telemon", + "achillus", + "galatus", + "paragon warsuit", + "nemesis dreadknight", + "invictor", + "talos", + "cronos" + ] + ], + [ + "Monster", + [ + "monster", + "carnifex", + "exocrine", + "haruspex", + "mawloc", + "trygon", + "tervigon", + "hierodule", + "hierophant", + "mutalith", + "bloat-drone", + "kharibdyss", + "gorkanaut", + "morkanaut", + "magnus", + "mortalith", + "fiend of slaanesh", + "plague drone", + "cave troll", + "balrog", + "carnosaur", + "stegadon", + "bastiladon", + "grorgeous" + ] + ], + [ + "Mounted", + [ + "mounted", + "thunderwolf", + "outrider", + "bike squad", + "scout biker", + "reaver jetbike", + "windrider", + "skyrunner", + "warbiker", + "allarus custodian on", + "vertus praetor", + "drakeling", + "boarboy", + "gruntaz", + "khan on", + "dracothian guard" + ] + ], + [ + "Battleline", + [ + "battleline", + "troops", + "tactical squad", + "intercessor", + "incursor", + "infiltrator", + "infantry squad", + "conscript", + "krieg", + "catachan", + "cadian", + "vostroyan", + "penal legion", + "ratling", + "veteran squad", + "fire warrior", + "pathfinder team", + "kroot", + "termagant", + "hormagaunt", + "necron warrior", + "necron immortal", + "guardian defender", + "storm guardian", + "kabalite warrior", + "boyz", + "gretchin", + "scion", + "scout squad", + "cultist", + "plague marine squad" + ] + ], + [ + "Infantry", + [ + "infantry", + "veteran", + "terminator", + "sternguard", + "bladeguard", + "aggressor", + "reiver", + "wulfen", + "wolf guard", + "deathshroud", + "blightlord", + "poxwalker", + "rubric marine", + "rubricae", + "scarab occult", + "tzaangor", + "chosen", + "possessed", + "obliterator", + "daemonette", + "bloodletter", + "plaguebearer", + "nurgling", + "juggernaut", + "chaos cultist", + "acolyte hybrid", + "aberrant", + "neophyte", + "purestrain", + "genestealer", + "lictor", + "deathmark", + "flayed one", + "lychguard", + "wraithguard", + "wraithblades", + "howling banshee", + "striking scorpion", + "warp spider", + "fire dragon", + "incubi", + "wrack", + "grotesque", + "assault marine", + "assault intercessor", + "inceptor", + "raptor", + "warp talon", + "flesh hound", + "screamer", + "hellion", + "scourge", + "mandrake", + "swooping hawk", + "shining spears", + "canoptek wraith", + "canoptek scarab", + "canoptek spyder", + "ravener", + "gargoyle", + "spore mine", + "pyrovore", + "khymera", + "beast pack", + "razorwing flock", + "zephyrim", + "seraphim", + "stormboy", + "deffkopta", + "skorpekh destroyer", + "skorpekh", + "retributor", + "dark reaper", + "sicarian", + "ruststalker", + "skitarii", + "hormagaunt brood", + "termagant brood", + "vanguard" + ] + ], + [ + "Hero", + [ + "hero", + "hq", + "captain", + "chapter master", + "primarch", + "lieutenant", + "librarian", + "chaplain", + "apothecary", + "farseer", + "warlock", + "spiritseer", + "autarch", + "warboss", + "big mek", + "weirdboy", + "painboy", + "commander", + "ethereal", + "hive tyrant", + "swarmlord", + "tyranid prime", + "neurothrope", + "deathleaper", + "patriarch", + "primus", + "magus", + "sanctus", + "kelermorph", + "overlord", + "imotekh", + "szarekh", + "zahndrekh", + "obyron", + "plaguecaster", + "necrosius", + "chaos lord", + "chaos sorcerer", + "daemon prince", + "exalted champion", + "herald", + "skulltaker", + "kairos", + "rotigus", + "be'lakor", + "great unclean one", + "lord of change", + "keeper of secrets", + "skarbrand", + "kharn", + "abaddon", + "typhus", + "mortarion", + "magnus", + "ahriman", + "lucius", + "fabius bile", + "vashtorr", + "canoness", + "morvenn", + "junith", + "immersa", + "dialogus", + "hospitaller", + "trajann", + "valdor", + "inquisitor", + "coteaz", + "eisenhorn", + "ravenor", + "draxus", + "celestine", + "commissar", + "priest", + "enginseer", + "dominus", + "manipulus", + "archmagos", + "belisarius cawl", + "farsight", + "shadowsun", + "aun'va", + "darkstrider", + "longstrike", + "shade runner" + ] + ], + [ + "Rules & Accessories", + [ + "codex", + "rulebook", + "rules", + "data cards", + "datacards", + "warscroll", + "index card", + "cheat sheet", + "reference" + ] + ] + ], + "group_of_faction": { + "Space Marines": "Space Marines", + "Ultramarines": "Space Marines", + "Blood Angels": "Space Marines", + "Dark Angels": "Space Marines", + "Space Wolves": "Space Marines", + "Black Templars": "Space Marines", + "Imperial Fists": "Space Marines", + "Raven Guard": "Space Marines", + "Iron Hands": "Space Marines", + "White Scars": "Space Marines", + "Salamanders": "Space Marines", + "Grey Knights": "Space Marines", + "Deathwatch": "Space Marines", + "Crimson Fists": "Space Marines", + "Flesh Tearers": "Space Marines", + "Astra Militarum": "Armies of the Imperium", + "Adeptus Mechanicus": "Armies of the Imperium", + "Adepta Sororitas": "Armies of the Imperium", + "Adeptus Custodes": "Armies of the Imperium", + "Imperial Knights": "Armies of the Imperium", + "Imperial Agents": "Armies of the Imperium", + "Chaos Space Marines": "Armies of Chaos", + "Death Guard": "Armies of Chaos", + "Thousand Sons": "Armies of Chaos", + "Chaos Daemons": "Armies of Chaos", + "Chaos Knights": "Armies of Chaos", + "World Eaters": "Armies of Chaos", + "Emperor's Children": "Armies of Chaos", + "Iron Warriors": "Armies of Chaos", + "Red Corsairs": "Armies of Chaos", + "Orks": "Xenos Armies", + "T'au Empire": "Xenos Armies", + "Tyranids": "Xenos Armies", + "Genestealer Cults": "Xenos Armies", + "Necrons": "Xenos Armies", + "Aeldari": "Xenos Armies", + "Drukhari": "Xenos Armies", + "Harlequins": "Xenos Armies", + "Leagues of Votann": "Xenos Armies", + "Stormcast Eternals": "Grand Alliance Order", + "Seraphon": "Grand Alliance Order", + "Sylvaneth": "Grand Alliance Order", + "Lumineth Realm-lords": "Grand Alliance Order", + "Daughters of Khaine": "Grand Alliance Order", + "Fyreslayers": "Grand Alliance Order", + "Kharadron Overlords": "Grand Alliance Order", + "Idoneth Deepkin": "Grand Alliance Order", + "Cities of Sigmar": "Grand Alliance Order", + "Orruk Warclans": "Grand Alliance Destruction", + "Gloomspite Gitz": "Grand Alliance Destruction", + "Ossiarch Bonereapers": "Grand Alliance Death", + "Nighthaunt": "Grand Alliance Death", + "Soulblight Gravelords": "Grand Alliance Death", + "Slaves to Darkness": "Grand Alliance Chaos", + "Blades of Khorne": "Grand Alliance Chaos", + "Maggotkin of Nurgle": "Grand Alliance Chaos", + "Skaven": "Grand Alliance Chaos", + "Space Marine Legions": "Space Marine Legions", + "Mechanicum": "Space Marine Legions", + "Kill Team": "Kill Team", + "Necromunda": "Necromunda", + "Adeptus Titanicus": "Adeptus Titanicus", + "Warhammer Underworlds": "Warhammer Underworlds", + "Aeronautica Imperialis": "Aeronautica Imperialis", + "Kingdom of Bretonnia": "Armies of the Old World", + "Orc and Goblin Tribes": "Armies of the Old World", + "Tomb Kings of Khemri": "Armies of the Old World", + "Empire of Man": "Armies of the Old World", + "Warriors of Chaos": "Armies of the Old World", + "High Elf Realms": "Armies of the Old World", + "Wood Elf Realms": "Armies of the Old World", + "Beastmen Brayherds": "Armies of the Old World", + "Dwarfen Mountain Holds": "Armies of the Old World", + "Rivendell": "Rivendell", + "Minas Tirith": "Minas Tirith", + "Mordor": "Mordor", + "Iron Hills": "Iron Hills", + "Moria": "Moria" + } +} \ No newline at end of file diff --git a/version-rust/src/catalogue.rs b/version-rust/src/catalogue.rs new file mode 100644 index 0000000..12cda7d --- /dev/null +++ b/version-rust/src/catalogue.rs @@ -0,0 +1,2 @@ +//! Catalogue: classify collected files into game system / faction / class — +//! Rust port of `version-python/dlphelper/catalogue.py`. diff --git a/version-rust/src/difflib.rs b/version-rust/src/difflib.rs new file mode 100644 index 0000000..0b022c1 --- /dev/null +++ b/version-rust/src/difflib.rs @@ -0,0 +1,253 @@ +//! Port of CPython's `difflib.SequenceMatcher` (Ratcliff/Obershelp) — the +//! exact ratio algorithm the python sorter relies on. A different fuzzy +//! metric (strsim etc.) would produce different scores and silently change +//! which files land where, so this is a faithful port including +//! real_quick_ratio/quick_ratio pruning and autojunk. +//! +//! Constructed like the python sorter uses it: `SequenceMatcher(None, a, b)` +//! — no external junk patterns, autojunk enabled (it only matters for +//! sequences of length >= 200). + +/// Longest matching block: (i in a, j in b, size). +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct Match { + i: usize, + j: usize, + size: usize, +} + +pub struct SequenceMatcher<'a> { + a: &'a str, + b: &'a str, + /// b[j] -> indices (purged of junk and popular elements, like `b2j`). + b2j: std::collections::HashMap>, + bjunk: std::collections::HashSet, +} + +impl<'a> SequenceMatcher<'a> { + pub fn new(a: &'a str, b: &'a str) -> Self { + // __chain_b with isjunk=None: no junk, but autojunk purges + // "popular" characters from long sequences (len(b) >= 200). + let mut b2j: std::collections::HashMap> = std::collections::HashMap::new(); + for (idx, elt) in b.chars().enumerate() { + b2j.entry(elt).or_default().push(idx); + } + let bjunk = std::collections::HashSet::new(); // isjunk is None + let mut bpopular = std::collections::HashSet::new(); + let n = b.chars().count(); + if n >= 200 { + let ntest = n / 100 + 1; + for (&elt, idxs) in &b2j { + if idxs.len() > ntest { + bpopular.insert(elt); + } + } + for &elt in &bpopular { + b2j.remove(&elt); + } + } + SequenceMatcher { a, b, b2j, bjunk } + } + + fn isbjunk(&self, elt: char) -> bool { + self.bjunk.contains(&elt) + } + + /// CPython SequenceMatcher.find_longest_match(alo, ahi, blo, bhi) over + /// char indices. + fn find_longest_match(&self, alo: usize, ahi: usize, blo: usize, bhi: usize) -> Match { + let a_chars: Vec = self.a.chars().collect(); + let b_chars: Vec = self.b.chars().collect(); + let nothing: Vec = Vec::new(); + + let mut besti = alo; + let mut bestj = blo; + let mut bestsize = 0usize; + // j2len[j] = length of the longest match ending at (a[i], b[j]) + let mut j2len: std::collections::HashMap = std::collections::HashMap::new(); + for i in alo..ahi { + let mut newj2len: std::collections::HashMap = + std::collections::HashMap::new(); + for &j in self.b2j.get(&a_chars[i]).unwrap_or(¬hing) { + if j < blo { + continue; + } + if j >= bhi { + break; + } + let k = j2len.get(&(j.wrapping_sub(1))).copied().unwrap_or(0) + 1; + newj2len.insert(j, k); + if k > bestsize { + besti = i + 1 - k; + bestj = j + 1 - k; + bestsize = k; + } + } + j2len = newj2len; + } + + // Extend the best by non-junk elements on each end. + while besti > alo + && bestj > blo + && !self.isbjunk(b_chars[bestj - 1]) + && a_chars[besti - 1] == b_chars[bestj - 1] + { + besti -= 1; + bestj -= 1; + bestsize += 1; + } + while besti + bestsize < ahi + && bestj + bestsize < bhi + && !self.isbjunk(b_chars[bestj + bestsize]) + && a_chars[besti + bestsize] == b_chars[bestj + bestsize] + { + bestsize += 1; + } + // Then suck up matching junk on each side of it. + while besti > alo + && bestj > blo + && self.isbjunk(b_chars[bestj - 1]) + && a_chars[besti - 1] == b_chars[bestj - 1] + { + besti -= 1; + bestj -= 1; + bestsize += 1; + } + while besti + bestsize < ahi + && bestj + bestsize < bhi + && self.isbjunk(b_chars[bestj + bestsize]) + && a_chars[besti + bestsize] == b_chars[bestj + bestsize] + { + bestsize += 1; + } + Match { + i: besti, + j: bestj, + size: bestsize, + } + } + + /// All matching blocks, in order (recursive queue algorithm). + pub fn get_matching_blocks(&self) -> Vec { + let la = self.a.chars().count(); + let lb = self.b.chars().count(); + let mut blocks: Vec = Vec::new(); + let mut queue: Vec<(usize, usize, usize, usize)> = vec![(0, la, 0, lb)]; + while let Some((alo, ahi, blo, bhi)) = queue.pop() { + let m = self.find_longest_match(alo, ahi, blo, bhi); + if m.size > 0 { + blocks.push(m); + if alo < m.i && blo < m.j { + queue.push((alo, m.i, blo, m.j)); + } + if m.i + m.size < ahi && m.j + m.size < bhi { + queue.push((m.i + m.size, ahi, m.j + m.size, bhi)); + } + } + } + blocks.sort_by_key(|m| (m.i, m.j, m.size)); + blocks + } + + fn calculate_ratio(matches: usize, la: usize, lb: usize) -> f64 { + let length = la + lb; + if length > 0 { + 2.0 * matches as f64 / length as f64 + } else { + 1.0 + } + } + + /// Upper bound computed from the cardinality of the char multiset + /// intersection (python `quick_ratio`). + pub fn quick_ratio(&self) -> f64 { + let mut fullbcount: std::collections::HashMap = + std::collections::HashMap::new(); + for elt in self.b.chars() { + *fullbcount.entry(elt).or_default() += 1; + } + let mut avail: std::collections::HashMap = std::collections::HashMap::new(); + let mut matches = 0usize; + for elt in self.a.chars() { + let numb = avail + .get(&elt) + .copied() + .unwrap_or_else(|| fullbcount.get(&elt).copied().unwrap_or(0)); + if numb > 0 { + avail.insert(elt, numb - 1); + matches += 1; + } + } + Self::calculate_ratio(matches, self.a.chars().count(), self.b.chars().count()) + } + + /// Trivial upper bound (python `real_quick_ratio`). + pub fn real_quick_ratio(&self) -> f64 { + let la = self.a.chars().count(); + let lb = self.b.chars().count(); + Self::calculate_ratio(la.min(lb), la, lb) + } + + /// Ratcliff/Obershelp similarity in [0, 1], exactly as python's + /// `SequenceMatcher(None, a, b).ratio()`. + pub fn ratio(&self) -> f64 { + let matches: usize = self.get_matching_blocks().iter().map(|m| m.size).sum(); + Self::calculate_ratio(matches, self.a.chars().count(), self.b.chars().count()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + /// Expected values generated with CPython 3.12 difflib (see + /// tools/dump_difflib_vectors.py to regenerate). + #[rustfmt::skip] + const VECTORS: &[( &str, &str, f64, f64, f64 )] = &[ + // a, b, real_quick_ratio, quick_ratio, ratio + ("telemon", "telemon heavy dreadnought", 0.4375, 0.4375, 0.4375), + ("aeldari rangers", "dark reapers", 0.8888888888888888, 0.7407407407407407, 0.6666666666666666), + ("aeldari rangers", "dwarf rangers", 0.9285714285714286, 0.7857142857142857, 0.7857142857142857), + ("guardian weapon team", "guardian squad", 0.8235294117647058, 0.5882352941176471, 0.5882352941176471), + ("frontline squad", "guardian squad", 0.9655172413793104, 0.6206896551724138, 0.5517241379310345), + ("2e catachany fellaz catachan jungle fighters x", "cadian command squad", 0.6060606060606061, 0.3939393939393939, 0.18181818181818182), + ("warp spiders", "warp spiders", 1.0, 1.0, 1.0), + ("thunderwolf cavalry", "thunderwolf mount", 0.9444444444444444, 0.6666666666666666, 0.6666666666666666), + ("lictor", "necron lieutenant with voidwalker", 0.3076923076923077, 0.3076923076923077, 0.2564102564102564), + ("aeldari pack", "harlequin troupe", 0.8571428571428571, 0.5, 0.35714285714285715), + ("xyzzy", "warp spiders", 0.5882352941176471, 0.0, 0.0), + ("guardian defender", "guardian squad", 0.9032258064516129, 0.6451612903225806, 0.6451612903225806), + ]; + + #[test] + fn matches_cpython_difflib_exactly() { + for (a, b, rqr, qr, r) in VECTORS { + let sm = SequenceMatcher::new(a, b); + assert_eq!( + sm.real_quick_ratio(), + *rqr, + "real_quick_ratio({a:?}, {b:?})" + ); + assert_eq!(sm.quick_ratio(), *qr, "quick_ratio({a:?}, {b:?})"); + assert_eq!(sm.ratio(), *r, "ratio({a:?}, {b:?})"); + } + } + + #[test] + fn empty_and_long_sequences() { + assert_eq!(SequenceMatcher::new("", "").ratio(), 1.0); + assert_eq!(SequenceMatcher::new("", "abc").ratio(), 0.0); + // autojunk path (len(b) >= 200): "unit unit" vs "unit " * 50 + let long_b = "unit ".repeat(50); + let sm = SequenceMatcher::new("unit unit", &long_b); + assert_eq!(sm.ratio(), 0.0694980694980695); + } + + #[test] + fn symmetry_of_ratio_value() { + // documented CPython behavior: ratio values are symmetric + let ab = SequenceMatcher::new("aeldari rangers", "dwarf rangers").ratio(); + let ba = SequenceMatcher::new("dwarf rangers", "aeldari rangers").ratio(); + assert_eq!(ab, ba); + } +} diff --git a/version-rust/src/discord.rs b/version-rust/src/discord.rs new file mode 100644 index 0000000..dbc4f23 --- /dev/null +++ b/version-rust/src/discord.rs @@ -0,0 +1,2 @@ +//! DCE docker export (JSON) + base64/plain URL extraction — Rust port of +//! `version-python/dlphelper/discord.py`. diff --git a/version-rust/src/extract.rs b/version-rust/src/extract.rs new file mode 100644 index 0000000..e5c4198 --- /dev/null +++ b/version-rust/src/extract.rs @@ -0,0 +1,9 @@ +//! Recursive archive extraction into a plain-file tree — Rust port of +//! `version-python/tools/extract_all.py` (extract_manifest.jsonl feeds the +//! sorter's provenance mode; failures go to .broken/; the run never stops). +//! +//! Extraction backend: `sevenz-rust2` for .7z, `zip` for .zip, `unrar` for +//! .rar, `tar`+`flate2`/`bzip2`/`xz2` for tar balls and bare compressed +//! files. Because extraction is pure Rust (no 7z CLI writing directly onto +//! CIFS), the python version's /var/tmp fallback + cp437 name repair is +//! not needed here. diff --git a/version-rust/src/gofile.rs b/version-rust/src/gofile.rs new file mode 100644 index 0000000..61e203c --- /dev/null +++ b/version-rust/src/gofile.rs @@ -0,0 +1,2 @@ +//! GoFile API client (one guest account per run) — Rust port of +//! `version-python/dlphelper/gofile.py`. diff --git a/version-rust/src/gwshop.rs b/version-rust/src/gwshop.rs new file mode 100644 index 0000000..0419707 --- /dev/null +++ b/version-rust/src/gwshop.rs @@ -0,0 +1,2 @@ +//! GW webshop catalog dump via Algolia — Rust port of +//! `version-python/dlphelper/gwshop.py`. diff --git a/version-rust/src/main.rs b/version-rust/src/main.rs index 56be2a1..d6d050d 100644 --- a/version-rust/src/main.rs +++ b/version-rust/src/main.rs @@ -1,7 +1,17 @@ +mod catalogue; +mod difflib; +mod discord; +mod extract; mod globalstore; +mod gofile; +mod gwshop; mod manifest; +mod orchestrate; +mod sorter; mod state; mod util; +mod warhammer_data; +mod zero807; fn main() { env_logger::init(); diff --git a/version-rust/src/orchestrate.rs b/version-rust/src/orchestrate.rs new file mode 100644 index 0000000..96a221b --- /dev/null +++ b/version-rust/src/orchestrate.rs @@ -0,0 +1,6 @@ +//! Orchestration: per-channel pipeline, gofile/0807 loops, subscriptions, +//! --assume-done — Rust port of the logic in `version-python/dlp.py`. +//! +//! Failure policy (the core requirement): a failure in one URL must never +//! abort the run. Catch, record in state.json, continue. Cooldown pauses +//! are the only permitted stall. diff --git a/version-rust/src/sorter.rs b/version-rust/src/sorter.rs new file mode 100644 index 0000000..3468cb4 --- /dev/null +++ b/version-rust/src/sorter.rs @@ -0,0 +1,7 @@ +//! Library sorter: inspect/classify/fuzzy-match against the catalog, plan + +//! hardlink apply, optional provenance unit mode — Rust port of +//! `version-python/dlphelper/sorter.py`. +//! +//! Matching rules are fixed (see version-python/AGENTS.md §7 "Sorter matching +//! rules"); they must be ported exactly or the Rust sorter will silently +//! sort differently than the battle-tested python one. diff --git a/version-rust/src/warhammer_data.rs b/version-rust/src/warhammer_data.rs new file mode 100644 index 0000000..4255f7a --- /dev/null +++ b/version-rust/src/warhammer_data.rs @@ -0,0 +1,137 @@ +//! Taxonomy: GW-named systems/factions, GW shop categories as classes, +//! GROUP_OF_FACTION map — Rust port of `version-python/dlphelper/warhammer_data.py`. +//! +//! The tables are NOT hand-transcribed: they are dumped from the python +//! module into `data/warhammer_data.json` (regenerate with +//! `version-rust/tools/dump_warhammer_data.py`) and parsed here, so both +//! versions work from byte-identical data. +//! +//! Python-dict ordering is preserved exactly (insertion order; a duplicate +//! key keeps its first insertion position while the *last* value wins), +//! because the catalogue's "most specific keyword" rule breaks ties by +//! first occurrence among equal-length keywords. + +use std::sync::OnceLock; + +use anyhow::Context as _; +use indexmap::IndexMap; +use serde::Deserialize; + +/// Insertion-ordered pair list with python-dict semantics for building. +fn dict_insert(vec: &mut Vec<(String, V)>, key: String, value: V) { + if let Some(slot) = vec.iter_mut().find(|(k, _)| *k == key) { + slot.1 = value; + } else { + vec.push((key, value)); + } +} + +/// system -> (faction, keyword aliases), python dict order. +pub type Systems = Vec<(String, Vec<(String, Vec)>)>; + +#[derive(Deserialize)] +struct Raw { + systems: IndexMap>>, + classes: Vec<(String, Vec)>, + group_of_faction: IndexMap, +} + +pub struct Data { + pub systems: Systems, + /// system -> (alias, faction), insertion order of first occurrence, + /// value = last faction seen (python dict semantics). + pub faction_aliases: Vec<(String, Vec<(String, String)>)>, + /// keyword -> class, insertion order of first occurrence. + pub unit_classes: Vec<(String, String)>, + pub group_of_faction: IndexMap, +} + +impl Data { + pub fn global() -> &'static Data { + static DATA: OnceLock = OnceLock::new(); + DATA.get_or_init(|| Data::load().expect("embedded warhammer_data.json is valid")) + } + + /// Parse the embedded JSON dump of the python taxonomy module. + fn load() -> anyhow::Result { + let raw: Raw = serde_json::from_str(include_str!("../data/warhammer_data.json")) + .context("parsing embedded warhammer_data.json")?; + + // SYSTEMS in dict order + let mut systems: Systems = Vec::new(); + for (system, factions) in &raw.systems { + let mut factions_vec: Vec<(String, Vec)> = Vec::new(); + for (faction, aliases) in factions { + dict_insert(&mut factions_vec, faction.clone(), aliases.clone()); + } + dict_insert(&mut systems, system.clone(), factions_vec); + } + + // FACTION_ALIASES = {system: {alias: faction ...}} in dict order + let mut faction_aliases: Vec<(String, Vec<(String, String)>)> = Vec::new(); + for (system, factions) in &systems { + let mut aliases_vec: Vec<(String, String)> = Vec::new(); + for (faction, aliases) in factions { + for alias in aliases { + dict_insert(&mut aliases_vec, alias.clone(), faction.clone()); + } + } + dict_insert(&mut faction_aliases, system.clone(), aliases_vec); + } + + // UNIT_CLASSES = {kw: klass for klass, kws in CLASSES for kw in kws} + let mut unit_classes: Vec<(String, String)> = Vec::new(); + for (klass, keywords) in &raw.classes { + for kw in keywords { + dict_insert(&mut unit_classes, kw.clone(), klass.clone()); + } + } + + Ok(Data { + systems, + faction_aliases, + unit_classes, + group_of_faction: raw.group_of_faction, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn tables_load_and_are_complete() { + let d = Data::global(); + assert!(d.systems.iter().any(|(s, _)| s == "Warhammer 40,000")); + assert!(d.systems.iter().any(|(s, _)| s == "Middle-Earth")); + let f40k = &d + .systems + .iter() + .find(|(s, _)| s == "Warhammer 40,000") + .unwrap() + .1; + assert!(f40k.iter().any(|(f, _)| f == "Space Wolves")); + // "magnus" is listed in both Monster and Hero -> last (Hero) wins + let magnus = d + .unit_classes + .iter() + .find(|(kw, _)| kw == "magnus") + .map(|(_, c)| c.as_str()); + assert_eq!(magnus, Some("Hero")); + // duplicate alias inside a system keeps first position, last value + let aliases = &d + .faction_aliases + .iter() + .find(|(s, _)| s == "Warhammer 40,000") + .unwrap() + .1; + let idx = aliases.iter().position(|(a, _)| a == "skull lord").unwrap(); + assert_eq!(aliases[idx].1, "World Eaters"); + // position kept from FIRST insertion (Chaos Daemons block): it sits + // between 'slaanesh' and 'shalaxi helbane' (verified against python) + assert_eq!(aliases[idx - 1].0, "slaanesh"); + assert_eq!(aliases[idx + 1].0, "shalaxi helbane"); + assert_eq!(d.group_of_faction["Space Wolves"], "Space Marines"); + } +} diff --git a/version-rust/src/zero807.rs b/version-rust/src/zero807.rs new file mode 100644 index 0000000..83047e3 --- /dev/null +++ b/version-rust/src/zero807.rs @@ -0,0 +1,2 @@ +//! curl-based downloader for 0807.st direct links — Rust port of +//! `version-python/dlphelper/zero807.py`. diff --git a/version-rust/tools/dump_warhammer_data.py b/version-rust/tools/dump_warhammer_data.py new file mode 100644 index 0000000..b897296 --- /dev/null +++ b/version-rust/tools/dump_warhammer_data.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +"""Regenerate version-rust/data/warhammer_data.json from the python module. + +Run from the repo root (the version containing the python layout): + + python3 version-rust/tools/dump_warhammer_data.py + +The Rust rewrite parses this file (src/warhammer_data.rs) instead of holding +a hand-transcribed copy of the taxonomy tables, so the two versions work +from byte-identical data. +""" + +import json +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent / "version-python")) + +from dlphelper import warhammer_data as w # noqa: E402 + +out = Path(__file__).resolve().parent.parent / "data" / "warhammer_data.json" + +payload = { + "systems": w.SYSTEMS, + "classes": [[name, keywords] for name, keywords in w.CLASSES], + "group_of_faction": w.GROUP_OF_FACTION, +} +out.write_text(json.dumps(payload, ensure_ascii=False, indent=1), encoding="utf-8") +print(f"wrote {out} ({out.stat().st_size} bytes)")