smol bot
-rw-r--r--.gitignore2
-rw-r--r--Cargo.lock2188
-rw-r--r--Cargo.toml44
-rw-r--r--LICENSE21
-rw-r--r--README.md6
-rw-r--r--src/bot/help_eval.md16
-rw-r--r--src/bot/logic.rs90
-rw-r--r--src/bot/mod.rs260
-rw-r--r--src/bot/schematic.rs95
-rw-r--r--src/bot/usage.md9
-rw-r--r--src/conv.rs285
-rw-r--r--src/main.rs9
12 files changed, 3025 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2476c73
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/target
+token
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..7f7af60
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,2188 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "addr2line"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "amap"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30fe7aeccff307fd97e9c9051bd4d5d81f77dbb09037467bb1c378976eb1836c"
+dependencies = [
+ "quote",
+ "syn 2.0.39",
+]
+
+[[package]]
+name = "anstream"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
+
+[[package]]
+name = "async-trait"
+version = "0.1.74"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.39",
+]
+
+[[package]]
+name = "async-tungstenite"
+version = "0.17.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1b71b31561643aa8e7df3effe284fa83ab1a840e52294c5f4bd7bfd8b2becbb"
+dependencies = [
+ "futures-io",
+ "futures-util",
+ "log",
+ "pin-project-lite",
+ "tokio",
+ "tokio-rustls 0.23.4",
+ "tungstenite",
+ "webpki-roots 0.22.6",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "backtrace"
+version = "0.3.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
+dependencies = [
+ "addr2line",
+ "cc",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+]
+
+[[package]]
+name = "base64"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
+
+[[package]]
+name = "base64"
+version = "0.21.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9"
+
+[[package]]
+name = "beef"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bitvec"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
+dependencies = [
+ "funty",
+ "radium",
+ "tap",
+ "wyz",
+]
+
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "bobbin-bits"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84a856508d80144eabeae3392de76f269e5fd2983226e4757219f8ce87c5e572"
+
+[[package]]
+name = "btparse"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca8fb3f04d0ef6cb7d39262d6c2bad0eec0c00071083ceddeb8bbcf693ff28a6"
+
+[[package]]
+name = "bumpalo"
+version = "3.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
+
+[[package]]
+name = "bytemuck"
+version = "1.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6"
+
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
+name = "bytes"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
+
+[[package]]
+name = "cc"
+version = "1.0.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "clipline"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01c033212f55b799c43650c2fb12866ba8fe873e5786e7e649810c4dc9a76561"
+
+[[package]]
+name = "cloudflare-zlib-sys"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c03221eaad27d2fe22f530de824f3068664354453672695627b29179c565da89"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "color-hex"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ecdffb913a326b6c642290a0d0ec8e8d6597291acdc07cc4c9cb4b3635d44cf9"
+
+[[package]]
+name = "comat"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f24f01cb5d7f027b65718cfab34b16ae783a3290d9b16e15d7e4310e0c24c173"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.39",
+]
+
+[[package]]
+name = "core-foundation"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crc32fast"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "darling"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
+dependencies = [
+ "darling_core",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "dashmap"
+version = "5.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
+dependencies = [
+ "cfg-if",
+ "hashbrown 0.14.2",
+ "lock_api",
+ "once_cell",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "deranged"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3"
+dependencies = [
+ "powerfmt",
+ "serde",
+]
+
+[[package]]
+name = "derivative"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+]
+
+[[package]]
+name = "encoding_rs"
+version = "0.8.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "enum_dispatch"
+version = "0.3.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f33313078bb8d4d05a2733a94ac4c2d8a0df9a2b84424ebf4f33bfc224a890e"
+dependencies = [
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.39",
+]
+
+[[package]]
+name = "equivalent"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+
+[[package]]
+name = "fdeflate"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64d6dafc854908ff5da46ff3f8f473c6984119a2876a383a860246dd7841a868"
+dependencies = [
+ "simd-adler32",
+]
+
+[[package]]
+name = "fer"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a02dba6a60cd31533cf16561ced53239686d18f1464bff49579dd320fcea081"
+
+[[package]]
+name = "fimg"
+version = "0.4.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6c8b28c6d8cb5a49b2c6dd5330be3064a243504a053c4e6fea8b323438f5acb"
+dependencies = [
+ "clipline",
+ "fer",
+ "mattr",
+ "png",
+ "stackblur-iter",
+ "umath",
+ "vecto",
+]
+
+[[package]]
+name = "flate2"
+version = "1.0.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
+dependencies = [
+ "cloudflare-zlib-sys",
+ "crc32fast",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "funty"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
+
+[[package]]
+name = "futures"
+version = "0.3.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"
+
+[[package]]
+name = "futures-io"
+version = "0.3.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.39",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"
+
+[[package]]
+name = "futures-task"
+version = "0.3.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2"
+
+[[package]]
+name = "futures-util"
+version = "0.3.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-macro",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "gimli"
+version = "0.28.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
+
+[[package]]
+name = "h2"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833"
+dependencies = [
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap 1.9.3",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "hashbrown"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
+
+[[package]]
+name = "http"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
+dependencies = [
+ "bytes",
+ "http",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "httparse"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
+
+[[package]]
+name = "httpdate"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
+
+[[package]]
+name = "hyper"
+version = "0.14.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "socket2 0.4.10",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "want",
+]
+
+[[package]]
+name = "hyper-rustls"
+version = "0.24.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
+dependencies = [
+ "futures-util",
+ "http",
+ "hyper",
+ "rustls 0.21.8",
+ "tokio",
+ "tokio-rustls 0.24.1",
+]
+
+[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
+name = "idna"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "imgref"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90d944e334f00f4449c9640b440a171f816be0152305c12ef90424fc35fd035c"
+
+[[package]]
+name = "imgref-iter"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58112733c0ee178b66dceba49e0445d0b293268719de579d2c7dd4c2290976aa"
+dependencies = [
+ "imgref",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+dependencies = [
+ "autocfg",
+ "hashbrown 0.12.3",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.14.2",
+]
+
+[[package]]
+name = "ipnet"
+version = "2.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
+
+[[package]]
+name = "itoa"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
+
+[[package]]
+name = "js-sys"
+version = "0.3.65"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "lemu"
+version = "0.2.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f9c46fe5db82ee90d927df148f4ff6b9fe5790d697f48d8735a05a9665c4aa76"
+dependencies = [
+ "beef",
+ "comat",
+ "enum_dispatch",
+ "fimg",
+ "lerr",
+ "logos",
+ "rust-fuzzy-search",
+ "thiserror",
+ "vecto",
+]
+
+[[package]]
+name = "lerr"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "318b7599710150e42b2d34f3582d047d3896de30c5d74c197d9b88a185a042b4"
+dependencies = [
+ "anstream",
+ "comat",
+ "unicode-width",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.150"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
+
+[[package]]
+name = "libdeflate-sys"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67921a7f85100c1559efc3d1c7c472091b7da05f304b4bbd5356f075e97f1cc2"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "libdeflater"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a31b22f662350ec294b13859f935aea772ba7b2bc8776269f4a5627308eab7d"
+dependencies = [
+ "libdeflate-sys",
+]
+
+[[package]]
+name = "lock_api"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
+
+[[package]]
+name = "logos"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c000ca4d908ff18ac99b93a062cb8958d331c3220719c52e77cb19cc6ac5d2c1"
+dependencies = [
+ "logos-derive",
+]
+
+[[package]]
+name = "logos-codegen"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc487311295e0002e452025d6b580b77bb17286de87b57138f3b5db711cded68"
+dependencies = [
+ "beef",
+ "fnv",
+ "proc-macro2",
+ "quote",
+ "regex-syntax 0.6.29",
+ "syn 2.0.39",
+]
+
+[[package]]
+name = "logos-derive"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbfc0d229f1f42d790440136d941afd806bc9e949e2bcb8faa813b0f00d1267e"
+dependencies = [
+ "logos-codegen",
+]
+
+[[package]]
+name = "mattr"
+version = "0.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f63dc7ec862e5d146c89d104d437548fef5216a6a653f4afc4b87c581970677"
+
+[[package]]
+name = "memchr"
+version = "2.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
+
+[[package]]
+name = "mime"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+
+[[package]]
+name = "mime_guess"
+version = "2.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
+dependencies = [
+ "mime",
+ "unicase",
+]
+
+[[package]]
+name = "mindus"
+version = "5.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49f1fa02a69a433e46bb555bfeef159157c62f9142d9367a1bf7db4dba8d47b8"
+dependencies = [
+ "amap",
+ "base64 0.21.5",
+ "bobbin-bits",
+ "color-hex",
+ "enum_dispatch",
+ "fimg",
+ "flate2",
+ "paste",
+ "phf",
+ "strconv",
+ "thiserror",
+ "walkdir",
+]
+
+[[package]]
+name = "miniz_oxide"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
+dependencies = [
+ "adler",
+ "simd-adler32",
+]
+
+[[package]]
+name = "mio"
+version = "0.8.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0"
+dependencies = [
+ "libc",
+ "wasi",
+ "windows-sys",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "object"
+version = "0.32.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
+
+[[package]]
+name = "ordered-float"
+version = "2.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "oxipng"
+version = "9.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28e5c341ef78a228e47a551bfd15ff885d8c501af49f953358763a538c01f14d"
+dependencies = [
+ "bitvec",
+ "indexmap 2.1.0",
+ "libdeflater",
+ "log",
+ "rgb",
+ "rustc-hash",
+ "rustc_version",
+]
+
+[[package]]
+name = "parking_lot"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-targets",
+]
+
+[[package]]
+name = "paste"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
+
+[[package]]
+name = "percent-encoding"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
+
+[[package]]
+name = "phf"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
+dependencies = [
+ "phf_macros",
+ "phf_shared",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
+dependencies = [
+ "phf_shared",
+ "rand",
+]
+
+[[package]]
+name = "phf_macros"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
+dependencies = [
+ "phf_generator",
+ "phf_shared",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.39",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
+dependencies = [
+ "siphasher",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "plent"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "btparse",
+ "dashmap",
+ "fimg",
+ "flate2",
+ "lemu",
+ "mindus",
+ "oxipng",
+ "paste",
+ "phf",
+ "poise",
+ "regex",
+ "serenity",
+ "tokio",
+]
+
+[[package]]
+name = "png"
+version = "0.17.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64"
+dependencies = [
+ "bitflags",
+ "crc32fast",
+ "fdeflate",
+ "flate2",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "poise"
+version = "0.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d104e4b5847283b2fbd6a7ec19fb6a8af328e2145623d056b66d750a30073fdf"
+dependencies = [
+ "async-trait",
+ "derivative",
+ "futures-core",
+ "futures-util",
+ "log",
+ "once_cell",
+ "parking_lot",
+ "poise_macros",
+ "regex",
+ "serenity",
+ "tokio",
+]
+
+[[package]]
+name = "poise_macros"
+version = "0.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fb516a8cf4e4ae4bd7ef5819d08c6ca408976461a9bea3ee3eec5138ac070c1"
+dependencies = [
+ "darling",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "radium"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "regex"
+version = "1.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax 0.8.2",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax 0.8.2",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
+
+[[package]]
+name = "reqwest"
+version = "0.11.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b"
+dependencies = [
+ "base64 0.21.5",
+ "bytes",
+ "encoding_rs",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-rustls",
+ "ipnet",
+ "js-sys",
+ "log",
+ "mime",
+ "mime_guess",
+ "once_cell",
+ "percent-encoding",
+ "pin-project-lite",
+ "rustls 0.21.8",
+ "rustls-pemfile",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "system-configuration",
+ "tokio",
+ "tokio-rustls 0.24.1",
+ "tokio-util",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "wasm-streams",
+ "web-sys",
+ "webpki-roots 0.25.2",
+ "winreg",
+]
+
+[[package]]
+name = "rgb"
+version = "0.8.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8"
+dependencies = [
+ "bytemuck",
+]
+
+[[package]]
+name = "ring"
+version = "0.16.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
+dependencies = [
+ "cc",
+ "libc",
+ "once_cell",
+ "spin 0.5.2",
+ "untrusted 0.7.1",
+ "web-sys",
+ "winapi",
+]
+
+[[package]]
+name = "ring"
+version = "0.17.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b"
+dependencies = [
+ "cc",
+ "getrandom",
+ "libc",
+ "spin 0.9.8",
+ "untrusted 0.9.0",
+ "windows-sys",
+]
+
+[[package]]
+name = "rust-fuzzy-search"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a157657054ffe556d8858504af8a672a054a6e0bd9e8ee531059100c0fa11bb2"
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
+
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
+name = "rustc_version"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+dependencies = [
+ "semver",
+]
+
+[[package]]
+name = "rustls"
+version = "0.20.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99"
+dependencies = [
+ "log",
+ "ring 0.16.20",
+ "sct",
+ "webpki",
+]
+
+[[package]]
+name = "rustls"
+version = "0.21.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c"
+dependencies = [
+ "log",
+ "ring 0.17.5",
+ "rustls-webpki",
+ "sct",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
+dependencies = [
+ "base64 0.21.5",
+]
+
+[[package]]
+name = "rustls-webpki"
+version = "0.101.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
+dependencies = [
+ "ring 0.17.5",
+ "untrusted 0.9.0",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
+
+[[package]]
+name = "ryu"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "sct"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
+dependencies = [
+ "ring 0.17.5",
+ "untrusted 0.9.0",
+]
+
+[[package]]
+name = "semver"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
+
+[[package]]
+name = "serde"
+version = "1.0.192"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde-value"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
+dependencies = [
+ "ordered-float",
+ "serde",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.192"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.39",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.108"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_urlencoded"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serenity"
+version = "0.11.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a7a89cef23483fc9d4caf2df41e6d3928e18aada84c56abd237439d929622c6"
+dependencies = [
+ "async-trait",
+ "async-tungstenite",
+ "base64 0.21.5",
+ "bitflags",
+ "bytes",
+ "cfg-if",
+ "flate2",
+ "futures",
+ "mime",
+ "mime_guess",
+ "percent-encoding",
+ "reqwest",
+ "rustversion",
+ "serde",
+ "serde-value",
+ "serde_json",
+ "time",
+ "tokio",
+ "tracing",
+ "typemap_rev",
+ "url",
+]
+
+[[package]]
+name = "sha-1"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "simd-adler32"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
+
+[[package]]
+name = "siphasher"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
+
+[[package]]
+name = "slab"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
+
+[[package]]
+name = "socket2"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "socket2"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "spin"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+
+[[package]]
+name = "spin"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+
+[[package]]
+name = "stackblur-iter"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712b7bee292d3d0ac59c5110f826d3d8aaafd8f39e455319acebe06c0eae3e7f"
+dependencies = [
+ "imgref",
+ "imgref-iter",
+]
+
+[[package]]
+name = "strconv"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f32df10f08eec2c31bc4e24768cef452df8f7c44c40f3c92c268a1c61195f8c4"
+dependencies = [
+ "syn 2.0.39",
+]
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "system-configuration"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
+dependencies = [
+ "bitflags",
+ "core-foundation",
+ "system-configuration-sys",
+]
+
+[[package]]
+name = "system-configuration-sys"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "tap"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
+
+[[package]]
+name = "thiserror"
+version = "1.0.50"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.50"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.39",
+]
+
+[[package]]
+name = "time"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5"
+dependencies = [
+ "deranged",
+ "itoa",
+ "powerfmt",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
+
+[[package]]
+name = "time-macros"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20"
+dependencies = [
+ "time-core",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
+[[package]]
+name = "tokio"
+version = "1.34.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9"
+dependencies = [
+ "backtrace",
+ "bytes",
+ "libc",
+ "mio",
+ "parking_lot",
+ "pin-project-lite",
+ "socket2 0.5.5",
+ "tokio-macros",
+ "windows-sys",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.39",
+]
+
+[[package]]
+name = "tokio-rustls"
+version = "0.23.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
+dependencies = [
+ "rustls 0.20.9",
+ "tokio",
+ "webpki",
+]
+
+[[package]]
+name = "tokio-rustls"
+version = "0.24.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
+dependencies = [
+ "rustls 0.21.8",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "tower-service"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
+
+[[package]]
+name = "tracing"
+version = "0.1.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
+dependencies = [
+ "log",
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.39",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
+
+[[package]]
+name = "tungstenite"
+version = "0.17.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0"
+dependencies = [
+ "base64 0.13.1",
+ "byteorder",
+ "bytes",
+ "http",
+ "httparse",
+ "log",
+ "rand",
+ "rustls 0.20.9",
+ "sha-1",
+ "thiserror",
+ "url",
+ "utf-8",
+ "webpki",
+]
+
+[[package]]
+name = "typemap_rev"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed5b74f0a24b5454580a79abb6994393b09adf0ab8070f15827cb666255de155"
+
+[[package]]
+name = "typenum"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+
+[[package]]
+name = "umath"
+version = "0.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42f74eb7957e3a63fa27bfa53c3d361e7ce3871e66f2518292a011eb8e2c00cc"
+
+[[package]]
+name = "unicase"
+version = "2.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
+dependencies = [
+ "version_check",
+]
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "unicode-width"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
+
+[[package]]
+name = "untrusted"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+
+[[package]]
+name = "untrusted"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+
+[[package]]
+name = "url"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+ "serde",
+]
+
+[[package]]
+name = "utf-8"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
+
+[[package]]
+name = "utf8parse"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
+
+[[package]]
+name = "vecto"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c9f1339978a8a20d3ca67ea5d6cbb13e5d06bfac55f5a2a05338fb13e36ab75d"
+dependencies = [
+ "umath",
+]
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "walkdir"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
+dependencies = [
+ "same-file",
+ "winapi-util",
+]
+
+[[package]]
+name = "want"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
+dependencies = [
+ "try-lock",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.88"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.88"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.39",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.88"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.88"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.39",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.88"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b"
+
+[[package]]
+name = "wasm-streams"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7"
+dependencies = [
+ "futures-util",
+ "js-sys",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+]
+
+[[package]]
+name = "web-sys"
+version = "0.3.65"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "webpki"
+version = "0.22.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53"
+dependencies = [
+ "ring 0.17.5",
+ "untrusted 0.9.0",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "0.22.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
+dependencies = [
+ "webpki",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "0.25.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+[[package]]
+name = "winreg"
+version = "0.50.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
+dependencies = [
+ "cfg-if",
+ "windows-sys",
+]
+
+[[package]]
+name = "wyz"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
+dependencies = [
+ "tap",
+]
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..8f305f6
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,44 @@
+[package]
+name = "plent"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+paste = "1.0.12"
+tokio = { version = "1.28.2", features = [
+ "net",
+ "sync",
+ "rt",
+ "parking_lot",
+], default-features = false }
+serenity = { version = "0.11.5", features = [
+ "builder",
+ "client",
+ "rustls_backend",
+ "gateway",
+], default-features = false }
+poise = { version = "0.5.5", default-features = false, features = [
+ "handle_panics",
+] }
+anyhow = "1.0.75"
+regex = { version = "1.8.4", features = ["std"], default-features = false }
+btparse = "0.1.1"
+mindus = { version = "5.0.7", features = [], default-features = false }
+flate2 = { version = "1.0", features = [
+ "cloudflare_zlib",
+], default-features = false }
+lemu = { features = ["diagnose"], default-features = false, version = "0.2.0" }
+dashmap = "5.5.3"
+oxipng = { version = "9.0.0", default-features = false }
+fimg = "0.4.26"
+phf = { version = "0.11.2", features = ["macros"] }
+
+[profile.release]
+strip = true
+lto = "thin"
+
+[profile.dev.package.mindus]
+opt-level = 3
+
+[profile.dev.package.fimg]
+opt-level = 3
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..1fafc15
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 bendn
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f08503a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,6 @@
+## plent
+
+[![add](https://img.shields.io/badge/discord-add-66c2a5?style=for-the-badge&labelColor=555555&logo=discord)](https://discord.com/oauth2/authorize?client_id=1174262682573082644&scope=bot "add this bot")
+![MSRV](https://img.shields.io/badge/msrv-nightly-blue?style=for-the-badge&logo=rust)
+
+smol discord bot to render your schematics, and maps for you. \ No newline at end of file
diff --git a/src/bot/help_eval.md b/src/bot/help_eval.md
new file mode 100644
index 0000000..dfd7aad
--- /dev/null
+++ b/src/bot/help_eval.md
@@ -0,0 +1,16 @@
+## how to use `}eval` <:micro_processor:1165059281087889479>
+
+type```
+}eval ​`​`​`arm
+print "xd"
+​`​`​`
+```for the bot to evaluate your MLOG
+
+you will have access to one large display.
+you are capped to a maximum of `52789849` instructions.
+you can set the number of iterations, by passing `}eval iters=10 ..`
+iterations are clamped `1..=50`.
+syntax errors will be gracefully reported, unknown instructions, such as `ubind`, `getlinks`, will be ignored.
+labels are supported.
+you may edit your message, and the mlog will be re-executed.
+@variables, such as `@time`, `@tick`, are not supported yet.
diff --git a/src/bot/logic.rs b/src/bot/logic.rs
new file mode 100644
index 0000000..30631fb
--- /dev/null
+++ b/src/bot/logic.rs
@@ -0,0 +1,90 @@
+use super::{Context, Result};
+use lemu::Executor;
+use poise::{serenity_prelude::AttachmentType, CodeBlock, KeyValueArgs};
+use std::borrow::Cow;
+
+#[poise::command(prefix_command, track_edits, rename = "eval")]
+pub async fn run(
+ ctx: Context<'_>,
+ #[description = "number of iterations"] kv: KeyValueArgs,
+ #[description = "Script"] block: CodeBlock,
+) -> Result<()> {
+ let _ = ctx.channel_id().start_typing(&ctx.serenity_context().http);
+ let lemu::Output {
+ output: Some(output),
+ displays,
+ ..
+ } = (match tokio::task::spawn_blocking(move || {
+ Executor::with_output(vec![])
+ .large_display()
+ .limit_iterations(
+ kv.get("iters")
+ .map_or(1, |v| v.parse::<usize>().unwrap_or(1).clamp(1, 50)),
+ )
+ .limit_instructions(52789849)
+ .program(&block.code)
+ .map(|mut v| {
+ v.run();
+ v.output()
+ })
+ .map_err(|e| format!("{}", e.diagnose(&block.code)).replace("`", "\u{200b}`"))
+ })
+ .await?
+ {
+ Ok(o) => o,
+ Err(e) => {
+ ctx.send(|c| {
+ c.allowed_mentions(|a| a.empty_parse())
+ .content(format!("```ansi\n{e}\n```"))
+ })
+ .await?;
+ return Ok(());
+ }
+ })
+ else {
+ unreachable!()
+ };
+ let displays: Box<[_; 1]> = displays.try_into().unwrap();
+ let [(display, _)] = *displays;
+ let display = if display.buffer().iter().any(|&n| n != 0) {
+ Some(
+ tokio::task::spawn_blocking(move || {
+ let p = oxipng::RawImage::new(
+ display.width(),
+ display.height(),
+ oxipng::ColorType::RGBA,
+ oxipng::BitDepth::Eight,
+ display.take_buffer(),
+ )
+ .unwrap();
+ p.create_optimized_png(&oxipng::Options::default()).unwrap()
+ })
+ .await?,
+ )
+ } else {
+ None
+ };
+
+ ctx.send(|c| {
+ if output.is_empty() && display.is_none() {
+ c.content("no output");
+ }
+ if !output.is_empty() {
+ c.content(format!(
+ "```\n{}\n```",
+ String::from_utf8_lossy(&output).replace('`', "\u{200b}`")
+ ));
+ }
+ if let Some(display) = display {
+ c.attachment(AttachmentType::Bytes {
+ data: Cow::from(display),
+ filename: "display1.png".to_string(),
+ })
+ .embed(|e| e.attachment("display1.png"));
+ }
+ c.allowed_mentions(|a| a.empty_parse())
+ })
+ .await?;
+
+ Ok(())
+}
diff --git a/src/bot/mod.rs b/src/bot/mod.rs
new file mode 100644
index 0000000..656d806
--- /dev/null
+++ b/src/bot/mod.rs
@@ -0,0 +1,260 @@
+mod logic;
+mod schematic;
+
+use anyhow::Result;
+use dashmap::DashMap;
+
+use poise::serenity_prelude::*;
+use serenity::model::channel::Message;
+use std::fmt::Write;
+use std::fs::read_to_string;
+use std::ops::ControlFlow;
+use std::sync::Arc;
+use std::time::Duration;
+
+#[derive(Debug)]
+pub struct Data {
+ // message -> resp
+ tracker: Arc<DashMap<MessageId, Message>>,
+}
+
+pub struct Msg {
+ author: String,
+ content: String,
+ channel: ChannelId,
+ attachments: Vec<Attachment>,
+}
+
+#[macro_export]
+macro_rules! send {
+ ($e:expr, $fmt:literal $(, $args:expr)* $(,)?) => {
+ $e.send(format!($fmt $(, $args)*))
+ };
+}
+
+const SUCCESS: (u8, u8, u8) = (34, 139, 34);
+
+const PFX: char = '}';
+
+pub struct Bot;
+impl Bot {
+ pub async fn spawn() {
+ println!("bot startup");
+ let tok = std::env::var("TOKEN").unwrap_or(read_to_string("token").expect("wher token"));
+ let f: poise::FrameworkBuilder<Data, anyhow::Error> = poise::Framework::builder()
+ .options(poise::FrameworkOptions {
+ commands: vec![logic::run(), help()],
+ event_handler: |c, e, _, d| {
+ Box::pin(async move {
+ match e {
+ poise::Event::Ready { .. } => {
+ println!("bot ready");
+ }
+ poise::Event::Message { new_message } => {
+ if new_message.content.starts_with('!')
+ || new_message.content.starts_with(PFX)
+ || new_message.author.bot
+ {
+ return Ok(());
+ }
+ if let ControlFlow::Break(m) = schematic::with(
+ Msg {
+ author: new_message
+ .author_nick(c)
+ .await
+ .unwrap_or(new_message.author.name.clone()),
+ attachments: new_message.attachments.clone(),
+ content: new_message.content.clone(),
+ channel: new_message.channel_id,
+ },
+ c,
+ )
+ .await?
+ {
+ d.tracker.insert(new_message.id, m);
+ return Ok(());
+ }
+ }
+ poise::Event::MessageUpdate { event, .. } => {
+ let MessageUpdateEvent {
+ author: Some(author),
+ guild_id: Some(guild_id),
+ content: Some(content),
+ attachments: Some(attachments),
+ ..
+ } = event.clone()
+ else {
+ return Ok(());
+ };
+ if let Some((_, r)) = d.tracker.remove(&event.id) {
+ r.delete(c).await.unwrap();
+ if let ControlFlow::Break(m) = schematic::with(
+ Msg {
+ author: author
+ .nick_in(c, guild_id)
+ .await
+ .unwrap_or(author.name.clone()),
+ content,
+ attachments,
+ channel: event.channel_id,
+ },
+ c,
+ )
+ .await?
+ {
+ d.tracker.insert(event.id, m);
+ }
+ }
+ }
+ poise::Event::MessageDelete {
+ deleted_message_id, ..
+ } => {
+ if let Some((_, r)) = d.tracker.remove(deleted_message_id) {
+ r.delete(c).await.unwrap();
+ }
+ }
+ _ => {}
+ };
+ Ok(())
+ })
+ },
+ on_error: |e| Box::pin(on_error(e)),
+ prefix_options: poise::PrefixFrameworkOptions {
+ edit_tracker: Some(poise::EditTracker::for_timespan(
+ std::time::Duration::from_secs(2 * 60),
+ )),
+ prefix: Some(PFX.to_string()),
+ ..Default::default()
+ },
+ ..Default::default()
+ })
+ .token(tok)
+ .intents(GatewayIntents::non_privileged() | GatewayIntents::MESSAGE_CONTENT)
+ .setup(|ctx, _ready, framework| {
+ Box::pin(async move {
+ poise::builtins::register_globally(ctx, &framework.options().commands).await?;
+ println!("registered");
+ let tracker = Arc::new(DashMap::new());
+ let tc = Arc::clone(&tracker);
+ tokio::spawn(async move {
+ loop {
+ // every 10 minutes
+ tokio::time::sleep(Duration::from_secs(60 * 10)).await;
+ tc.retain(|_, v: &mut Message| {
+ // prune messagees older than 3 hours
+ Timestamp::now().unix_timestamp() - v.timestamp.unix_timestamp()
+ < 60 * 60 * 3
+ });
+ }
+ });
+ Ok(Data { tracker })
+ // todo: voting::fixall() auto
+ })
+ });
+ f.run().await.unwrap();
+ }
+}
+
+type Context<'a> = poise::Context<'a, Data, anyhow::Error>;
+
+async fn on_error(error: poise::FrameworkError<'_, Data, anyhow::Error>) {
+ use poise::FrameworkError::Command;
+ match error {
+ Command { error, ctx } => {
+ let mut msg;
+ {
+ let mut chain = error.chain();
+ msg = format!("e: `{}`", chain.next().unwrap());
+ for mut source in chain {
+ write!(msg, "from: `{source}`").unwrap();
+ while let Some(next) = source.source() {
+ write!(msg, "from: `{next}`").unwrap();
+ source = next;
+ }
+ }
+ }
+ let bt = error.backtrace();
+ if bt.status() == std::backtrace::BacktraceStatus::Captured {
+ let parsed = btparse::deserialize(dbg!(error.backtrace())).unwrap();
+ let mut s = vec![];
+ for frame in parsed.frames {
+ if let Some(line) = frame.line
+ && (frame.function.contains("panel")
+ || frame.function.contains("poise")
+ || frame.function.contains("serenity")
+ || frame.function.contains("mindus")
+ || frame.function.contains("image"))
+ {
+ s.push(format!("l{}@{}", line, frame.function));
+ }
+ }
+ s.truncate(15);
+ write!(msg, "trace: ```rs\n{}\n```", s.join("\n")).unwrap();
+ }
+ ctx.say(msg).await.unwrap();
+ }
+ err => poise::builtins::on_error(err).await.unwrap(),
+ }
+}
+
+pub fn strip_colors(from: &str) -> String {
+ let mut result = String::new();
+ result.reserve(from.len());
+ let mut level: u8 = 0;
+ for c in from.chars() {
+ if c == '[' {
+ level += 1;
+ } else if c == ']' {
+ level -= 1;
+ } else if level == 0 {
+ result.push(c);
+ }
+ }
+ result
+}
+
+#[poise::command(slash_command)]
+pub async fn help(
+ ctx: Context<'_>,
+ #[description = "command to show help about"]
+ #[autocomplete = "poise::builtins::autocomplete_command"]
+ command: Option<String>,
+) -> Result<()> {
+ ctx.send(|m| {
+ m.ephemeral(true).content(
+ if matches!(
+ command.as_deref(),
+ Some("eval") | Some("exec") | Some("run")
+ ) {
+ include_str!("help_eval.md")
+ } else {
+ include_str!("usage.md")
+ },
+ )
+ })
+ .await?;
+ Ok(())
+}
+
+pub fn png(p: fimg::Image<Vec<u8>, 3>) -> Vec<u8> {
+ use oxipng::*;
+ let p = RawImage::new(
+ p.width(),
+ p.height(),
+ ColorType::RGB {
+ transparent_color: None,
+ },
+ BitDepth::Eight,
+ p.take_buffer(),
+ )
+ .unwrap();
+ p.create_optimized_png(&oxipng::Options {
+ filter: indexset! { RowFilter::None },
+ bit_depth_reduction: false,
+ color_type_reduction: false,
+ palette_reduction: false,
+ grayscale_reduction: false,
+ ..oxipng::Options::from_preset(0)
+ })
+ .unwrap()
+}
diff --git a/src/bot/schematic.rs b/src/bot/schematic.rs
new file mode 100644
index 0000000..f409952
--- /dev/null
+++ b/src/bot/schematic.rs
@@ -0,0 +1,95 @@
+use anyhow::{anyhow, Result};
+use mindus::data::DataRead;
+use mindus::*;
+use poise::serenity_prelude::*;
+use regex::Regex;
+use std::fmt::Write;
+use std::sync::LazyLock;
+use std::{borrow::Cow, ops::ControlFlow};
+
+use super::{strip_colors, Msg, SUCCESS};
+
+static RE: LazyLock<Regex> =
+ LazyLock::new(|| Regex::new(r"(```)?(\n)?([^`]+)(\n)?(```)?").unwrap());
+
+async fn from_attachments(attchments: &[Attachment]) -> Result<Option<Schematic>> {
+ for a in attchments {
+ if a.filename.ends_with("msch") {
+ let s = a.download().await?;
+ let mut s = DataRead::new(&s);
+ let Ok(s) = Schematic::deserialize(&mut s) else {
+ continue;
+ };
+ return Ok(Some(s));
+ // discord uploads base64 as a file when its too long
+ } else if a.filename == "message.txt" {
+ let Ok(s) = String::from_utf8(a.download().await?) else {
+ continue;
+ };
+ let Ok(s) = Schematic::deserialize_base64(&s) else {
+ continue;
+ };
+ return Ok(Some(s));
+ }
+ }
+ Ok(None)
+}
+
+pub async fn with(m: Msg, c: &serenity::client::Context) -> Result<ControlFlow<Message, ()>> {
+ let author = m.author;
+ let send = |v: Schematic| async move {
+ let d = v.tags.get("description").map(|t| crate::conv::replace(t));
+ let name = crate::conv::replace(&strip_colors(v.tags.get("name").unwrap()));
+ let cost = v.compute_total_cost().0;
+ let p = tokio::task::spawn_blocking(move || to_png(&v)).await?;
+ anyhow::Ok(
+ m.channel
+ .send_message(c, |m| {
+ m.add_file(AttachmentType::Bytes {
+ data: Cow::Owned(p),
+ filename: "image.png".to_string(),
+ })
+ .embed(|e| {
+ e.attachment("image.png");
+ d.map(|v| e.description(v));
+ let mut s = String::new();
+ for (i, n) in cost.iter() {
+ if n == 0 {
+ continue;
+ }
+ write!(s, "{} {n} ", crate::conv::item(i)).unwrap();
+ }
+ e.field("req", s, true);
+ e.title(name)
+ .footer(|f| f.text(format!("requested by {author}")))
+ .color(SUCCESS)
+ })
+ })
+ .await?,
+ )
+ };
+
+ if let Ok(Some(v)) = from_attachments(&m.attachments).await {
+ println!("sent {}", v.tags.get("name").unwrap());
+ return Ok(ControlFlow::Break(send(v).await?));
+ }
+ if let Ok(v) = from_msg(&m.content) {
+ println!("sent {}", v.tags.get("name").unwrap());
+ return Ok(ControlFlow::Break(send(v).await?));
+ }
+ Ok(ControlFlow::Continue(()))
+}
+
+pub fn to_png(s: &Schematic) -> Vec<u8> {
+ super::png(s.render())
+}
+
+fn from_msg(msg: &str) -> Result<Schematic> {
+ let schem_text = RE
+ .captures(msg)
+ .ok_or(anyhow!("couldnt find schematic"))?
+ .get(3)
+ .unwrap()
+ .as_str();
+ Ok(Schematic::deserialize_base64(schem_text)?)
+}
diff --git a/src/bot/usage.md b/src/bot/usage.md
new file mode 100644
index 0000000..51b55aa
--- /dev/null
+++ b/src/bot/usage.md
@@ -0,0 +1,9 @@
+## usage <:wrench:1174277587493715979>
+
+upload a file, with a msch extension (eg `24tpi_imp.msch`) and a schematic preview will be generated.
+you may instead upload a message containing a base64 encoded schematic.
+
+commands:
+- `eval`: executes mlog. see `/help eval` for more info.
+
+bugs to be reported [here](<https://github.com/bend-n/mindus/issues/new>), or ping <@696196765564534825>. \ No newline at end of file
diff --git a/src/conv.rs b/src/conv.rs
new file mode 100644
index 0000000..c5902f1
--- /dev/null
+++ b/src/conv.rs
@@ -0,0 +1,285 @@
+use mindus::fluid::Type as Fluid;
+use mindus::item::Type as Item;
+
+static E2E: phf::Map<char, &str> = phf::phf_map! {
+ '' => "<:launch_pad:1165059549477220382>",
+ '' => "<:surge_conveyor:1165056614835945542>",
+ '' => "<:pyratite_mixer:1164832608002256906>",
+ '' => "<:poly:1165060238341316720>",
+ '' => "<:vault:1165057825110761583>",
+ '' => "<:copper_wall_large:1164868430726430790>",
+ '' => "<:segment:1164869661591089163>",
+ '' => "<:ripple:1164869672458530816>",
+ '' => "<:hail:1164869685133717564>",
+ '' => "<:force_projector:1164868932440698891>",
+ '' => "<:distributor:1165056571445874798>",
+ '' => "<:message:1165059277409484820>",
+ '' => "<:naval_factory:1164846856094875738>",
+ '' => "<:liquid_source:1165056998862237857>",
+ '' => "<:impact_reactor:1165057397711179846>",
+ '' => "<:illuminator:1165057394418655311>",
+ '' => "<:melter:1164832622455824395>",
+ '' => "<:item_source:1165056586012700793>",
+ '' => "<:logic_processor:1165059269356433459>",
+ '' => "<:payload_source:1165055051648209008>",
+ '' => "<:phase_conduit:1165057015228407899>",
+ '' => "<:disassembler:1164832634598346813>",
+ '' => "<:minke:1165060225489981440>",
+ '' => "<:titanium_wall:1164868373335773184>",
+ '' => "<:plastanium_wall:1164868410379874404>",
+ '' => "<:scrap_wall_gigantic:1164868400410005545>",
+ '' => "<:bridge_conveyor:1165056566337220678>",
+ '' => "<:payload_loader:1165055042408165376>",
+ '' => "<:container:1165057808954310667>",
+ '' => "<:zenith:1165060268607418440>",
+ '' => "<:hyper_processor:1165059260837806110>",
+ '' => "<:phase_weaver:1164832617389113374>",
+ '' => "<:cyerce:1165060197996310618>",
+ '' => "<:world_cell:1165059286414659657>",
+ '' => "<:vela:1165060264958382081>",
+ '' => "<:liquid_container:1165056989135655034>",
+ '' => "<:scatter:1164869667295346732>",
+ '' => "<:liquid_void:1165057004889444402>",
+ '' => "<:payload_router:1165055049630748672>",
+ '' => "<:quad:1165060243500322967>",
+ '' => "<:memory_cell:1165059275572387921>",
+ '' => "<:salvo:1164869669224722432>",
+ '' => "<:liquid_router:1165056995783614574>",
+ '' => "<:wave:1164869646873280562>",
+ '' => "<:overdrive_dome:1164868924186316940>",
+ '' => "<:payload_void:1165055058988240906>",
+ '' => "<:meltdown:1164869678598979655>",
+ '' => "<:scrap_wall_huge:1164868397377527849>",
+ '' => "<:core_nucleus:1165057814801170583>",
+ '' => "<:tsunami:1164869649125605396>",
+ '' => "<:swarmer:1164869653357670480>",
+ '' => "<:cryofluid_mixer:1164832639807655988>",
+ '' => "<:oil_extractor:1165059446301536317>",
+ '' => "<:plated_conduit:1165057017388482660>",
+ '' => "<:pulverizer:1164832611500310548>",
+ '' => "<:rotary_pump:1165057025089228891>",
+ '' => "<:surge_wall:1164868390024921148>",
+ '' => "<:duct:1165056574872633354>",
+ '' => "<:micro_processor:1165059281087889479>",
+ '' => "<:nova:1165060232070828062>",
+ '' => "<:water_extractor:1165059449917018143>",
+ '' => "<:interplanetary_accelerator:1165059547526860950>",
+ '' => "<:fortress:1165060214580580352>",
+ '' => "<:mega:1165060222956621847>",
+ '' => "<:inverted_sorter:1165056577020121190>",
+ '' => "<:air_factory:1164846858871513148>",
+ '' => "<:rtg_generator:1165057406506651708>",
+ '' => "<:thruster:1164868368235507754>",
+ '' => "<:ground_factory:1164846860800892938>",
+ '' => "<:copper_wall:1164868434006392842>",
+ '' => "<:junction:1165056592169926677>",
+ '' => "<:payload_conveyor:1165055040411668500>",
+ '' => "<:multiplicative_reconstructor:1164846850013134920>",
+ '' => "<:pulsar:1165060241394765834>",
+ '' => "<:phase_conveyor:1165056600520802305>",
+ '' => "<:conduit:1165056982974210179>",
+ '' => "<:surge_wall_large:1164868386929512509>",
+ '' => "<:tetrative_reconstructor:1164846844053028945>",
+ '' => "<:bryde:1165060187229519963>",
+ '' => "<:unloader:1165057822791307344>",
+ '' => "<:armored_conveyor:1165056561492803644>",
+ '' => "<:reign:1165060249892433940>",
+ '' => "<:toxopid:1165060263368736920>",
+ '' => "<:scepter:1165060256276164668>",
+ '' => "<:arkyid:1165060180455739535>",
+ '' => "<:canvas:1165059258124087356>",
+ '' => "<:core_shard:1165057818148225064>",
+ '' => "<:item_void:1165056589275865168>",
+ '' => "<:corvus:1165060189876125806>",
+ '' => "<:combustion_generator:1165057385799352321>",
+ '' => "<:power_node_large:1165057403176358018>",
+ '' => "<:plastanium_compressor:1164832614096576555>",
+ '' => "<:battery:1165057379935727756>",
+ '' => "<:silicon_smelter:1164832599328444447>",
+ '' => "<:crawler:1165060193940422786>",
+ '' => "<:antumbra:1165060178392129698>",
+ '' => "<:scorch:1164869663663071282>",
+ '' => "<:mend_projector:1164868930616180746>",
+ '' => "<:logic_display:1165059267267674224>",
+ '' => "<:router:1165056609395949638>",
+ '' => "<:liquid_junction:1165056991853559868>",
+ '' => "<:dagger:1165060204858183690>",
+ '' => "<:cyclone:1164869703437668392>",
+ '' => "<:differential_generator:1165057389242896395>",
+ '' => "<:payload_unloader:1165055055473410048>",
+ '' => "<:mono:1165060228618928178>",
+ '' => "<:world_message:1165059289648480297>",
+ '' => "<:plastanium_conveyor:1165056604174045277>",
+ '' => "<:conveyor:1165056569621369013>",
+ '' => "<:foreshadow:1164869696064073760>",
+ '' => "<:thermal_generator:1165057421899726968>",
+ '' => "<:mender:1164868927264915466>",
+ '' => "<:fuse:1164869692591198208>",
+ '' => "<:overdrive_projector:1164868922135289996>",
+ '' => "<:switch:1165059283331862620>",
+ '' => "<:battery_large:1165057382066434149>",
+ '' => "<:graphite_press:1164832630643105853>",
+ '' => "<:memory_bank:1165059272426668102>",
+ '' => "<:incinerator:1164832628642431037>",
+ '' => "<:oct:1165060234310598788>",
+ '' => "<:solar_panel:1165057408616366101>",
+ '' => "<:armored_duct:1165056563300544523>",
+ '' => "<:arc:1164869705882943580>",
+ '' => "<:retusa:1165060254183206942>",
+ '' => "<:quasar:1165060246646046740>",
+ '' => "<:thorium_wall:1164868384018665552>",
+ '' => "<:overflow_gate:1165056597467332678>",
+ '' => "<:power_node:1165057399678308383>",
+ '' => "<:blast_drill:1165059437363474504>",
+ '' => "<:kiln:1164832625547018251>",
+ '' => "<:mass_driver:1165056595466649620>",
+ '' => "<:separator:1164832606160961606>",
+ '' => "<:liquid_tank:1165057003027181649>",
+ '' => "<:mechanical_drill:1165059443264864307>",
+ '' => "<:core_foundation:1165057811387011203>",
+ '' => "<:impulse_pump:1165056986040250448>",
+ '' => "<:titanium_wall_large:1164868370177466388>",
+ '' => "<:sei:1165060259719680160>",
+ '' => "<:atrax:1165060183593074710>",
+ '' => "<:gamma:1165060216719683664>",
+ '' => "<:shield_projector:1164868919903928330>",
+ '' => "<:exponential_reconstructor:1164846847148445716>",
+ '' => "<:mechanical_pump:1165057009620635749>",
+ '' => "<:scrap_wall:1164868403593482281>",
+ '' => "<:horizon:1165060220070932551>",
+ '' => "<:payload_mass_driver:1165055046216585226>",
+ '' => "<:surge_tower:1165057419894853725>",
+ '' => "<:phase_wall_large:1164868414100213760>",
+ '' => "<:door_large:1164868422555926538>",
+ '' => "<:bridge_conduit:1165056979702657024>",
+ '' => "<:titanium_conveyor:1165056617809715210>",
+ '' => "<:sorter:1165056611480502322>",
+ '' => "<:thorium_reactor:1165057424915431474>",
+ '' => "<:cultivator:1164832636452216922>",
+ '' => "<:phase_wall:1164868417803796490>",
+ '' => "<:coal_centrifuge:1164832643246989333>",
+ '' => "<:thorium_wall_large:1164868375353249793>",
+ '' => "<:flare:1165060210944127067>",
+ '' => "<:multi_press:1164832620522242068>",
+ '' => "<:lancer:1164869681472094219>",
+ '' => "<:world_processor:1165059291473006612>",
+ '' => "<:duo:1164869699817967616>",
+ '' => "<:plastanium_wall_large:1164868405661278229>",
+ '' => "<:diode:1165057391172272188>",
+ '' => "<:underflow_gate:1165056619873320981>",
+ '' => "<:pneumatic_drill:1165059448058953728>",
+ '' => "<:pulse_conduit:1165057021205303336>",
+ '' => "<:eclipse:1165060207517372456>",
+ '' => "<:steam_generator:1165057415658614795>",
+ '' => "<:laser_drill:1165059440077189140>",
+ '' => "<:blast_mixer:1164832645126041600>",
+ '' => "<:door:1164868425294823524>",
+ '' => "<:parallax:1164869674568261683>",
+ '' => "<:scrap_wall_large:1164868391950106704>",
+ '' => "<:spectre:1164869658365673512>",
+ '' => "<:surge_smelter:1164832648426950706>",
+ '' => "<:solar_panel_large:1165057412126998649>",
+ '' => "<:silicon_crucible:1164832602696462346>",
+ '' => "<:large_logic_display:1165059264230981702>",
+ '' => "<:spore_press:1164832597411647508>",
+ '' => "<:additive_reconstructor:1164846854006120551>",
+ '' => item(Item::Tungsten),
+ '' => item(Item::Titanium),
+ '' => item(Item::Thorium),
+ '' => item(Item::SurgeAlloy),
+ '' => item(Item::SporePod),
+ '' => item(Item::Silicon),
+ '' => item(Item::Scrap),
+ '' => item(Item::Sand),
+ '' => item(Item::Pyratite),
+ '' => item(Item::Plastanium),
+ '' => item(Item::PhaseFabric),
+ '' => item(Item::Metaglass),
+ '' => item(Item::Lead),
+ '' => item(Item::Graphite),
+ '' => item(Item::FissileMatter),
+ '' => item(Item::DormantCyst),
+ '' => item(Item::Copper),
+ '' => item(Item::Coal),
+ '' => item(Item::Carbide),
+ '' => item(Item::BlastCompound),
+ '' => item(Item::Beryllium),
+ '' => item(Item::Oxide),
+ '' => fluid(Fluid::Water),
+ '' => fluid(Fluid::Slag),
+ '' => fluid(Fluid::Oil),
+ '' => fluid(Fluid::Cryofluid),
+ '' => fluid(Fluid::Neoplasm),
+ '' => fluid(Fluid::Arkycite),
+ '' => fluid(Fluid::Gallium),
+ '' => fluid(Fluid::Ozone),
+ '' => fluid(Fluid::Hydrogen),
+ '' => fluid(Fluid::Nitrogen),
+ '' => fluid(Fluid::Cyanogen),
+};
+
+pub const fn fluid(f: Fluid) -> &'static str {
+ use Fluid::*;
+ match f {
+ Water => "<:water:1144220582204944434>",
+ Slag => "<:slag:1144220603671396352>",
+ Oil => "<:oil:1144220637448118353>",
+ Cryofluid => "<:cryofluid:1144220686018154599>",
+ Neoplasm => "<:neoplasm:1144220645794791505>",
+ Arkycite => "<:arkycite:1144220710106038383>",
+ Gallium => "<:gallium:1144220668238516264>",
+ Ozone => "<:ozone:1144220628627497091>",
+ Hydrogen => "<:hydrogen:1144220658746798090>",
+ Nitrogen => "<:nitrogen:1144220641160077363>",
+ Cyanogen => "<:cyanogen:1144220681945489408>",
+ }
+}
+
+/// Returns the emoji of a item
+pub const fn item(i: Item) -> &'static str {
+ use Item::*;
+ match i {
+ Tungsten => "<:tungsten:1144220586382458970>",
+ Titanium => "<:titanium:1144220588978749551>",
+ Thorium => "<:thorium:1144220593068191784>",
+ SurgeAlloy => "<:surgealloy:1144220597484789822>",
+ SporePod => "<:sporepod:1144220601205149777>",
+ Silicon => "<:silicon:1144220607710502922>",
+ Scrap => "<:scrap:1144220611531505704>",
+ Sand => "<:sand:1144220613880315934>",
+ Pyratite => "<:pyratite:1144220617319657572>",
+ Plastanium => "<:plastanium:1144220622403153971>",
+ PhaseFabric => "<:phasefabric:1144220626224156794>",
+ Metaglass => "<:metaglass:1144220649901019206>",
+ Lead => "<:lead:1144220654686699570>",
+ Graphite => "<:graphite:1144220661137551400>",
+ FissileMatter => "<:fissilematter:1144220673670131742>",
+ DormantCyst => "<:dormantcyst:1144220677994446928>",
+ Copper => "<:copper:1144220690216648704>",
+ Coal => "<:coal:1144220692729036800>",
+ Carbide => "<:carbide:1144220696927555584>",
+ BlastCompound => "<:blastcompound:1144220701671305319>",
+ Beryllium => "<:beryllium:1144220705739788288>",
+ Oxide => "<:oxide:1144220632746295316>",
+ }
+}
+
+pub fn replace(s: &str) -> String {
+ let mut o = String::with_capacity(s.len());
+ for ch in s.chars() {
+ if let Some(mtch) = E2E.get(&ch) {
+ o.push_str(mtch)
+ } else {
+ o.push(ch);
+ }
+ }
+ o
+}
+
+#[test]
+fn convrt() {
+ assert_eq!(
+ replace("the  will output many /s"),
+ "the <:spore_press:1164832597411647508> will output many <:sporepod:1144220601205149777>/s"
+ );
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..fcdcd0e
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,9 @@
+#![feature(lazy_cell, let_chains)]
+#[macro_use]
+mod bot;
+mod conv;
+
+#[tokio::main(flavor = "current_thread")]
+async fn main() {
+ bot::Bot::spawn().await;
+}