commit 5031ee4c9e78066a7c9a2898e5c767e88b10c0c0 parent 4afe02a72eb6b576493eb721bb2069832eed8be4 Author: triesap <triesap@radroots.dev> Date: Tue, 4 Nov 2025 00:27:15 +0000 Add `wasm` crate with modularized `core` and `model` crates, implementing browser-based keystore persistence and WASM SQLite executor. Refactor storage abstraction to support localStorage on web targets, integrate workspace dependency management, and remove legacy modules. Diffstat:
116 files changed, 1485 insertions(+), 11132 deletions(-)
diff --git a/.cargo/config.toml b/.cargo/config.toml @@ -0,0 +1,2 @@ +[target.wasm32-unknown-unknown] +rustflags = ["--cfg=wasm_js"] diff --git a/.gitignore b/.gitignore @@ -34,12 +34,9 @@ yarn-debug.log* yarn-error.log* # local -.tmp* -.backup* -.dev* +.local* .vscode notes*.txt -notes*.md git-diff.txt justfile dev*.py diff --git a/Cargo.lock b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -29,41 +29,14 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] [[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[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" @@ -73,183 +46,16 @@ dependencies = [ ] [[package]] -name = "anyhow" -version = "1.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" - -[[package]] name = "arrayvec" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] -name = "ashpd" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df" -dependencies = [ - "enumflags2", - "futures-channel", - "futures-util", - "rand 0.9.1", - "raw-window-handle", - "serde", - "serde_repr", - "tokio", - "url", - "zbus", -] - -[[package]] -name = "async-broadcast" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" -dependencies = [ - "event-listener", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-channel" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "slab", -] - -[[package]] -name = "async-fs" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" -dependencies = [ - "async-lock", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-io" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" -dependencies = [ - "async-lock", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix 0.38.44", - "slab", - "tracing", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-lock" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" -dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-process" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" -dependencies = [ - "async-channel", - "async-io", - "async-lock", - "async-signal", - "async-task", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "rustix 0.38.44", - "tracing", -] - -[[package]] -name = "async-recursion" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", -] - -[[package]] -name = "async-signal" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if", - "futures-core", - "futures-io", - "rustix 0.38.44", - "signal-hook-registry", - "slab", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - -[[package]] -name = "async-trait" -version = "0.1.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", -] - -[[package]] name = "async-utility" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a349201d80b4aa18d17a34a182bdd7f8ddf845e9e57d2ea130a12e10ef1e3a47" +checksum = "a34a3b57207a7a1007832416c3e4862378c8451b4e8e093e436f48c2d3d2c151" dependencies = [ "futures-util", "gloo-timers", @@ -259,9 +65,9 @@ dependencies = [ [[package]] name = "async-wsocket" -version = "0.10.1" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d50cb541e6d09e119e717c64c46ed33f49be7fa592fa805d56c11d6a7ff093c" +checksum = "9a7d8c7d34a225ba919dd9ba44d4b9106d20142da545e086be8ae21d1897e043" dependencies = [ "async-utility", "futures", @@ -277,51 +83,10 @@ dependencies = [ ] [[package]] -name = "atk" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241b621213072e993be4f6f3a9e4b45f65b7e6faad43001be957184b7bb1824b" -dependencies = [ - "atk-sys", - "glib", - "libc", -] - -[[package]] -name = "atk-sys" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e48b684b0ca77d2bbadeef17424c2ea3c897d44d566a1617e7e8f30614d086" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "atoi" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" -dependencies = [ - "num-traits", -] - -[[package]] name = "atomic-destructor" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d919cb60ba95c87ba42777e9e246c4e8d658057299b437b7512531ce0a09a23" -dependencies = [ - "tracing", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +checksum = "ef49f5882e4b6afaac09ad239a4f8c70a24b8f2b0897edb1f706008efd109cf4" [[package]] name = "autocfg" @@ -341,26 +106,10 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] -name = "base58ck" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c8d66485a3a2ea485c1913c4572ce0256067a5377ac8c75c4960e1cda98605f" -dependencies = [ - "bitcoin-internals 0.3.0", - "bitcoin_hashes 0.14.0", -] - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -390,61 +139,24 @@ dependencies = [ ] [[package]] -name = "bitcoin" -version = "0.32.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6bc65742dea50536e35ad42492b234c27904a27f0abdcbce605015cb4ea026" -dependencies = [ - "base58ck", - "bech32", - "bitcoin-internals 0.3.0", - "bitcoin-io", - "bitcoin-units", - "bitcoin_hashes 0.14.0", - "hex-conservative 0.2.1", - "hex_lit", - "secp256k1", - "serde", -] - -[[package]] name = "bitcoin-internals" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" [[package]] -name = "bitcoin-internals" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2" -dependencies = [ - "serde", -] - -[[package]] name = "bitcoin-io" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf" [[package]] -name = "bitcoin-units" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5285c8bcaa25876d07f37e3d30c303f2609179716e11d688f51e8f1fe70063e2" -dependencies = [ - "bitcoin-internals 0.3.0", - "serde", -] - -[[package]] name = "bitcoin_hashes" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" dependencies = [ - "bitcoin-internals 0.2.0", + "bitcoin-internals", "hex-conservative 0.1.2", ] @@ -461,18 +173,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" -dependencies = [ - "serde", -] [[package]] name = "block-buffer" @@ -493,6008 +196,1574 @@ dependencies = [ ] [[package]] -name = "block2" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" -dependencies = [ - "objc2 0.5.2", -] - -[[package]] -name = "block2" -version = "0.6.1" +name = "bumpalo" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "340d2f0bdb2a43c1d3cd40513185b2bd7def0aa1052f956455114bc98f82dcf2" -dependencies = [ - "objc2 0.6.1", -] +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] -name = "blocking" -version = "1.6.1" +name = "bytes" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" -dependencies = [ - "async-channel", - "async-task", - "futures-io", - "futures-lite", - "piper", -] +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] -name = "brotli" -version = "7.0.0" +name = "cbc" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", + "cipher", ] [[package]] -name = "brotli-decompressor" -version = "4.0.3" +name = "cc" +version = "1.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a334ef7c9e23abf0ce748e8cd309037da93e606ad52eb372e4ce327a0dcfbdfd" +checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a" dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", + "shlex", ] [[package]] -name = "bumpalo" -version = "3.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" - -[[package]] -name = "bytemuck" -version = "1.22.0" +name = "cfg-if" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "byteorder" -version = "1.5.0" +name = "chacha20" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] [[package]] -name = "bytes" -version = "1.10.1" +name = "chacha20poly1305" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ - "serde", + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", ] [[package]] -name = "cairo-rs" -version = "0.18.5" +name = "chrono" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "bitflags 2.9.0", - "cairo-sys-rs", - "glib", - "libc", - "once_cell", - "thiserror 1.0.69", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", ] [[package]] -name = "cairo-sys-rs" -version = "0.18.2" +name = "cipher" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "glib-sys", - "libc", - "system-deps", + "crypto-common", + "inout", + "zeroize", ] [[package]] -name = "camino" -version = "1.1.9" +name = "console_error_panic_hook" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" dependencies = [ - "serde", + "cfg-if", + "wasm-bindgen", ] [[package]] -name = "cargo-platform" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo_metadata" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" -dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", - "thiserror 2.0.12", -] - -[[package]] -name = "cargo_toml" -version = "0.22.1" +name = "core-foundation-sys" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02260d489095346e5cafd04dea8e8cb54d1d74fcd759022a9b72986ebe9a1257" -dependencies = [ - "serde", - "toml", -] +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] -name = "cbc" -version = "0.1.2" +name = "cpufeatures" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ - "cipher", + "libc", ] [[package]] -name = "cc" -version = "1.2.20" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "shlex", + "generic-array", + "rand_core 0.6.4", + "typenum", ] [[package]] -name = "cesu8" -version = "1.1.0" +name = "data-encoding" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] -name = "cfb" -version = "0.7.3" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "byteorder", - "fnv", - "uuid", + "block-buffer", + "crypto-common", + "subtle", ] [[package]] -name = "cfg-expr" -version = "0.15.8" +name = "displaydoc" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ - "smallvec", - "target-lexicon", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" +name = "either" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] -name = "chacha20" -version = "0.9.1" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "chacha20poly1305" -version = "0.10.1" +name = "form_urlencoded" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ - "aead", - "chacha20", - "cipher", - "poly1305", - "zeroize", + "percent-encoding", ] [[package]] -name = "chrono" -version = "0.4.40" +name = "futures" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "serde", - "wasm-bindgen", - "windows-link", + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] -name = "cipher" -version = "0.4.4" +name = "futures-channel" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ - "crypto-common", - "inout", - "zeroize", + "futures-core", + "futures-sink", ] [[package]] -name = "combine" -version = "4.6.7" +name = "futures-core" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "memchr", -] +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] -name = "concurrent-queue" -version = "2.5.0" +name = "futures-io" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] -name = "const-oid" -version = "0.9.6" +name = "futures-sink" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] -name = "convert_case" -version = "0.4.0" +name = "futures-task" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] -name = "cookie" -version = "0.18.1" +name = "futures-util" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ - "percent-encoding", - "time", - "version_check", + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", ] [[package]] -name = "cookie_store" -version = "0.21.1" +name = "generic-array" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ - "cookie", - "document-features", - "idna", - "log", - "publicsuffix", - "serde", - "serde_derive", - "serde_json", - "time", - "url", + "typenum", + "version_check", ] [[package]] -name = "core-foundation" -version = "0.9.4" +name = "getrandom" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ - "core-foundation-sys", + "cfg-if", + "js-sys", "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] -name = "core-foundation" -version = "0.10.0" +name = "getrandom" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ - "core-foundation-sys", + "cfg-if", "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] -name = "core-foundation-sys" -version = "0.8.7" +name = "gimli" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] -name = "core-graphics" -version = "0.24.0" +name = "gloo-timers" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" dependencies = [ - "bitflags 2.9.0", - "core-foundation 0.10.0", - "core-graphics-types", - "foreign-types", - "libc", + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "core-graphics-types" -version = "0.2.0" +name = "hex-conservative" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" + +[[package]] +name = "hex-conservative" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" +checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" dependencies = [ - "bitflags 2.9.0", - "core-foundation 0.10.0", - "libc", + "arrayvec", ] [[package]] -name = "cpufeatures" -version = "0.2.17" +name = "hmac" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "libc", + "digest", ] [[package]] -name = "crc" -version = "3.2.1" +name = "http" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ - "crc-catalog", + "bytes", + "fnv", + "itoa", ] [[package]] -name = "crc-catalog" -version = "2.4.0" +name = "httparse" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] -name = "crc32fast" -version = "1.4.2" +name = "iana-time-zone" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ - "cfg-if", + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", ] [[package]] -name = "crossbeam-channel" -version = "0.5.15" +name = "iana-time-zone-haiku" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "crossbeam-utils", + "cc", ] [[package]] -name = "crossbeam-queue" -version = "0.3.12" +name = "icu_collections" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ - "crossbeam-utils", + "displaydoc", + "yoke", + "zerofrom", + "zerovec", ] [[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crypto-common" -version = "0.1.6" +name = "icu_locid" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ - "generic-array", - "rand_core 0.6.4", - "typenum", + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", ] [[package]] -name = "cssparser" -version = "0.27.2" +name = "icu_locid_transform" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" dependencies = [ - "cssparser-macros", - "dtoa-short", - "itoa 0.4.8", - "matches", - "phf 0.8.0", - "proc-macro2", - "quote", - "smallvec", - "syn 1.0.109", + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", ] [[package]] -name = "cssparser-macros" -version = "0.6.1" +name = "icu_locid_transform_data" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" -dependencies = [ - "quote", - "syn 2.0.101", -] +checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" [[package]] -name = "ctor" -version = "0.2.9" +name = "icu_normalizer" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" dependencies = [ - "quote", - "syn 2.0.101", + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", ] [[package]] -name = "darling" -version = "0.20.11" +name = "icu_normalizer_data" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" -dependencies = [ - "darling_core", - "darling_macro", -] +checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" [[package]] -name = "darling_core" -version = "0.20.11" +name = "icu_properties" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.101", + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", ] [[package]] -name = "darling_macro" -version = "0.20.11" +name = "icu_properties_data" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.101", -] +checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" [[package]] -name = "data-encoding" -version = "2.9.0" +name = "icu_provider" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] [[package]] -name = "data-url" -version = "0.3.1" +name = "icu_provider_macros" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "der" -version = "0.7.10" +name = "idna" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", + "idna_adapter", + "smallvec", + "utf8_iter", ] [[package]] -name = "deranged" -version = "0.4.0" +name = "idna_adapter" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ - "powerfmt", - "serde", + "icu_normalizer", + "icu_properties", ] [[package]] -name = "derive_more" -version = "0.99.20" +name = "inout" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.101", + "block-padding", + "generic-array", ] [[package]] -name = "digest" -version = "0.10.7" +name = "instant" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", - "subtle", + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", ] [[package]] -name = "dirs" -version = "6.0.0" +name = "itoa" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" -dependencies = [ - "dirs-sys", -] +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] -name = "dirs-sys" -version = "0.5.0" +name = "js-sys" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.59.0", + "once_cell", + "wasm-bindgen", ] [[package]] -name = "dispatch" -version = "0.2.0" +name = "libc" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] -name = "dispatch2" -version = "0.2.0" +name = "litemap" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a0d569e003ff27784e0e14e4a594048698e0c0f0b66cabcb51511be55a7caa0" -dependencies = [ - "bitflags 2.9.0", - "block2 0.6.1", - "libc", - "objc2 0.6.1", -] +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" [[package]] -name = "dispatch2" -version = "0.3.0" +name = "log" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" -dependencies = [ - "bitflags 2.9.0", - "objc2 0.6.1", -] +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] -name = "displaydoc" -version = "0.2.5" +name = "lru" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", -] +checksum = "96051b46fc183dc9cd4a223960ef37b9af631b55191852a8274bfef064cda20f" [[package]] -name = "dlopen2" -version = "0.7.0" +name = "memchr" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1297103d2bbaea85724fcee6294c2d50b1081f9ad47d0f6f6f61eda65315a6" -dependencies = [ - "dlopen2_derive", - "libc", - "once_cell", - "winapi", -] +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] -name = "dlopen2_derive" -version = "0.4.0" +name = "miniz_oxide" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", + "adler2", ] [[package]] -name = "document-features" -version = "0.2.11" +name = "mio" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "litrs", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys", ] [[package]] -name = "dotenvy" -version = "0.15.7" +name = "negentropy" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +checksum = "f0efe882e02d206d8d279c20eb40e03baf7cb5136a1476dc084a324fbc3ec42d" [[package]] -name = "dpi" -version = "0.1.1" +name = "nostr" +version = "0.43.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" +checksum = "62a97d745f1bd8d5e05a978632bbb87b0614567d5142906fe7c86fb2440faac6" dependencies = [ + "base64", + "bech32", + "bip39", + "bitcoin_hashes 0.14.0", + "cbc", + "chacha20", + "chacha20poly1305", + "getrandom 0.2.16", + "instant", + "scrypt", + "secp256k1", "serde", + "serde_json", + "unicode-normalization", + "url", ] [[package]] -name = "dtoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" - -[[package]] -name = "dtoa-short" -version = "0.3.5" +name = "nostr-database" +version = "0.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +checksum = "b1c75a8c2175d2785ba73cfddef21d1e30da5fbbdf158569b6808ba44973a15b" dependencies = [ - "dtoa", + "lru", + "nostr", + "tokio", ] [[package]] -name = "dunce" -version = "1.0.5" +name = "nostr-relay-pool" +version = "0.43.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +checksum = "2b2f43b70d13dfc50508a13cd902e11f4625312b2ce0e4b7c4c2283fd04001bd" +dependencies = [ + "async-utility", + "async-wsocket", + "atomic-destructor", + "lru", + "negentropy", + "nostr", + "nostr-database", + "tokio", + "tracing", +] [[package]] -name = "dyn-clone" -version = "1.0.19" +name = "nostr-sdk" +version = "0.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" +checksum = "599f8963d6a1522a13b1a2b0ea6e168acfc367706606f1d33fa595e91fa22db0" +dependencies = [ + "async-utility", + "nostr", + "nostr-database", + "nostr-relay-pool", + "tokio", +] [[package]] -name = "either" -version = "1.15.0" +name = "num-traits" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ - "serde", + "autocfg", ] [[package]] -name = "embed-resource" -version = "3.0.2" +name = "object" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fbc6e0d8e0c03a655b53ca813f0463d2c956bc4db8138dbc89f120b066551e3" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ - "cc", "memchr", - "rustc_version", - "toml", - "vswhom", - "winreg", ] [[package]] -name = "embed_plist" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" - -[[package]] -name = "encoding_rs" -version = "0.8.35" +name = "once_cell" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "endi" -version = "1.1.0" +name = "opaque-debug" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] -name = "enumflags2" -version = "0.7.11" +name = "password-hash" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba2f4b465f5318854c6f8dd686ede6c0a9dc67d4b1ac241cf0eb51521a309147" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ - "enumflags2_derive", - "serde", + "base64ct", + "rand_core 0.6.4", + "subtle", ] [[package]] -name = "enumflags2_derive" -version = "0.7.11" +name = "pbkdf2" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4caf64a58d7a6d65ab00639b046ff54399a39f5f2554728895ace4b297cd79" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", + "digest", + "hmac", ] [[package]] -name = "equivalent" -version = "1.0.2" +name = "percent-encoding" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] -name = "erased-serde" -version = "0.4.6" +name = "pin-project-lite" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" -dependencies = [ - "serde", - "typeid", -] +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] -name = "errno" -version = "0.3.11" +name = "pin-utils" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "etcetera" +name = "poly1305" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ - "cfg-if", - "home", - "windows-sys 0.48.0", + "cpufeatures", + "opaque-debug", + "universal-hash", ] [[package]] -name = "event-listener" -version = "5.4.0" +name = "ppv-lite86" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", + "zerocopy", ] [[package]] -name = "event-listener-strategy" -version = "0.5.4" +name = "proc-macro2" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ - "event-listener", - "pin-project-lite", + "unicode-ident", ] [[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "fdeflate" -version = "0.3.7" +name = "quote" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ - "simd-adler32", + "proc-macro2", ] [[package]] -name = "field-offset" -version = "0.3.6" +name = "r-efi" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" -dependencies = [ - "memoffset", - "rustc_version", -] +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" [[package]] -name = "flate2" -version = "1.1.1" +name = "rand" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "crc32fast", - "miniz_oxide", + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", ] [[package]] -name = "flume" -version = "0.11.1" +name = "rand" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ - "futures-core", - "futures-sink", - "spin", + "rand_chacha 0.9.0", + "rand_core 0.9.3", ] [[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "foreign-types" -version = "0.5.0" +name = "rand_chacha" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ - "foreign-types-macros", - "foreign-types-shared", + "ppv-lite86", + "rand_core 0.6.4", ] [[package]] -name = "foreign-types-macros" -version = "0.2.3" +name = "rand_chacha" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] -name = "foreign-types-shared" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" +name = "rand_core" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "percent-encoding", + "getrandom 0.2.16", ] [[package]] -name = "futf" -version = "0.1.5" +name = "rand_core" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "mac", - "new_debug_unreachable", + "getrandom 0.3.2", ] [[package]] -name = "futures" -version = "0.3.31" +name = "regex" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", ] [[package]] -name = "futures-channel" -version = "0.3.31" +name = "regex-automata" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ - "futures-core", - "futures-sink", + "aho-corasick", + "memchr", + "regex-syntax", ] [[package]] -name = "futures-core" -version = "0.3.31" +name = "regex-syntax" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] -name = "futures-executor" -version = "0.3.31" +name = "ring" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ - "futures-core", - "futures-task", - "futures-util", + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys", ] [[package]] -name = "futures-intrusive" -version = "0.5.0" +name = "rustc-demangle" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" -dependencies = [ - "futures-core", - "lock_api", - "parking_lot", -] +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] -name = "futures-io" -version = "0.3.31" +name = "rustls" +version = "0.23.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] [[package]] -name = "futures-lite" -version = "2.6.0" +name = "rustls-pki-types" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" [[package]] -name = "futures-macro" -version = "0.3.31" +name = "rustls-webpki" +version = "0.103.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", + "ring", + "rustls-pki-types", + "untrusted", ] [[package]] -name = "futures-sink" -version = "0.3.31" +name = "rustversion" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" [[package]] -name = "futures-task" -version = "0.3.31" +name = "ryu" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] -name = "futures-util" -version = "0.3.31" +name = "salsa20" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", + "cipher", ] [[package]] -name = "fxhash" -version = "0.2.1" +name = "scrypt" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" dependencies = [ - "byteorder", + "password-hash", + "pbkdf2", + "salsa20", + "sha2", ] [[package]] -name = "gdk" -version = "0.18.2" +name = "secp256k1" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691" +checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" dependencies = [ - "cairo-rs", - "gdk-pixbuf", - "gdk-sys", - "gio", - "glib", - "libc", - "pango", + "rand 0.8.5", + "secp256k1-sys", + "serde", ] [[package]] -name = "gdk-pixbuf" -version = "0.18.5" +name = "secp256k1-sys" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" dependencies = [ - "gdk-pixbuf-sys", - "gio", - "glib", - "libc", - "once_cell", + "cc", ] [[package]] -name = "gdk-pixbuf-sys" -version = "0.18.0" +name = "serde" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "system-deps", + "serde_derive", ] [[package]] -name = "gdk-sys" -version = "0.18.2" +name = "serde-wasm-bindgen" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" dependencies = [ - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "pango-sys", - "pkg-config", - "system-deps", + "js-sys", + "serde", + "wasm-bindgen", ] [[package]] -name = "gdkwayland-sys" -version = "0.18.2" +name = "serde_derive" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ - "gdk-sys", - "glib-sys", - "gobject-sys", - "libc", - "pkg-config", - "system-deps", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "gdkx11" -version = "0.18.2" +name = "serde_json" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3caa00e14351bebbc8183b3c36690327eb77c49abc2268dd4bd36b856db3fbfe" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ - "gdk", - "gdkx11-sys", - "gio", - "glib", - "libc", - "x11", + "itoa", + "memchr", + "ryu", + "serde", ] [[package]] -name = "gdkx11-sys" -version = "0.18.2" +name = "sha1" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e7445fe01ac26f11601db260dd8608fe172514eb63b3b5e261ea6b0f4428d" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "gdk-sys", - "glib-sys", - "libc", - "system-deps", - "x11", + "cfg-if", + "cpufeatures", + "digest", ] [[package]] -name = "generic-array" -version = "0.14.7" +name = "sha2" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ - "typenum", - "version_check", + "cfg-if", + "cpufeatures", + "digest", ] [[package]] -name = "gethostname" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed7131e57abbde63513e0e6636f76668a1ca9798dcae2df4e283cae9ee83859e" -dependencies = [ - "rustix 1.0.5", - "windows-targets 0.52.6", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[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.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi", - "wasi 0.14.2+wasi-0.2.4", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "gio" -version = "0.18.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-util", - "gio-sys", - "glib", - "libc", - "once_cell", - "pin-project-lite", - "smallvec", - "thiserror 1.0.69", -] - -[[package]] -name = "gio-sys" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", - "winapi", -] - -[[package]] -name = "glib" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" -dependencies = [ - "bitflags 2.9.0", - "futures-channel", - "futures-core", - "futures-executor", - "futures-task", - "futures-util", - "gio-sys", - "glib-macros", - "glib-sys", - "gobject-sys", - "libc", - "memchr", - "once_cell", - "smallvec", - "thiserror 1.0.69", -] - -[[package]] -name = "glib-macros" -version = "0.18.5" +name = "shlex" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" -dependencies = [ - "heck 0.4.1", - "proc-macro-crate 2.0.0", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.101", -] +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] -name = "glib-sys" -version = "0.18.1" +name = "slab" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ - "libc", - "system-deps", + "autocfg", ] [[package]] -name = "glob" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" - -[[package]] -name = "gloo-timers" -version = "0.2.6" +name = "smallvec" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" [[package]] -name = "gobject-sys" -version = "0.18.0" +name = "socket2" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" dependencies = [ - "glib-sys", "libc", - "system-deps", + "windows-sys", ] [[package]] -name = "gtk" -version = "0.18.2" +name = "stable_deref_trait" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd56fb197bfc42bd5d2751f4f017d44ff59fbb58140c6b49f9b3b2bdab08506a" -dependencies = [ - "atk", - "cairo-rs", - "field-offset", - "futures-channel", - "gdk", - "gdk-pixbuf", - "gio", - "glib", - "gtk-sys", - "gtk3-macros", - "libc", - "pango", - "pkg-config", -] +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "gtk-sys" -version = "0.18.2" +name = "subtle" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f29a1c21c59553eb7dd40e918be54dccd60c52b049b75119d5d96ce6b624414" -dependencies = [ - "atk-sys", - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gdk-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "pango-sys", - "system-deps", -] +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] -name = "gtk3-macros" -version = "0.18.2" +name = "syn" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ff3c5b21f14f0736fed6dcfc0bfb4225ebf5725f3c0209edeec181e4d73e9d" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.101", -] - -[[package]] -name = "h2" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75249d144030531f8dee69fe9cea04d3edf809a017ae445e2abdff6629e86633" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http", - "indexmap 2.9.0", - "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.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash", -] - -[[package]] -name = "hashlink" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" -dependencies = [ - "hashbrown 0.15.2", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hex-conservative" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" - -[[package]] -name = "hex-conservative" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" -dependencies = [ - "arrayvec", -] - -[[package]] -name = "hex_lit" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" - -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "home" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" -dependencies = [ - "windows-sys 0.59.0", + "unicode-ident", ] [[package]] -name = "html5ever" -version = "0.26.0" +name = "synstructure" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ - "log", - "mac", - "markup5ever", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] -name = "http" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +name = "tangle_core" +version = "0.1.0" dependencies = [ - "bytes", - "fnv", - "itoa 1.0.15", + "base64", + "chrono", + "getrandom 0.2.16", + "nostr-sdk", + "regex", + "serde", + "serde_json", + "thiserror 1.0.69", + "uuid", + "wasm-bindgen", + "web-sys", ] [[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +name = "tangle_model" +version = "0.1.0" dependencies = [ - "bytes", - "http", + "js-sys", + "serde", + "serde-wasm-bindgen", + "serde_json", + "tangle_core", + "thiserror 1.0.69", + "wasm-bindgen", + "wasm-bindgen-futures", ] [[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +name = "tangle_wasm" +version = "0.1.0" dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "http-range" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[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", - "h2", - "http", - "http-body", - "httparse", - "itoa 1.0.15", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" -dependencies = [ - "futures-util", - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", - "webpki-roots", -] - -[[package]] -name = "hyper-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "hyper", - "libc", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", -] - -[[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 = "ico" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc50b891e4acf8fe0e71ef88ec43ad82ee07b3810ad09de10f1d01f072ed4b98" -dependencies = [ - "byteorder", - "png", -] - -[[package]] -name = "icu_collections" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locid" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" - -[[package]] -name = "icu_normalizer" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "utf16_iter", - "utf8_iter", - "write16", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" - -[[package]] -name = "icu_properties" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locid_transform", - "icu_properties_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" - -[[package]] -name = "icu_provider" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_provider_macros", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" -dependencies = [ - "equivalent", - "hashbrown 0.15.2", - "serde", -] - -[[package]] -name = "infer" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" -dependencies = [ - "cfb", -] - -[[package]] -name = "inout" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" -dependencies = [ - "block-padding", - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "is-docker" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" -dependencies = [ - "once_cell", -] - -[[package]] -name = "is-wsl" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" -dependencies = [ - "is-docker", - "once_cell", -] - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "itoa" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - -[[package]] -name = "javascriptcore-rs" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc" -dependencies = [ - "bitflags 1.3.2", - "glib", - "javascriptcore-rs-sys", -] - -[[package]] -name = "javascriptcore-rs-sys" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if", - "combine", - "jni-sys", - "log", - "thiserror 1.0.69", - "walkdir", - "windows-sys 0.45.0", -] - -[[package]] -name = "jni-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" - -[[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 = "json-patch" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08" -dependencies = [ - "jsonptr", - "serde", - "serde_json", - "thiserror 1.0.69", -] - -[[package]] -name = "jsonptr" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "keyboard-types" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" -dependencies = [ - "bitflags 2.9.0", - "serde", - "unicode-segmentation", -] - -[[package]] -name = "kuchikiki" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e4755b7b995046f510a7520c42b2fed58b77bd94d5a87a8eb43d2fd126da8" -dependencies = [ - "cssparser", - "html5ever", - "indexmap 1.9.3", - "matches", - "selectors", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin", -] - -[[package]] -name = "libappindicator" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03589b9607c868cc7ae54c0b2a22c8dc03dd41692d48f2d7df73615c6a95dc0a" -dependencies = [ - "glib", - "gtk", - "gtk-sys", - "libappindicator-sys", - "log", -] - -[[package]] -name = "libappindicator-sys" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" -dependencies = [ - "gtk-sys", - "libloading", - "once_cell", -] - -[[package]] -name = "libc" -version = "0.2.172" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" - -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - -[[package]] -name = "libm" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72" - -[[package]] -name = "libredox" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags 2.9.0", - "libc", -] - -[[package]] -name = "libsqlite3-sys" -version = "0.30.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[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.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" - -[[package]] -name = "litrs" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" - -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" - -[[package]] -name = "lru" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" -dependencies = [ - "hashbrown 0.15.2", -] - -[[package]] -name = "mac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" - -[[package]] -name = "mac-notification-sys" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b95dfb34071d1592b45622bf93e315e3a72d414b6782aca9a015c12bec367ef" -dependencies = [ - "cc", - "objc2 0.6.1", - "objc2-foundation 0.3.1", - "time", -] - -[[package]] -name = "markup5ever" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" -dependencies = [ - "log", - "phf 0.10.1", - "phf_codegen 0.10.0", - "string_cache", - "string_cache_codegen", - "tendril", -] - -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - -[[package]] -name = "md-5" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" -dependencies = [ - "cfg-if", - "digest", -] - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "miniz_oxide" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" -dependencies = [ - "adler2", - "simd-adler32", -] - -[[package]] -name = "mio" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" -dependencies = [ - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", -] - -[[package]] -name = "muda" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de14a9b5d569ca68d7c891d613b390cf5ab4f851c77aaa2f9e435555d3d9492" -dependencies = [ - "crossbeam-channel", - "dpi", - "gtk", - "keyboard-types", - "objc2 0.6.1", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation 0.3.1", - "once_cell", - "png", - "serde", - "thiserror 2.0.12", - "windows-sys 0.59.0", -] - -[[package]] -name = "ndk" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" -dependencies = [ - "bitflags 2.9.0", - "jni-sys", - "log", - "ndk-sys", - "num_enum", - "raw-window-handle", - "thiserror 1.0.69", -] - -[[package]] -name = "ndk-context" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" - -[[package]] -name = "ndk-sys" -version = "0.6.0+11769913" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" -dependencies = [ - "jni-sys", -] - -[[package]] -name = "negentropy" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e664971378a3987224f7a0e10059782035e89899ae403718ee07de85bec42afe" - -[[package]] -name = "negentropy" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a88da9dd148bbcdce323dd6ac47d369b4769d4a3b78c6c52389b9269f77932" - -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - -[[package]] -name = "nix" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" -dependencies = [ - "bitflags 2.9.0", - "cfg-if", - "cfg_aliases", - "libc", - "memoffset", -] - -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - -[[package]] -name = "nostr" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8aad4b767bbed24ac5eb4465bfb83bc1210522eb99d67cf4e547ec2ec7e47786" -dependencies = [ - "async-trait", - "base64 0.22.1", - "bech32", - "bip39", - "bitcoin", - "cbc", - "chacha20", - "chacha20poly1305", - "getrandom 0.2.16", - "instant", - "negentropy 0.3.1", - "negentropy 0.4.3", - "once_cell", - "scrypt", - "serde", - "serde_json", - "unicode-normalization", - "url", -] - -[[package]] -name = "nostr-database" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23696338d51e45cd44e061823847f4b0d1d362eca80d5033facf9c184149f72f" -dependencies = [ - "async-trait", - "lru", - "nostr", - "thiserror 1.0.69", - "tokio", - "tracing", -] - -[[package]] -name = "nostr-relay-pool" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15fcc6e3f0ca54d0fc779009bc5f2684cea9147be3b6aa68a7d301ea590f95f5" -dependencies = [ - "async-utility", - "async-wsocket", - "atomic-destructor", - "negentropy 0.3.1", - "negentropy 0.4.3", - "nostr", - "nostr-database", - "thiserror 1.0.69", - "tokio", - "tokio-stream", - "tracing", -] - -[[package]] -name = "nostr-sdk" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "491221fc89b1aa189a0de640127127d68b4e7c5c1d44371b04d9a6d10694b5af" -dependencies = [ - "async-utility", - "atomic-destructor", - "nostr", - "nostr-database", - "nostr-relay-pool", - "thiserror 1.0.69", - "tokio", - "tracing", -] - -[[package]] -name = "notify-rust" -version = "4.11.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6442248665a5aa2514e794af3b39661a8e73033b1cc5e59899e1276117ee4400" -dependencies = [ - "futures-lite", - "log", - "mac-notification-sys", - "serde", - "tauri-winrt-notification", - "zbus", -] - -[[package]] -name = "num-bigint-dig" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" -dependencies = [ - "byteorder", - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand 0.8.5", - "smallvec", - "zeroize", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "num_enum" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" -dependencies = [ - "proc-macro-crate 3.3.0", - "proc-macro2", - "quote", - "syn 2.0.101", -] - -[[package]] -name = "objc-sys" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" - -[[package]] -name = "objc2" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" -dependencies = [ - "objc-sys", - "objc2-encode", -] - -[[package]] -name = "objc2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88c6597e14493ab2e44ce58f2fdecf095a51f12ca57bec060a11c57332520551" -dependencies = [ - "objc2-encode", - "objc2-exception-helper", -] - -[[package]] -name = "objc2-app-kit" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" -dependencies = [ - "bitflags 2.9.0", - "block2 0.6.1", - "libc", - "objc2 0.6.1", - "objc2-cloud-kit", - "objc2-core-data", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-core-image", - "objc2-foundation 0.3.1", - "objc2-quartz-core 0.3.1", -] - -[[package]] -name = "objc2-cloud-kit" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17614fdcd9b411e6ff1117dfb1d0150f908ba83a7df81b1f118005fe0a8ea15d" -dependencies = [ - "bitflags 2.9.0", - "objc2 0.6.1", - "objc2-foundation 0.3.1", -] - -[[package]] -name = "objc2-core-data" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291fbbf7d29287518e8686417cf7239c74700fd4b607623140a7d4a3c834329d" -dependencies = [ - "bitflags 2.9.0", - "objc2 0.6.1", - "objc2-foundation 0.3.1", -] - -[[package]] -name = "objc2-core-foundation" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" -dependencies = [ - "bitflags 2.9.0", - "dispatch2 0.3.0", - "objc2 0.6.1", -] - -[[package]] -name = "objc2-core-graphics" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" -dependencies = [ - "bitflags 2.9.0", - "dispatch2 0.3.0", - "objc2 0.6.1", - "objc2-core-foundation", - "objc2-io-surface", -] - -[[package]] -name = "objc2-core-image" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b3dc0cc4386b6ccf21c157591b34a7f44c8e75b064f85502901ab2188c007e" -dependencies = [ - "objc2 0.6.1", - "objc2-foundation 0.3.1", -] - -[[package]] -name = "objc2-encode" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" - -[[package]] -name = "objc2-exception-helper" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a" -dependencies = [ - "cc", -] - -[[package]] -name = "objc2-foundation" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" -dependencies = [ - "bitflags 2.9.0", - "block2 0.5.1", - "libc", - "objc2 0.5.2", -] - -[[package]] -name = "objc2-foundation" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" -dependencies = [ - "bitflags 2.9.0", - "block2 0.6.1", - "libc", - "objc2 0.6.1", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-io-surface" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c" -dependencies = [ - "bitflags 2.9.0", - "objc2 0.6.1", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-metal" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" -dependencies = [ - "bitflags 2.9.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-quartz-core" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" -dependencies = [ - "bitflags 2.9.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-metal", -] - -[[package]] -name = "objc2-quartz-core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ffb6a0cd5f182dc964334388560b12a57f7b74b3e2dec5e2722aa2dfb2ccd5" -dependencies = [ - "bitflags 2.9.0", - "objc2 0.6.1", - "objc2-foundation 0.3.1", -] - -[[package]] -name = "objc2-ui-kit" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b1312ad7bc8a0e92adae17aa10f90aae1fb618832f9b993b022b591027daed" -dependencies = [ - "bitflags 2.9.0", - "objc2 0.6.1", - "objc2-core-foundation", - "objc2-foundation 0.3.1", -] - -[[package]] -name = "objc2-web-kit" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91672909de8b1ce1c2252e95bbee8c1649c9ad9d14b9248b3d7b4c47903c47ad" -dependencies = [ - "bitflags 2.9.0", - "block2 0.6.1", - "objc2 0.6.1", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation 0.3.1", -] - -[[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 = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "open" -version = "5.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2483562e62ea94312f3576a7aca397306df7990b8d89033e18766744377ef95" -dependencies = [ - "dunce", - "is-wsl", - "libc", - "pathdiff", -] - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "ordered-stream" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" -dependencies = [ - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "os_info" -version = "3.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a604e53c24761286860eba4e2c8b23a0161526476b1de520139d69cdb85a6b5" -dependencies = [ - "log", - "serde", - "windows-sys 0.52.0", -] - -[[package]] -name = "os_pipe" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "pango" -version = "0.18.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" -dependencies = [ - "gio", - "glib", - "libc", - "once_cell", - "pango-sys", -] - -[[package]] -name = "pango-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -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 0.6.4", - "subtle", -] - -[[package]] -name = "pathdiff" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" - -[[package]] -name = "pbkdf2" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" -dependencies = [ - "digest", - "hmac", -] - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "phf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" -dependencies = [ - "phf_macros 0.8.0", - "phf_shared 0.8.0", - "proc-macro-hack", -] - -[[package]] -name = "phf" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" -dependencies = [ - "phf_shared 0.10.0", -] - -[[package]] -name = "phf" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" -dependencies = [ - "phf_macros 0.11.3", - "phf_shared 0.11.3", -] - -[[package]] -name = "phf_codegen" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" -dependencies = [ - "phf_generator 0.8.0", - "phf_shared 0.8.0", -] - -[[package]] -name = "phf_codegen" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", -] - -[[package]] -name = "phf_generator" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" -dependencies = [ - "phf_shared 0.8.0", - "rand 0.7.3", -] - -[[package]] -name = "phf_generator" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" -dependencies = [ - "phf_shared 0.10.0", - "rand 0.8.5", -] - -[[package]] -name = "phf_generator" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" -dependencies = [ - "phf_shared 0.11.3", - "rand 0.8.5", -] - -[[package]] -name = "phf_macros" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" -dependencies = [ - "phf_generator 0.8.0", - "phf_shared 0.8.0", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "phf_macros" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" -dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", - "proc-macro2", - "quote", - "syn 2.0.101", -] - -[[package]] -name = "phf_shared" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" -dependencies = [ - "siphasher 0.3.11", -] - -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher 0.3.11", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher 1.0.1", -] - -[[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 = "piper" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - -[[package]] -name = "pkcs1" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" -dependencies = [ - "der", - "pkcs8", - "spki", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "plist" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac26e981c03a6e53e0aee43c113e3202f5581d5360dae7bd2c70e800dd0451d" -dependencies = [ - "base64 0.22.1", - "indexmap 2.9.0", - "quick-xml 0.32.0", - "serde", - "time", -] - -[[package]] -name = "png" -version = "0.17.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" -dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - -[[package]] -name = "polling" -version = "3.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" -dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi", - "pin-project-lite", - "rustix 0.38.44", - "tracing", - "windows-sys 0.59.0", -] - -[[package]] -name = "poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - -[[package]] -name = "proc-macro-crate" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" -dependencies = [ - "toml_edit 0.20.7", -] - -[[package]] -name = "proc-macro-crate" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" -dependencies = [ - "toml_edit 0.22.25", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - -[[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 = "psl-types" -version = "2.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" - -[[package]] -name = "publicsuffix" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf" -dependencies = [ - "idna", - "psl-types", -] - -[[package]] -name = "quick-xml" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" -dependencies = [ - "memchr", -] - -[[package]] -name = "quick-xml" -version = "0.37.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" -dependencies = [ - "memchr", -] - -[[package]] -name = "quinn" -version = "0.11.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" -dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash", - "rustls", - "socket2", - "thiserror 2.0.12", - "tokio", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-proto" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcbafbbdbb0f638fe3f35f3c56739f77a8a1d070cb25603226c83339b391472b" -dependencies = [ - "bytes", - "getrandom 0.3.2", - "rand 0.9.1", - "ring", - "rustc-hash", - "rustls", - "rustls-pki-types", - "slab", - "thiserror 2.0.12", - "tinyvec", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-udp" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "541d0f57c6ec747a90738a52741d3221f7960e8ac2f0ff4b1a63680e033b4ab5" -dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.59.0", -] - -[[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.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", - "rand_pcg", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", -] - -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" -dependencies = [ - "getrandom 0.3.2", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_pcg" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "raw-window-handle" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" - -[[package]] -name = "redox_syscall" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" -dependencies = [ - "bitflags 2.9.0", -] - -[[package]] -name = "redox_users" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" -dependencies = [ - "getrandom 0.2.16", - "libredox", - "thiserror 2.0.12", -] - -[[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 = "reqwest" -version = "0.12.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" -dependencies = [ - "base64 0.22.1", - "bytes", - "cookie", - "cookie_store", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-pemfile", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", - "tokio", - "tokio-rustls", - "tokio-util", - "tower", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "webpki-roots", - "windows-registry", -] - -[[package]] -name = "rfd" -version = "0.15.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80c844748fdc82aae252ee4594a89b6e7ebef1063de7951545564cbc4e57075d" -dependencies = [ - "ashpd", - "block2 0.6.1", - "dispatch2 0.2.0", - "glib-sys", - "gobject-sys", - "gtk-sys", - "js-sys", - "log", - "objc2 0.6.1", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation 0.3.1", - "raw-window-handle", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "windows-sys 0.59.0", -] - -[[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 = "rsa" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" -dependencies = [ - "const-oid", - "digest", - "num-bigint-dig", - "num-integer", - "num-traits", - "pkcs1", - "pkcs8", - "rand_core 0.6.4", - "signature", - "spki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.9.0", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustix" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" -dependencies = [ - "bitflags 2.9.0", - "errno", - "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustls" -version = "0.23.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0" -dependencies = [ - "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.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" -dependencies = [ - "web-time", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" - -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "salsa20" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" -dependencies = [ - "cipher", -] - -[[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 = "schemars" -version = "0.8.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" -dependencies = [ - "dyn-clone", - "indexmap 1.9.3", - "schemars_derive", - "serde", - "serde_json", - "url", - "uuid", -] - -[[package]] -name = "schemars_derive" -version = "0.8.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 2.0.101", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "scrypt" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" -dependencies = [ - "password-hash", - "pbkdf2", - "salsa20", - "sha2", -] - -[[package]] -name = "secp256k1" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" -dependencies = [ - "bitcoin_hashes 0.14.0", - "rand 0.8.5", - "secp256k1-sys", - "serde", -] - -[[package]] -name = "secp256k1-sys" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" -dependencies = [ - "cc", -] - -[[package]] -name = "selectors" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" -dependencies = [ - "bitflags 1.3.2", - "cssparser", - "derive_more", - "fxhash", - "log", - "matches", - "phf 0.8.0", - "phf_codegen 0.8.0", - "precomputed-hash", - "servo_arc", - "smallvec", - "thin-slice", -] - -[[package]] -name = "semver" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" -dependencies = [ - "serde", -] - -[[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-untagged" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "299d9c19d7d466db4ab10addd5703e4c615dec2a5a16dbbafe191045e87ee66e" -dependencies = [ - "erased-serde", - "serde", - "typeid", -] - -[[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 2.0.101", -] - -[[package]] -name = "serde_derive_internals" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", -] - -[[package]] -name = "serde_json" -version = "1.0.140" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" -dependencies = [ - "indexmap 2.9.0", - "itoa 1.0.15", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", -] - -[[package]] -name = "serde_spanned" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa 1.0.15", - "ryu", - "serde", -] - -[[package]] -name = "serde_with" -version = "3.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" -dependencies = [ - "base64 0.22.1", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.9.0", - "serde", - "serde_derive", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.101", -] - -[[package]] -name = "serialize-to-javascript" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9823f2d3b6a81d98228151fdeaf848206a7855a7a042bbf9bf870449a66cafb" -dependencies = [ - "serde", - "serde_json", - "serialize-to-javascript-impl", -] - -[[package]] -name = "serialize-to-javascript-impl" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "servo_arc" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" -dependencies = [ - "nodrop", - "stable_deref_trait", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "shared_child" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fa9338aed9a1df411814a5b2252f7cd206c55ae9bf2fa763f8de84603aa60c" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest", - "rand_core 0.6.4", -] - -[[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 = "siphasher" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" - -[[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.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" -dependencies = [ - "serde", -] - -[[package]] -name = "socket2" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "softbuffer" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18051cdd562e792cad055119e0cdb2cfc137e44e3987532e0f9659a77931bb08" -dependencies = [ - "bytemuck", - "cfg_aliases", - "core-graphics", - "foreign-types", - "js-sys", - "log", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-quartz-core 0.2.2", - "raw-window-handle", - "redox_syscall", - "wasm-bindgen", - "web-sys", - "windows-sys 0.59.0", -] - -[[package]] -name = "soup3" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f" -dependencies = [ - "futures-channel", - "gio", - "glib", - "libc", - "soup3-sys", -] - -[[package]] -name = "soup3-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27" -dependencies = [ - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "sqlx" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c3a85280daca669cfd3bcb68a337882a8bc57ec882f72c5d13a430613a738e" -dependencies = [ - "sqlx-core", - "sqlx-macros", - "sqlx-mysql", - "sqlx-postgres", - "sqlx-sqlite", -] - -[[package]] -name = "sqlx-core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f743f2a3cea30a58cd479013f75550e879009e3a02f616f18ca699335aa248c3" -dependencies = [ - "base64 0.22.1", - "bytes", - "crc", - "crossbeam-queue", - "either", - "event-listener", - "futures-core", - "futures-intrusive", - "futures-io", - "futures-util", - "hashbrown 0.15.2", - "hashlink", - "indexmap 2.9.0", - "log", - "memchr", - "once_cell", - "percent-encoding", - "serde", - "serde_json", - "sha2", - "smallvec", - "thiserror 2.0.12", - "tokio", - "tokio-stream", - "tracing", - "url", -] - -[[package]] -name = "sqlx-macros" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4200e0fde19834956d4252347c12a083bdcb237d7a1a1446bffd8768417dce" -dependencies = [ - "proc-macro2", - "quote", - "sqlx-core", - "sqlx-macros-core", - "syn 2.0.101", -] - -[[package]] -name = "sqlx-macros-core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882ceaa29cade31beca7129b6beeb05737f44f82dbe2a9806ecea5a7093d00b7" -dependencies = [ - "dotenvy", - "either", - "heck 0.5.0", - "hex", - "once_cell", - "proc-macro2", - "quote", - "serde", - "serde_json", - "sha2", - "sqlx-core", - "sqlx-mysql", - "sqlx-postgres", - "sqlx-sqlite", - "syn 2.0.101", - "tempfile", - "tokio", - "url", -] - -[[package]] -name = "sqlx-mysql" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0afdd3aa7a629683c2d750c2df343025545087081ab5942593a5288855b1b7a7" -dependencies = [ - "atoi", - "base64 0.22.1", - "bitflags 2.9.0", - "byteorder", - "bytes", - "crc", - "digest", - "dotenvy", - "either", - "futures-channel", - "futures-core", - "futures-io", - "futures-util", - "generic-array", - "hex", - "hkdf", - "hmac", - "itoa 1.0.15", - "log", - "md-5", - "memchr", - "once_cell", - "percent-encoding", - "rand 0.8.5", - "rsa", - "serde", - "sha1", - "sha2", - "smallvec", - "sqlx-core", - "stringprep", - "thiserror 2.0.12", - "tracing", - "whoami", -] - -[[package]] -name = "sqlx-postgres" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0bedbe1bbb5e2615ef347a5e9d8cd7680fb63e77d9dafc0f29be15e53f1ebe6" -dependencies = [ - "atoi", - "base64 0.22.1", - "bitflags 2.9.0", - "byteorder", - "crc", - "dotenvy", - "etcetera", - "futures-channel", - "futures-core", - "futures-util", - "hex", - "hkdf", - "hmac", - "home", - "itoa 1.0.15", - "log", - "md-5", - "memchr", - "once_cell", - "rand 0.8.5", - "serde", - "serde_json", - "sha2", - "smallvec", - "sqlx-core", - "stringprep", - "thiserror 2.0.12", - "tracing", - "whoami", -] - -[[package]] -name = "sqlx-sqlite" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c26083e9a520e8eb87a06b12347679b142dc2ea29e6e409f805644a7a979a5bc" -dependencies = [ - "atoi", - "flume", - "futures-channel", - "futures-core", - "futures-executor", - "futures-intrusive", - "futures-util", - "libsqlite3-sys", - "log", - "percent-encoding", - "serde", - "serde_urlencoded", - "sqlx-core", - "thiserror 2.0.12", - "tracing", - "url", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[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 0.11.3", - "precomputed-hash", - "serde", -] - -[[package]] -name = "string_cache_codegen" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" -dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", - "proc-macro2", - "quote", -] - -[[package]] -name = "stringprep" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" -dependencies = [ - "unicode-bidi", - "unicode-normalization", - "unicode-properties", -] - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "swift-rs" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4057c98e2e852d51fdcfca832aac7b571f6b351ad159f9eda5db1655f8d0c4d7" -dependencies = [ - "base64 0.21.7", - "serde", - "serde_json", -] - -[[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.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" -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" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", -] - -[[package]] -name = "sys-locale" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4" -dependencies = [ - "libc", -] - -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags 2.9.0", - "core-foundation 0.9.4", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "system-deps" -version = "6.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" -dependencies = [ - "cfg-expr", - "heck 0.5.0", - "pkg-config", - "toml", - "version-compare", -] - -[[package]] -name = "tangle" -version = "0.0.1" -dependencies = [ - "serde", - "serde_json", - "sqlx", - "tangle_core", - "tangle_model", - "tauri", - "tauri-build", - "tauri-plugin-dialog", - "tauri-plugin-fs", - "tauri-plugin-geolocation", - "tauri-plugin-http", - "tauri-plugin-notification", - "tauri-plugin-os", - "tauri-plugin-shell", - "tauri-plugin-store", -] - -[[package]] -name = "tangle_core" -version = "0.0.1" -dependencies = [ - "base64 0.22.1", - "chrono", - "nostr-sdk", - "regex", - "serde", - "serde_json", - "thiserror 1.0.69", - "uuid", -] - -[[package]] -name = "tangle_model" -version = "0.0.1" -dependencies = [ - "futures", - "serde", - "serde_json", - "sqlx", - "tangle_core", - "thiserror 1.0.69", -] - -[[package]] -name = "tao" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e59c1f38e657351a2e822eadf40d6a2ad4627b9c25557bc1180ec1b3295ef82" -dependencies = [ - "bitflags 2.9.0", - "core-foundation 0.10.0", - "core-graphics", - "crossbeam-channel", - "dispatch", - "dlopen2", - "dpi", - "gdkwayland-sys", - "gdkx11-sys", - "gtk", - "jni", - "lazy_static", - "libc", - "log", - "ndk", - "ndk-context", - "ndk-sys", - "objc2 0.6.1", - "objc2-app-kit", - "objc2-foundation 0.3.1", - "once_cell", - "parking_lot", - "raw-window-handle", - "scopeguard", - "tao-macros", - "unicode-segmentation", - "url", - "windows", - "windows-core", - "windows-version", - "x11-dl", -] - -[[package]] -name = "tao-macros" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", -] - -[[package]] -name = "target-lexicon" -version = "0.12.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" - -[[package]] -name = "tauri" -version = "2.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7b0bc1aec81bda6bc455ea98fcaed26b3c98c1648c627ad6ff1c704e8bf8cbc" -dependencies = [ - "anyhow", - "bytes", - "dirs", - "dunce", - "embed_plist", - "futures-util", - "getrandom 0.2.16", - "glob", - "gtk", - "heck 0.5.0", - "http", - "http-range", - "jni", - "libc", - "log", - "mime", - "muda", - "objc2 0.6.1", - "objc2-app-kit", - "objc2-foundation 0.3.1", - "objc2-ui-kit", - "percent-encoding", - "plist", - "raw-window-handle", - "reqwest", - "serde", - "serde_json", - "serde_repr", - "serialize-to-javascript", - "swift-rs", - "tauri-build", - "tauri-macros", - "tauri-runtime", - "tauri-runtime-wry", - "tauri-utils", - "thiserror 2.0.12", - "tokio", - "tray-icon", - "url", - "urlpattern", - "webkit2gtk", - "webview2-com", - "window-vibrancy", - "windows", -] - -[[package]] -name = "tauri-build" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a0350f0df1db385ca5c02888a83e0e66655c245b7443db8b78a70da7d7f8fc" -dependencies = [ - "anyhow", - "cargo_toml", - "dirs", - "glob", - "heck 0.5.0", - "json-patch", - "schemars", - "semver", - "serde", - "serde_json", - "tauri-utils", - "tauri-winres", - "toml", - "walkdir", -] - -[[package]] -name = "tauri-codegen" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93f035551bf7b11b3f51ad9bc231ebbe5e085565527991c16cf326aa38cdf47" -dependencies = [ - "base64 0.22.1", - "brotli", - "ico", - "json-patch", - "plist", - "png", - "proc-macro2", - "quote", - "semver", - "serde", - "serde_json", - "sha2", - "syn 2.0.101", - "tauri-utils", - "thiserror 2.0.12", - "time", - "url", - "uuid", - "walkdir", -] - -[[package]] -name = "tauri-macros" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8db4df25e2d9d45de0c4c910da61cd5500190da14ae4830749fee3466dddd112" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.101", - "tauri-codegen", - "tauri-utils", -] - -[[package]] -name = "tauri-plugin" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a5ebe6a610d1b78a94650896e6f7c9796323f408800cef436e0fa0539de601" -dependencies = [ - "anyhow", - "glob", - "plist", - "schemars", - "serde", - "serde_json", - "tauri-utils", - "toml", - "walkdir", -] - -[[package]] -name = "tauri-plugin-dialog" -version = "2.2.1" -dependencies = [ - "log", - "raw-window-handle", - "rfd", - "serde", - "serde_json", - "tauri", - "tauri-plugin", - "tauri-plugin-fs", - "thiserror 2.0.12", - "url", -] - -[[package]] -name = "tauri-plugin-fs" -version = "2.2.1" -dependencies = [ - "anyhow", - "dunce", - "glob", - "percent-encoding", - "schemars", - "serde", - "serde_json", - "serde_repr", - "tauri", - "tauri-plugin", - "tauri-utils", - "thiserror 2.0.12", - "toml", - "url", -] - -[[package]] -name = "tauri-plugin-geolocation" -version = "2.2.4" -dependencies = [ - "log", - "serde", - "serde_json", - "tauri", - "tauri-plugin", - "thiserror 2.0.12", -] - -[[package]] -name = "tauri-plugin-http" -version = "2.4.3" -dependencies = [ - "bytes", - "cookie_store", - "data-url", - "http", - "regex", - "reqwest", - "schemars", - "serde", - "serde_json", - "tauri", - "tauri-plugin", - "tauri-plugin-fs", - "thiserror 2.0.12", - "tokio", - "url", - "urlpattern", -] - -[[package]] -name = "tauri-plugin-notification" -version = "2.2.2" -dependencies = [ - "log", - "notify-rust", - "rand 0.8.5", - "serde", - "serde_json", - "serde_repr", - "tauri", - "tauri-plugin", - "thiserror 2.0.12", - "time", - "url", -] - -[[package]] -name = "tauri-plugin-os" -version = "2.2.1" -dependencies = [ - "gethostname", - "log", - "os_info", - "serde", - "serde_json", - "serialize-to-javascript", - "sys-locale", - "tauri", - "tauri-plugin", - "thiserror 2.0.12", -] - -[[package]] -name = "tauri-plugin-shell" -version = "2.2.1" -dependencies = [ - "encoding_rs", - "log", - "open", - "os_pipe", - "regex", - "schemars", - "serde", - "serde_json", - "shared_child", - "tauri", - "tauri-plugin", - "thiserror 2.0.12", - "tokio", -] - -[[package]] -name = "tauri-plugin-store" -version = "2.2.0" -dependencies = [ - "dunce", - "serde", - "serde_json", - "tauri", - "tauri-plugin", - "thiserror 2.0.12", - "tokio", - "tracing", -] - -[[package]] -name = "tauri-runtime" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f004905d549854069e6774533d742b03cacfd6f03deb08940a8677586cbe39" -dependencies = [ - "cookie", - "dpi", - "gtk", - "http", - "jni", - "objc2 0.6.1", - "objc2-ui-kit", - "raw-window-handle", - "serde", - "serde_json", - "tauri-utils", - "thiserror 2.0.12", - "url", - "windows", -] - -[[package]] -name = "tauri-runtime-wry" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f85d056f4d4b014fe874814034f3416d57114b617a493a4fe552580851a3f3a2" -dependencies = [ - "gtk", - "http", - "jni", - "log", - "objc2 0.6.1", - "objc2-app-kit", - "objc2-foundation 0.3.1", - "once_cell", - "percent-encoding", - "raw-window-handle", - "softbuffer", - "tao", - "tauri-runtime", - "tauri-utils", - "url", - "webkit2gtk", - "webview2-com", - "windows", - "wry", -] - -[[package]] -name = "tauri-utils" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2900399c239a471bcff7f15c4399eb1a8c4fe511ba2853e07c996d771a5e0a4" -dependencies = [ - "anyhow", - "brotli", - "cargo_metadata", - "ctor", - "dunce", - "glob", - "html5ever", - "http", - "infer", - "json-patch", - "kuchikiki", - "log", - "memchr", - "phf 0.11.3", - "proc-macro2", - "quote", - "regex", - "schemars", - "semver", - "serde", - "serde-untagged", - "serde_json", - "serde_with", - "swift-rs", - "thiserror 2.0.12", - "toml", - "url", - "urlpattern", - "uuid", - "walkdir", -] - -[[package]] -name = "tauri-winres" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d321dbc6f998d825ab3f0d62673e810c861aac2d0de2cc2c395328f1d113b4" -dependencies = [ - "embed-resource", - "indexmap 2.9.0", - "toml", -] - -[[package]] -name = "tauri-winrt-notification" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b1e66e07de489fe43a46678dd0b8df65e0c973909df1b60ba33874e297ba9b9" -dependencies = [ - "quick-xml 0.37.5", - "thiserror 2.0.12", - "windows", - "windows-version", -] - -[[package]] -name = "tempfile" -version = "3.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" -dependencies = [ - "fastrand", - "getrandom 0.3.2", - "once_cell", - "rustix 1.0.5", - "windows-sys 0.59.0", -] - -[[package]] -name = "tendril" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" -dependencies = [ - "futf", - "mac", - "utf-8", -] - -[[package]] -name = "thin-slice" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" - -[[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 2.0.101", -] - -[[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 2.0.101", -] - -[[package]] -name = "time" -version = "0.3.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" -dependencies = [ - "deranged", - "itoa 1.0.15", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" - -[[package]] -name = "time-macros" -version = "0.2.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinystr" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tinyvec" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" -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.44.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "tracing", - "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 2.0.101", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-socks" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4770b8024672c1101b3f6733eab95b18007dbe0847a8afe341fcf79e06043f" -dependencies = [ - "either", - "futures-util", - "thiserror 1.0.69", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-tungstenite" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" -dependencies = [ - "futures-util", - "log", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tungstenite", - "webpki-roots", -] - -[[package]] -name = "tokio-util" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900f6c86a685850b1bc9f6223b20125115ee3f31e01207d81655bbcc0aea9231" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.22.25", -] - -[[package]] -name = "toml_datetime" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.9.0", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.20.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" -dependencies = [ - "indexmap 2.9.0", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10558ed0bd2a1562e630926a2d1f0b98c827da99fabd3fe20920a59642504485" -dependencies = [ - "indexmap 2.9.0", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", - "winnow 0.7.7", -] - -[[package]] -name = "toml_write" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28391a4201ba7eb1984cfeb6862c0b3ea2cfe23332298967c749dddc0d6cd976" - -[[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", -] - -[[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-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", -] - -[[package]] -name = "tracing-core" -version = "0.1.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" -dependencies = [ - "once_cell", -] - -[[package]] -name = "tray-icon" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7eee98ec5c90daf179d55c20a49d8c0d043054ce7c26336c09a24d31f14fa0" -dependencies = [ - "crossbeam-channel", - "dirs", - "libappindicator", - "muda", - "objc2 0.6.1", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-foundation 0.3.1", - "once_cell", - "png", + "console_error_panic_hook", + "getrandom 0.2.16", "serde", - "thiserror 2.0.12", - "windows-sys 0.59.0", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "tungstenite" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http", - "httparse", - "log", - "rand 0.8.5", - "rustls", - "rustls-pki-types", - "sha1", + "serde-wasm-bindgen", + "serde_json", + "tangle_core", + "tangle_model", "thiserror 1.0.69", - "utf-8", -] - -[[package]] -name = "typeid" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" - -[[package]] -name = "typenum" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" - -[[package]] -name = "uds_windows" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" -dependencies = [ - "memoffset", - "tempfile", - "winapi", -] - -[[package]] -name = "unic-char-property" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" -dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-ucd-ident" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" - -[[package]] -name = "unicode-ident" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" - -[[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-properties" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common", - "subtle", -] - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "urlpattern" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70acd30e3aa1450bc2eece896ce2ad0d178e9c079493819301573dae3c37ba6d" -dependencies = [ - "regex", - "serde", - "unic-ucd-ident", - "url", -] - -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "uuid" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" -dependencies = [ - "getrandom 0.3.2", - "serde", -] - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version-compare" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "vswhom" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" -dependencies = [ - "libc", - "vswhom-sys", -] - -[[package]] -name = "vswhom-sys" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb067e4cbd1ff067d1df46c9194b5de0e98efd2810bbc95c5d5e5f25a3231150" -dependencies = [ - "cc", - "libc", -] - -[[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 = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "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 = "wasite" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" - -[[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", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", ] [[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" +name = "thiserror" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.101", - "wasm-bindgen-shared", + "thiserror-impl 1.0.69", ] [[package]] -name = "wasm-bindgen-futures" -version = "0.4.50" +name = "thiserror" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "cfg-if", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", + "thiserror-impl 2.0.12", ] [[package]] -name = "wasm-bindgen-macro" -version = "0.2.100" +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ + "proc-macro2", "quote", - "wasm-bindgen-macro-support", + "syn", ] [[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.100" +name = "thiserror-impl" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", - "wasm-bindgen-backend", - "wasm-bindgen-shared", + "syn", ] [[package]] -name = "wasm-bindgen-shared" -version = "0.2.100" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "unicode-ident", + "displaydoc", + "zerovec", ] [[package]] -name = "wasm-streams" -version = "0.4.2" +name = "tinyvec" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" dependencies = [ - "futures-util", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", + "tinyvec_macros", ] [[package]] -name = "web-sys" -version = "0.3.77" +name = "tinyvec_macros" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.44.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" dependencies = [ - "js-sys", - "wasm-bindgen", + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys", ] [[package]] -name = "web-time" -version = "1.1.0" +name = "tokio-macros" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ - "js-sys", - "wasm-bindgen", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "webkit2gtk" -version = "2.0.1" +name = "tokio-rustls" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76b1bc1e54c581da1e9f179d0b38512ba358fb1af2d634a1affe42e37172361a" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ - "bitflags 1.3.2", - "cairo-rs", - "gdk", - "gdk-sys", - "gio", - "gio-sys", - "glib", - "glib-sys", - "gobject-sys", - "gtk", - "gtk-sys", - "javascriptcore-rs", - "libc", - "once_cell", - "soup3", - "webkit2gtk-sys", + "rustls", + "tokio", ] [[package]] -name = "webkit2gtk-sys" -version = "2.0.1" +name = "tokio-socks" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62daa38afc514d1f8f12b8693d30d5993ff77ced33ce30cd04deebc267a6d57c" +checksum = "0d4770b8024672c1101b3f6733eab95b18007dbe0847a8afe341fcf79e06043f" dependencies = [ - "bitflags 1.3.2", - "cairo-sys-rs", - "gdk-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "gtk-sys", - "javascriptcore-rs-sys", - "libc", - "pkg-config", - "soup3-sys", - "system-deps", + "either", + "futures-util", + "thiserror 1.0.69", + "tokio", ] [[package]] -name = "webpki-roots" -version = "0.26.9" +name = "tokio-tungstenite" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29aad86cec885cafd03e8305fd727c418e970a521322c91688414d5b8efba16b" +checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" dependencies = [ + "futures-util", + "log", + "rustls", "rustls-pki-types", + "tokio", + "tokio-rustls", + "tungstenite", + "webpki-roots", ] [[package]] -name = "webview2-com" -version = "0.37.0" +name = "tracing" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b542b5cfbd9618c46c2784e4d41ba218c336ac70d44c55e47b251033e7d85601" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ - "webview2-com-macros", - "webview2-com-sys", - "windows", - "windows-core", - "windows-implement", - "windows-interface", + "pin-project-lite", + "tracing-core", ] [[package]] -name = "webview2-com-macros" -version = "0.8.0" +name = "tracing-core" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", -] +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" [[package]] -name = "webview2-com-sys" -version = "0.37.0" +name = "tungstenite" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae2d11c4a686e4409659d7891791254cf9286d3cfe0eef54df1523533d22295" +checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" dependencies = [ + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.9.1", + "rustls", + "rustls-pki-types", + "sha1", "thiserror 2.0.12", - "windows", - "windows-core", + "utf-8", ] [[package]] -name = "whoami" -version = "1.6.0" +name = "typenum" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7" -dependencies = [ - "redox_syscall", - "wasite", -] +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] -name = "winapi" -version = "0.3.9" +name = "unicode-ident" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "unicode-normalization" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] [[package]] -name = "winapi-util" -version = "0.1.9" +name = "universal-hash" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "windows-sys 0.59.0", + "crypto-common", + "subtle", ] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "untrusted" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] -name = "window-vibrancy" -version = "0.6.0" +name = "url" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ - "objc2 0.6.1", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation 0.3.1", - "raw-window-handle", - "windows-sys 0.59.0", - "windows-version", + "form_urlencoded", + "idna", + "percent-encoding", + "serde", ] [[package]] -name = "windows" -version = "0.61.1" +name = "utf-8" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419" -dependencies = [ - "windows-collections", - "windows-core", - "windows-future", - "windows-link", - "windows-numerics", -] +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] -name = "windows-collections" -version = "0.2.0" +name = "utf16_iter" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" -dependencies = [ - "windows-core", -] +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" [[package]] -name = "windows-core" -version = "0.61.0" +name = "utf8_iter" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings 0.4.0", -] +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] -name = "windows-future" -version = "0.2.0" +name = "uuid" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ - "windows-core", - "windows-link", + "getrandom 0.3.2", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "windows-implement" -version = "0.60.0" +name = "version_check" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", -] +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] -name = "windows-interface" -version = "0.59.1" +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", -] +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "windows-link" -version = "0.1.1" +name = "wasi" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] [[package]] -name = "windows-numerics" -version = "0.2.0" +name = "wasm-bindgen" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ - "windows-core", - "windows-link", + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", ] [[package]] -name = "windows-registry" -version = "0.4.0" +name = "wasm-bindgen-backend" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ - "windows-result", - "windows-strings 0.3.1", - "windows-targets 0.53.0", + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", ] [[package]] -name = "windows-result" -version = "0.3.2" +name = "wasm-bindgen-futures" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ - "windows-link", + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", ] [[package]] -name = "windows-strings" -version = "0.3.1" +name = "wasm-bindgen-macro" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ - "windows-link", + "quote", + "wasm-bindgen-macro-support", ] [[package]] -name = "windows-strings" -version = "0.4.0" +name = "wasm-bindgen-macro-support" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ - "windows-link", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", ] [[package]] -name = "windows-sys" -version = "0.45.0" +name = "wasm-bindgen-shared" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" dependencies = [ - "windows-targets 0.42.2", + "unicode-ident", ] [[package]] -name = "windows-sys" -version = "0.48.0" +name = "web-sys" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ - "windows-targets 0.48.5", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "windows-sys" -version = "0.52.0" +name = "webpki-roots" +version = "0.26.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "29aad86cec885cafd03e8305fd727c418e970a521322c91688414d5b8efba16b" dependencies = [ - "windows-targets 0.52.6", + "rustls-pki-types", ] [[package]] -name = "windows-sys" -version = "0.59.0" +name = "windows-core" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ - "windows-targets 0.52.6", + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] -name = "windows-targets" -version = "0.42.2" +name = "windows-implement" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-interface" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "windows-targets" -version = "0.52.6" +name = "windows-link" +version = "0.2.1" 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", -] +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] -name = "windows-targets" -version = "0.53.0" +name = "windows-result" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" 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", + "windows-link", ] [[package]] -name = "windows-version" -version = "0.1.4" +name = "windows-strings" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e04a5c6627e310a23ad2358483286c7df260c964eb2d003d8efd6d0f4e79265c" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ "windows-link", ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" +name = "windows-targets" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] [[package]] name = "windows_aarch64_gnullvm" @@ -6503,202 +1772,54 @@ 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.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] name = "windows_aarch64_msvc" version = "0.52.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.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] name = "windows_i686_gnu" version = "0.52.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.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] name = "windows_i686_msvc" version = "0.52.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.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] name = "windows_x86_64_gnu" version = "0.52.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.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] name = "windows_x86_64_gnullvm" version = "0.52.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.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] name = "windows_x86_64_msvc" version = "0.52.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.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb8234a863ea0e8cd7284fcdd4f145233eb00fee02bbdd9861aec44e6477bc5" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - -[[package]] name = "wit-bindgen-rt" version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.0", + "bitflags", ] [[package]] @@ -6714,81 +1835,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] -name = "wry" -version = "0.51.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c886a0a9d2a94fd90cfa1d929629b79cfefb1546e2c7430c63a47f0664c0e4e2" -dependencies = [ - "base64 0.22.1", - "block2 0.6.1", - "cookie", - "crossbeam-channel", - "dpi", - "dunce", - "gdkx11", - "gtk", - "html5ever", - "http", - "javascriptcore-rs", - "jni", - "kuchikiki", - "libc", - "ndk", - "objc2 0.6.1", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation 0.3.1", - "objc2-ui-kit", - "objc2-web-kit", - "once_cell", - "percent-encoding", - "raw-window-handle", - "sha2", - "soup3", - "tao-macros", - "thiserror 2.0.12", - "url", - "webkit2gtk", - "webkit2gtk-sys", - "webview2-com", - "windows", - "windows-core", - "windows-version", - "x11-dl", -] - -[[package]] -name = "x11" -version = "2.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" -dependencies = [ - "libc", - "pkg-config", -] - -[[package]] -name = "x11-dl" -version = "2.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" -dependencies = [ - "libc", - "once_cell", - "pkg-config", -] - -[[package]] -name = "xdg-home" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] name = "yoke" version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6808,75 +1854,11 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn", "synstructure", ] [[package]] -name = "zbus" -version = "5.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59c333f648ea1b647bc95dc1d34807c8e25ed7a6feff3394034dc4776054b236" -dependencies = [ - "async-broadcast", - "async-executor", - "async-fs", - "async-io", - "async-lock", - "async-process", - "async-recursion", - "async-task", - "async-trait", - "blocking", - "enumflags2", - "event-listener", - "futures-core", - "futures-lite", - "hex", - "nix", - "ordered-stream", - "serde", - "serde_repr", - "static_assertions", - "tokio", - "tracing", - "uds_windows", - "windows-sys 0.59.0", - "winnow 0.7.7", - "xdg-home", - "zbus_macros", - "zbus_names", - "zvariant", -] - -[[package]] -name = "zbus_macros" -version = "5.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f325ad10eb0d0a3eb060203494c3b7ec3162a01a59db75d2deee100339709fc0" -dependencies = [ - "proc-macro-crate 3.3.0", - "proc-macro2", - "quote", - "syn 2.0.101", - "zbus_names", - "zvariant", - "zvariant_utils", -] - -[[package]] -name = "zbus_names" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" -dependencies = [ - "serde", - "static_assertions", - "winnow 0.7.7", - "zvariant", -] - -[[package]] name = "zerocopy" version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6893,7 +1875,7 @@ checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn", ] [[package]] @@ -6913,7 +1895,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn", "synstructure", ] @@ -6942,48 +1924,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", -] - -[[package]] -name = "zvariant" -version = "5.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2df9ee044893fcffbdc25de30546edef3e32341466811ca18421e3cd6c5a3ac" -dependencies = [ - "endi", - "enumflags2", - "serde", - "static_assertions", - "url", - "winnow 0.7.7", - "zvariant_derive", - "zvariant_utils", -] - -[[package]] -name = "zvariant_derive" -version = "5.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74170caa85b8b84cc4935f2d56a57c7a15ea6185ccdd7eadb57e6edd90f94b2f" -dependencies = [ - "proc-macro-crate 3.3.0", - "proc-macro2", - "quote", - "syn 2.0.101", - "zvariant_utils", -] - -[[package]] -name = "zvariant_utils" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16edfee43e5d7b553b77872d99bc36afdda75c223ca7ad5e3fbecd82ca5fc34" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "static_assertions", - "syn 2.0.101", - "winnow 0.7.7", + "syn", ] diff --git a/Cargo.toml b/Cargo.toml @@ -1,7 +1,17 @@ [workspace] -resolver = "2" -members = [ - "crates/core", - "crates/model", - "crates/tangle", +members = [ + "crates/*", ] +resolver = "2" + +[workspace.package] +version = "0.1.0" +edition = "2024" +rust-version = "1.88.0" +license = "GPL-3.0" + +[workspace.dependencies] +anyhow = { version = "1" } +serde = { version = "1", features = ["derive"] } +serde_json = { version = "1" } +thiserror = { version = "1" } diff --git a/README.md b/README.md @@ -1,20 +1,20 @@ <div align="center"> -# tangle | rad roots +# rad roots | PWA -_a farmer's market app built on Nostr_ +_collaborative agriculture on Nostr_ <p align="center"><a href="https://opensource.org/license/gpl-3-0"><img src="https://img.shields.io/badge/license-GPLv3-blue.svg"></a></p> -<img src="./docs/design/ios/setup.png" alt="Tangle iOS Setup" title="Tangle iOS Setup" width="240"/> +<img src="./docs/design/ios/setup.png" alt="iOS Setup" title="iOS Setup" width="240"/> </div> ## Overview -Tangle is a decentralized social networking application built on the Nostr protocol. We are building it for farmers around the world to market their products, and share their activities and knowledge. +Rad Roots is a collaborative agriculture network built on the Nostr protocol. We are building it for farmers around the world to market their products, and share their activities and knowledge. -Built for adaptability to remote areas, Tangle is designed with offline-first principles and includes a local database and on-device geocoder. Upon network connection the application will synchronize local data to the Nostr network. +Built for adaptability to remote areas, the app is designed with offline-first principles and includes a local database and on-device geocoder. Upon network connection the application will synchronize local data to the Nostr network. ## Supported Features diff --git a/app/package.json b/app/package.json @@ -2,7 +2,7 @@ "name": "app", "private": true, "version": "0.0.0", - "license": "GPLv3", + "license": "GPL-3.0", "type": "module", "scripts": { "build": "vite build --mode production", diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml @@ -1,15 +1,32 @@ [package] name = "tangle_core" -version = "0.0.1" -license = "GPLv3" -edition = "2021" +version.workspace = true +edition.workspace = true +authors = ["Radroots Authors"] +rust-version.workspace = true +license.workspace = true + +[lib] +name = "tangle_core" +path = "src/lib.rs" +crate-type = ["rlib"] [dependencies] -serde_json = "1.0" -serde = { version = "1.0", features = ["derive"] } -thiserror = "1.0.64" +serde = { workspace = true } +serde_json = { workspace = true } +thiserror = { workspace = true } uuid = { version = "1", features = ["v4"] } -chrono = "0.4" +chrono = "0.4" regex = "1.11.0" base64 = "0.22" -nostr-sdk = { version = "0.37", features = [] } +nostr-sdk = { version = "0.43" } +wasm-bindgen = { version = "0.2", optional = true } + +[features] +default = [] +wasm = ["wasm-bindgen"] + +[target.wasm32-unknown-unknown.dependencies] +getrandom = { version = "0.2", features = ["js"] } +uuid = { version = "1", features = ["v4", "js"], package = "uuid" } +web-sys = { version = "0.3", features = ["Window", "Storage"] } diff --git a/crates/core/LICENSE b/crates/core/LICENSE @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - <program> Copyright (C) <year> <name of author> - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -<https://www.gnu.org/licenses/>. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -<https://www.gnu.org/licenses/why-not-lgpl.html>. -\ No newline at end of file diff --git a/crates/core/src/keystore.rs b/crates/core/src/keystore.rs @@ -1,9 +1,10 @@ -use base64::{engine::general_purpose, Engine as _}; +use base64::{Engine as _, engine::general_purpose}; use serde_json::json; use thiserror::Error; use uuid::Uuid; -use crate::util::json_keys; +#[cfg(target_arch = "wasm32")] +use web_sys::window; #[derive(Error, Debug)] pub enum KeystoreError { @@ -11,8 +12,6 @@ pub enum KeystoreError { JsonError(#[from] serde_json::Error), #[error("UUID error: {0}")] UuidError(#[from] uuid::Error), - #[error("File error: {0}")] - FileError(#[from] std::io::Error), #[error("Base64 error: {0}")] Base64Error(#[from] base64::DecodeError), #[error("UTF-8 error: {0}")] @@ -21,106 +20,166 @@ pub enum KeystoreError { KeyError(#[from] nostr_sdk::key::Error), #[error("error.keystore.key_not_found")] KeyNotFound, + #[error("Storage error")] + Storage, } pub type KeystoreResult<T> = std::result::Result<T, KeystoreError>; -fn get_keystore_path(data_dir: &std::path::Path) -> std::path::PathBuf { - data_dir.join("keystore.json") +pub trait Storage { + fn read_text(&self, path: &str) -> KeystoreResult<Option<String>>; + fn write_text(&self, path: &str, data: &str) -> KeystoreResult<()>; + fn exists(&self, path: &str) -> KeystoreResult<bool>; } -fn get_keystore_key(data_dir: &std::path::Path) -> Vec<u8> { - let keystore_file = data_dir.join("keystore.key"); - let keystore_key = if keystore_file.exists() { - std::fs::read_to_string(&keystore_file) - .map_err(KeystoreError::FileError) - .and_then(|s| s.parse::<Uuid>().map_err(KeystoreError::UuidError)) +#[cfg(target_arch = "wasm32")] +pub struct BrowserStorage; + +#[cfg(target_arch = "wasm32")] +impl Storage for BrowserStorage { + fn read_text(&self, path: &str) -> KeystoreResult<Option<String>> { + let storage = window() + .ok_or(KeystoreError::Storage)? + .local_storage() + .map_err(|_| KeystoreError::Storage)? + .ok_or(KeystoreError::Storage)?; + storage.get_item(path).map_err(|_| KeystoreError::Storage) + } + + fn write_text(&self, path: &str, data: &str) -> KeystoreResult<()> { + let storage = window() + .ok_or(KeystoreError::Storage)? + .local_storage() + .map_err(|_| KeystoreError::Storage)? + .ok_or(KeystoreError::Storage)?; + storage + .set_item(path, data) + .map_err(|_| KeystoreError::Storage)?; + Ok(()) + } + + fn exists(&self, path: &str) -> KeystoreResult<bool> { + let storage = window() + .ok_or(KeystoreError::Storage)? + .local_storage() + .map_err(|_| KeystoreError::Storage)? + .ok_or(KeystoreError::Storage)?; + storage + .get_item(path) + .map_err(|_| KeystoreError::Storage) + .map(|v| v.is_some()) + } +} + +#[cfg(not(target_arch = "wasm32"))] +struct NullStorage; + +#[cfg(not(target_arch = "wasm32"))] +impl Storage for NullStorage { + fn read_text(&self, _path: &str) -> KeystoreResult<Option<String>> { + Ok(None) + } + fn write_text(&self, _path: &str, _data: &str) -> KeystoreResult<()> { + Err(KeystoreError::Storage) + } + fn exists(&self, _path: &str) -> KeystoreResult<bool> { + Ok(false) + } +} + +fn get_keystore_key<S: Storage>(st: &S) -> KeystoreResult<Vec<u8>> { + let key_path = "keystore.key"; + if st.exists(key_path)? { + let s = st.read_text(key_path)?.ok_or(KeystoreError::Storage)?; + let id = s.parse::<Uuid>()?; + Ok(id.as_bytes().to_vec()) } else { - let new_keystore_key = Uuid::new_v4(); - let _ = std::fs::create_dir_all(data_dir).map_err(KeystoreError::FileError); - let _ = std::fs::write(keystore_file, new_keystore_key.to_string()) - .map_err(KeystoreError::FileError); - Ok(new_keystore_key) - }; - keystore_key - .expect("Couldn't unwrap keystore key") - .as_bytes() - .to_vec() + let id = Uuid::new_v4(); + st.write_text(key_path, &id.to_string())?; + Ok(id.as_bytes().to_vec()) + } } -fn obfuscate(data: &str, data_dir: &std::path::Path) -> String { - let keystore_key = get_keystore_key(data_dir); +fn obfuscate<S: Storage>(st: &S, data: &str) -> KeystoreResult<String> { + let keystore_key = get_keystore_key(st)?; let xored: Vec<u8> = data .as_bytes() .iter() .zip(keystore_key.iter().cycle()) .map(|(&x1, &x2)| x1 ^ x2) .collect(); - general_purpose::STANDARD_NO_PAD.encode(xored) + Ok(general_purpose::STANDARD_NO_PAD.encode(xored)) } -fn deobfuscate(data: &str, data_dir: &std::path::Path) -> KeystoreResult<String> { - let keystore_key = get_keystore_key(data_dir); - let decoded = general_purpose::STANDARD_NO_PAD - .decode(data) - .map_err(KeystoreError::Base64Error)?; +fn deobfuscate<S: Storage>(st: &S, data: &str) -> KeystoreResult<String> { + let keystore_key = get_keystore_key(st)?; + let decoded = general_purpose::STANDARD_NO_PAD.decode(data)?; let xored: Vec<u8> = decoded .iter() .zip(keystore_key.iter().cycle()) .map(|(&x1, &x2)| x1 ^ x2) .collect(); - String::from_utf8(xored).map_err(KeystoreError::Utf8Error) + Ok(String::from_utf8(xored)?) } -fn read_keystore_file(data_dir: &std::path::Path) -> KeystoreResult<serde_json::Value> { - let content = match std::fs::read_to_string(get_keystore_path(data_dir)) { - Ok(content) => content, - Err(e) if e.kind() == std::io::ErrorKind::NotFound => String::from("{}"), - Err(e) => return Err(e.into()), - }; +fn read_keystore_file<S: Storage>(st: &S) -> KeystoreResult<serde_json::Value> { + let content = st + .read_text("keystore.json")? + .unwrap_or_else(|| "{}".to_string()); Ok(serde_json::from_str(&content)?) } -fn write_keystore_file( - data_dir: &std::path::Path, - secrets: &serde_json::Value, -) -> KeystoreResult<()> { +fn write_keystore_file<S: Storage>(st: &S, secrets: &serde_json::Value) -> KeystoreResult<()> { let content = serde_json::to_string_pretty(secrets)?; - std::fs::write(get_keystore_path(data_dir), content)?; + st.write_text("keystore.json", &content)?; Ok(()) } -pub fn key_add(keys: &nostr_sdk::Keys, data_dir: &std::path::Path) -> KeystoreResult<()> { - let mut secrets = read_keystore_file(data_dir).unwrap_or(json!({})); - let obfuscated_key = obfuscate(keys.secret_key().to_secret_hex().as_str(), data_dir); +#[cfg(target_arch = "wasm32")] +fn storage() -> BrowserStorage { + BrowserStorage +} + +#[cfg(not(target_arch = "wasm32"))] +fn storage() -> NullStorage { + NullStorage +} + +pub fn key_add(keys: &nostr_sdk::Keys) -> KeystoreResult<()> { + let st = storage(); + let mut secrets = read_keystore_file(&st).unwrap_or(json!({})); + let obfuscated_key = obfuscate(&st, keys.secret_key().to_secret_hex().as_str())?; secrets[keys.public_key().to_hex()] = json!(obfuscated_key); - write_keystore_file(data_dir, &secrets)?; + write_keystore_file(&st, &secrets)?; Ok(()) } -pub fn key_read(public_key: &str, data_dir: &std::path::Path) -> KeystoreResult<nostr_sdk::Keys> { - let secrets = read_keystore_file(data_dir)?; +pub fn key_read(public_key: &str) -> KeystoreResult<nostr_sdk::Keys> { + let st = storage(); + let secrets = read_keystore_file(&st)?; let obfuscated_key = secrets[public_key] .as_str() .ok_or(KeystoreError::KeyNotFound)?; - let secret_key = deobfuscate(obfuscated_key, data_dir)?; - nostr_sdk::Keys::parse(&secret_key).map_err(KeystoreError::KeyError) + let secret_key = deobfuscate(&st, obfuscated_key)?; + Ok(nostr_sdk::Keys::parse(&secret_key)?) } -pub fn key_delete(public_key: &str, data_dir: &std::path::Path) -> KeystoreResult<()> { - let mut secrets = read_keystore_file(data_dir)?; +pub fn key_delete(public_key: &str) -> KeystoreResult<()> { + let st = storage(); + let mut secrets = read_keystore_file(&st)?; secrets.as_object_mut().map(|obj| obj.remove(public_key)); - write_keystore_file(data_dir, &secrets)?; + write_keystore_file(&st, &secrets)?; Ok(()) } -pub fn keys_read_all(data_dir: &std::path::Path) -> KeystoreResult<Vec<String>> { - let secrets = read_keystore_file(data_dir)?; - let results = json_keys(&secrets); - Ok(results) +pub fn keys_read_all() -> KeystoreResult<Vec<String>> { + let st = storage(); + let secrets = read_keystore_file(&st)?; + Ok(crate::util::json_keys(&secrets)) } -pub fn reset(data_dir: &std::path::Path) -> KeystoreResult<()> { - write_keystore_file(data_dir, &json!({}))?; +pub fn reset() -> KeystoreResult<()> { + let st = storage(); + write_keystore_file(&st, &json!({}))?; Ok(()) } diff --git a/crates/core/src/nostr/keys.rs b/crates/core/src/nostr/keys.rs @@ -1,5 +1,4 @@ use nostr_sdk::prelude::*; - use thiserror::Error; #[derive(Error, Debug)] diff --git a/crates/core/src/types.rs b/crates/core/src/types.rs @@ -1,5 +1,3 @@ -pub type IModelsQueryBindValueTuple = (String, String); - #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct IResult<T> { pub result: T, diff --git a/crates/model/Cargo.toml b/crates/model/Cargo.toml @@ -1,14 +1,20 @@ [package] name = "tangle_model" -version = "0.0.1" -license = "GPLv3" -edition = "2021" +version.workspace = true +edition.workspace = true +authors = ["Radroots Authors"] +rust-version.workspace = true +license.workspace = true + +[lib] +crate-type = ["rlib"] [dependencies] -serde_json = "1.0" +wasm-bindgen = "0.2" +wasm-bindgen-futures = "0.4" serde = { version = "1.0", features = ["derive"] } -sqlx = { version = "0.8.2", features = ["sqlite", "runtime-tokio"] } -thiserror = "1.0.64" -futures = "0.3.31" - +serde_json = "1.0" +serde-wasm-bindgen = "0.6" +js-sys = "0.3" +thiserror = "1.0" tangle_core = { path = "../core" } diff --git a/crates/model/LICENSE b/crates/model/LICENSE @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - <program> Copyright (C) <year> <name of author> - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -<https://www.gnu.org/licenses/>. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -<https://www.gnu.org/licenses/why-not-lgpl.html>. -\ No newline at end of file diff --git a/crates/model/src/lib.rs b/crates/model/src/lib.rs @@ -1,4 +1,4 @@ pub mod error; -pub mod tables; pub mod types; pub mod util; +pub mod wasm_executor; diff --git a/crates/model/src/tables/farm.rs b/crates/model/src/tables/farm.rs @@ -1,227 +0,0 @@ -use futures::TryStreamExt; -use tangle_core::{ - types::{IModelsQueryBindValueTuple, IResult, IResultList, IResultPass}, - util::{time_created_on, uuidv4}, -}; - -use crate::{error::ModelError, types::DatabaseConnection, util::parse_query_value}; - -#[derive(Debug, serde::Serialize, serde::Deserialize, sqlx::FromRow)] -pub struct Farm { - id: String, - created_at: String, - updated_at: String, - name: String, - area: Option<String>, - area_unit: Option<String>, - title: Option<String>, - description: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct IFarmFields { - pub name: String, - pub area: Option<String>, - pub area_unit: Option<String>, - pub title: Option<String>, - pub description: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct IFarmFieldsPartial { - pub name: Option<String>, - pub area: Option<String>, - pub area_unit: Option<String>, - pub title: Option<String>, - pub description: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct IFarmFieldsFilter { - pub created_at: Option<String>, - pub updated_at: Option<String>, - pub name: Option<String>, - pub area: Option<String>, - pub area_unit: Option<String>, - pub title: Option<String>, - pub description: Option<String>, -} - -#[derive(Clone, serde::Serialize, serde::Deserialize)] -#[serde(untagged)] -pub enum FarmQueryBindValues { - Id { id: String }, -} - -pub fn farm_query_bind_values(opts: FarmQueryBindValues) -> IModelsQueryBindValueTuple { - match opts { - FarmQueryBindValues::Id { id } => ("id".to_string(), id), - } -} - -fn lib_table_farm_parse_fields( - opts: IFarmFields, -) -> Result<serde_json::Map<String, serde_json::Value>, ModelError> { - let fields = serde_json::to_value(opts) - .map_err(|err| ModelError::SerializationError(err.to_string()))? - .as_object() - .ok_or_else(|| ModelError::SerializationError("Expected an object".to_string()))? - .clone(); - Ok(fields) -} - -pub type IFarmCreate = IFarmFields; -pub type IFarmCreateResolve = IResult<String>; - -pub async fn lib_model_farm_create( - db: &DatabaseConnection, - opts: IFarmCreate, -) -> Result<IFarmCreateResolve, ModelError> { - let id: String = uuidv4(); - let created_at: String = time_created_on(); - let updated_at: String = created_at.clone(); - let fields = lib_table_farm_parse_fields(opts)?; - - let query = format!( - "INSERT INTO farm (id, created_at, updated_at, {}) VALUES (?, ?, ?, {});", - fields - .keys() - .map(|k| k.to_string()) - .collect::<Vec<String>>() - .join(","), - (0..fields.len()) - .map(|_| "?") - .collect::<Vec<&str>>() - .join(",") - ); - - let mut query_builder = sqlx::query(&query); - query_builder = query_builder.bind(&id); - query_builder = query_builder.bind(&created_at); - query_builder = query_builder.bind(&updated_at); - for (_, value) in fields.iter() { - match value { - serde_json::Value::Bool(b) => { - let bool_str = if *b { "1" } else { "0" }; - query_builder = query_builder.bind(bool_str); - } - serde_json::Value::Number(n) => { - if let Some(f) = n.as_f64() { - query_builder = query_builder.bind(f); - } else if let Some(i64) = n.as_i64() { - query_builder = query_builder.bind(i64); - } else if let Some(u64) = n.as_u64() { - if u64 <= u32::MAX as u64 { - query_builder = query_builder.bind(u64 as u32); - } - } - } - serde_json::Value::String(s) => { - query_builder = query_builder.bind(s); - } - _ => { - query_builder = query_builder.bind::<Option<serde_json::Value>>(None); - } - } - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResult { result: id }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct IFarmQueryRead { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type IFarmRead = IFarmQueryRead; -pub type IFarmReadResolve = IResultList<Farm>; - -pub async fn lib_model_farm_read( - db: &DatabaseConnection, - opts: IFarmRead, -) -> Result<IFarmReadResolve, ModelError> { - let mut query_builder = sqlx::query_as::<_, Farm>(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - let results = query_builder - .fetch(db) - .try_collect() - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultList { results }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct IFarmQueryReadList { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type IFarmReadList = IFarmQueryReadList; -pub type IFarmReadListResolve = IResultList<Farm>; - -pub async fn lib_model_farm_read_list( - db: &DatabaseConnection, - opts: IFarmReadList, -) -> Result<IFarmReadListResolve, ModelError> { - let mut query_builder = sqlx::query_as::<_, Farm>(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - let results = query_builder - .fetch(db) - .try_collect() - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultList { results }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct IFarmQueryUpdate { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type IFarmUpdate = IFarmQueryUpdate; -pub type IFarmUpdateResolve = IResultPass; - -pub async fn lib_model_farm_update( - db: &sqlx::Pool<sqlx::Sqlite>, - opts: IFarmUpdate, -) -> Result<IFarmUpdateResolve, ModelError> { - let mut query_builder = sqlx::query(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} - -pub type IFarmDelete = FarmQueryBindValues; -pub type IFarmDeleteResolve = IResultPass; - -pub async fn lib_model_farm_delete( - db: &DatabaseConnection, - opts: IFarmDelete, -) -> Result<IFarmDeleteResolve, ModelError> { - let (bv_k, bv) = farm_query_bind_values(opts); - let query = format!("DELETE FROM farm WHERE {} = ?1;", bv_k); - let result = sqlx::query(&query) - .bind(bv) - .execute(db) - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - if result.rows_affected() > 0 { - Ok(IResultPass { pass: true }) - } else { - Err(ModelError::NotFound("model.farm.name".to_string())) - } -} diff --git a/crates/model/src/tables/farm_location.rs b/crates/model/src/tables/farm_location.rs @@ -1,58 +0,0 @@ -use super::{ - farm::{farm_query_bind_values, FarmQueryBindValues}, - location_gcs::{location_gcs_query_bind_values, LocationGcsQueryBindValues}, -}; -use crate::{error::ModelError, types::DatabaseConnection}; -use tangle_core::types::IResultPass; - -#[derive(serde::Serialize, serde::Deserialize, sqlx::FromRow)] -pub struct FarmLocation { - tb_farm: String, - tb_lg: String, -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct IFarmLocationTables { - pub farm: FarmQueryBindValues, - pub location_gcs: LocationGcsQueryBindValues, -} - -pub type IFarmLocationRelation = IFarmLocationTables; -pub type IFarmLocationResolve = IResultPass; - -pub async fn lib_model_farm_location_set( - db: &DatabaseConnection, - opts: IFarmLocationRelation, -) -> Result<IFarmLocationResolve, ModelError> { - let (bv_farm_k, bv_farm) = farm_query_bind_values(opts.farm); - let (bv_lg_k, bv_lg) = location_gcs_query_bind_values(opts.location_gcs); - let query_vals = vec![bv_farm, bv_lg]; - let query = format!("INSERT INTO farm_location (tb_farm, tb_lg) VALUES ((SELECT id FROM farm WHERE {} = ?), (SELECT id FROM location_gcs WHERE {} = ?));", bv_farm_k, bv_lg_k); - let mut query_builder = sqlx::query(&query); - for value in query_vals.iter() { - query_builder = query_builder.bind(value); - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} -pub async fn lib_model_farm_location_unset( - db: &DatabaseConnection, - opts: IFarmLocationRelation, -) -> Result<IFarmLocationResolve, ModelError> { - let (bv_farm_k, bv_farm) = farm_query_bind_values(opts.farm); - let (bv_lg_k, bv_lg) = location_gcs_query_bind_values(opts.location_gcs); - let query_vals = vec![bv_farm, bv_lg]; - let query = format!("DELETE FROM farm_location WHERE tb_farm = (SELECT id FROM farm WHERE {} = ?) AND tb_lg = (SELECT id FROM location_gcs WHERE {} = ?);", bv_farm_k, bv_lg_k); - let mut query_builder = sqlx::query(&query); - for value in query_vals.iter() { - query_builder = query_builder.bind(value); - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} diff --git a/crates/model/src/tables/location_gcs.rs b/crates/model/src/tables/location_gcs.rs @@ -1,269 +0,0 @@ -use futures::TryStreamExt; -use tangle_core::{ - types::{IModelsQueryBindValueTuple, IResult, IResultList, IResultPass}, - util::{time_created_on, uuidv4}, -}; - -use crate::{error::ModelError, types::DatabaseConnection, util::parse_query_value}; - -#[derive(Debug, serde::Serialize, serde::Deserialize, sqlx::FromRow)] -pub struct LocationGcs { - id: String, - created_at: String, - updated_at: String, - lat: f64, - lng: f64, - geohash: String, - tag_0: Option<String>, - label: Option<String>, - area: Option<f64>, - elevation: Option<u32>, - soil: Option<String>, - climate: Option<String>, - gc_id: Option<String>, - gc_name: Option<String>, - gc_admin1_id: Option<String>, - gc_admin1_name: Option<String>, - gc_country_id: Option<String>, - gc_country_name: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct ILocationGcsFields { - pub lat: f64, - pub lng: f64, - pub geohash: String, - pub tag_0: Option<String>, - pub label: Option<String>, - pub area: Option<f64>, - pub elevation: Option<u32>, - pub soil: Option<String>, - pub climate: Option<String>, - pub gc_id: Option<String>, - pub gc_name: Option<String>, - pub gc_admin1_id: Option<String>, - pub gc_admin1_name: Option<String>, - pub gc_country_id: Option<String>, - pub gc_country_name: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct ILocationGcsFieldsPartial { - pub lat: Option<f64>, - pub lng: Option<f64>, - pub geohash: Option<String>, - pub tag_0: Option<String>, - pub label: Option<String>, - pub area: Option<f64>, - pub elevation: Option<u32>, - pub soil: Option<String>, - pub climate: Option<String>, - pub gc_id: Option<String>, - pub gc_name: Option<String>, - pub gc_admin1_id: Option<String>, - pub gc_admin1_name: Option<String>, - pub gc_country_id: Option<String>, - pub gc_country_name: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct ILocationGcsFieldsFilter { - pub created_at: Option<String>, - pub updated_at: Option<String>, - pub lat: Option<String>, - pub lng: Option<String>, - pub geohash: Option<String>, - pub tag_0: Option<String>, - pub label: Option<String>, - pub area: Option<String>, - pub elevation: Option<String>, - pub soil: Option<String>, - pub climate: Option<String>, - pub gc_id: Option<String>, - pub gc_name: Option<String>, - pub gc_admin1_id: Option<String>, - pub gc_admin1_name: Option<String>, - pub gc_country_id: Option<String>, - pub gc_country_name: Option<String>, -} - -#[derive(Clone, serde::Serialize, serde::Deserialize)] -#[serde(untagged)] -pub enum LocationGcsQueryBindValues { - Id { id: String }, - Geohash { geohash: String }, -} - -pub fn location_gcs_query_bind_values(opts: LocationGcsQueryBindValues) -> IModelsQueryBindValueTuple { - match opts { - LocationGcsQueryBindValues::Id { id } => ("id".to_string(), id), - LocationGcsQueryBindValues::Geohash { geohash } => ("geohash".to_string(), geohash), - } -} - -fn lib_table_location_gcs_parse_fields( - opts: ILocationGcsFields, -) -> Result<serde_json::Map<String, serde_json::Value>, ModelError> { - let fields = serde_json::to_value(opts) - .map_err(|err| ModelError::SerializationError(err.to_string()))? - .as_object() - .ok_or_else(|| ModelError::SerializationError("Expected an object".to_string()))? - .clone(); - Ok(fields) -} - -pub type ILocationGcsCreate = ILocationGcsFields; -pub type ILocationGcsCreateResolve = IResult<String>; - -pub async fn lib_model_location_gcs_create( - db: &DatabaseConnection, - opts: ILocationGcsCreate, -) -> Result<ILocationGcsCreateResolve, ModelError> { - let id: String = uuidv4(); - let created_at: String = time_created_on(); - let updated_at: String = created_at.clone(); - let fields = lib_table_location_gcs_parse_fields(opts)?; - - let query = format!( - "INSERT INTO location_gcs (id, created_at, updated_at, {}) VALUES (?, ?, ?, {});", - fields - .keys() - .map(|k| k.to_string()) - .collect::<Vec<String>>() - .join(","), - (0..fields.len()) - .map(|_| "?") - .collect::<Vec<&str>>() - .join(",") - ); - - let mut query_builder = sqlx::query(&query); - query_builder = query_builder.bind(&id); - query_builder = query_builder.bind(&created_at); - query_builder = query_builder.bind(&updated_at); - for (_, value) in fields.iter() { - match value { - serde_json::Value::Bool(b) => { - let bool_str = if *b { "1" } else { "0" }; - query_builder = query_builder.bind(bool_str); - } - serde_json::Value::Number(n) => { - if let Some(f) = n.as_f64() { - query_builder = query_builder.bind(f); - } else if let Some(i64) = n.as_i64() { - query_builder = query_builder.bind(i64); - } else if let Some(u64) = n.as_u64() { - if u64 <= u32::MAX as u64 { - query_builder = query_builder.bind(u64 as u32); - } - } - } - serde_json::Value::String(s) => { - query_builder = query_builder.bind(s); - } - _ => { - query_builder = query_builder.bind::<Option<serde_json::Value>>(None); - } - } - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResult { result: id }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct ILocationGcsQueryRead { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type ILocationGcsRead = ILocationGcsQueryRead; -pub type ILocationGcsReadResolve = IResultList<LocationGcs>; - -pub async fn lib_model_location_gcs_read( - db: &DatabaseConnection, - opts: ILocationGcsRead, -) -> Result<ILocationGcsReadResolve, ModelError> { - let mut query_builder = sqlx::query_as::<_, LocationGcs>(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - let results = query_builder - .fetch(db) - .try_collect() - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultList { results }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct ILocationGcsQueryReadList { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type ILocationGcsReadList = ILocationGcsQueryReadList; -pub type ILocationGcsReadListResolve = IResultList<LocationGcs>; - -pub async fn lib_model_location_gcs_read_list( - db: &DatabaseConnection, - opts: ILocationGcsReadList, -) -> Result<ILocationGcsReadListResolve, ModelError> { - let mut query_builder = sqlx::query_as::<_, LocationGcs>(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - let results = query_builder - .fetch(db) - .try_collect() - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultList { results }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct ILocationGcsQueryUpdate { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type ILocationGcsUpdate = ILocationGcsQueryUpdate; -pub type ILocationGcsUpdateResolve = IResultPass; - -pub async fn lib_model_location_gcs_update( - db: &sqlx::Pool<sqlx::Sqlite>, - opts: ILocationGcsUpdate, -) -> Result<ILocationGcsUpdateResolve, ModelError> { - let mut query_builder = sqlx::query(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} - -pub type ILocationGcsDelete = LocationGcsQueryBindValues; -pub type ILocationGcsDeleteResolve = IResultPass; - -pub async fn lib_model_location_gcs_delete( - db: &DatabaseConnection, - opts: ILocationGcsDelete, -) -> Result<ILocationGcsDeleteResolve, ModelError> { - let (bv_k, bv) = location_gcs_query_bind_values(opts); - let query = format!("DELETE FROM location_gcs WHERE {} = ?1;", bv_k); - let result = sqlx::query(&query) - .bind(bv) - .execute(db) - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - if result.rows_affected() > 0 { - Ok(IResultPass { pass: true }) - } else { - Err(ModelError::NotFound("model.location_gcs.name".to_string())) - } -} diff --git a/crates/model/src/tables/log_error.rs b/crates/model/src/tables/log_error.rs @@ -1,241 +0,0 @@ -use futures::TryStreamExt; -use tangle_core::{ - types::{IModelsQueryBindValueTuple, IResult, IResultList, IResultPass}, - util::{time_created_on, uuidv4}, -}; - -use crate::{error::ModelError, types::DatabaseConnection, util::parse_query_value}; - -#[derive(Debug, serde::Serialize, serde::Deserialize, sqlx::FromRow)] -pub struct LogError { - id: String, - created_at: String, - updated_at: String, - error: String, - message: String, - stack_trace: Option<String>, - cause: Option<String>, - app_system: String, - app_version: String, - nostr_pubkey: String, - data: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct ILogErrorFields { - pub error: String, - pub message: String, - pub stack_trace: Option<String>, - pub cause: Option<String>, - pub app_system: String, - pub app_version: String, - pub nostr_pubkey: String, - pub data: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct ILogErrorFieldsPartial { - pub error: Option<String>, - pub message: Option<String>, - pub stack_trace: Option<String>, - pub cause: Option<String>, - pub app_system: Option<String>, - pub app_version: Option<String>, - pub nostr_pubkey: Option<String>, - pub data: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct ILogErrorFieldsFilter { - pub created_at: Option<String>, - pub updated_at: Option<String>, - pub error: Option<String>, - pub message: Option<String>, - pub stack_trace: Option<String>, - pub cause: Option<String>, - pub app_system: Option<String>, - pub app_version: Option<String>, - pub nostr_pubkey: Option<String>, - pub data: Option<String>, -} - -#[derive(Clone, serde::Serialize, serde::Deserialize)] -#[serde(untagged)] -pub enum LogErrorQueryBindValues { - Id { id: String }, - NostrPubkey { nostr_pubkey: String }, -} - -pub fn log_error_query_bind_values(opts: LogErrorQueryBindValues) -> IModelsQueryBindValueTuple { - match opts { - LogErrorQueryBindValues::Id { id } => ("id".to_string(), id), - LogErrorQueryBindValues::NostrPubkey { nostr_pubkey } => ("nostr_pubkey".to_string(), nostr_pubkey), - } -} - -fn lib_table_log_error_parse_fields( - opts: ILogErrorFields, -) -> Result<serde_json::Map<String, serde_json::Value>, ModelError> { - let fields = serde_json::to_value(opts) - .map_err(|err| ModelError::SerializationError(err.to_string()))? - .as_object() - .ok_or_else(|| ModelError::SerializationError("Expected an object".to_string()))? - .clone(); - Ok(fields) -} - -pub type ILogErrorCreate = ILogErrorFields; -pub type ILogErrorCreateResolve = IResult<String>; - -pub async fn lib_model_log_error_create( - db: &DatabaseConnection, - opts: ILogErrorCreate, -) -> Result<ILogErrorCreateResolve, ModelError> { - let id: String = uuidv4(); - let created_at: String = time_created_on(); - let updated_at: String = created_at.clone(); - let fields = lib_table_log_error_parse_fields(opts)?; - - let query = format!( - "INSERT INTO log_error (id, created_at, updated_at, {}) VALUES (?, ?, ?, {});", - fields - .keys() - .map(|k| k.to_string()) - .collect::<Vec<String>>() - .join(","), - (0..fields.len()) - .map(|_| "?") - .collect::<Vec<&str>>() - .join(",") - ); - - let mut query_builder = sqlx::query(&query); - query_builder = query_builder.bind(&id); - query_builder = query_builder.bind(&created_at); - query_builder = query_builder.bind(&updated_at); - for (_, value) in fields.iter() { - match value { - serde_json::Value::Bool(b) => { - let bool_str = if *b { "1" } else { "0" }; - query_builder = query_builder.bind(bool_str); - } - serde_json::Value::Number(n) => { - if let Some(f) = n.as_f64() { - query_builder = query_builder.bind(f); - } else if let Some(i64) = n.as_i64() { - query_builder = query_builder.bind(i64); - } else if let Some(u64) = n.as_u64() { - if u64 <= u32::MAX as u64 { - query_builder = query_builder.bind(u64 as u32); - } - } - } - serde_json::Value::String(s) => { - query_builder = query_builder.bind(s); - } - _ => { - query_builder = query_builder.bind::<Option<serde_json::Value>>(None); - } - } - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResult { result: id }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct ILogErrorQueryRead { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type ILogErrorRead = ILogErrorQueryRead; -pub type ILogErrorReadResolve = IResultList<LogError>; - -pub async fn lib_model_log_error_read( - db: &DatabaseConnection, - opts: ILogErrorRead, -) -> Result<ILogErrorReadResolve, ModelError> { - let mut query_builder = sqlx::query_as::<_, LogError>(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - let results = query_builder - .fetch(db) - .try_collect() - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultList { results }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct ILogErrorQueryReadList { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type ILogErrorReadList = ILogErrorQueryReadList; -pub type ILogErrorReadListResolve = IResultList<LogError>; - -pub async fn lib_model_log_error_read_list( - db: &DatabaseConnection, - opts: ILogErrorReadList, -) -> Result<ILogErrorReadListResolve, ModelError> { - let mut query_builder = sqlx::query_as::<_, LogError>(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - let results = query_builder - .fetch(db) - .try_collect() - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultList { results }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct ILogErrorQueryUpdate { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type ILogErrorUpdate = ILogErrorQueryUpdate; -pub type ILogErrorUpdateResolve = IResultPass; - -pub async fn lib_model_log_error_update( - db: &sqlx::Pool<sqlx::Sqlite>, - opts: ILogErrorUpdate, -) -> Result<ILogErrorUpdateResolve, ModelError> { - let mut query_builder = sqlx::query(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} - -pub type ILogErrorDelete = LogErrorQueryBindValues; -pub type ILogErrorDeleteResolve = IResultPass; - -pub async fn lib_model_log_error_delete( - db: &DatabaseConnection, - opts: ILogErrorDelete, -) -> Result<ILogErrorDeleteResolve, ModelError> { - let (bv_k, bv) = log_error_query_bind_values(opts); - let query = format!("DELETE FROM log_error WHERE {} = ?1;", bv_k); - let result = sqlx::query(&query) - .bind(bv) - .execute(db) - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - if result.rows_affected() > 0 { - Ok(IResultPass { pass: true }) - } else { - Err(ModelError::NotFound("model.log_error.name".to_string())) - } -} diff --git a/crates/model/src/tables/media_image.rs b/crates/model/src/tables/media_image.rs @@ -1,233 +0,0 @@ -use futures::TryStreamExt; -use tangle_core::{ - types::{IModelsQueryBindValueTuple, IResult, IResultList, IResultPass}, - util::{time_created_on, uuidv4}, -}; - -use crate::{error::ModelError, types::DatabaseConnection, util::parse_query_value}; - -#[derive(Debug, serde::Serialize, serde::Deserialize, sqlx::FromRow)] -pub struct MediaImage { - id: String, - created_at: String, - updated_at: String, - file_path: String, - mime_type: String, - res_base: String, - res_path: String, - label: Option<String>, - description: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct IMediaImageFields { - pub file_path: String, - pub mime_type: String, - pub res_base: String, - pub res_path: String, - pub label: Option<String>, - pub description: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct IMediaImageFieldsPartial { - pub file_path: Option<String>, - pub mime_type: Option<String>, - pub res_base: Option<String>, - pub res_path: Option<String>, - pub label: Option<String>, - pub description: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct IMediaImageFieldsFilter { - pub created_at: Option<String>, - pub updated_at: Option<String>, - pub file_path: Option<String>, - pub mime_type: Option<String>, - pub res_base: Option<String>, - pub res_path: Option<String>, - pub label: Option<String>, - pub description: Option<String>, -} - -#[derive(Clone, serde::Serialize, serde::Deserialize)] -#[serde(untagged)] -pub enum MediaImageQueryBindValues { - Id { id: String }, - FilePath { file_path: String }, -} - -pub fn media_image_query_bind_values(opts: MediaImageQueryBindValues) -> IModelsQueryBindValueTuple { - match opts { - MediaImageQueryBindValues::Id { id } => ("id".to_string(), id), - MediaImageQueryBindValues::FilePath { file_path } => ("file_path".to_string(), file_path), - } -} - -fn lib_table_media_image_parse_fields( - opts: IMediaImageFields, -) -> Result<serde_json::Map<String, serde_json::Value>, ModelError> { - let fields = serde_json::to_value(opts) - .map_err(|err| ModelError::SerializationError(err.to_string()))? - .as_object() - .ok_or_else(|| ModelError::SerializationError("Expected an object".to_string()))? - .clone(); - Ok(fields) -} - -pub type IMediaImageCreate = IMediaImageFields; -pub type IMediaImageCreateResolve = IResult<String>; - -pub async fn lib_model_media_image_create( - db: &DatabaseConnection, - opts: IMediaImageCreate, -) -> Result<IMediaImageCreateResolve, ModelError> { - let id: String = uuidv4(); - let created_at: String = time_created_on(); - let updated_at: String = created_at.clone(); - let fields = lib_table_media_image_parse_fields(opts)?; - - let query = format!( - "INSERT INTO media_image (id, created_at, updated_at, {}) VALUES (?, ?, ?, {});", - fields - .keys() - .map(|k| k.to_string()) - .collect::<Vec<String>>() - .join(","), - (0..fields.len()) - .map(|_| "?") - .collect::<Vec<&str>>() - .join(",") - ); - - let mut query_builder = sqlx::query(&query); - query_builder = query_builder.bind(&id); - query_builder = query_builder.bind(&created_at); - query_builder = query_builder.bind(&updated_at); - for (_, value) in fields.iter() { - match value { - serde_json::Value::Bool(b) => { - let bool_str = if *b { "1" } else { "0" }; - query_builder = query_builder.bind(bool_str); - } - serde_json::Value::Number(n) => { - if let Some(f) = n.as_f64() { - query_builder = query_builder.bind(f); - } else if let Some(i64) = n.as_i64() { - query_builder = query_builder.bind(i64); - } else if let Some(u64) = n.as_u64() { - if u64 <= u32::MAX as u64 { - query_builder = query_builder.bind(u64 as u32); - } - } - } - serde_json::Value::String(s) => { - query_builder = query_builder.bind(s); - } - _ => { - query_builder = query_builder.bind::<Option<serde_json::Value>>(None); - } - } - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResult { result: id }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct IMediaImageQueryRead { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type IMediaImageRead = IMediaImageQueryRead; -pub type IMediaImageReadResolve = IResultList<MediaImage>; - -pub async fn lib_model_media_image_read( - db: &DatabaseConnection, - opts: IMediaImageRead, -) -> Result<IMediaImageReadResolve, ModelError> { - let mut query_builder = sqlx::query_as::<_, MediaImage>(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - let results = query_builder - .fetch(db) - .try_collect() - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultList { results }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct IMediaImageQueryReadList { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type IMediaImageReadList = IMediaImageQueryReadList; -pub type IMediaImageReadListResolve = IResultList<MediaImage>; - -pub async fn lib_model_media_image_read_list( - db: &DatabaseConnection, - opts: IMediaImageReadList, -) -> Result<IMediaImageReadListResolve, ModelError> { - let mut query_builder = sqlx::query_as::<_, MediaImage>(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - let results = query_builder - .fetch(db) - .try_collect() - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultList { results }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct IMediaImageQueryUpdate { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type IMediaImageUpdate = IMediaImageQueryUpdate; -pub type IMediaImageUpdateResolve = IResultPass; - -pub async fn lib_model_media_image_update( - db: &sqlx::Pool<sqlx::Sqlite>, - opts: IMediaImageUpdate, -) -> Result<IMediaImageUpdateResolve, ModelError> { - let mut query_builder = sqlx::query(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} - -pub type IMediaImageDelete = MediaImageQueryBindValues; -pub type IMediaImageDeleteResolve = IResultPass; - -pub async fn lib_model_media_image_delete( - db: &DatabaseConnection, - opts: IMediaImageDelete, -) -> Result<IMediaImageDeleteResolve, ModelError> { - let (bv_k, bv) = media_image_query_bind_values(opts); - let query = format!("DELETE FROM media_image WHERE {} = ?1;", bv_k); - let result = sqlx::query(&query) - .bind(bv) - .execute(db) - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - if result.rows_affected() > 0 { - Ok(IResultPass { pass: true }) - } else { - Err(ModelError::NotFound("model.media_image.name".to_string())) - } -} diff --git a/crates/model/src/tables/mod.rs b/crates/model/src/tables/mod.rs @@ -1,23 +0,0 @@ -use crate::{error::ModelError, types::DatabaseConnection}; -use tangle_core::types::IResultPass; - -pub mod farm; -pub mod farm_location; -pub mod location_gcs; -pub mod log_error; -pub mod media_image; -pub mod nostr_profile; -pub mod nostr_profile_relay; -pub mod nostr_relay; -pub mod trade_product; -pub mod trade_product_location; -pub mod trade_product_media; - -pub async fn lib_model_tables_reset(db: &DatabaseConnection) -> Result<IResultPass, ModelError> { - let query = format!("DELETE FROM location_gcs; DELETE FROM trade_product; DELETE FROM nostr_profile; DELETE FROM nostr_relay; DELETE FROM media_image; DELETE FROM log_error; DELETE FROM farm;DELETE FROM nostr_profile_relay; DELETE FROM farm_location; DELETE FROM trade_product_location; DELETE FROM trade_product_media;"); - sqlx::query(&query) - .execute(db) - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} diff --git a/crates/model/src/tables/nostr_profile.rs b/crates/model/src/tables/nostr_profile.rs @@ -1,249 +0,0 @@ -use futures::TryStreamExt; -use tangle_core::{ - types::{IModelsQueryBindValueTuple, IResult, IResultList, IResultPass}, - util::{time_created_on, uuidv4}, -}; - -use crate::{error::ModelError, types::DatabaseConnection, util::parse_query_value}; - -#[derive(Debug, serde::Serialize, serde::Deserialize, sqlx::FromRow)] -pub struct NostrProfile { - id: String, - created_at: String, - updated_at: String, - public_key: String, - name: Option<String>, - display_name: Option<String>, - about: Option<String>, - website: Option<String>, - picture: Option<String>, - banner: Option<String>, - nip05: Option<String>, - lud06: Option<String>, - lud16: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct INostrProfileFields { - pub public_key: String, - pub name: Option<String>, - pub display_name: Option<String>, - pub about: Option<String>, - pub website: Option<String>, - pub picture: Option<String>, - pub banner: Option<String>, - pub nip05: Option<String>, - pub lud06: Option<String>, - pub lud16: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct INostrProfileFieldsPartial { - pub public_key: Option<String>, - pub name: Option<String>, - pub display_name: Option<String>, - pub about: Option<String>, - pub website: Option<String>, - pub picture: Option<String>, - pub banner: Option<String>, - pub nip05: Option<String>, - pub lud06: Option<String>, - pub lud16: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct INostrProfileFieldsFilter { - pub created_at: Option<String>, - pub updated_at: Option<String>, - pub public_key: Option<String>, - pub name: Option<String>, - pub display_name: Option<String>, - pub about: Option<String>, - pub website: Option<String>, - pub picture: Option<String>, - pub banner: Option<String>, - pub nip05: Option<String>, - pub lud06: Option<String>, - pub lud16: Option<String>, -} - -#[derive(Clone, serde::Serialize, serde::Deserialize)] -#[serde(untagged)] -pub enum NostrProfileQueryBindValues { - Id { id: String }, - PublicKey { public_key: String }, -} - -pub fn nostr_profile_query_bind_values(opts: NostrProfileQueryBindValues) -> IModelsQueryBindValueTuple { - match opts { - NostrProfileQueryBindValues::Id { id } => ("id".to_string(), id), - NostrProfileQueryBindValues::PublicKey { public_key } => ("public_key".to_string(), public_key), - } -} - -fn lib_table_nostr_profile_parse_fields( - opts: INostrProfileFields, -) -> Result<serde_json::Map<String, serde_json::Value>, ModelError> { - let fields = serde_json::to_value(opts) - .map_err(|err| ModelError::SerializationError(err.to_string()))? - .as_object() - .ok_or_else(|| ModelError::SerializationError("Expected an object".to_string()))? - .clone(); - Ok(fields) -} - -pub type INostrProfileCreate = INostrProfileFields; -pub type INostrProfileCreateResolve = IResult<String>; - -pub async fn lib_model_nostr_profile_create( - db: &DatabaseConnection, - opts: INostrProfileCreate, -) -> Result<INostrProfileCreateResolve, ModelError> { - let id: String = uuidv4(); - let created_at: String = time_created_on(); - let updated_at: String = created_at.clone(); - let fields = lib_table_nostr_profile_parse_fields(opts)?; - - let query = format!( - "INSERT INTO nostr_profile (id, created_at, updated_at, {}) VALUES (?, ?, ?, {});", - fields - .keys() - .map(|k| k.to_string()) - .collect::<Vec<String>>() - .join(","), - (0..fields.len()) - .map(|_| "?") - .collect::<Vec<&str>>() - .join(",") - ); - - let mut query_builder = sqlx::query(&query); - query_builder = query_builder.bind(&id); - query_builder = query_builder.bind(&created_at); - query_builder = query_builder.bind(&updated_at); - for (_, value) in fields.iter() { - match value { - serde_json::Value::Bool(b) => { - let bool_str = if *b { "1" } else { "0" }; - query_builder = query_builder.bind(bool_str); - } - serde_json::Value::Number(n) => { - if let Some(f) = n.as_f64() { - query_builder = query_builder.bind(f); - } else if let Some(i64) = n.as_i64() { - query_builder = query_builder.bind(i64); - } else if let Some(u64) = n.as_u64() { - if u64 <= u32::MAX as u64 { - query_builder = query_builder.bind(u64 as u32); - } - } - } - serde_json::Value::String(s) => { - query_builder = query_builder.bind(s); - } - _ => { - query_builder = query_builder.bind::<Option<serde_json::Value>>(None); - } - } - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResult { result: id }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct INostrProfileQueryRead { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type INostrProfileRead = INostrProfileQueryRead; -pub type INostrProfileReadResolve = IResultList<NostrProfile>; - -pub async fn lib_model_nostr_profile_read( - db: &DatabaseConnection, - opts: INostrProfileRead, -) -> Result<INostrProfileReadResolve, ModelError> { - let mut query_builder = sqlx::query_as::<_, NostrProfile>(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - let results = query_builder - .fetch(db) - .try_collect() - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultList { results }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct INostrProfileQueryReadList { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type INostrProfileReadList = INostrProfileQueryReadList; -pub type INostrProfileReadListResolve = IResultList<NostrProfile>; - -pub async fn lib_model_nostr_profile_read_list( - db: &DatabaseConnection, - opts: INostrProfileReadList, -) -> Result<INostrProfileReadListResolve, ModelError> { - let mut query_builder = sqlx::query_as::<_, NostrProfile>(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - let results = query_builder - .fetch(db) - .try_collect() - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultList { results }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct INostrProfileQueryUpdate { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type INostrProfileUpdate = INostrProfileQueryUpdate; -pub type INostrProfileUpdateResolve = IResultPass; - -pub async fn lib_model_nostr_profile_update( - db: &sqlx::Pool<sqlx::Sqlite>, - opts: INostrProfileUpdate, -) -> Result<INostrProfileUpdateResolve, ModelError> { - let mut query_builder = sqlx::query(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} - -pub type INostrProfileDelete = NostrProfileQueryBindValues; -pub type INostrProfileDeleteResolve = IResultPass; - -pub async fn lib_model_nostr_profile_delete( - db: &DatabaseConnection, - opts: INostrProfileDelete, -) -> Result<INostrProfileDeleteResolve, ModelError> { - let (bv_k, bv) = nostr_profile_query_bind_values(opts); - let query = format!("DELETE FROM nostr_profile WHERE {} = ?1;", bv_k); - let result = sqlx::query(&query) - .bind(bv) - .execute(db) - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - if result.rows_affected() > 0 { - Ok(IResultPass { pass: true }) - } else { - Err(ModelError::NotFound("model.nostr_profile.name".to_string())) - } -} diff --git a/crates/model/src/tables/nostr_profile_relay.rs b/crates/model/src/tables/nostr_profile_relay.rs @@ -1,58 +0,0 @@ -use super::{ - nostr_profile::{nostr_profile_query_bind_values, NostrProfileQueryBindValues}, - nostr_relay::{nostr_relay_query_bind_values, NostrRelayQueryBindValues}, -}; -use crate::{error::ModelError, types::DatabaseConnection}; -use tangle_core::types::IResultPass; - -#[derive(serde::Serialize, serde::Deserialize, sqlx::FromRow)] -pub struct NostrProfileRelay { - tb_pr: String, - tb_rl: String, -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct INostrProfileRelayTables { - pub nostr_profile: NostrProfileQueryBindValues, - pub nostr_relay: NostrRelayQueryBindValues, -} - -pub type INostrProfileRelayRelation = INostrProfileRelayTables; -pub type INostrProfileRelayResolve = IResultPass; - -pub async fn lib_model_nostr_profile_relay_set( - db: &DatabaseConnection, - opts: INostrProfileRelayRelation, -) -> Result<INostrProfileRelayResolve, ModelError> { - let (bv_pr_k, bv_pr) = nostr_profile_query_bind_values(opts.nostr_profile); - let (bv_rl_k, bv_rl) = nostr_relay_query_bind_values(opts.nostr_relay); - let query_vals = vec![bv_pr, bv_rl]; - let query = format!("INSERT INTO nostr_profile_relay (tb_pr, tb_rl) VALUES ((SELECT id FROM nostr_profile WHERE {} = ?), (SELECT id FROM nostr_relay WHERE {} = ?));", bv_pr_k, bv_rl_k); - let mut query_builder = sqlx::query(&query); - for value in query_vals.iter() { - query_builder = query_builder.bind(value); - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} -pub async fn lib_model_nostr_profile_relay_unset( - db: &DatabaseConnection, - opts: INostrProfileRelayRelation, -) -> Result<INostrProfileRelayResolve, ModelError> { - let (bv_pr_k, bv_pr) = nostr_profile_query_bind_values(opts.nostr_profile); - let (bv_rl_k, bv_rl) = nostr_relay_query_bind_values(opts.nostr_relay); - let query_vals = vec![bv_pr, bv_rl]; - let query = format!("DELETE FROM nostr_profile_relay WHERE tb_pr = (SELECT id FROM nostr_profile WHERE {} = ?) AND tb_rl = (SELECT id FROM nostr_relay WHERE {} = ?);", bv_pr_k, bv_rl_k); - let mut query_builder = sqlx::query(&query); - for value in query_vals.iter() { - query_builder = query_builder.bind(value); - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} diff --git a/crates/model/src/tables/nostr_relay.rs b/crates/model/src/tables/nostr_relay.rs @@ -1,249 +0,0 @@ -use futures::TryStreamExt; -use tangle_core::{ - types::{IModelsQueryBindValueTuple, IResult, IResultList, IResultPass}, - util::{time_created_on, uuidv4}, -}; - -use crate::{error::ModelError, types::DatabaseConnection, util::parse_query_value}; - -#[derive(Debug, serde::Serialize, serde::Deserialize, sqlx::FromRow)] -pub struct NostrRelay { - id: String, - created_at: String, - updated_at: String, - url: String, - relay_id: Option<String>, - name: Option<String>, - description: Option<String>, - pubkey: Option<String>, - contact: Option<String>, - supported_nips: Option<String>, - software: Option<String>, - version: Option<String>, - data: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct INostrRelayFields { - pub url: String, - pub relay_id: Option<String>, - pub name: Option<String>, - pub description: Option<String>, - pub pubkey: Option<String>, - pub contact: Option<String>, - pub supported_nips: Option<String>, - pub software: Option<String>, - pub version: Option<String>, - pub data: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct INostrRelayFieldsPartial { - pub url: Option<String>, - pub relay_id: Option<String>, - pub name: Option<String>, - pub description: Option<String>, - pub pubkey: Option<String>, - pub contact: Option<String>, - pub supported_nips: Option<String>, - pub software: Option<String>, - pub version: Option<String>, - pub data: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct INostrRelayFieldsFilter { - pub created_at: Option<String>, - pub updated_at: Option<String>, - pub url: Option<String>, - pub relay_id: Option<String>, - pub name: Option<String>, - pub description: Option<String>, - pub pubkey: Option<String>, - pub contact: Option<String>, - pub supported_nips: Option<String>, - pub software: Option<String>, - pub version: Option<String>, - pub data: Option<String>, -} - -#[derive(Clone, serde::Serialize, serde::Deserialize)] -#[serde(untagged)] -pub enum NostrRelayQueryBindValues { - Id { id: String }, - Url { url: String }, -} - -pub fn nostr_relay_query_bind_values(opts: NostrRelayQueryBindValues) -> IModelsQueryBindValueTuple { - match opts { - NostrRelayQueryBindValues::Id { id } => ("id".to_string(), id), - NostrRelayQueryBindValues::Url { url } => ("url".to_string(), url), - } -} - -fn lib_table_nostr_relay_parse_fields( - opts: INostrRelayFields, -) -> Result<serde_json::Map<String, serde_json::Value>, ModelError> { - let fields = serde_json::to_value(opts) - .map_err(|err| ModelError::SerializationError(err.to_string()))? - .as_object() - .ok_or_else(|| ModelError::SerializationError("Expected an object".to_string()))? - .clone(); - Ok(fields) -} - -pub type INostrRelayCreate = INostrRelayFields; -pub type INostrRelayCreateResolve = IResult<String>; - -pub async fn lib_model_nostr_relay_create( - db: &DatabaseConnection, - opts: INostrRelayCreate, -) -> Result<INostrRelayCreateResolve, ModelError> { - let id: String = uuidv4(); - let created_at: String = time_created_on(); - let updated_at: String = created_at.clone(); - let fields = lib_table_nostr_relay_parse_fields(opts)?; - - let query = format!( - "INSERT INTO nostr_relay (id, created_at, updated_at, {}) VALUES (?, ?, ?, {});", - fields - .keys() - .map(|k| k.to_string()) - .collect::<Vec<String>>() - .join(","), - (0..fields.len()) - .map(|_| "?") - .collect::<Vec<&str>>() - .join(",") - ); - - let mut query_builder = sqlx::query(&query); - query_builder = query_builder.bind(&id); - query_builder = query_builder.bind(&created_at); - query_builder = query_builder.bind(&updated_at); - for (_, value) in fields.iter() { - match value { - serde_json::Value::Bool(b) => { - let bool_str = if *b { "1" } else { "0" }; - query_builder = query_builder.bind(bool_str); - } - serde_json::Value::Number(n) => { - if let Some(f) = n.as_f64() { - query_builder = query_builder.bind(f); - } else if let Some(i64) = n.as_i64() { - query_builder = query_builder.bind(i64); - } else if let Some(u64) = n.as_u64() { - if u64 <= u32::MAX as u64 { - query_builder = query_builder.bind(u64 as u32); - } - } - } - serde_json::Value::String(s) => { - query_builder = query_builder.bind(s); - } - _ => { - query_builder = query_builder.bind::<Option<serde_json::Value>>(None); - } - } - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResult { result: id }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct INostrRelayQueryRead { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type INostrRelayRead = INostrRelayQueryRead; -pub type INostrRelayReadResolve = IResultList<NostrRelay>; - -pub async fn lib_model_nostr_relay_read( - db: &DatabaseConnection, - opts: INostrRelayRead, -) -> Result<INostrRelayReadResolve, ModelError> { - let mut query_builder = sqlx::query_as::<_, NostrRelay>(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - let results = query_builder - .fetch(db) - .try_collect() - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultList { results }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct INostrRelayQueryReadList { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type INostrRelayReadList = INostrRelayQueryReadList; -pub type INostrRelayReadListResolve = IResultList<NostrRelay>; - -pub async fn lib_model_nostr_relay_read_list( - db: &DatabaseConnection, - opts: INostrRelayReadList, -) -> Result<INostrRelayReadListResolve, ModelError> { - let mut query_builder = sqlx::query_as::<_, NostrRelay>(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - let results = query_builder - .fetch(db) - .try_collect() - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultList { results }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct INostrRelayQueryUpdate { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type INostrRelayUpdate = INostrRelayQueryUpdate; -pub type INostrRelayUpdateResolve = IResultPass; - -pub async fn lib_model_nostr_relay_update( - db: &sqlx::Pool<sqlx::Sqlite>, - opts: INostrRelayUpdate, -) -> Result<INostrRelayUpdateResolve, ModelError> { - let mut query_builder = sqlx::query(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} - -pub type INostrRelayDelete = NostrRelayQueryBindValues; -pub type INostrRelayDeleteResolve = IResultPass; - -pub async fn lib_model_nostr_relay_delete( - db: &DatabaseConnection, - opts: INostrRelayDelete, -) -> Result<INostrRelayDeleteResolve, ModelError> { - let (bv_k, bv) = nostr_relay_query_bind_values(opts); - let query = format!("DELETE FROM nostr_relay WHERE {} = ?1;", bv_k); - let result = sqlx::query(&query) - .bind(bv) - .execute(db) - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - if result.rows_affected() > 0 { - Ok(IResultPass { pass: true }) - } else { - Err(ModelError::NotFound("model.nostr_relay.name".to_string())) - } -} diff --git a/crates/model/src/tables/trade_product.rs b/crates/model/src/tables/trade_product.rs @@ -1,275 +0,0 @@ -use futures::TryStreamExt; -use tangle_core::{ - types::{IModelsQueryBindValueTuple, IResult, IResultList, IResultPass}, - util::{time_created_on, uuidv4}, -}; - -use crate::{error::ModelError, types::DatabaseConnection, util::parse_query_value}; - -#[derive(Debug, serde::Serialize, serde::Deserialize, sqlx::FromRow)] -pub struct TradeProduct { - id: String, - created_at: String, - updated_at: String, - key: String, - category: String, - title: String, - summary: String, - process: String, - lot: String, - profile: String, - year: i64, - qty_amt: i64, - qty_unit: String, - qty_label: Option<String>, - qty_avail: Option<i64>, - price_amt: f64, - price_currency: String, - price_qty_amt: u32, - price_qty_unit: String, - notes: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct ITradeProductFields { - pub key: String, - pub category: String, - pub title: String, - pub summary: String, - pub process: String, - pub lot: String, - pub profile: String, - pub year: i64, - pub qty_amt: i64, - pub qty_unit: String, - pub qty_label: Option<String>, - pub qty_avail: Option<i64>, - pub price_amt: f64, - pub price_currency: String, - pub price_qty_amt: u32, - pub price_qty_unit: String, - pub notes: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct ITradeProductFieldsPartial { - pub key: Option<String>, - pub category: Option<String>, - pub title: Option<String>, - pub summary: Option<String>, - pub process: Option<String>, - pub lot: Option<String>, - pub profile: Option<String>, - pub year: Option<i64>, - pub qty_amt: Option<i64>, - pub qty_unit: Option<String>, - pub qty_label: Option<String>, - pub qty_avail: Option<i64>, - pub price_amt: Option<f64>, - pub price_currency: Option<String>, - pub price_qty_amt: Option<u32>, - pub price_qty_unit: Option<String>, - pub notes: Option<String>, -} - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct ITradeProductFieldsFilter { - pub created_at: Option<String>, - pub updated_at: Option<String>, - pub key: Option<String>, - pub category: Option<String>, - pub title: Option<String>, - pub summary: Option<String>, - pub process: Option<String>, - pub lot: Option<String>, - pub profile: Option<String>, - pub year: Option<String>, - pub qty_amt: Option<String>, - pub qty_unit: Option<String>, - pub qty_label: Option<String>, - pub qty_avail: Option<String>, - pub price_amt: Option<String>, - pub price_currency: Option<String>, - pub price_qty_amt: Option<String>, - pub price_qty_unit: Option<String>, - pub notes: Option<String>, -} - -#[derive(Clone, serde::Serialize, serde::Deserialize)] -#[serde(untagged)] -pub enum TradeProductQueryBindValues { - Id { id: String }, -} - -pub fn trade_product_query_bind_values(opts: TradeProductQueryBindValues) -> IModelsQueryBindValueTuple { - match opts { - TradeProductQueryBindValues::Id { id } => ("id".to_string(), id), - } -} - -fn lib_table_trade_product_parse_fields( - opts: ITradeProductFields, -) -> Result<serde_json::Map<String, serde_json::Value>, ModelError> { - let fields = serde_json::to_value(opts) - .map_err(|err| ModelError::SerializationError(err.to_string()))? - .as_object() - .ok_or_else(|| ModelError::SerializationError("Expected an object".to_string()))? - .clone(); - Ok(fields) -} - -pub type ITradeProductCreate = ITradeProductFields; -pub type ITradeProductCreateResolve = IResult<String>; - -pub async fn lib_model_trade_product_create( - db: &DatabaseConnection, - opts: ITradeProductCreate, -) -> Result<ITradeProductCreateResolve, ModelError> { - let id: String = uuidv4(); - let created_at: String = time_created_on(); - let updated_at: String = created_at.clone(); - let fields = lib_table_trade_product_parse_fields(opts)?; - - let query = format!( - "INSERT INTO trade_product (id, created_at, updated_at, {}) VALUES (?, ?, ?, {});", - fields - .keys() - .map(|k| k.to_string()) - .collect::<Vec<String>>() - .join(","), - (0..fields.len()) - .map(|_| "?") - .collect::<Vec<&str>>() - .join(",") - ); - - let mut query_builder = sqlx::query(&query); - query_builder = query_builder.bind(&id); - query_builder = query_builder.bind(&created_at); - query_builder = query_builder.bind(&updated_at); - for (_, value) in fields.iter() { - match value { - serde_json::Value::Bool(b) => { - let bool_str = if *b { "1" } else { "0" }; - query_builder = query_builder.bind(bool_str); - } - serde_json::Value::Number(n) => { - if let Some(f) = n.as_f64() { - query_builder = query_builder.bind(f); - } else if let Some(i64) = n.as_i64() { - query_builder = query_builder.bind(i64); - } else if let Some(u64) = n.as_u64() { - if u64 <= u32::MAX as u64 { - query_builder = query_builder.bind(u64 as u32); - } - } - } - serde_json::Value::String(s) => { - query_builder = query_builder.bind(s); - } - _ => { - query_builder = query_builder.bind::<Option<serde_json::Value>>(None); - } - } - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResult { result: id }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct ITradeProductQueryRead { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type ITradeProductRead = ITradeProductQueryRead; -pub type ITradeProductReadResolve = IResultList<TradeProduct>; - -pub async fn lib_model_trade_product_read( - db: &DatabaseConnection, - opts: ITradeProductRead, -) -> Result<ITradeProductReadResolve, ModelError> { - let mut query_builder = sqlx::query_as::<_, TradeProduct>(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - let results = query_builder - .fetch(db) - .try_collect() - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultList { results }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct ITradeProductQueryReadList { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type ITradeProductReadList = ITradeProductQueryReadList; -pub type ITradeProductReadListResolve = IResultList<TradeProduct>; - -pub async fn lib_model_trade_product_read_list( - db: &DatabaseConnection, - opts: ITradeProductReadList, -) -> Result<ITradeProductReadListResolve, ModelError> { - let mut query_builder = sqlx::query_as::<_, TradeProduct>(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - let results = query_builder - .fetch(db) - .try_collect() - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultList { results }) -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct ITradeProductQueryUpdate { - pub query: String, - pub bind_values: Vec<serde_json::Value>, -} - -pub type ITradeProductUpdate = ITradeProductQueryUpdate; -pub type ITradeProductUpdateResolve = IResultPass; - -pub async fn lib_model_trade_product_update( - db: &sqlx::Pool<sqlx::Sqlite>, - opts: ITradeProductUpdate, -) -> Result<ITradeProductUpdateResolve, ModelError> { - let mut query_builder = sqlx::query(&opts.query); - for value in opts.bind_values.iter() { - query_builder = query_builder.bind(parse_query_value(value)?); - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} - -pub type ITradeProductDelete = TradeProductQueryBindValues; -pub type ITradeProductDeleteResolve = IResultPass; - -pub async fn lib_model_trade_product_delete( - db: &DatabaseConnection, - opts: ITradeProductDelete, -) -> Result<ITradeProductDeleteResolve, ModelError> { - let (bv_k, bv) = trade_product_query_bind_values(opts); - let query = format!("DELETE FROM trade_product WHERE {} = ?1;", bv_k); - let result = sqlx::query(&query) - .bind(bv) - .execute(db) - .await - .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; - if result.rows_affected() > 0 { - Ok(IResultPass { pass: true }) - } else { - Err(ModelError::NotFound("model.trade_product.name".to_string())) - } -} diff --git a/crates/model/src/tables/trade_product_location.rs b/crates/model/src/tables/trade_product_location.rs @@ -1,58 +0,0 @@ -use super::{ - location_gcs::{location_gcs_query_bind_values, LocationGcsQueryBindValues}, - trade_product::{trade_product_query_bind_values, TradeProductQueryBindValues}, -}; -use crate::{error::ModelError, types::DatabaseConnection}; -use tangle_core::types::IResultPass; - -#[derive(serde::Serialize, serde::Deserialize, sqlx::FromRow)] -pub struct TradeProductLocation { - tb_tp: String, - tb_lg: String, -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct ITradeProductLocationTables { - pub trade_product: TradeProductQueryBindValues, - pub location_gcs: LocationGcsQueryBindValues, -} - -pub type ITradeProductLocationRelation = ITradeProductLocationTables; -pub type ITradeProductLocationResolve = IResultPass; - -pub async fn lib_model_trade_product_location_set( - db: &DatabaseConnection, - opts: ITradeProductLocationRelation, -) -> Result<ITradeProductLocationResolve, ModelError> { - let (bv_tp_k, bv_tp) = trade_product_query_bind_values(opts.trade_product); - let (bv_lg_k, bv_lg) = location_gcs_query_bind_values(opts.location_gcs); - let query_vals = vec![bv_tp, bv_lg]; - let query = format!("INSERT INTO trade_product_location (tb_tp, tb_lg) VALUES ((SELECT id FROM trade_product WHERE {} = ?), (SELECT id FROM location_gcs WHERE {} = ?));", bv_tp_k, bv_lg_k); - let mut query_builder = sqlx::query(&query); - for value in query_vals.iter() { - query_builder = query_builder.bind(value); - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} -pub async fn lib_model_trade_product_location_unset( - db: &DatabaseConnection, - opts: ITradeProductLocationRelation, -) -> Result<ITradeProductLocationResolve, ModelError> { - let (bv_tp_k, bv_tp) = trade_product_query_bind_values(opts.trade_product); - let (bv_lg_k, bv_lg) = location_gcs_query_bind_values(opts.location_gcs); - let query_vals = vec![bv_tp, bv_lg]; - let query = format!("DELETE FROM trade_product_location WHERE tb_tp = (SELECT id FROM trade_product WHERE {} = ?) AND tb_lg = (SELECT id FROM location_gcs WHERE {} = ?);", bv_tp_k, bv_lg_k); - let mut query_builder = sqlx::query(&query); - for value in query_vals.iter() { - query_builder = query_builder.bind(value); - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} diff --git a/crates/model/src/tables/trade_product_media.rs b/crates/model/src/tables/trade_product_media.rs @@ -1,58 +0,0 @@ -use super::{ - media_image::{media_image_query_bind_values, MediaImageQueryBindValues}, - trade_product::{trade_product_query_bind_values, TradeProductQueryBindValues}, -}; -use crate::{error::ModelError, types::DatabaseConnection}; -use tangle_core::types::IResultPass; - -#[derive(serde::Serialize, serde::Deserialize, sqlx::FromRow)] -pub struct TradeProductMedia { - tb_tp: String, - tb_mu: String, -} - -#[derive(serde::Serialize, serde::Deserialize)] -pub struct ITradeProductMediaTables { - pub trade_product: TradeProductQueryBindValues, - pub media_image: MediaImageQueryBindValues, -} - -pub type ITradeProductMediaRelation = ITradeProductMediaTables; -pub type ITradeProductMediaResolve = IResultPass; - -pub async fn lib_model_trade_product_media_set( - db: &DatabaseConnection, - opts: ITradeProductMediaRelation, -) -> Result<ITradeProductMediaResolve, ModelError> { - let (bv_tp_k, bv_tp) = trade_product_query_bind_values(opts.trade_product); - let (bv_mu_k, bv_mu) = media_image_query_bind_values(opts.media_image); - let query_vals = vec![bv_tp, bv_mu]; - let query = format!("INSERT INTO trade_product_media (tb_tp, tb_mu) VALUES ((SELECT id FROM trade_product WHERE {} = ?), (SELECT id FROM media_image WHERE {} = ?));", bv_tp_k, bv_mu_k); - let mut query_builder = sqlx::query(&query); - for value in query_vals.iter() { - query_builder = query_builder.bind(value); - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} -pub async fn lib_model_trade_product_media_unset( - db: &DatabaseConnection, - opts: ITradeProductMediaRelation, -) -> Result<ITradeProductMediaResolve, ModelError> { - let (bv_tp_k, bv_tp) = trade_product_query_bind_values(opts.trade_product); - let (bv_mu_k, bv_mu) = media_image_query_bind_values(opts.media_image); - let query_vals = vec![bv_tp, bv_mu]; - let query = format!("DELETE FROM trade_product_media WHERE tb_tp = (SELECT id FROM trade_product WHERE {} = ?) AND tb_mu = (SELECT id FROM media_image WHERE {} = ?);", bv_tp_k, bv_mu_k); - let mut query_builder = sqlx::query(&query); - for value in query_vals.iter() { - query_builder = query_builder.bind(value); - } - query_builder - .execute(db) - .await - .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; - Ok(IResultPass { pass: true }) -} diff --git a/crates/model/src/types.rs b/crates/model/src/types.rs @@ -1,9 +1,49 @@ -pub type DatabaseConnection = sqlx::Pool<sqlx::Sqlite>; +use serde::{Deserialize, Serialize}; +use tangle_core::types::IResultPass; -#[derive(Debug)] -pub enum ModelsQueryBindValue { +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum BindValue { String(String), Number(f64), Boolean(bool), Null, } + +pub trait ModelExecutor { + fn query_one(&self, sql: &str, binds: &[BindValue]) -> Result<serde_json::Value, String>; + fn query_all(&self, sql: &str, binds: &[BindValue]) -> Result<Vec<serde_json::Value>, String>; + fn execute(&self, sql: &str, binds: &[BindValue]) -> Result<u64, String>; +} + +pub struct WasmDb(pub(crate) crate::wasm_executor::WasmExecutor); + +pub fn new_wasm_db() -> WasmDb { + WasmDb(crate::wasm_executor::WasmExecutor::new()) +} + +impl ModelExecutor for WasmDb { + fn query_one(&self, sql: &str, binds: &[BindValue]) -> Result<serde_json::Value, String> { + self.0.query_one(sql, binds) + } + fn query_all(&self, sql: &str, binds: &[BindValue]) -> Result<Vec<serde_json::Value>, String> { + self.0.query_all(sql, binds) + } + fn execute(&self, sql: &str, binds: &[BindValue]) -> Result<u64, String> { + self.0.execute(sql, binds) + } +} + +pub fn reset_all<E: ModelExecutor>(exec: &E) -> Result<IResultPass, String> { + let sql = "DELETE FROM location_gcs; +DELETE FROM trade_product; +DELETE FROM nostr_profile; +DELETE FROM nostr_relay; +DELETE FROM media_image; +DELETE FROM log_error; +DELETE FROM farm; +DELETE FROM nostr_profile_relay; +DELETE FROM farm_location; +DELETE FROM trade_product_location; +DELETE FROM trade_product_media;"; + exec.execute(sql, &[]).map(|_| IResultPass { pass: true }) +} diff --git a/crates/model/src/util.rs b/crates/model/src/util.rs @@ -1,20 +1,18 @@ -use crate::{error::ModelError, types::DatabaseConnection}; +use crate::error::ModelError; +use crate::types::BindValue; -pub fn parse_query_value(value: &serde_json::Value) -> Result<String, ModelError> { +pub fn parse_query_value(value: &serde_json::Value) -> Result<BindValue, ModelError> { match value { - serde_json::Value::String(s) => Ok(s.to_string()), - serde_json::Value::Number(n) if n.is_i64() => Ok(n.to_string()), - serde_json::Value::Bool(b) => Ok((*b as u8).to_string()), - _ => Err(ModelError::InvalidArgument(format!( - "Unsupported value type: {:?}", - value - ))), + serde_json::Value::String(s) => Ok(BindValue::String(s.clone())), + serde_json::Value::Number(n) => { + Ok(BindValue::Number(n.as_f64().ok_or_else(|| { + ModelError::InvalidArgument("invalid number".to_string()) + })?)) + } + serde_json::Value::Bool(b) => Ok(BindValue::Boolean(*b)), + serde_json::Value::Null => Ok(BindValue::Null), + _ => Err(ModelError::InvalidArgument( + "Unsupported bind value".to_string(), + )), } } - -pub async fn db_conn(db_path: std::path::PathBuf) -> DatabaseConnection { - sqlx::sqlite::SqlitePoolOptions::new() - .connect(db_path.to_str().unwrap()) - .await - .unwrap() -} diff --git a/crates/model/src/wasm_executor.rs b/crates/model/src/wasm_executor.rs @@ -0,0 +1,93 @@ +use serde::{Deserialize, Serialize}; +use serde_wasm_bindgen::{from_value, to_value}; +use wasm_bindgen::prelude::*; + +use crate::types::BindValue; + +#[wasm_bindgen(module = "/web/sdk/sqlite/opfs.js")] +extern "C" { + #[wasm_bindgen(js_name = dbInit)] + fn db_init(name: Option<String>) -> js_sys::Promise; + #[wasm_bindgen(js_name = dbQueryOne)] + fn db_query_one(sql: &str, binds: JsValue) -> JsValue; + #[wasm_bindgen(js_name = dbQueryAll)] + fn db_query_all(sql: &str, binds: JsValue) -> JsValue; + #[wasm_bindgen(js_name = dbExecute)] + fn db_execute(sql: &str, binds: JsValue) -> JsValue; +} + +#[derive(Serialize, Deserialize)] +struct JsBind { + t: &'static str, + s: Option<String>, + n: Option<f64>, + b: Option<bool>, +} + +fn to_js_binds(binds: &[BindValue]) -> JsValue { + let v: Vec<JsBind> = binds + .iter() + .map(|b| match b { + BindValue::String(s) => JsBind { + t: "s", + s: Some(s.clone()), + n: None, + b: None, + }, + BindValue::Number(n) => JsBind { + t: "n", + s: None, + n: Some(*n), + b: None, + }, + BindValue::Boolean(x) => JsBind { + t: "b", + s: None, + n: None, + b: Some(*x), + }, + BindValue::Null => JsBind { + t: "null", + s: None, + n: None, + b: None, + }, + }) + .collect(); + to_value(&v).unwrap_or(JsValue::NULL) +} + +pub struct WasmExecutor { + _priv: (), +} + +impl WasmExecutor { + pub fn new() -> Self { + Self { _priv: () } + } + + pub async fn init(name: Option<String>) { + let _ = wasm_bindgen_futures::JsFuture::from(db_init(name)).await; + } + + pub fn query_one(&self, sql: &str, binds: &[BindValue]) -> Result<serde_json::Value, String> { + let js = db_query_one(sql, to_js_binds(binds)); + from_value::<serde_json::Value>(js).map_err(|e| e.to_string()) // ✨ + } + + pub fn query_all( + &self, + sql: &str, + binds: &[BindValue], + ) -> Result<Vec<serde_json::Value>, String> { + let js = db_query_all(sql, to_js_binds(binds)); + from_value::<Vec<serde_json::Value>>(js).map_err(|e| e.to_string()) // ✨ + } + + pub fn execute(&self, sql: &str, binds: &[BindValue]) -> Result<u64, String> { + let js = db_execute(sql, to_js_binds(binds)); + js.as_f64() + .map(|n| n as u64) + .ok_or_else(|| "execute failed".to_string()) + } +} diff --git a/crates/model/web/sdk/sqlite/opfs.js b/crates/model/web/sdk/sqlite/opfs.js @@ -0,0 +1,27 @@ +// crates/model/web/sdk/sqlite/opfs.js +// Minimal JS bridge stub for wasm_bindgen module interop. +// Extend these functions to integrate actual SQLite OPFS logic. + +export async function db_init(name) { + console.log("[opfs.js] db_init:", name); + // Placeholder: Initialize your OPFS-based SQLite database here + return true; +} + +export function db_query_one(sql, binds) { + console.log("[opfs.js] db_query_one:", sql, binds); + // Placeholder: Run a SQL query returning a single row + return null; +} + +export function db_query_all(sql, binds) { + console.log("[opfs.js] db_query_all:", sql, binds); + // Placeholder: Run a SQL query returning all rows + return []; +} + +export function db_execute(sql, binds) { + console.log("[opfs.js] db_execute:", sql, binds); + // Placeholder: Execute a SQL statement (INSERT, UPDATE, DELETE) + return true; +} diff --git a/crates/radroots-common b/crates/radroots-common @@ -1 +0,0 @@ -Subproject commit 0cad39ff98de6e8d7f27b42588ff9917309de886 diff --git a/crates/tangle/.gitignore b/crates/tangle/.gitignore @@ -1,4 +0,0 @@ -# Generated by Cargo -# will have compiled files and executables -/target/ -/gen/schemas diff --git a/crates/tangle/Cargo.toml b/crates/tangle/Cargo.toml @@ -1,32 +0,0 @@ -[package] -name = "tangle" -version = "0.0.1" -authors = ["Radroots Authors"] -license = "GPLv3" -edition = "2021" -rust-version = "1.77.2" - -[lib] -name = "tangle_lib" -crate-type = ["staticlib", "cdylib", "rlib"] - -[build-dependencies] -tauri-build = { version = "2.0.0", features = [] } - -[dependencies] -tauri = { version = "2.2.0", features = ["protocol-asset"] } -tauri-plugin-dialog = { path = "../../../lib/plugins-workspace/plugins/dialog" } -tauri-plugin-fs = { path = "../../../lib/plugins-workspace/plugins/fs" } -tauri-plugin-geolocation = { path = "../../../lib/plugins-workspace/plugins/geolocation" } -tauri-plugin-http = { path = "../../../lib/plugins-workspace/plugins/http" } -tauri-plugin-notification = { path = "../../../lib/plugins-workspace/plugins/notification" } -tauri-plugin-os = { path = "../../../lib/plugins-workspace/plugins/os" } -tauri-plugin-store = { path = "../../../lib/plugins-workspace/plugins/store" } -tauri-plugin-shell = { path = "../../../lib/plugins-workspace/plugins/shell" } - -tangle_core = { path = "../core" } -tangle_model = { path = "../model" } - -serde = "1.0" -serde_json = "1.0" -sqlx = { version = "0.8.2", features = ["sqlite", "runtime-tokio"] } diff --git a/crates/tangle/LICENSE b/crates/tangle/LICENSE @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - <program> Copyright (C) <year> <name of author> - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -<https://www.gnu.org/licenses/>. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -<https://www.gnu.org/licenses/why-not-lgpl.html>. -\ No newline at end of file diff --git a/crates/tangle/build.rs b/crates/tangle/build.rs @@ -1,3 +0,0 @@ -fn main() { - tauri_build::build() -} diff --git a/crates/tangle/capabilities/default.json b/crates/tangle/capabilities/default.json @@ -1,32 +0,0 @@ -{ - "$schema": "../gen/schemas/capabilities.json", - "identifier": "default", - "windows": [ - "main" - ], - "permissions": [ - "core:default", - "dialog:default", - "fs:default", - "fs:allow-stat", - { - "identifier": "http:default", - "allow": [ - { - "url": "https://*" - }, - { - "url": "http://*" - }, - { - "url": "http://127.0.0.1:*" - } - ], - "deny": [] - }, - "notification:default", - "os:default", - "store:default", - "shell:allow-open" - ] -} -\ No newline at end of file diff --git a/crates/tangle/capabilities/desktop.json b/crates/tangle/capabilities/desktop.json @@ -1,13 +0,0 @@ -{ - "$schema": "../gen/schemas/capabilities.json", - "identifier": "desktop", - "windows": [ - "main" - ], - "platforms": [ - "linux", - "macOS", - "windows" - ], - "permissions": [] -} -\ No newline at end of file diff --git a/crates/tangle/capabilities/mobile.json b/crates/tangle/capabilities/mobile.json @@ -1,19 +0,0 @@ -{ - "$schema": "../gen/schemas/mobile-schema.json", - "identifier": "mobile", - "windows": [ - "main" - ], - "platforms": [ - "iOS", - "android" - ], - "permissions": [ - "geolocation:allow-check-permissions", - "geolocation:allow-get-current-position", - "geolocation:allow-request-permissions", - "geolocation:allow-watch-position", - "geolocation:allow-clear-permissions", - "geolocation:allow-clear-watch" - ] -} -\ No newline at end of file diff --git a/crates/tangle/icons/128x128.png b/crates/tangle/icons/128x128.png Binary files differ. diff --git a/crates/tangle/icons/128x128@2x.png b/crates/tangle/icons/128x128@2x.png Binary files differ. diff --git a/crates/tangle/icons/32x32.png b/crates/tangle/icons/32x32.png Binary files differ. diff --git a/crates/tangle/icons/Square107x107Logo.png b/crates/tangle/icons/Square107x107Logo.png Binary files differ. diff --git a/crates/tangle/icons/Square142x142Logo.png b/crates/tangle/icons/Square142x142Logo.png Binary files differ. diff --git a/crates/tangle/icons/Square150x150Logo.png b/crates/tangle/icons/Square150x150Logo.png Binary files differ. diff --git a/crates/tangle/icons/Square284x284Logo.png b/crates/tangle/icons/Square284x284Logo.png Binary files differ. diff --git a/crates/tangle/icons/Square30x30Logo.png b/crates/tangle/icons/Square30x30Logo.png Binary files differ. diff --git a/crates/tangle/icons/Square310x310Logo.png b/crates/tangle/icons/Square310x310Logo.png Binary files differ. diff --git a/crates/tangle/icons/Square44x44Logo.png b/crates/tangle/icons/Square44x44Logo.png Binary files differ. diff --git a/crates/tangle/icons/Square71x71Logo.png b/crates/tangle/icons/Square71x71Logo.png Binary files differ. diff --git a/crates/tangle/icons/Square89x89Logo.png b/crates/tangle/icons/Square89x89Logo.png Binary files differ. diff --git a/crates/tangle/icons/StoreLogo.png b/crates/tangle/icons/StoreLogo.png Binary files differ. diff --git a/crates/tangle/icons/android/mipmap-hdpi/ic_launcher.png b/crates/tangle/icons/android/mipmap-hdpi/ic_launcher.png Binary files differ. diff --git a/crates/tangle/icons/android/mipmap-hdpi/ic_launcher_foreground.png b/crates/tangle/icons/android/mipmap-hdpi/ic_launcher_foreground.png Binary files differ. diff --git a/crates/tangle/icons/android/mipmap-hdpi/ic_launcher_round.png b/crates/tangle/icons/android/mipmap-hdpi/ic_launcher_round.png Binary files differ. diff --git a/crates/tangle/icons/android/mipmap-mdpi/ic_launcher.png b/crates/tangle/icons/android/mipmap-mdpi/ic_launcher.png Binary files differ. diff --git a/crates/tangle/icons/android/mipmap-mdpi/ic_launcher_foreground.png b/crates/tangle/icons/android/mipmap-mdpi/ic_launcher_foreground.png Binary files differ. diff --git a/crates/tangle/icons/android/mipmap-mdpi/ic_launcher_round.png b/crates/tangle/icons/android/mipmap-mdpi/ic_launcher_round.png Binary files differ. diff --git a/crates/tangle/icons/android/mipmap-xhdpi/ic_launcher.png b/crates/tangle/icons/android/mipmap-xhdpi/ic_launcher.png Binary files differ. diff --git a/crates/tangle/icons/android/mipmap-xhdpi/ic_launcher_foreground.png b/crates/tangle/icons/android/mipmap-xhdpi/ic_launcher_foreground.png Binary files differ. diff --git a/crates/tangle/icons/android/mipmap-xhdpi/ic_launcher_round.png b/crates/tangle/icons/android/mipmap-xhdpi/ic_launcher_round.png Binary files differ. diff --git a/crates/tangle/icons/android/mipmap-xxhdpi/ic_launcher.png b/crates/tangle/icons/android/mipmap-xxhdpi/ic_launcher.png Binary files differ. diff --git a/crates/tangle/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png b/crates/tangle/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png Binary files differ. diff --git a/crates/tangle/icons/android/mipmap-xxhdpi/ic_launcher_round.png b/crates/tangle/icons/android/mipmap-xxhdpi/ic_launcher_round.png Binary files differ. diff --git a/crates/tangle/icons/android/mipmap-xxxhdpi/ic_launcher.png b/crates/tangle/icons/android/mipmap-xxxhdpi/ic_launcher.png Binary files differ. diff --git a/crates/tangle/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png b/crates/tangle/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png Binary files differ. diff --git a/crates/tangle/icons/android/mipmap-xxxhdpi/ic_launcher_round.png b/crates/tangle/icons/android/mipmap-xxxhdpi/ic_launcher_round.png Binary files differ. diff --git a/crates/tangle/icons/icon.icns b/crates/tangle/icons/icon.icns Binary files differ. diff --git a/crates/tangle/icons/icon.ico b/crates/tangle/icons/icon.ico Binary files differ. diff --git a/crates/tangle/icons/icon.png b/crates/tangle/icons/icon.png Binary files differ. diff --git a/crates/tangle/migrations/down/0001_location_gcs.sql b/crates/tangle/migrations/down/0001_location_gcs.sql @@ -1 +0,0 @@ -DROP TABLE IF EXISTS location_gcs; -\ No newline at end of file diff --git a/crates/tangle/migrations/down/0002_trade_product.sql b/crates/tangle/migrations/down/0002_trade_product.sql @@ -1 +0,0 @@ -DROP TABLE IF EXISTS trade_product; -\ No newline at end of file diff --git a/crates/tangle/migrations/down/0003_nostr_profile.sql b/crates/tangle/migrations/down/0003_nostr_profile.sql @@ -1 +0,0 @@ -DROP TABLE IF EXISTS nostr_profile; -\ No newline at end of file diff --git a/crates/tangle/migrations/down/0004_nostr_relay.sql b/crates/tangle/migrations/down/0004_nostr_relay.sql @@ -1 +0,0 @@ -DROP TABLE IF EXISTS nostr_relay; -\ No newline at end of file diff --git a/crates/tangle/migrations/down/0005_media_image.sql b/crates/tangle/migrations/down/0005_media_image.sql @@ -1 +0,0 @@ -DROP TABLE IF EXISTS media_image; -\ No newline at end of file diff --git a/crates/tangle/migrations/down/0006_log_error.sql b/crates/tangle/migrations/down/0006_log_error.sql @@ -1 +0,0 @@ -DROP TABLE IF EXISTS log_error; -\ No newline at end of file diff --git a/crates/tangle/migrations/down/0007_farm.sql b/crates/tangle/migrations/down/0007_farm.sql @@ -1 +0,0 @@ -DROP TABLE IF EXISTS farm; -\ No newline at end of file diff --git a/crates/tangle/migrations/down/0008_nostr_profile_relay.sql b/crates/tangle/migrations/down/0008_nostr_profile_relay.sql @@ -1 +0,0 @@ -DROP TABLE IF EXISTS nostr_profile_relay; -\ No newline at end of file diff --git a/crates/tangle/migrations/down/0009_farm_location.sql b/crates/tangle/migrations/down/0009_farm_location.sql @@ -1 +0,0 @@ -DROP TABLE IF EXISTS farm_location; -\ No newline at end of file diff --git a/crates/tangle/migrations/down/0010_trade_product_location.sql b/crates/tangle/migrations/down/0010_trade_product_location.sql @@ -1 +0,0 @@ -DROP TABLE IF EXISTS trade_product_location; -\ No newline at end of file diff --git a/crates/tangle/migrations/down/0011_trade_product_media.sql b/crates/tangle/migrations/down/0011_trade_product_media.sql @@ -1 +0,0 @@ -DROP TABLE IF EXISTS trade_product_media; -\ No newline at end of file diff --git a/crates/tangle/src/app.rs b/crates/tangle/src/app.rs @@ -1,24 +0,0 @@ -use std::path::PathBuf; - -use tangle_model::types::DatabaseConnection; - -use crate::util; - -pub struct Tangle { - pub db: DatabaseConnection, - pub data_dir: PathBuf, - pub logs_dir: PathBuf, -} - -impl Tangle { - pub async fn new(data_dir: PathBuf, logs_dir: PathBuf) -> Self { - util::init_keyring(&data_dir).await; - let db = util::init_db(&data_dir).await; - - Self { - db, - data_dir, - logs_dir, - } - } -} diff --git a/crates/tangle/src/commands/keys.rs b/crates/tangle/src/commands/keys.rs @@ -1,69 +0,0 @@ -use tangle_core::{ - keystore, - nostr::keys::{ - lib_nostr_keys_gen, lib_nostr_keys_parse, lib_nostr_public_key_hex, - lib_nostr_secret_key_hex, - }, - types::{IResult, IResultList, IResultPass}, -}; - -use crate::app::Tangle; - -#[tauri::command(rename_all = "snake_case")] -pub async fn keys_nostr_gen(rr: tauri::State<'_, Tangle>) -> Result<IResult<String>, String> { - let keys = lib_nostr_keys_gen(); - keystore::key_add(&keys, &rr.data_dir).map_err(|e| e.to_string())?; - Ok(IResult { - result: keys.public_key.to_hex(), - }) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn keys_nostr_add( - secret_key: String, - rr: tauri::State<'_, Tangle>, -) -> Result<IResult<String>, String> { - let keys = lib_nostr_keys_parse(secret_key).map_err(|e| e.to_string())?; - keystore::key_add(&keys, &rr.data_dir).map_err(|e| e.to_string())?; - Ok(IResult { - result: lib_nostr_public_key_hex(keys), - }) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn keys_nostr_read( - public_key: String, - rr: tauri::State<'_, Tangle>, -) -> Result<IResult<String>, String> { - let keys = keystore::key_read(&public_key, &rr.data_dir).map_err(|e| e.to_string())?; - Ok(IResult { - result: lib_nostr_secret_key_hex(keys), - }) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn keys_nostr_read_all( - rr: tauri::State<'_, Tangle>, -) -> Result<IResultList<String>, String> { - let keystore_keys = keystore::keys_read_all(&rr.data_dir).map_err(|e| e.to_string())?; - Ok(IResultList { - results: keystore_keys, - }) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn keys_nostr_delete( - public_key: String, - rr: tauri::State<'_, Tangle>, -) -> Result<IResultPass, String> { - keystore::key_delete(&public_key, &rr.data_dir).map_err(|e| e.to_string())?; - Ok(IResultPass { pass: true }) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn keys_nostr_keystore_reset( - rr: tauri::State<'_, Tangle>, -) -> Result<IResultPass, String> { - keystore::reset(&rr.data_dir).map_err(|e| e.to_string())?; - Ok(IResultPass { pass: true }) -} diff --git a/crates/tangle/src/commands/mod.rs b/crates/tangle/src/commands/mod.rs @@ -1,2 +0,0 @@ -pub mod keys; -pub mod model; diff --git a/crates/tangle/src/commands/model/farm.rs b/crates/tangle/src/commands/model/farm.rs @@ -1,60 +0,0 @@ -use crate::app::Tangle; -use tangle_core::types::IError; -use tangle_model::{ - tables::farm::{lib_model_farm_create, IFarmCreate, IFarmCreateResolve, lib_model_farm_read, IFarmRead, IFarmReadResolve, lib_model_farm_read_list, IFarmReadList, IFarmReadListResolve, lib_model_farm_delete, IFarmDelete, IFarmDeleteResolve, lib_model_farm_update, IFarmUpdate, IFarmUpdateResolve}, -}; - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_farm_create( - state: tauri::State<'_, Tangle>, - args: IFarmCreate, -) -> Result<IFarmCreateResolve, IError> { - match lib_model_farm_create(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_farm_read( - state: tauri::State<'_, Tangle>, - args: IFarmRead, -) -> Result<IFarmReadResolve, IError> { - match lib_model_farm_read(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_farm_read_list( - state: tauri::State<'_, Tangle>, - args: IFarmReadList, -) -> Result<IFarmReadListResolve, IError> { - match lib_model_farm_read_list(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_farm_update( - state: tauri::State<'_, Tangle>, - args: IFarmUpdate, -) -> Result<IFarmUpdateResolve, IError> { - match lib_model_farm_update(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_farm_delete( - state: tauri::State<'_, Tangle>, - args: IFarmDelete, -) -> Result<IFarmDeleteResolve, IError> { - match lib_model_farm_delete(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} -\ No newline at end of file diff --git a/crates/tangle/src/commands/model/farm_location.rs b/crates/tangle/src/commands/model/farm_location.rs @@ -1,28 +0,0 @@ -use crate::app::Tangle; -use tangle_core::types::IError; -use tangle_model::tables::farm_location::{ - lib_model_farm_location_set, lib_model_farm_location_unset, - IFarmLocationRelation, IFarmLocationResolve, -}; - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_farm_location_set( - state: tauri::State<'_, Tangle>, - args: IFarmLocationRelation, -) -> Result<IFarmLocationResolve, IError> { - match lib_model_farm_location_set(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_farm_location_unset( - state: tauri::State<'_, Tangle>, - args: IFarmLocationRelation, -) -> Result<IFarmLocationResolve, IError> { - match lib_model_farm_location_unset(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} -\ No newline at end of file diff --git a/crates/tangle/src/commands/model/location_gcs.rs b/crates/tangle/src/commands/model/location_gcs.rs @@ -1,60 +0,0 @@ -use crate::app::Tangle; -use tangle_core::types::IError; -use tangle_model::{ - tables::location_gcs::{lib_model_location_gcs_create, ILocationGcsCreate, ILocationGcsCreateResolve, lib_model_location_gcs_read, ILocationGcsRead, ILocationGcsReadResolve, lib_model_location_gcs_read_list, ILocationGcsReadList, ILocationGcsReadListResolve, lib_model_location_gcs_delete, ILocationGcsDelete, ILocationGcsDeleteResolve, lib_model_location_gcs_update, ILocationGcsUpdate, ILocationGcsUpdateResolve}, -}; - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_location_gcs_create( - state: tauri::State<'_, Tangle>, - args: ILocationGcsCreate, -) -> Result<ILocationGcsCreateResolve, IError> { - match lib_model_location_gcs_create(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_location_gcs_read( - state: tauri::State<'_, Tangle>, - args: ILocationGcsRead, -) -> Result<ILocationGcsReadResolve, IError> { - match lib_model_location_gcs_read(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_location_gcs_read_list( - state: tauri::State<'_, Tangle>, - args: ILocationGcsReadList, -) -> Result<ILocationGcsReadListResolve, IError> { - match lib_model_location_gcs_read_list(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_location_gcs_update( - state: tauri::State<'_, Tangle>, - args: ILocationGcsUpdate, -) -> Result<ILocationGcsUpdateResolve, IError> { - match lib_model_location_gcs_update(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_location_gcs_delete( - state: tauri::State<'_, Tangle>, - args: ILocationGcsDelete, -) -> Result<ILocationGcsDeleteResolve, IError> { - match lib_model_location_gcs_delete(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} -\ No newline at end of file diff --git a/crates/tangle/src/commands/model/log_error.rs b/crates/tangle/src/commands/model/log_error.rs @@ -1,60 +0,0 @@ -use crate::app::Tangle; -use tangle_core::types::IError; -use tangle_model::{ - tables::log_error::{lib_model_log_error_create, ILogErrorCreate, ILogErrorCreateResolve, lib_model_log_error_read, ILogErrorRead, ILogErrorReadResolve, lib_model_log_error_read_list, ILogErrorReadList, ILogErrorReadListResolve, lib_model_log_error_delete, ILogErrorDelete, ILogErrorDeleteResolve, lib_model_log_error_update, ILogErrorUpdate, ILogErrorUpdateResolve}, -}; - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_log_error_create( - state: tauri::State<'_, Tangle>, - args: ILogErrorCreate, -) -> Result<ILogErrorCreateResolve, IError> { - match lib_model_log_error_create(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_log_error_read( - state: tauri::State<'_, Tangle>, - args: ILogErrorRead, -) -> Result<ILogErrorReadResolve, IError> { - match lib_model_log_error_read(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_log_error_read_list( - state: tauri::State<'_, Tangle>, - args: ILogErrorReadList, -) -> Result<ILogErrorReadListResolve, IError> { - match lib_model_log_error_read_list(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_log_error_update( - state: tauri::State<'_, Tangle>, - args: ILogErrorUpdate, -) -> Result<ILogErrorUpdateResolve, IError> { - match lib_model_log_error_update(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_log_error_delete( - state: tauri::State<'_, Tangle>, - args: ILogErrorDelete, -) -> Result<ILogErrorDeleteResolve, IError> { - match lib_model_log_error_delete(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} -\ No newline at end of file diff --git a/crates/tangle/src/commands/model/media_image.rs b/crates/tangle/src/commands/model/media_image.rs @@ -1,60 +0,0 @@ -use crate::app::Tangle; -use tangle_core::types::IError; -use tangle_model::{ - tables::media_image::{lib_model_media_image_create, IMediaImageCreate, IMediaImageCreateResolve, lib_model_media_image_read, IMediaImageRead, IMediaImageReadResolve, lib_model_media_image_read_list, IMediaImageReadList, IMediaImageReadListResolve, lib_model_media_image_delete, IMediaImageDelete, IMediaImageDeleteResolve, lib_model_media_image_update, IMediaImageUpdate, IMediaImageUpdateResolve}, -}; - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_media_image_create( - state: tauri::State<'_, Tangle>, - args: IMediaImageCreate, -) -> Result<IMediaImageCreateResolve, IError> { - match lib_model_media_image_create(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_media_image_read( - state: tauri::State<'_, Tangle>, - args: IMediaImageRead, -) -> Result<IMediaImageReadResolve, IError> { - match lib_model_media_image_read(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_media_image_read_list( - state: tauri::State<'_, Tangle>, - args: IMediaImageReadList, -) -> Result<IMediaImageReadListResolve, IError> { - match lib_model_media_image_read_list(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_media_image_update( - state: tauri::State<'_, Tangle>, - args: IMediaImageUpdate, -) -> Result<IMediaImageUpdateResolve, IError> { - match lib_model_media_image_update(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_media_image_delete( - state: tauri::State<'_, Tangle>, - args: IMediaImageDelete, -) -> Result<IMediaImageDeleteResolve, IError> { - match lib_model_media_image_delete(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} -\ No newline at end of file diff --git a/crates/tangle/src/commands/model/mod.rs b/crates/tangle/src/commands/model/mod.rs @@ -1,23 +0,0 @@ -use crate::app::Tangle; -use tangle_core::types::{IError, IResultPass}; -use tangle_model::tables::lib_model_tables_reset; - -pub(crate) mod farm; -pub(crate) mod farm_location; -pub(crate) mod location_gcs; -pub(crate) mod log_error; -pub(crate) mod media_image; -pub(crate) mod nostr_profile; -pub(crate) mod nostr_profile_relay; -pub(crate) mod nostr_relay; -pub(crate) mod trade_product; -pub(crate) mod trade_product_location; -pub(crate) mod trade_product_media; - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_tables_reset(state: tauri::State<'_, Tangle>) -> Result<IResultPass, IError> { - match lib_model_tables_reset(&state.db).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} diff --git a/crates/tangle/src/commands/model/nostr_profile.rs b/crates/tangle/src/commands/model/nostr_profile.rs @@ -1,60 +0,0 @@ -use crate::app::Tangle; -use tangle_core::types::IError; -use tangle_model::{ - tables::nostr_profile::{lib_model_nostr_profile_create, INostrProfileCreate, INostrProfileCreateResolve, lib_model_nostr_profile_read, INostrProfileRead, INostrProfileReadResolve, lib_model_nostr_profile_read_list, INostrProfileReadList, INostrProfileReadListResolve, lib_model_nostr_profile_delete, INostrProfileDelete, INostrProfileDeleteResolve, lib_model_nostr_profile_update, INostrProfileUpdate, INostrProfileUpdateResolve}, -}; - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_nostr_profile_create( - state: tauri::State<'_, Tangle>, - args: INostrProfileCreate, -) -> Result<INostrProfileCreateResolve, IError> { - match lib_model_nostr_profile_create(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_nostr_profile_read( - state: tauri::State<'_, Tangle>, - args: INostrProfileRead, -) -> Result<INostrProfileReadResolve, IError> { - match lib_model_nostr_profile_read(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_nostr_profile_read_list( - state: tauri::State<'_, Tangle>, - args: INostrProfileReadList, -) -> Result<INostrProfileReadListResolve, IError> { - match lib_model_nostr_profile_read_list(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_nostr_profile_update( - state: tauri::State<'_, Tangle>, - args: INostrProfileUpdate, -) -> Result<INostrProfileUpdateResolve, IError> { - match lib_model_nostr_profile_update(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_nostr_profile_delete( - state: tauri::State<'_, Tangle>, - args: INostrProfileDelete, -) -> Result<INostrProfileDeleteResolve, IError> { - match lib_model_nostr_profile_delete(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} -\ No newline at end of file diff --git a/crates/tangle/src/commands/model/nostr_profile_relay.rs b/crates/tangle/src/commands/model/nostr_profile_relay.rs @@ -1,28 +0,0 @@ -use crate::app::Tangle; -use tangle_core::types::IError; -use tangle_model::tables::nostr_profile_relay::{ - lib_model_nostr_profile_relay_set, lib_model_nostr_profile_relay_unset, - INostrProfileRelayRelation, INostrProfileRelayResolve, -}; - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_nostr_profile_relay_set( - state: tauri::State<'_, Tangle>, - args: INostrProfileRelayRelation, -) -> Result<INostrProfileRelayResolve, IError> { - match lib_model_nostr_profile_relay_set(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_nostr_profile_relay_unset( - state: tauri::State<'_, Tangle>, - args: INostrProfileRelayRelation, -) -> Result<INostrProfileRelayResolve, IError> { - match lib_model_nostr_profile_relay_unset(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} -\ No newline at end of file diff --git a/crates/tangle/src/commands/model/nostr_relay.rs b/crates/tangle/src/commands/model/nostr_relay.rs @@ -1,60 +0,0 @@ -use crate::app::Tangle; -use tangle_core::types::IError; -use tangle_model::{ - tables::nostr_relay::{lib_model_nostr_relay_create, INostrRelayCreate, INostrRelayCreateResolve, lib_model_nostr_relay_read, INostrRelayRead, INostrRelayReadResolve, lib_model_nostr_relay_read_list, INostrRelayReadList, INostrRelayReadListResolve, lib_model_nostr_relay_delete, INostrRelayDelete, INostrRelayDeleteResolve, lib_model_nostr_relay_update, INostrRelayUpdate, INostrRelayUpdateResolve}, -}; - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_nostr_relay_create( - state: tauri::State<'_, Tangle>, - args: INostrRelayCreate, -) -> Result<INostrRelayCreateResolve, IError> { - match lib_model_nostr_relay_create(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_nostr_relay_read( - state: tauri::State<'_, Tangle>, - args: INostrRelayRead, -) -> Result<INostrRelayReadResolve, IError> { - match lib_model_nostr_relay_read(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_nostr_relay_read_list( - state: tauri::State<'_, Tangle>, - args: INostrRelayReadList, -) -> Result<INostrRelayReadListResolve, IError> { - match lib_model_nostr_relay_read_list(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_nostr_relay_update( - state: tauri::State<'_, Tangle>, - args: INostrRelayUpdate, -) -> Result<INostrRelayUpdateResolve, IError> { - match lib_model_nostr_relay_update(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_nostr_relay_delete( - state: tauri::State<'_, Tangle>, - args: INostrRelayDelete, -) -> Result<INostrRelayDeleteResolve, IError> { - match lib_model_nostr_relay_delete(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} -\ No newline at end of file diff --git a/crates/tangle/src/commands/model/trade_product.rs b/crates/tangle/src/commands/model/trade_product.rs @@ -1,60 +0,0 @@ -use crate::app::Tangle; -use tangle_core::types::IError; -use tangle_model::{ - tables::trade_product::{lib_model_trade_product_create, ITradeProductCreate, ITradeProductCreateResolve, lib_model_trade_product_read, ITradeProductRead, ITradeProductReadResolve, lib_model_trade_product_read_list, ITradeProductReadList, ITradeProductReadListResolve, lib_model_trade_product_delete, ITradeProductDelete, ITradeProductDeleteResolve, lib_model_trade_product_update, ITradeProductUpdate, ITradeProductUpdateResolve}, -}; - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_trade_product_create( - state: tauri::State<'_, Tangle>, - args: ITradeProductCreate, -) -> Result<ITradeProductCreateResolve, IError> { - match lib_model_trade_product_create(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_trade_product_read( - state: tauri::State<'_, Tangle>, - args: ITradeProductRead, -) -> Result<ITradeProductReadResolve, IError> { - match lib_model_trade_product_read(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_trade_product_read_list( - state: tauri::State<'_, Tangle>, - args: ITradeProductReadList, -) -> Result<ITradeProductReadListResolve, IError> { - match lib_model_trade_product_read_list(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_trade_product_update( - state: tauri::State<'_, Tangle>, - args: ITradeProductUpdate, -) -> Result<ITradeProductUpdateResolve, IError> { - match lib_model_trade_product_update(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_trade_product_delete( - state: tauri::State<'_, Tangle>, - args: ITradeProductDelete, -) -> Result<ITradeProductDeleteResolve, IError> { - match lib_model_trade_product_delete(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} -\ No newline at end of file diff --git a/crates/tangle/src/commands/model/trade_product_location.rs b/crates/tangle/src/commands/model/trade_product_location.rs @@ -1,28 +0,0 @@ -use crate::app::Tangle; -use tangle_core::types::IError; -use tangle_model::tables::trade_product_location::{ - lib_model_trade_product_location_set, lib_model_trade_product_location_unset, - ITradeProductLocationRelation, ITradeProductLocationResolve, -}; - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_trade_product_location_set( - state: tauri::State<'_, Tangle>, - args: ITradeProductLocationRelation, -) -> Result<ITradeProductLocationResolve, IError> { - match lib_model_trade_product_location_set(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_trade_product_location_unset( - state: tauri::State<'_, Tangle>, - args: ITradeProductLocationRelation, -) -> Result<ITradeProductLocationResolve, IError> { - match lib_model_trade_product_location_unset(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} -\ No newline at end of file diff --git a/crates/tangle/src/commands/model/trade_product_media.rs b/crates/tangle/src/commands/model/trade_product_media.rs @@ -1,28 +0,0 @@ -use crate::app::Tangle; -use tangle_core::types::IError; -use tangle_model::tables::trade_product_media::{ - lib_model_trade_product_media_set, lib_model_trade_product_media_unset, - ITradeProductMediaRelation, ITradeProductMediaResolve, -}; - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_trade_product_media_set( - state: tauri::State<'_, Tangle>, - args: ITradeProductMediaRelation, -) -> Result<ITradeProductMediaResolve, IError> { - match lib_model_trade_product_media_set(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn model_trade_product_media_unset( - state: tauri::State<'_, Tangle>, - args: ITradeProductMediaRelation, -) -> Result<ITradeProductMediaResolve, IError> { - match lib_model_trade_product_media_unset(&state.db, args).await { - Ok(result) => Ok(result), - Err(e) => Err(IError { err: e.to_string() }), - } -} -\ No newline at end of file diff --git a/crates/tangle/src/lib.rs b/crates/tangle/src/lib.rs @@ -1,148 +0,0 @@ -pub mod app; -pub mod commands; -pub mod util; - -use app::Tangle; -use commands::keys::{ - keys_nostr_add, keys_nostr_delete, keys_nostr_gen, keys_nostr_keystore_reset, keys_nostr_read, - keys_nostr_read_all, -}; -use commands::model::farm::{ - model_farm_create, model_farm_delete, model_farm_read, - model_farm_read_list, model_farm_update, - }; -use commands::model::farm_location::{ - model_farm_location_set, model_farm_location_unset, - }; -use commands::model::location_gcs::{ - model_location_gcs_create, model_location_gcs_delete, model_location_gcs_read, - model_location_gcs_read_list, model_location_gcs_update, - }; -use commands::model::log_error::{ - model_log_error_create, model_log_error_delete, model_log_error_read, - model_log_error_read_list, model_log_error_update, - }; -use commands::model::media_image::{ - model_media_image_create, model_media_image_delete, model_media_image_read, - model_media_image_read_list, model_media_image_update, - }; -use commands::model::model_tables_reset; -use commands::model::nostr_profile::{ - model_nostr_profile_create, model_nostr_profile_delete, model_nostr_profile_read, - model_nostr_profile_read_list, model_nostr_profile_update, - }; -use commands::model::nostr_profile_relay::{ - model_nostr_profile_relay_set, model_nostr_profile_relay_unset, - }; -use commands::model::nostr_relay::{ - model_nostr_relay_create, model_nostr_relay_delete, model_nostr_relay_read, - model_nostr_relay_read_list, model_nostr_relay_update, - }; -use commands::model::trade_product::{ - model_trade_product_create, model_trade_product_delete, model_trade_product_read, - model_trade_product_read_list, model_trade_product_update, - }; -use commands::model::trade_product_location::{ - model_trade_product_location_set, model_trade_product_location_unset, - }; -use commands::model::trade_product_media::{ - model_trade_product_media_set, model_trade_product_media_unset, - }; -use std::path::PathBuf; -use tauri::Manager; - -#[cfg_attr(mobile, tauri::mobile_entry_point)] -pub fn run() { - tauri::Builder::default() - .plugin(tauri_plugin_shell::init()) - .plugin(tauri_plugin_dialog::init()) - .plugin(tauri_plugin_fs::init()) - .plugin(tauri_plugin_geolocation::init()) - .plugin(tauri_plugin_http::init()) - .plugin(tauri_plugin_notification::init()) - .plugin(tauri_plugin_os::init()) - .plugin(tauri_plugin_store::Builder::new().build()) - .setup(|app| { - let data_dir = app - .handle() - .path() - .app_data_dir() - .expect("Failed to resolve app data dir"); - - let logs_dir = app.handle().path().app_log_dir().unwrap(); - - let fmt_data_dir = if cfg!(dev) { - PathBuf::from(format!("{}/dev", data_dir.to_string_lossy())) - } else { - PathBuf::from(format!("{}/release", data_dir.to_string_lossy())) - }; - - let fmt_logs_dir = if cfg!(dev) { - PathBuf::from(format!("{}/dev", logs_dir.to_string_lossy())) - } else { - PathBuf::from(format!("{}/release", logs_dir.to_string_lossy())) - }; - - tauri::async_runtime::block_on(async move { - let tangle = Tangle::new(fmt_data_dir, fmt_logs_dir).await; - app.manage(tangle); - }); - Ok(()) - }) - .invoke_handler(tauri::generate_handler![ - // %model% - model_farm_create, - model_farm_delete, - model_farm_location_set, - model_farm_location_unset, - model_farm_read, - model_farm_read_list, - model_farm_update, - model_location_gcs_create, - model_location_gcs_delete, - model_location_gcs_read, - model_location_gcs_read_list, - model_location_gcs_update, - model_log_error_create, - model_log_error_delete, - model_log_error_read, - model_log_error_read_list, - model_log_error_update, - model_media_image_create, - model_media_image_delete, - model_media_image_read, - model_media_image_read_list, - model_media_image_update, - model_nostr_profile_create, - model_nostr_profile_delete, - model_nostr_profile_read, - model_nostr_profile_read_list, - model_nostr_profile_relay_set, - model_nostr_profile_relay_unset, - model_nostr_profile_update, - model_nostr_relay_create, - model_nostr_relay_delete, - model_nostr_relay_read, - model_nostr_relay_read_list, - model_nostr_relay_update, - model_tables_reset, - model_trade_product_create, - model_trade_product_delete, - model_trade_product_location_set, - model_trade_product_location_unset, - model_trade_product_media_set, - model_trade_product_media_unset, - model_trade_product_read, - model_trade_product_read_list, - model_trade_product_update, - // %model% - keys_nostr_gen, - keys_nostr_add, - keys_nostr_read, - keys_nostr_read_all, - keys_nostr_delete, - keys_nostr_keystore_reset - ]) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); -} diff --git a/crates/tangle/src/main.rs b/crates/tangle/src/main.rs @@ -1,6 +0,0 @@ -// Prevents additional console window on Windows in release, DO NOT REMOVE!! -#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] - -fn main() { - tangle_lib::run(); -} diff --git a/crates/tangle/src/util.rs b/crates/tangle/src/util.rs @@ -1,63 +0,0 @@ -use std::fs::OpenOptions; -use std::path::PathBuf; - -use tangle_model::types::DatabaseConnection; -use tangle_model::util::db_conn; - -pub async fn init_db(data_dir: &PathBuf) -> DatabaseConnection { - let mut path = data_dir.clone(); - match std::fs::create_dir_all(path.clone()) { - Ok(_) => {} - Err(e) => { - panic!("Error resolving databse directory {}", e); - } - }; - path.push("tangle.db"); - let result = OpenOptions::new().create_new(true).write(true).open(&path); - match result { - Ok(_) => println!("Database file created"), - Err(e) => match e.kind() { - std::io::ErrorKind::AlreadyExists => println!("Database file exists"), - _ => { - panic!("Error creating databse file {}", e); - } - }, - } - let db = db_conn(path).await; - sqlx::migrate!("./migrations/up").run(&db).await.unwrap(); - db -} - -pub async fn init_keyring(data_dir: &PathBuf) -> String { - let mut path = data_dir.clone(); - match std::fs::create_dir_all(path.clone()) { - Ok(_) => {} - Err(err) => { - panic!("Error resolving databse directory {}", err); - } - }; - path.push("keyring_id.txt"); - if path.exists() { - let keyring_read = match std::fs::read_to_string(&path) { - Ok(res) => res, - Err(e) => { - panic!("Error reading keyring_id.txt {}", e); - } - }; - keyring_read.trim().to_string() - } else { - let keyring_new = "test-keyring-id".to_string(); - - match OpenOptions::new().create_new(true).write(true).open(&path) { - Ok(_) => match std::fs::write(&path, &keyring_new) { - Ok(_) => keyring_new, - Err(e) => { - panic!("Error writing keyring_id.txt {}", e); - } - }, - Err(e) => { - panic!("Unexpected error {}", e); - } - } - } -} diff --git a/crates/tangle/tauri.conf.json b/crates/tangle/tauri.conf.json @@ -1,33 +0,0 @@ -{ - "$schema": "../../node_modules/@tauri-apps/cli/config.schema.json", - "identifier": "tangle.radroots.app", - "productName": "Tangle", - "mainBinaryName": "tangle", - "build": { - "frontendDist": "../../app/build", - "devUrl": "http://localhost:3000", - "beforeDevCommand": "cd app && pnpm run dev:hmr", - "beforeBuildCommand": "cd app && pnpm run build" - }, - "app": { - "windows": [ - { - "title": "tangle | rad roots", - "resizable": false, - "fullscreen": true, - "visible": true - } - ] - }, - "bundle": { - "active": false, - "targets": "all", - "icon": [ - "icons/32x32.png", - "icons/128x128.png", - "icons/128x128@2x.png", - "icons/icon.icns", - "icons/icon.ico" - ] - } -} -\ No newline at end of file diff --git a/crates/wasm/Cargo.toml b/crates/wasm/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "tangle_wasm" +version.workspace = true +edition.workspace = true +authors = ["Radroots Authors"] +rust-version.workspace = true +license.workspace = true + +[lib] +crate-type = ["cdylib"] + +[dependencies] +serde = { workspace = true } +serde_json = { workspace = true } +thiserror = { workspace = true } +wasm-bindgen = "0.2" +wasm-bindgen-futures = "0.4" +console_error_panic_hook = "0.1" +serde-wasm-bindgen = "0.6" + +tangle_core = { path = "../core", features = ["wasm"] } +tangle_model = { path = "../model" } + +[package.metadata.wasm-pack.profile.release] +wasm-opt = ["-Os"] + +[target.wasm32-unknown-unknown.dependencies] +getrandom = { version = "0.2", features = ["js"] } +uuid = { version = "1", features = ["v4", "js"], package = "uuid" } diff --git a/crates/wasm/src/ffi.rs b/crates/wasm/src/ffi.rs @@ -0,0 +1,70 @@ +use serde::{Deserialize, Serialize}; +use serde_wasm_bindgen::{from_value, to_value}; +use tangle_model::types::{new_wasm_db, BindValue, ModelExecutor, WasmDb}; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub struct Db { + exec: WasmDb, +} + +fn parse_binds(binds: &JsValue) -> Vec<BindValue> { + if binds.is_undefined() || binds.is_null() { + Vec::new() + } else { + from_value(binds.clone()).unwrap_or_default() + } +} + +#[wasm_bindgen] +impl Db { + #[wasm_bindgen(constructor)] + pub fn new() -> Db { + Db { + exec: new_wasm_db(), + } + } + + pub fn execute(&self, sql: &str, binds: &JsValue) -> Result<u64, JsValue> { + let binds = parse_binds(binds); + self.exec + .execute(sql, &binds) + .map_err(|e| JsValue::from_str(&e)) + } + + pub fn query_one(&self, sql: &str, binds: &JsValue) -> Result<JsValue, JsValue> { + let binds = parse_binds(binds); + self.exec + .query_one(sql, &binds) + .and_then(|v| to_value(&v).map_err(|e| e.to_string())) + .map_err(|e| JsValue::from_str(&e)) + } + + pub fn query_all(&self, sql: &str, binds: &JsValue) -> Result<JsValue, JsValue> { + let binds = parse_binds(binds); + self.exec + .query_all(sql, &binds) + .and_then(|v| to_value(&v).map_err(|e| e.to_string())) + .map_err(|e| JsValue::from_str(&e)) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct IError { + pub err: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct IResult<T> { + pub result: T, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct IResultList<T> { + pub results: Vec<T>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct IResultPass { + pub pass: bool, +} diff --git a/crates/wasm/src/lib.rs b/crates/wasm/src/lib.rs @@ -0,0 +1,107 @@ +use serde::{Deserialize, Serialize}; +use serde_wasm_bindgen::to_value; +use tangle_core::{ + keystore, + nostr::keys::{ + lib_nostr_keys_gen, lib_nostr_keys_parse, lib_nostr_public_key_hex, + lib_nostr_secret_key_hex, + }, +}; +use tangle_model::{types::new_wasm_db, wasm_executor::WasmExecutor}; +use wasm_bindgen::prelude::*; + +pub mod ffi; +pub mod migrate; + +#[wasm_bindgen(start)] +pub fn wasm_start() { + console_error_panic_hook::set_once(); +} + +#[wasm_bindgen] +pub async fn init(db_name: Option<String>) -> Result<JsValue, JsValue> { + WasmExecutor::init(db_name).await; + let db = ffi::Db::new(); + migrate::apply_migrations(db) + .await + .map(|_| ffi::IResultPass { pass: true }) + .and_then(|p| to_value(&p).map_err(|e| JsValue::from_str(&e.to_string()))) +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct IError { + pub err: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct IResult<T> { + pub result: T, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct IResultList<T> { + pub results: Vec<T>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct IResultPass { + pub pass: bool, +} + +#[wasm_bindgen] +pub fn keys_nostr_gen() -> Result<JsValue, JsValue> { + let keys = lib_nostr_keys_gen(); + keystore::key_add(&keys).map_err(|e| JsValue::from_str(&e.to_string()))?; + to_value(&IResult { + result: keys.public_key().to_hex(), + }) + .map_err(|e| JsValue::from_str(&e.to_string())) +} + +#[wasm_bindgen] +pub fn keys_nostr_add(secret_key: String) -> Result<JsValue, JsValue> { + let keys = lib_nostr_keys_parse(secret_key).map_err(|e| JsValue::from_str(&e.to_string()))?; + keystore::key_add(&keys).map_err(|e| JsValue::from_str(&e.to_string()))?; + to_value(&IResult { + result: lib_nostr_public_key_hex(keys), + }) + .map_err(|e| JsValue::from_str(&e.to_string())) +} + +#[wasm_bindgen] +pub fn keys_nostr_read(public_key: String) -> Result<JsValue, JsValue> { + let keys = keystore::key_read(&public_key).map_err(|e| JsValue::from_str(&e.to_string()))?; + to_value(&IResult { + result: lib_nostr_secret_key_hex(keys), + }) + .map_err(|e| JsValue::from_str(&e.to_string())) +} + +#[wasm_bindgen] +pub fn keys_nostr_read_all() -> Result<JsValue, JsValue> { + let results = keystore::keys_read_all().map_err(|e| JsValue::from_str(&e.to_string()))?; + to_value(&IResultList { results }).map_err(|e| JsValue::from_str(&e.to_string())) +} + +#[wasm_bindgen] +pub fn keys_nostr_delete(public_key: String) -> Result<JsValue, JsValue> { + keystore::key_delete(&public_key).map_err(|e| JsValue::from_str(&e.to_string()))?; + to_value(&IResultPass { pass: true }).map_err(|e| JsValue::from_str(&e.to_string())) +} + +#[wasm_bindgen] +pub fn keys_nostr_keystore_reset() -> Result<JsValue, JsValue> { + keystore::reset().map_err(|e| JsValue::from_str(&e.to_string()))?; + to_value(&IResultPass { pass: true }).map_err(|e| JsValue::from_str(&e.to_string())) +} + +#[wasm_bindgen] +pub fn model_tables_reset() -> Result<JsValue, JsValue> { + let exec = new_wasm_db(); + tangle_model::types::reset_all(&exec) + .map_err(|e| JsValue::from_str(&e)) + .and_then(|p| { + to_value(&ffi::IResultPass { pass: p.pass }) + .map_err(|e| JsValue::from_str(&e.to_string())) + }) +} diff --git a/crates/wasm/src/migrate.rs b/crates/wasm/src/migrate.rs @@ -0,0 +1,26 @@ +use crate::ffi::Db; +use wasm_bindgen::prelude::*; + +const MIG_0001: &str = include_str!("../tangle_migrations/0001_location_gcs.sql"); +const MIG_0002: &str = include_str!("../tangle_migrations/0002_trade_product.sql"); +const MIG_0003: &str = include_str!("../tangle_migrations/0003_nostr_profile.sql"); +const MIG_0004: &str = include_str!("../tangle_migrations/0004_nostr_relay.sql"); +const MIG_0005: &str = include_str!("../tangle_migrations/0005_media_image.sql"); +const MIG_0006: &str = include_str!("../tangle_migrations/0006_log_error.sql"); +const MIG_0007: &str = include_str!("../tangle_migrations/0007_farm.sql"); +const MIG_0008: &str = include_str!("../tangle_migrations/0008_nostr_profile_relay.sql"); +const MIG_0009: &str = include_str!("../tangle_migrations/0009_farm_location.sql"); +const MIG_0010: &str = include_str!("../tangle_migrations/0010_trade_product_location.sql"); +const MIG_0011: &str = include_str!("../tangle_migrations/0011_trade_product_media.sql"); + +#[wasm_bindgen] +pub async fn apply_migrations(db: Db) -> Result<bool, JsValue> { + let steps = [ + MIG_0001, MIG_0002, MIG_0003, MIG_0004, MIG_0005, MIG_0006, MIG_0007, MIG_0008, MIG_0009, + MIG_0010, MIG_0011, + ]; + for sql in steps.iter() { + db.execute(sql, &JsValue::UNDEFINED)?; + } + Ok(true) +} diff --git a/crates/tangle/migrations/up/0001_location_gcs.sql b/crates/wasm/tangle_migrations/0001_location_gcs.sql diff --git a/crates/tangle/migrations/up/0002_trade_product.sql b/crates/wasm/tangle_migrations/0002_trade_product.sql diff --git a/crates/tangle/migrations/up/0003_nostr_profile.sql b/crates/wasm/tangle_migrations/0003_nostr_profile.sql diff --git a/crates/tangle/migrations/up/0004_nostr_relay.sql b/crates/wasm/tangle_migrations/0004_nostr_relay.sql diff --git a/crates/tangle/migrations/up/0005_media_image.sql b/crates/wasm/tangle_migrations/0005_media_image.sql diff --git a/crates/tangle/migrations/up/0006_log_error.sql b/crates/wasm/tangle_migrations/0006_log_error.sql diff --git a/crates/tangle/migrations/up/0007_farm.sql b/crates/wasm/tangle_migrations/0007_farm.sql diff --git a/crates/tangle/migrations/up/0008_nostr_profile_relay.sql b/crates/wasm/tangle_migrations/0008_nostr_profile_relay.sql diff --git a/crates/tangle/migrations/up/0009_farm_location.sql b/crates/wasm/tangle_migrations/0009_farm_location.sql diff --git a/crates/tangle/migrations/up/0010_trade_product_location.sql b/crates/wasm/tangle_migrations/0010_trade_product_location.sql diff --git a/crates/tangle/migrations/up/0011_trade_product_media.sql b/crates/wasm/tangle_migrations/0011_trade_product_media.sql diff --git a/package.json b/package.json @@ -1,7 +1,7 @@ { "name": "tangle", "private": true, - "license": "GPLv3", + "license": "GPL-3.0", "scripts": { "build": "turbo build --filter=app", "dev": "turbo dev --concurrency 11 --filter=@radroots/*", diff --git a/rust-toolchain.toml b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "1.81.0" +channel = "1.88.0"