]> Humopery - waterslager.git/commitdiff
Initial commit
authorfozzie <fozzie@humopery.space>
Fri, 18 Jul 2025 05:03:44 +0000 (00:03 -0500)
committerfozzie <fozzie@humopery.space>
Fri, 18 Jul 2025 05:03:44 +0000 (00:03 -0500)
13 files changed:
.env [new file with mode: 0644]
.gitignore [new file with mode: 0644]
Cargo.lock [new file with mode: 0644]
Cargo.toml [new file with mode: 0644]
README.md [new file with mode: 0644]
src/handler.rs [new file with mode: 0644]
src/main.rs [new file with mode: 0644]
src/verify.rs [new file with mode: 0644]
templates/base.html [new file with mode: 0644]
templates/showcheckform.html [new file with mode: 0644]
trust/k.yaml [new file with mode: 0644]
trust/s.yaml [new file with mode: 0644]
trust/w.yaml [new file with mode: 0644]

diff --git a/.env b/.env
new file mode 100644 (file)
index 0000000..1237571
--- /dev/null
+++ b/.env
@@ -0,0 +1,2 @@
+BIND_HOST=127.0.0.1
+BIND_PORT=3000
diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..ea8c4bf
--- /dev/null
@@ -0,0 +1 @@
+/target
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644 (file)
index 0000000..a19fbd9
--- /dev/null
@@ -0,0 +1,2380 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "addr2line"
+version = "0.24.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
+name = "adler2"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "android-tzdata"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.98"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
+
+[[package]]
+name = "argon2"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072"
+dependencies = [
+ "base64ct",
+ "blake2",
+ "cpufeatures",
+ "password-hash",
+]
+
+[[package]]
+name = "ascii-canvas"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6"
+dependencies = [
+ "term",
+]
+
+[[package]]
+name = "askama"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f75363874b771be265f4ffe307ca705ef6f3baa19011c149da8674a87f1b75c4"
+dependencies = [
+ "askama_derive",
+ "itoa",
+ "percent-encoding",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "askama_derive"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "129397200fe83088e8a68407a8e2b1f826cf0086b21ccdb866a722c8bcd3a94f"
+dependencies = [
+ "askama_parser",
+ "basic-toml",
+ "memchr",
+ "proc-macro2",
+ "quote",
+ "rustc-hash 2.1.1",
+ "serde",
+ "serde_derive",
+ "syn",
+]
+
+[[package]]
+name = "askama_parser"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6ab5630b3d5eaf232620167977f95eb51f3432fc76852328774afbd242d4358"
+dependencies = [
+ "memchr",
+ "serde",
+ "serde_derive",
+ "winnow",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
+
+[[package]]
+name = "axum"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5"
+dependencies = [
+ "axum-core",
+ "bytes",
+ "form_urlencoded",
+ "futures-util",
+ "http",
+ "http-body",
+ "http-body-util",
+ "hyper",
+ "hyper-util",
+ "itoa",
+ "matchit",
+ "memchr",
+ "mime",
+ "percent-encoding",
+ "pin-project-lite",
+ "rustversion",
+ "serde",
+ "serde_json",
+ "serde_path_to_error",
+ "serde_urlencoded",
+ "sync_wrapper",
+ "tokio",
+ "tower",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "axum-core"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "http",
+ "http-body",
+ "http-body-util",
+ "mime",
+ "pin-project-lite",
+ "rustversion",
+ "sync_wrapper",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "backtrace"
+version = "0.3.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002"
+dependencies = [
+ "addr2line",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
+[[package]]
+name = "base64ct"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba"
+
+[[package]]
+name = "basic-toml"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "bindgen"
+version = "0.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f"
+dependencies = [
+ "bitflags",
+ "cexpr",
+ "clang-sys",
+ "itertools 0.13.0",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "rustc-hash 1.1.0",
+ "shlex",
+ "syn",
+]
+
+[[package]]
+name = "bit-set"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
+dependencies = [
+ "bit-vec",
+]
+
+[[package]]
+name = "bit-vec"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
+
+[[package]]
+name = "bitflags"
+version = "2.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
+
+[[package]]
+name = "blake2"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
+dependencies = [
+ "digest",
+]
+
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array 0.14.7",
+]
+
+[[package]]
+name = "buffered-reader"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db26bf1f092fd5e05b5ab3be2f290915aeb6f3f20c4e9f86ce0f07f336c2412f"
+dependencies = [
+ "bzip2",
+ "flate2",
+ "libc",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
+
+[[package]]
+name = "bytes"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
+
+[[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-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 = "cc"
+version = "1.2.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362"
+dependencies = [
+ "shlex",
+]
+
+[[package]]
+name = "cexpr"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
+
+[[package]]
+name = "chrono"
+version = "0.4.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
+dependencies = [
+ "android-tzdata",
+ "iana-time-zone",
+ "js-sys",
+ "num-traits",
+ "wasm-bindgen",
+ "windows-link",
+]
+
+[[package]]
+name = "clang-sys"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
+dependencies = [
+ "glob",
+ "libc",
+ "libloading",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crc32fast"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "crunchy"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array 0.14.7",
+ "typenum",
+]
+
+[[package]]
+name = "deranged"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
+dependencies = [
+ "powerfmt",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+ "subtle",
+]
+
+[[package]]
+name = "dirs-next"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
+dependencies = [
+ "cfg-if",
+ "dirs-sys-next",
+]
+
+[[package]]
+name = "dirs-sys-next"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
+dependencies = [
+ "libc",
+ "redox_users",
+ "winapi",
+]
+
+[[package]]
+name = "displaydoc"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "dotenvy"
+version = "0.15.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
+
+[[package]]
+name = "dyn-clone"
+version = "1.0.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005"
+
+[[package]]
+name = "either"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+
+[[package]]
+name = "ena"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5"
+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.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
+dependencies = [
+ "libc",
+ "windows-sys 0.60.2",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
+
+[[package]]
+name = "fixedbitset"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
+
+[[package]]
+name = "flate2"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d"
+dependencies = [
+ "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.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "futures"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
+
+[[package]]
+name = "futures-task"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
+
+[[package]]
+name = "futures-util"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
+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 = "generic-array"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8c8444bc9d71b935156cc0ccab7f622180808af7867b1daae6547d773591703"
+dependencies = [
+ "typenum",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "libc",
+ "wasi 0.11.1+wasi-snapshot-preview1",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "wasi 0.14.2+wasi-0.2.4",
+]
+
+[[package]]
+name = "gimli"
+version = "0.31.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
+
+[[package]]
+name = "glob"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
+
+[[package]]
+name = "hashbrown"
+version = "0.15.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
+
+[[package]]
+name = "http"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
+dependencies = [
+ "bytes",
+ "http",
+]
+
+[[package]]
+name = "http-body-util"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
+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 = "httpdate"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
+
+[[package]]
+name = "hyper"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-util",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "smallvec",
+ "tokio",
+]
+
+[[package]]
+name = "hyper-util"
+version = "0.1.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f66d5bd4c6f02bf0542fad85d626775bab9258cf795a4256dcaf3161114d1df"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "http",
+ "http-body",
+ "hyper",
+ "pin-project-lite",
+ "tokio",
+ "tower-service",
+]
+
+[[package]]
+name = "iana-time-zone"
+version = "0.1.63"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "log",
+ "wasm-bindgen",
+ "windows-core",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "icu_collections"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
+dependencies = [
+ "displaydoc",
+ "potential_utf",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locale_core"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
+dependencies = [
+ "displaydoc",
+ "litemap",
+ "tinystr",
+ "writeable",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979"
+dependencies = [
+ "displaydoc",
+ "icu_collections",
+ "icu_normalizer_data",
+ "icu_properties",
+ "icu_provider",
+ "smallvec",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer_data"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
+
+[[package]]
+name = "icu_properties"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b"
+dependencies = [
+ "displaydoc",
+ "icu_collections",
+ "icu_locale_core",
+ "icu_properties_data",
+ "icu_provider",
+ "potential_utf",
+ "zerotrie",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_properties_data"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632"
+
+[[package]]
+name = "icu_provider"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
+dependencies = [
+ "displaydoc",
+ "icu_locale_core",
+ "stable_deref_trait",
+ "tinystr",
+ "writeable",
+ "yoke",
+ "zerofrom",
+ "zerotrie",
+ "zerovec",
+]
+
+[[package]]
+name = "idna"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
+dependencies = [
+ "idna_adapter",
+ "smallvec",
+ "utf8_iter",
+]
+
+[[package]]
+name = "idna_adapter"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
+dependencies = [
+ "icu_normalizer",
+ "icu_properties",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
+dependencies = [
+ "equivalent",
+ "hashbrown",
+]
+
+[[package]]
+name = "io-uring"
+version = "0.7.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "libc",
+]
+
+[[package]]
+name = "itertools"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itertools"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
+
+[[package]]
+name = "js-sys"
+version = "0.3.77"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
+dependencies = [
+ "once_cell",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "lalrpop"
+version = "0.20.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca"
+dependencies = [
+ "ascii-canvas",
+ "bit-set",
+ "ena",
+ "itertools 0.11.0",
+ "lalrpop-util",
+ "petgraph",
+ "regex",
+ "regex-syntax",
+ "string_cache",
+ "term",
+ "tiny-keccak",
+ "unicode-xid",
+ "walkdir",
+]
+
+[[package]]
+name = "lalrpop-util"
+version = "0.20.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553"
+dependencies = [
+ "regex-automata",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.174"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
+
+[[package]]
+name = "libloading"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
+dependencies = [
+ "cfg-if",
+ "windows-targets 0.53.2",
+]
+
+[[package]]
+name = "libredox"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638"
+dependencies = [
+ "bitflags",
+ "libc",
+]
+
+[[package]]
+name = "libyml"
+version = "0.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3302702afa434ffa30847a83305f0a69d6abd74293b6554c18ec85c7ef30c980"
+dependencies = [
+ "anyhow",
+ "version_check",
+]
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
+
+[[package]]
+name = "litemap"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
+
+[[package]]
+name = "lock_api"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
+
+[[package]]
+name = "matchit"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
+
+[[package]]
+name = "memchr"
+version = "2.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
+
+[[package]]
+name = "memsec"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c797b9d6bb23aab2fc369c65f871be49214f5c759af65bde26ffaaa2b646b492"
+
+[[package]]
+name = "mime"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.8.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
+dependencies = [
+ "adler2",
+]
+
+[[package]]
+name = "mio"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
+dependencies = [
+ "libc",
+ "wasi 0.11.1+wasi-snapshot-preview1",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "nettle"
+version = "7.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44e6ff4a94e5d34a1fd5abbd39418074646e2fa51b257198701330f22fcd6936"
+dependencies = [
+ "getrandom 0.2.16",
+ "libc",
+ "nettle-sys",
+ "thiserror 1.0.69",
+ "typenum",
+]
+
+[[package]]
+name = "nettle-sys"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61a3f5406064d310d59b1a219d3c5c9a49caf4047b6496032e3f930876488c34"
+dependencies = [
+ "bindgen",
+ "cc",
+ "libc",
+ "pkg-config",
+ "tempfile",
+ "vcpkg",
+]
+
+[[package]]
+name = "new_debug_unreachable"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
+
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "num-conv"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+
+[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "object"
+version = "0.36.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+
+[[package]]
+name = "parking_lot"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "password-hash"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166"
+dependencies = [
+ "base64ct",
+ "rand_core",
+ "subtle",
+]
+
+[[package]]
+name = "percent-encoding"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
+
+[[package]]
+name = "petgraph"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
+dependencies = [
+ "fixedbitset",
+ "indexmap",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
+dependencies = [
+ "siphasher",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
+
+[[package]]
+name = "potential_utf"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
+dependencies = [
+ "zerovec",
+]
+
+[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
+[[package]]
+name = "precomputed-hash"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+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 = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+
+[[package]]
+name = "redox_syscall"
+version = "0.5.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "redox_users"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
+dependencies = [
+ "getrandom 0.2.16",
+ "libredox",
+ "thiserror 1.0.69",
+]
+
+[[package]]
+name = "regex"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+
+[[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.16",
+ "libc",
+ "untrusted",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"
+
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
+name = "rustc-hash"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
+
+[[package]]
+name = "rustix"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.60.2",
+]
+
+[[package]]
+name = "rustls"
+version = "0.23.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2491382039b29b9b11ff08b76ff6c97cf287671dbb74f0be44bda389fffe9bd1"
+dependencies = [
+ "log",
+ "once_cell",
+ "ring",
+ "rustls-pki-types",
+ "rustls-webpki",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
+dependencies = [
+ "rustls-pki-types",
+]
+
+[[package]]
+name = "rustls-pki-types"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
+dependencies = [
+ "zeroize",
+]
+
+[[package]]
+name = "rustls-webpki"
+version = "0.103.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc"
+dependencies = [
+ "ring",
+ "rustls-pki-types",
+ "untrusted",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
+
+[[package]]
+name = "ryu"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
+
+[[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 = "sequoia-openpgp"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "015e5fc3d023418b9db98ca9a7f3e90b305872eeafe5ca45c5c32b5eb335c1e8"
+dependencies = [
+ "anyhow",
+ "argon2",
+ "base64",
+ "buffered-reader",
+ "bzip2",
+ "chrono",
+ "dyn-clone",
+ "flate2",
+ "getrandom 0.2.16",
+ "idna",
+ "lalrpop",
+ "lalrpop-util",
+ "libc",
+ "memsec",
+ "nettle",
+ "regex",
+ "regex-syntax",
+ "sha1collisiondetection",
+ "thiserror 2.0.12",
+ "xxhash-rust",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.219"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.219"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.140"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
+dependencies = [
+ "itoa",
+ "memchr",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_path_to_error"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a"
+dependencies = [
+ "itoa",
+ "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 = "serde_yml"
+version = "0.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd"
+dependencies = [
+ "indexmap",
+ "itoa",
+ "libyml",
+ "memchr",
+ "ryu",
+ "serde",
+ "version_check",
+]
+
+[[package]]
+name = "sha1collisiondetection"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f606421e4a6012877e893c399822a4ed4b089164c5969424e1b9d1e66e6964b"
+dependencies = [
+ "digest",
+ "generic-array 1.2.0",
+]
+
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
+name = "siphasher"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
+
+[[package]]
+name = "slab"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d"
+
+[[package]]
+name = "smallvec"
+version = "1.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
+
+[[package]]
+name = "socket2"
+version = "0.5.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
+dependencies = [
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
+
+[[package]]
+name = "string_cache"
+version = "0.8.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f"
+dependencies = [
+ "new_debug_unreachable",
+ "parking_lot",
+ "phf_shared",
+ "precomputed-hash",
+]
+
+[[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.104"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "sync_wrapper"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
+
+[[package]]
+name = "synstructure"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
+dependencies = [
+ "fastrand",
+ "getrandom 0.3.3",
+ "once_cell",
+ "rustix",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "term"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
+dependencies = [
+ "dirs-next",
+ "rustversion",
+ "winapi",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
+dependencies = [
+ "thiserror-impl 1.0.69",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
+dependencies = [
+ "thiserror-impl 2.0.12",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "time"
+version = "0.3.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
+dependencies = [
+ "deranged",
+ "num-conv",
+ "powerfmt",
+ "serde",
+ "time-core",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
+
+[[package]]
+name = "tiny-keccak"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
+dependencies = [
+ "crunchy",
+]
+
+[[package]]
+name = "tinystr"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
+dependencies = [
+ "displaydoc",
+ "zerovec",
+]
+
+[[package]]
+name = "tokio"
+version = "1.46.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
+dependencies = [
+ "backtrace",
+ "io-uring",
+ "libc",
+ "mio",
+ "pin-project-lite",
+ "slab",
+ "socket2",
+ "tokio-macros",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tower"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "pin-project-lite",
+ "sync_wrapper",
+ "tokio",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[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.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
+dependencies = [
+ "log",
+ "pin-project-lite",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "typenum"
+version = "1.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
+
+[[package]]
+name = "untrusted"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+
+[[package]]
+name = "ureq"
+version = "3.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f0fde9bc91026e381155f8c67cb354bcd35260b2f4a29bcc84639f762760c39"
+dependencies = [
+ "base64",
+ "flate2",
+ "log",
+ "percent-encoding",
+ "rustls",
+ "rustls-pemfile",
+ "rustls-pki-types",
+ "ureq-proto",
+ "utf-8",
+ "webpki-roots 0.26.11",
+]
+
+[[package]]
+name = "ureq-proto"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59db78ad1923f2b1be62b6da81fe80b173605ca0d57f85da2e005382adf693f7"
+dependencies = [
+ "base64",
+ "http",
+ "httparse",
+ "log",
+]
+
+[[package]]
+name = "utf-8"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
+
+[[package]]
+name = "utf8_iter"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
+
+[[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 = "walkdir"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
+dependencies = [
+ "same-file",
+ "winapi-util",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.1+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
+
+[[package]]
+name = "wasi"
+version = "0.14.2+wasi-0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
+dependencies = [
+ "wit-bindgen-rt",
+]
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "rustversion",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
+dependencies = [
+ "bumpalo",
+ "log",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "waterslager"
+version = "0.1.0"
+dependencies = [
+ "askama",
+ "axum",
+ "dotenvy",
+ "futures",
+ "sequoia-openpgp",
+ "serde",
+ "serde_yml",
+ "time",
+ "tokio",
+ "ureq",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "0.26.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
+dependencies = [
+ "webpki-roots 1.0.1",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8782dd5a41a24eed3a4f40b606249b3e236ca61adf1f25ea4d45c73de122b502"
+dependencies = [
+ "rustls-pki-types",
+]
+
+[[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.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
+dependencies = [
+ "windows-sys 0.59.0",
+]
+
+[[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.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
+dependencies = [
+ "windows-implement",
+ "windows-interface",
+ "windows-link",
+ "windows-result",
+ "windows-strings",
+]
+
+[[package]]
+name = "windows-implement"
+version = "0.60.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "windows-interface"
+version = "0.59.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "windows-link"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
+
+[[package]]
+name = "windows-result"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
+name = "windows-strings"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
+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 0.52.6",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.60.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
+dependencies = [
+ "windows-targets 0.53.2",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
+ "windows_i686_gnullvm 0.52.6",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.53.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
+dependencies = [
+ "windows_aarch64_gnullvm 0.53.0",
+ "windows_aarch64_msvc 0.53.0",
+ "windows_i686_gnu 0.53.0",
+ "windows_i686_gnullvm 0.53.0",
+ "windows_i686_msvc 0.53.0",
+ "windows_x86_64_gnu 0.53.0",
+ "windows_x86_64_gnullvm 0.53.0",
+ "windows_x86_64_msvc 0.53.0",
+]
+
+[[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_gnullvm"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
+
+[[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_gnu"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
+
+[[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_gnullvm"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
+
+[[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_gnu"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
+
+[[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_gnullvm"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
+
+[[package]]
+name = "winnow"
+version = "0.7.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "wit-bindgen-rt"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "writeable"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
+
+[[package]]
+name = "xxhash-rust"
+version = "0.8.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3"
+
+[[package]]
+name = "yoke"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
+dependencies = [
+ "serde",
+ "stable_deref_trait",
+ "yoke-derive",
+ "zerofrom",
+]
+
+[[package]]
+name = "yoke-derive"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "zerofrom"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
+dependencies = [
+ "zerofrom-derive",
+]
+
+[[package]]
+name = "zerofrom-derive"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "zeroize"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
+
+[[package]]
+name = "zerotrie"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
+dependencies = [
+ "displaydoc",
+ "yoke",
+ "zerofrom",
+]
+
+[[package]]
+name = "zerovec"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428"
+dependencies = [
+ "yoke",
+ "zerofrom",
+ "zerovec-derive",
+]
+
+[[package]]
+name = "zerovec-derive"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644 (file)
index 0000000..1c69832
--- /dev/null
@@ -0,0 +1,16 @@
+[package]
+name = "waterslager"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
+askama = "0.14.0"
+axum = "0.8.4"
+dotenvy = "0.15.7"
+futures = "0.3.31"
+sequoia-openpgp = "2.0.0"
+serde = { version = "1.0.219", features = ["derive"] }
+serde_yml = "0.0.12"
+time = "0.3.41"
+tokio = { version = "1.45.0", features = ["macros", "rt-multi-thread"] }
+ureq = "3.0.12"
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..7d2b1f3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,15 @@
+## Overview
+
+waterslager is a small web tool that can be used to verify certain GPG-signed warrant canary files published to the web. Enter a URL into the form, and waterslager will download the signed canary file and verify it against the certificates in its PostgreSQL database.
+
+A waterslager is a type of canary.
+
+## Local development
+
+1. 'cargo run' as normal
+
+2. Open http://localhost:3000
+
+## Adding a trusted signer cert
+
+see the files trust/*.yaml and copy the format. The files are only read once when the application starts, so changing anything in trust/ requires restarting the app.
diff --git a/src/handler.rs b/src/handler.rs
new file mode 100644 (file)
index 0000000..572ce6e
--- /dev/null
@@ -0,0 +1,118 @@
+use std::io::Read;
+
+use askama::Template;
+use axum::extract::State;
+use axum::http::StatusCode;
+use axum::response::{Html,IntoResponse};
+use axum::Form;
+use sequoia_openpgp::parse::stream::{Verifier, VerifierBuilder};
+use sequoia_openpgp::parse::Parse;
+use sequoia_openpgp::policy::StandardPolicy;
+use crate::AppState;
+use crate::CertMap;
+use crate::verify::Helper;
+use serde::Deserialize;
+
+#[derive(Template)]
+#[template(path="showcheckform.html")]
+struct ShowCheckFormTemplate{
+    url: Option<String>,
+    message: Option<String>,
+    key_fingerprint: Option<String>,
+    key_description: Option<String>,
+    error: Option<String>,
+}
+
+pub async fn show_check_form() -> impl IntoResponse {
+    let signed_doc_url = "https://socialistra.org/canary/dl/27/matt.asc";
+
+    Html(ShowCheckFormTemplate{
+       url: Some(signed_doc_url.to_string()),
+       message: None,
+       key_fingerprint: None,
+       key_description: None,
+       error: None,
+    }.render().unwrap())
+}
+
+#[derive(Deserialize)]
+#[derive(Debug)]
+pub struct CheckCanaryFormData{
+    pub checkurl: Option<String>,
+}
+
+type CheckResponse = (StatusCode, Html<std::string::String>);
+
+fn error_response(code: StatusCode, error: String) -> CheckResponse {
+    (code, Html(ShowCheckFormTemplate{
+       url: None,
+       message: None,
+       error: Some(error),
+       key_fingerprint: None,
+       key_description: None,
+    }.render().unwrap()
+    ))
+}
+
+pub async fn check_canary_result(
+    State(state): State<AppState>,
+    Form(form_data): Form<CheckCanaryFormData>,
+) -> CheckResponse {
+
+    let Some(uri) = form_data.checkurl else {
+       return error_response(StatusCode::BAD_REQUEST,
+                             "URI missing from form data".to_string());
+    };
+    match ureq::get(uri.clone()).call() {
+       Ok(mut resp) =>
+           match resp.body_mut().read_to_string() {
+               Ok(signed_message) => do_verify(signed_message, state.certs, uri).await,
+               Err(e) =>
+                   error_response(StatusCode::BAD_REQUEST,
+                                  format!("Error decoding signed message to string: {}",e))
+           },
+       Err(e) =>
+           error_response(StatusCode::INTERNAL_SERVER_ERROR,
+                          format!("Error reading message from upstream: {}",e))
+    }
+}
+
+
+fn read_verifier(mut verifier: Verifier<'_,Helper>, url: String) -> CheckResponse {
+    let mut content = Vec::new();
+    match verifier.read_to_end(&mut content) {
+       Ok(_) => decode_message_bytes(content,verifier.into_helper(),url),
+       _ => error_response(StatusCode::BAD_REQUEST,
+                           "Unable to read signed doc".to_string())
+    }
+}
+
+fn decode_message_bytes(content: Vec<u8>, helper: Helper, url: String) -> CheckResponse {
+    match String::from_utf8(content) {
+       Ok(content) => (StatusCode::OK,Html(ShowCheckFormTemplate{
+           url: Some(url),
+           message: Some(content),
+           error: None,
+           key_fingerprint: helper.get_fingerprint(),
+           key_description: helper.get_description(),
+       }.render().unwrap())),
+       _ => error_response(StatusCode::BAD_REQUEST,
+                           "Unable to decode signed doc into UTF-8".to_string())
+    }
+}
+
+async fn do_verify(signed_message: String, certs: CertMap, url: String) -> CheckResponse {
+
+    let policy = &StandardPolicy::new();
+    let verbuilder =
+       VerifierBuilder::from_bytes(&signed_message).unwrap();
+
+    let verifier_result =
+       verbuilder.with_policy(policy,None, Helper::new(certs));
+
+    match verifier_result {
+       Ok(verifier) => read_verifier(verifier,url),
+       Err(err) => error_response(StatusCode::BAD_REQUEST,
+                                  err.to_string())
+    }
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644 (file)
index 0000000..6f949b6
--- /dev/null
@@ -0,0 +1,69 @@
+mod handler;
+mod verify;
+
+use axum::{routing::{get,post}, Router};
+use axum::serve;
+use serde::Deserialize;
+use std::{collections::HashMap, env, fs::{read_dir, File}};
+use std::net::SocketAddr;
+use tokio::net::TcpListener;
+
+#[derive(Clone)]
+struct AppState {
+    certs: CertMap,
+}
+
+pub type CertMap = HashMap<String,(String,String)>;
+
+#[derive(Deserialize)]
+struct CertSpec {
+    fingerprint: String,
+    description: String,
+    certificate: String,
+}
+
+async fn load_certs_from_fs() -> Result<CertMap,Box<dyn std::error::Error>> {
+    let mut map = HashMap::new();
+
+    let trust_files = read_dir("trust").unwrap();
+    for trust_file in trust_files {
+       let f = File::open(trust_file.unwrap().path()).unwrap();
+       let spec: CertSpec = serde_yml::de::from_reader(f).unwrap();
+       map.insert(spec.fingerprint, (spec.description, spec.certificate));
+    }
+
+    Ok(map)
+}
+
+#[tokio::main]
+async fn main() -> Result<(),Box<dyn std::error::Error>> {
+    
+    // Set default config values, then override with .env
+    unsafe {
+       env::set_var("BIND_HOST","127.0.0.1");
+       env::set_var("BIND_PORT","3000");
+    }
+    dotenvy::dotenv_override()?;
+
+    let certs = load_certs_from_fs().await.unwrap();
+
+    let app_state = AppState{
+       certs,
+    };
+
+    let all_routes = Router::new()
+       .route("/", get(handler::show_check_form))
+       .route("/", post(handler::check_canary_result))
+       .with_state(app_state);
+
+    let addr = SocketAddr::new(
+       env::var("BIND_HOST")?.parse()?,
+       env::var("BIND_PORT")?.parse()?);
+    let listener = TcpListener::bind(&addr).await.unwrap();
+    serve(listener, all_routes.into_make_service())
+        .await
+        .unwrap();
+
+    Ok(())
+}
+
diff --git a/src/verify.rs b/src/verify.rs
new file mode 100644 (file)
index 0000000..571e14f
--- /dev/null
@@ -0,0 +1,83 @@
+use sequoia_openpgp::packet::Signature;
+use sequoia_openpgp::parse::stream::{MessageLayer, MessageStructure, VerificationHelper};
+use sequoia_openpgp::parse::Parse;
+use sequoia_openpgp::parse::stream::VerificationError;
+use crate::CertMap;
+use sequoia_openpgp::{self, anyhow, Cert, KeyHandle};
+
+pub struct Helper{
+    cert_map: CertMap,
+    key_fingerprint: Option<String>,
+    key_description: Option<String>,
+}
+impl Helper {
+    pub fn new(cert_map: CertMap) -> Helper {
+       Helper{
+           cert_map,
+           key_fingerprint: None,
+           key_description: None,
+       }
+    }
+
+    pub fn get_fingerprint(&self) -> Option<String> {
+       self.key_fingerprint.clone()
+    }
+    pub fn get_description(&self) -> Option<String> {
+       self.key_description.clone()
+    }
+    fn map_fingerprint(&mut self, sig: &Signature) {
+       if let Some(first_fingerprint) = sig.issuer_fingerprints().next() {
+           if let Some(cert) = self.cert_map.get(&first_fingerprint.to_string()) {
+               self.key_description = Some(cert.0.clone());
+           }
+           self.key_fingerprint = Some(first_fingerprint.to_string());
+       }
+    }
+}
+impl VerificationHelper for Helper {
+    fn get_certs(&mut self, ids: &[KeyHandle]) -> sequoia_openpgp::Result<Vec<Cert>> {
+
+       let mut certs = Vec::new();
+       let known_certs = &self.cert_map;
+       for id in ids {
+
+           match known_certs.get(&id.to_string()) {
+               Some((_description,cert)) =>
+                   certs.push(Cert::from_bytes(&cert).unwrap()),
+               None => return Err(anyhow::anyhow!("signature not known"))
+           }
+       }
+       Ok(certs)
+    }
+
+    fn check(&mut self, structure: MessageStructure) -> sequoia_openpgp::Result<()> {
+
+       let Some(layer) = structure.into_iter().next() else {
+           return Err(anyhow::anyhow!("message had no layers"));
+       };
+
+       let MessageLayer::SignatureGroup { results } = layer else {
+           return Err(anyhow::anyhow!("first message layer wasn't a signature group"));
+       };
+
+       if let Some(result) = results.into_iter().next() {
+           match result {
+               Ok(result) => {
+                   self.map_fingerprint(result.sig);
+                   return Ok(());
+               },
+               // expired keys are okay
+               Err(VerificationError::BadKey { sig, ka: _, error }) => {
+                   if error.to_string() == "The primary key is not live" {
+                       self.map_fingerprint(sig);
+                       return Ok(());
+                   }
+                   return Err(anyhow::anyhow!("signed with bad key"))
+               },
+               Err(_) => { return Err(anyhow::anyhow!("no valid signature found")) },
+           }
+       }
+
+       Err(anyhow::anyhow!("signature group had no results"))
+    }
+}
diff --git a/templates/base.html b/templates/base.html
new file mode 100644 (file)
index 0000000..4169f5a
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+  <head>
+    <style>
+      body { font-family: sans-serif; }
+      input#checkurl { width: 30em; }
+    </style>
+  </head>
+  <body>
+    {% block body %}{% endblock %}
+  </body>
+</html>
diff --git a/templates/showcheckform.html b/templates/showcheckform.html
new file mode 100644 (file)
index 0000000..9c6cacb
--- /dev/null
@@ -0,0 +1,36 @@
+{% extends "base.html" %}
+
+{% block body %}
+<div>URL to check:
+  <form method="POST" action="/">
+{% match url %}
+  {% when Some with (val) %}
+    <input type="text" id="checkurl" name="checkurl" value="{{val}}" />
+  {% when None %}
+    <input type="text" id="checkurl" name="checkurl" />
+  {% endmatch %}
+    <br/>
+    <input type="submit" name="submit" value="Submit"/>
+  </form>
+</div>
+
+{% match message %}
+  {% when Some with (val) %}
+<div>Signed message
+    {%- match key_fingerprint %}
+      {% when Some with (print) %} with print {{print}}
+      {%- else %}{% endmatch %}
+    {%- match key_description %}
+      {% when Some with (desc) %} ({{ desc }})
+      {%- else %}{% endmatch %}:
+  <pre>{{val}}</pre>
+</div>
+  {% when None %}
+  {% match error %}
+    {% when Some with (val) %}
+<p>Error: {{val}}</p>
+    {% when None %}
+  {% endmatch %}
+{% endmatch %}
+
+{% endblock %}
diff --git a/trust/k.yaml b/trust/k.yaml
new file mode 100644 (file)
index 0000000..965988f
--- /dev/null
@@ -0,0 +1,66 @@
+fingerprint: 46FEDD324C803CC0EC426ED41BD4BC6C454F6E37
+description: kvuzet
+certificate: |
+  -----BEGIN PGP PUBLIC KEY BLOCK-----
+  
+  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
+  =ruy0
+  -----END PGP PUBLIC KEY BLOCK-----
diff --git a/trust/s.yaml b/trust/s.yaml
new file mode 100644 (file)
index 0000000..09a1399
--- /dev/null
@@ -0,0 +1,45 @@
+---
+fingerprint: 5F757D255E42C51C7D8CCC7EDE58CC99BCA104CA
+description: s@4d2.org
+certificate: |
+  -----BEGIN PGP PUBLIC KEY BLOCK-----
+  
+  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
+  /p23MRREA9FegSiV8i6tWoDPFuadGvZ6eUD50g==
+  =liay
+  -----END PGP PUBLIC KEY BLOCK-----
diff --git a/trust/w.yaml b/trust/w.yaml
new file mode 100644 (file)
index 0000000..3b17f6d
--- /dev/null
@@ -0,0 +1,67 @@
+---
+fingerprint: 8ED05D2A82E2779F73758BE720018229C42DCC74
+description: whargoul
+certificate: |
+  -----BEGIN PGP PUBLIC KEY BLOCK-----
+  
+  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
+  =bGjD
+  -----END PGP PUBLIC KEY BLOCK-----