diff --git a/Cargo.lock b/Cargo.lock index 73ff803..08302c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,10 +178,12 @@ dependencies = [ "color-eyre", "eframe", "egui_commonmark", + "egui_extras", "enigo", "futures", "get-selected-text", "global-hotkey", + "llm_utils", "objc2-app-kit", "objc2-foundation", "reqwew", @@ -194,6 +196,27 @@ dependencies = [ "vergen", ] +[[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + +[[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.18" @@ -227,6 +250,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" +[[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" @@ -236,6 +265,55 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "anyhow" version = "1.0.86" @@ -264,6 +342,12 @@ dependencies = [ "objc", ] +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" + [[package]] name = "arboard" version = "3.4.0" @@ -282,6 +366,17 @@ dependencies = [ "x11rb", ] +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "arrayref" version = "0.3.7" @@ -294,6 +389,29 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "article_scraper" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f3fa375ebee9245309680ef4b2178782a9ac5e7b1f7bf869cff93f8f3c55c6" +dependencies = [ + "base64 0.22.1", + "chrono", + "encoding_rs", + "escaper", + "futures", + "image 0.25.1", + "libxml", + "log", + "once_cell", + "regex", + "reqwest", + "rust-embed", + "thiserror", + "tokio", + "url", +] + [[package]] name = "as-raw-xcb-connection" version = "1.0.1" @@ -326,9 +444,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" dependencies = [ "concurrent-queue", - "event-listener-strategy 0.5.2", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-compression" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd066d0b4ef8ecb03a55319dc13aa6910616d0f44008a045bb1835af830abff5" +dependencies = [ + "brotli", + "flate2", "futures-core", + "memchr", "pin-project-lite", + "tokio", ] [[package]] @@ -387,17 +519,17 @@ dependencies = [ [[package]] name = "async-io" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" dependencies = [ - "async-lock 3.3.0", + "async-lock 3.4.0", "cfg-if", "concurrent-queue", "futures-io", "futures-lite 2.3.0", "parking", - "polling 3.7.0", + "polling 3.7.1", "rustix 0.38.34", "slab", "tracing", @@ -415,12 +547,12 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener 4.0.3", - "event-listener-strategy 0.4.0", + "event-listener 5.3.1", + "event-listener-strategy", "pin-project-lite", ] @@ -432,9 +564,9 @@ checksum = "9338790e78aa95a416786ec8389546c4b6a1dfc3dc36071ed9518a9413a542eb" [[package]] name = "async-openai" -version = "0.23.0" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca2eac999dc8d4c074688270df3e407f6118d9098e7cf435d33fb73ed878968" +checksum = "a851fe1ea66feec2e15ba280823ee3e6a4ede4e7afde576fe312dfb012965a91" dependencies = [ "async-convert", "backoff", @@ -486,12 +618,12 @@ dependencies = [ [[package]] name = "async-signal" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afe66191c335039c7bb78f99dc7520b0cbb166b3a1cb33a03f53d8a1c6f2afda" +checksum = "794f185324c2f00e771cd9f1ae8b5ac68be2ca7abb129a87afd6e86d228bc54d" dependencies = [ - "async-io 2.3.2", - "async-lock 3.3.0", + "async-io 2.3.3", + "async-lock 3.4.0", "atomic-waker", "cfg-if", "futures-core", @@ -579,6 +711,29 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" +dependencies = [ + "arrayvec", +] + [[package]] name = "backoff" version = "0.4.0" @@ -608,6 +763,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.21.7" @@ -658,6 +819,12 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.3.2" @@ -673,6 +840,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitstream-io" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "415f8399438eb5e4b2f73ed3152a3448b98149dda642a957ee704e1daa5cf1d8" + [[package]] name = "block" version = "0.1.6" @@ -758,6 +931,44 @@ dependencies = [ "piper", ] +[[package]] +name = "brotli" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bstr" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +dependencies = [ + "memchr", + "regex-automata", + "serde", +] + +[[package]] +name = "built" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6a6c0b39c38fd754ac338b00a88066436389c0f029da5d37d1e01091d9b7c17" + [[package]] name = "bumpalo" version = "3.16.0" @@ -790,6 +1001,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.6.0" @@ -804,7 +1021,7 @@ checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" dependencies = [ "bitflags 2.5.0", "log", - "polling 3.7.0", + "polling 3.7.1", "rustix 0.38.34", "slab", "thiserror", @@ -856,9 +1073,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.98" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" dependencies = [ "jobserver", "libc", @@ -880,6 +1097,16 @@ dependencies = [ "nom", ] +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -901,6 +1128,20 @@ dependencies = [ "libc", ] +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.5", +] + [[package]] name = "clang-sys" version = "1.8.1" @@ -912,6 +1153,46 @@ dependencies = [ "libloading 0.8.3", ] +[[package]] +name = "clap" +version = "4.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "clap_lex" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" + [[package]] name = "clipboard-win" version = "5.3.1" @@ -1010,6 +1291,22 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys 0.48.0", +] + [[package]] name = "com" version = "0.6.0" @@ -1051,6 +1348,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "comfy-table" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7" +dependencies = [ + "crossterm", + "strum", + "strum_macros", + "unicode-width", +] + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -1060,6 +1369,19 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.52.0", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -1140,12 +1462,59 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "crossterm" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +dependencies = [ + "bitflags 2.5.0", + "crossterm_winapi", + "libc", + "parking_lot", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -1197,6 +1566,12 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "data-url" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" + [[package]] name = "debug_print" version = "1.0.0" @@ -1254,6 +1629,12 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "digest" version = "0.10.7" @@ -1275,8 +1656,29 @@ dependencies = [ ] [[package]] -name = "dirs-sys-next" -version = "0.1.2" +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ @@ -1291,6 +1693,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "dlib" version = "0.5.2" @@ -1309,6 +1722,12 @@ dependencies = [ "litrs", ] +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + [[package]] name = "downcast-rs" version = "1.2.1" @@ -1447,6 +1866,7 @@ dependencies = [ "image 0.24.9", "log", "mime_guess2", + "resvg", "serde", ] @@ -1482,6 +1902,12 @@ dependencies = [ "serde", ] +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "encoding_rs" version = "0.8.34" @@ -1508,6 +1934,12 @@ dependencies = [ "xkeysym", ] +[[package]] +name = "entities" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" + [[package]] name = "enum-map" version = "2.7.3" @@ -1531,9 +1963,9 @@ dependencies = [ [[package]] name = "enumflags2" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3278c9d5fb675e0a51dabcf4c0d355f692b064171535ba72361be1528a9d8e8d" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" dependencies = [ "enumflags2_derive", "serde", @@ -1541,9 +1973,9 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", @@ -1601,27 +2033,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b" [[package]] -name = "event-listener" -version = "2.5.3" +name = "esaxx-rs" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +checksum = "d817e038c30374a4bcb22f94d0a8a0e216958d4c3dcde369b1439fec4bdda6e6" +dependencies = [ + "cc", +] [[package]] -name = "event-listener" -version = "3.1.0" +name = "escaper" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +checksum = "a53eb97b7349ba1bdb31839eceafe9aaae8f1d8d944dc589b67fb0b26e1c1666" dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", + "entities", ] [[package]] name = "event-listener" -version = "4.0.3" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" dependencies = [ "concurrent-queue", "parking", @@ -1639,16 +2078,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "event-listener-strategy" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" -dependencies = [ - "event-listener 4.0.3", - "pin-project-lite", -] - [[package]] name = "event-listener-strategy" version = "0.5.2" @@ -1670,6 +2099,22 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "exr" +version = "1.72.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "eyre" version = "0.6.12" @@ -1680,6 +2125,27 @@ dependencies = [ "once_cell", ] +[[package]] +name = "fancy-regex" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7493d4c459da9f84325ad297371a6b2b8a162800873a22e3b6b6512e61d18c05" +dependencies = [ + "bit-set", + "regex", +] + +[[package]] +name = "fancy-regex" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "531e46835a22af56d1e3b66f04844bed63158bc094a628bec1d321d9b4c44bf2" +dependencies = [ + "bit-set", + "regex-automata", + "regex-syntax", +] + [[package]] name = "fastrand" version = "1.9.0" @@ -1714,6 +2180,21 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1771,6 +2252,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + [[package]] name = "futures" version = "0.3.30" @@ -1894,6 +2385,19 @@ dependencies = [ "slab", ] +[[package]] +name = "gbnf" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdf6228362f4014ccbdb75788bb664ab1d2bb4c97fe0b8af13c7e7ea00bc5da4" +dependencies = [ + "nom", + "pretty_assertions", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1946,6 +2450,32 @@ dependencies = [ "wasi", ] +[[package]] +name = "gguf-rs" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1aaed814f5a923f69200703b0283ffa5da63f2bb2dfea8f7fa9c0e69f38eb67" +dependencies = [ + "anyhow", + "byteorder", + "clap", + "comfy-table", + "log", + "serde", + "serde_json", + "simple_logger", +] + +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gimli" version = "0.28.1" @@ -2134,6 +2664,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -2159,6 +2699,12 @@ dependencies = [ "winapi", ] +[[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.3.9" @@ -2177,6 +2723,23 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "hf-hub" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b780635574b3d92f036890d8373433d6f9fc7abb320ee42a5c25897fc8ed732" +dependencies = [ + "dirs", + "indicatif", + "log", + "native-tls", + "rand", + "serde", + "serde_json", + "thiserror", + "ureq", +] + [[package]] name = "home" version = "0.5.9" @@ -2186,6 +2749,33 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "html2text" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c66ee488a63a92237d5b48875b7e05bb293be8fb2894641c8118b60c08ab5ef" +dependencies = [ + "html5ever", + "markup5ever", + "tendril", + "thiserror", + "unicode-width", +] + +[[package]] +name = "html5ever" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "http" version = "1.1.0" @@ -2209,12 +2799,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", - "futures-core", + "futures-util", "http", "http-body", "pin-project-lite", @@ -2222,9 +2812,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "d0e7a4dd27b9476dc40cb050d3632d3bba3a70ddbff012285f7f8559a1e7e545" [[package]] name = "hyper" @@ -2299,6 +2889,29 @@ dependencies = [ "tracing", ] +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core 0.52.0", +] + +[[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 = "icrate" version = "0.0.4" @@ -2320,6 +2933,124 @@ dependencies = [ "objc2 0.5.2", ] +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[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.66", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -2328,12 +3059,14 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.5.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "icu_normalizer", + "icu_properties", + "smallvec", + "utf8_iter", ] [[package]] @@ -2357,13 +3090,45 @@ checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" dependencies = [ "bytemuck", "byteorder", + "color_quant", + "exr", + "gif", + "image-webp", "num-traits", "png", + "qoi", + "ravif", + "rayon", + "rgb", "tiff", + "zune-core", + "zune-jpeg", ] [[package]] -name = "indenter" +name = "image-webp" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d730b085583c4d789dfd07fdcf185be59501666a90c97c40162b37e4fdad272d" +dependencies = [ + "byteorder-lite", + "thiserror", +] + +[[package]] +name = "imagesize" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284" + +[[package]] +name = "imgref" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" + +[[package]] +name = "indenter" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" @@ -2378,6 +3143,19 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "indicatif" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + [[package]] name = "instant" version = "0.1.13" @@ -2387,6 +3165,17 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "io-lifetimes" version = "1.0.11" @@ -2404,6 +3193,30 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -2484,6 +3297,15 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" +[[package]] +name = "kurbo" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd85a5776cd9500c2e2059c8c76c3b01528566b7fcbaf8098b55a33fc298849b" +dependencies = [ + "arrayvec", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -2496,12 +3318,29 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "libc" version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +[[package]] +name = "libfuzzer-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + [[package]] name = "libloading" version = "0.7.4" @@ -2543,6 +3382,17 @@ dependencies = [ "libc", ] +[[package]] +name = "libxml" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fe73cdec2bcb36d25a9fe3f607ffcd44bb8907ca0100c4098d1aa342d1e7bec" +dependencies = [ + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -2555,12 +3405,43 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + [[package]] name = "litrs" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" +[[package]] +name = "llm_utils" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2995481ffb0dbe978cee3d4c959bb90fdc36e17b3c6565d7dc00458ad15fa" +dependencies = [ + "anyhow", + "article_scraper", + "dotenv", + "fancy-regex 0.13.0", + "gbnf", + "gguf-rs", + "hf-hub", + "html2text", + "lazy_static", + "minijinja", + "regex", + "serde", + "serde_json", + "tiktoken-rs", + "tokenizers", + "toml", + "unicode-segmentation", +] + [[package]] name = "lock_api" version = "0.4.12" @@ -2577,6 +3458,15 @@ version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + [[package]] name = "lru" version = "0.12.3" @@ -2586,6 +3476,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + [[package]] name = "macos-accessibility-client" version = "0.0.1" @@ -2596,6 +3492,22 @@ dependencies = [ "core-foundation-sys", ] +[[package]] +name = "macro_rules_attribute" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a82271f7bc033d84bbca59a3ce3e4159938cb08a9c3aebbe54d215131518a13" +dependencies = [ + "macro_rules_attribute-proc_macro", + "paste", +] + +[[package]] +name = "macro_rules_attribute-proc_macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dd856d451cc0da70e2ef2ce95a18e39a93b7558bedf10201ad28503f918568" + [[package]] name = "malloc_buf" version = "0.0.6" @@ -2605,11 +3517,35 @@ dependencies = [ "libc", ] +[[package]] +name = "markup5ever" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45" +dependencies = [ + "log", + "phf", + "phf_codegen", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" @@ -2688,6 +3624,15 @@ dependencies = [ "unicase", ] +[[package]] +name = "minijinja" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e136ef580d7955019ab0a407b68d77c292a9976907e217900f3f76bc8f6dc1a4" +dependencies = [ + "serde", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2715,6 +3660,27 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "monostate" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d208407d7552cd041d8cdb69a1bc3303e029c598738177a3d87082004dc0e1e" +dependencies = [ + "monostate-impl", + "serde", +] + +[[package]] +name = "monostate-impl" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ce64b975ed4f123575d11afd9491f2e37bbd5813fbfbc0f09ae1fbddea74e0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "naga" version = "0.19.2" @@ -2783,6 +3749,12 @@ dependencies = [ "jni-sys", ] +[[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.26.4" @@ -2811,6 +3783,12 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -2821,12 +3799,53 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-bigint" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[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-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -2861,7 +3880,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 2.0.66", @@ -2876,6 +3895,12 @@ dependencies = [ "libc", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "objc" version = "0.2.7" @@ -3051,6 +4076,28 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "onig" +version = "6.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f" +dependencies = [ + "bitflags 1.3.2", + "libc", + "once_cell", + "onig_sys", +] + +[[package]] +name = "onig_sys" +version = "69.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "openssl" version = "0.10.64" @@ -3095,6 +4142,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "orbclient" version = "0.3.47" @@ -3182,6 +4235,69 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", +] + +[[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", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + [[package]] name = "pin-project" version = "1.1.5" @@ -3216,9 +4332,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464db0c665917b13ebb5d453ccdec4add5658ee1adc7affc7677615356a8afaf" +checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" dependencies = [ "atomic-waker", "fastrand 2.1.0", @@ -3262,9 +4378,9 @@ dependencies = [ [[package]] name = "polling" -version = "3.7.0" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645493cf344456ef24219d02a768cf1fb92ddf8c92161679ae3d91b91a637be3" +checksum = "5e6a007746f34ed64099e88783b0ae369eaa3da6392868ba262e2af9b8fbaea1" dependencies = [ "cfg-if", "concurrent-queue", @@ -3275,6 +4391,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + [[package]] name = "powerfmt" version = "0.2.0" @@ -3287,12 +4409,28 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + [[package]] name = "presser" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +dependencies = [ + "diff", + "yansi", +] + [[package]] name = "prettyplease" version = "0.2.20" @@ -3313,11 +4451,20 @@ dependencies = [ "toml_edit 0.19.15", ] +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + [[package]] name = "proc-macro2" -version = "1.0.84" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] @@ -3327,6 +4474,19 @@ name = "profiling" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" +dependencies = [ + "quote", + "syn 2.0.66", +] [[package]] name = "pulldown-cmark" @@ -3339,6 +4499,21 @@ dependencies = [ "unicase", ] +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quick-xml" version = "0.30.0" @@ -3396,6 +4571,56 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools 0.12.1", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand", + "rand_chacha", + "simd_helpers", + "system-deps", + "thiserror", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67376f469e7e7840d0040bbf4b9b3334005bb167f814621326e4c7ab8cd6e944" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + [[package]] name = "raw-window-handle" version = "0.5.2" @@ -3408,6 +4633,43 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-cond" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "059f538b55efd2309c9794130bc149c6a553db90e9d99c2030785c82f0bd7df9" +dependencies = [ + "either", + "itertools 0.11.0", + "rayon", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rctree" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b42e27ef78c35d3998403c1d26f3efd9e135d3e5121b0a4845cc5cc27547f4f" + [[package]] name = "redox_syscall" version = "0.3.5" @@ -3448,9 +4710,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -3460,9 +4722,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -3471,9 +4733,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "renderdoc-sys" @@ -3487,6 +4749,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" dependencies = [ + "async-compression", "base64 0.22.1", "bytes", "encoding_rs", @@ -3549,9 +4812,9 @@ dependencies = [ [[package]] name = "reqwew" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35dc7112189e48f5963b8cadd25b30d43c7265e21c7e853bef0992b6138a6611" +checksum = "f32e40eb45193ac3fe4d16f5e80c505e309bcc06d3025fe311ee9e3028cc6e2e" dependencies = [ "bytes", "once_cell", @@ -3563,6 +4826,29 @@ dependencies = [ "tracing", ] +[[package]] +name = "resvg" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadccb3d99a9efb8e5e00c16fbb732cbe400db2ec7fc004697ee7d97d86cf1f4" +dependencies = [ + "log", + "pico-args", + "rgb", + "svgtypes", + "tiny-skia", + "usvg", +] + +[[package]] +name = "rgb" +version = "0.8.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" +dependencies = [ + "bytemuck", +] + [[package]] name = "ring" version = "0.17.8" @@ -3590,6 +4876,46 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "roxmltree" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" + +[[package]] +name = "rust-embed" +version = "8.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19549741604902eb99a7ed0ee177a0663ee1eda51a29f71401f166e47e77806a" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb9f96e283ec64401f30d3df8ee2aaeb2561f34c824381efa24a35f79bf40ee4" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn 2.0.66", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c74a686185620830701348de757fd36bef4aa9680fd23c49fc539ddcc1af32" +dependencies = [ + "sha2", + "walkdir", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -3806,6 +5132,7 @@ version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ + "indexmap", "itoa", "ryu", "serde", @@ -3854,6 +5181,17 @@ dependencies = [ "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 = "sharded-slab" version = "0.1.7" @@ -3884,6 +5222,42 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + +[[package]] +name = "simple_logger" +version = "4.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e7e46c8c90251d47d08b28b8a419ffb4aede0f87c2eea95e17d1d5bacbf3ef1" +dependencies = [ + "colored", + "log", + "time", + "windows-sys 0.48.0", +] + +[[package]] +name = "simplecss" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a11be7c62927d9427e9f40f3444d5499d868648e2edbc4e2116de69e7ec0e89d" +dependencies = [ + "log", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" @@ -3978,6 +5352,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "spirv" @@ -3988,23 +5365,89 @@ dependencies = [ "bitflags 2.5.0", ] +[[package]] +name = "spm_precompiled" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5851699c4033c63636f7ea4cf7b7c1f1bf06d0cc03cfb42e711de5a5c46cf326" +dependencies = [ + "base64 0.13.1", + "nom", + "serde", + "unicode-segmentation", +] + +[[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" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strict-num" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" +dependencies = [ + "float-cmp", +] + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot", + "phf_shared 0.10.0", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] -name = "strict-num" -version = "0.1.1" +name = "strum" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" [[package]] -name = "strsim" -version = "0.11.1" +name = "strum_macros" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.66", +] [[package]] name = "subtle" @@ -4012,6 +5455,16 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +[[package]] +name = "svgtypes" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e44e288cd960318917cbd540340968b90becc8bc81f171345d706e7a89d9d70" +dependencies = [ + "kurbo", + "siphasher", +] + [[package]] name = "syn" version = "1.0.109" @@ -4040,6 +5493,17 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[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.66", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -4061,6 +5525,25 @@ dependencies = [ "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", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.12.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" + [[package]] name = "tempfile" version = "3.10.1" @@ -4073,6 +5556,17 @@ dependencies = [ "windows-sys 0.52.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 = "termcolor" version = "1.4.1" @@ -4114,15 +5608,30 @@ dependencies = [ [[package]] name = "tiff" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" dependencies = [ "flate2", "jpeg-decoder", "weezl", ] +[[package]] +name = "tiktoken-rs" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c314e7ce51440f9e8f5a497394682a57b7c323d0f4d0a6b1b13c429056e0e234" +dependencies = [ + "anyhow", + "base64 0.21.7", + "bstr", + "fancy-regex 0.12.0", + "lazy_static", + "parking_lot", + "rustc-hash", +] + [[package]] name = "time" version = "0.3.36" @@ -4167,6 +5676,7 @@ dependencies = [ "bytemuck", "cfg-if", "log", + "png", "tiny-skia-path", ] @@ -4182,19 +5692,46 @@ dependencies = [ ] [[package]] -name = "tinyvec" -version = "1.6.0" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "tinyvec_macros", + "displaydoc", + "zerovec", ] [[package]] -name = "tinyvec_macros" -version = "0.1.1" +name = "tokenizers" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "e500fad1dd3af3d626327e6a3fe5050e664a6eaa4708b8ca92f1794aaf73e6fd" +dependencies = [ + "aho-corasick", + "derive_builder", + "esaxx-rs", + "getrandom", + "indicatif", + "itertools 0.12.1", + "lazy_static", + "log", + "macro_rules_attribute", + "monostate", + "onig", + "paste", + "rand", + "rayon", + "rayon-cond", + "regex", + "regex-syntax", + "serde", + "serde_json", + "spm_precompiled", + "thiserror", + "unicode-normalization-alignments", + "unicode-segmentation", + "unicode_categories", +] [[package]] name = "tokio" @@ -4271,14 +5808,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" +checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.13", + "toml_edit 0.22.14", ] [[package]] @@ -4303,15 +5840,26 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.13" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" +checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.9", + "winnow 0.6.13", ] [[package]] @@ -4455,12 +6003,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - [[package]] name = "unicode-ident" version = "1.0.12" @@ -4468,12 +6010,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "unicode-normalization" -version = "0.1.23" +name = "unicode-normalization-alignments" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "43f613e4fa046e69818dd287fdc4bc78175ff20331479dab6e1b0f98d57062de" dependencies = [ - "tinyvec", + "smallvec", ] [[package]] @@ -4484,9 +6026,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" @@ -4494,23 +6036,128 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + [[package]] name = "untrusted" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "ureq" +version = "2.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d11a831e3c0b56e438a28308e7c810799e3c118417f342d30ecec080105395cd" +dependencies = [ + "base64 0.22.1", + "flate2", + "log", + "native-tls", + "once_cell", + "rustls", + "rustls-pki-types", + "rustls-webpki", + "serde", + "serde_json", + "url", + "webpki-roots", +] + [[package]] name = "url" -version = "2.5.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] +[[package]] +name = "usvg" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b0a51b72ab80ca511d126b77feeeb4fb1e972764653e61feac30adc161a756" +dependencies = [ + "base64 0.21.7", + "log", + "pico-args", + "usvg-parser", + "usvg-tree", + "xmlwriter", +] + +[[package]] +name = "usvg-parser" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd4e3c291f45d152929a31f0f6c819245e2921bfd01e7bd91201a9af39a2bdc" +dependencies = [ + "data-url", + "flate2", + "imagesize", + "kurbo", + "log", + "roxmltree", + "simplecss", + "siphasher", + "svgtypes", + "usvg-tree", +] + +[[package]] +name = "usvg-tree" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee3d202ebdb97a6215604b8f5b4d6ef9024efd623cf2e373a6416ba976ec7d3" +dependencies = [ + "rctree", + "strict-num", + "svgtypes", + "tiny-skia-path", +] + +[[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 = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + [[package]] name = "valuable" version = "0.1.0" @@ -4537,6 +6184,12 @@ dependencies = [ "time", ] +[[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.4" @@ -4655,9 +6308,9 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d50fa61ce90d76474c87f5fc002828d81b32677340112b4ef08079a9d459a40" +checksum = "34e9e6b6d4a2bb4e7e69433e0b35c7923b95d4dc8503a84d25ec917a4bbfdf07" dependencies = [ "cc", "downcast-rs", @@ -4669,9 +6322,9 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.2" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82fb96ee935c2cea6668ccb470fb7771f6215d1691746c2d896b447a00ad3f1f" +checksum = "1e63801c85358a431f986cffa74ba9599ff571fc5774ac113ed3b490c19a1133" dependencies = [ "bitflags 2.5.0", "rustix 0.38.34", @@ -4692,9 +6345,9 @@ dependencies = [ [[package]] name = "wayland-cursor" -version = "0.31.1" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71ce5fa868dd13d11a0d04c5e2e65726d0897be8de247c0c5a65886e283231ba" +checksum = "a206e8b2b53b1d3fcb9428fec72bc278ce539e2fa81fe2bfc1ab27703d5187b9" dependencies = [ "rustix 0.38.34", "wayland-client", @@ -4741,9 +6394,9 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.1" +version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63b3a62929287001986fb58c789dce9b67604a397c15c611ad9f747300b6c283" +checksum = "67da50b9f80159dec0ea4c11c13e24ef9e7574bd6ce24b01860a175010cea565" dependencies = [ "proc-macro2", "quick-xml 0.31.0", @@ -4752,9 +6405,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.31.1" +version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15a0c8eaff5216d07f226cb7a549159267f3467b289d9a2e52fd3ef5aae2b7af" +checksum = "105b1842da6554f91526c14a2a2172897b7f745a805d62af4ce698706be79c12" dependencies = [ "dlib", "log", @@ -4799,11 +6452,20 @@ dependencies = [ "web-sys", ] +[[package]] +name = "webpki-roots" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "weezl" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" [[package]] name = "wgpu" @@ -5326,9 +6988,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.9" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86c949fede1d13936a99f14fafd3e76fd642b556dd2ce96287fbe2e0151bfac6" +checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" dependencies = [ "memchr", ] @@ -5343,6 +7005,18 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "x11-dl" version = "2.21.0" @@ -5400,12 +7074,12 @@ checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" [[package]] name = "xdg-home" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e5a325c3cb8398ad6cf859c1135b25dd29e186679cf2da7581d9679f63b38e" +checksum = "ca91dcf8f93db085f3a0a29358cd0b9d670915468f4290e8b85d118a34211ab8" dependencies = [ "libc", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -5434,9 +7108,9 @@ dependencies = [ [[package]] name = "xkeysym" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054a8e68b76250b253f671d1268cb7f1ae089ec35e195b2efb2a4e9a836d0621" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xml-rs" @@ -5444,6 +7118,42 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" +[[package]] +name = "xmlwriter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure", +] + [[package]] name = "zbus" version = "3.15.2" @@ -5491,7 +7201,7 @@ version = "3.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "regex", @@ -5530,12 +7240,79 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure", +] + [[package]] name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +[[package]] +name = "zerovec" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2cc8827d6c0994478a15c53f374f46fbd41bea663d809b14744bc42e6b109c" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448" +dependencies = [ + "zune-core", +] + [[package]] name = "zvariant" version = "3.15.2" @@ -5556,7 +7333,7 @@ version = "3.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 1.0.109", diff --git a/Cargo.toml b/Cargo.toml index ed83e17..74e9616 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,10 +35,13 @@ async-openai = { version = "0.23" } color-eyre = { version = "0.6" } eframe = { version = "0.27", features = ["persistence"] } egui_commonmark = { version = "0.16" } +egui_extras = { version = "0.27", features = ["svg"] } enigo = { version = "0.2" } futures = { version = "0.3" } get-selected-text = { version = "0.1" } global-hotkey = { version = "0.5" } +# TODO?: remove it since it requires libxml2. +llm_utils = { version = "0.0.6" } reqwew = { version = "0.2" } serde = { version = "1.0", features = ["derive"] } thiserror = { version = "1.0" } diff --git a/asset/check.svg b/asset/check.svg new file mode 100644 index 0000000..441a187 --- /dev/null +++ b/asset/check.svg @@ -0,0 +1 @@ + diff --git a/asset/copy.svg b/asset/copy.svg new file mode 100644 index 0000000..89f4440 --- /dev/null +++ b/asset/copy.svg @@ -0,0 +1 @@ + diff --git a/src/air.rs b/src/air.rs index e27941d..03aa4fb 100644 --- a/src/air.rs +++ b/src/air.rs @@ -1,3 +1,5 @@ +// TODO: use unwrap here and return result in other places. + // std use std::{ sync::{atomic::Ordering, Once}, @@ -12,6 +14,7 @@ use crate::{ os::{AppKit, Os}, prelude::Result, service::Services, + state::State, ui::Uis, }; @@ -20,20 +23,22 @@ struct AiR { once: Once, runtime: Runtime, components: Components, + state: State, services: Services, uis: Uis, } impl AiR { - fn init(ctx: &Context) -> Self { - Self::set_fonts(ctx); + fn init(ctx: Context) -> Self { + Self::set_fonts(&ctx); let once = Once::new(); - let runtime = Runtime::new().expect("runtime must be created"); - let components = Components::init(); - let services = Services::init(ctx); + let runtime = Runtime::new().unwrap(); + let mut components = Components::init().unwrap(); + let state = Default::default(); + let services = Services::init(&ctx, &runtime, &mut components, &state).unwrap(); let uis = Uis::init(); - Self { once, runtime, components, services, uis } + Self { once, runtime, components, state, services, uis } } fn set_fonts(ctx: &Context) { @@ -62,20 +67,20 @@ impl AiR { } fn try_unhide(&mut self, ctx: &Context) { - let to_hidden = self.services.to_hidden.load(Ordering::SeqCst); + let to_hide = self.state.to_hide.load(Ordering::SeqCst); let focused = ctx.input(|i| i.focused); - if to_hidden && !focused { + if to_hide && !focused { self.components.active_timer.refresh(); - self.services.to_hidden.store(true, Ordering::SeqCst); + self.state.to_hide.store(true, Ordering::SeqCst); // TODO: https://github.com/emilk/egui/discussions/4635. // ctx.send_viewport_cmd(ViewportCommand::Minimized(true)); Os::hide(); - } else if !to_hidden && focused { + } else if !to_hide && focused { // TODO: find a better place to initialize this. self.once.call_once(Os::set_move_to_active_space); - self.services.to_hidden.store(true, Ordering::SeqCst); + self.state.to_hide.store(true, Ordering::SeqCst); } } } @@ -83,15 +88,16 @@ impl App for AiR { fn update(&mut self, ctx: &Context, _: &mut Frame) { let air_ctx = AiRContext { egui_ctx: ctx, - runtime: &self.runtime, components: &mut self.components, - services: &mut self.services, + state: &self.state, + services: &self.services, }; self.uis.draw(air_ctx); - // TODO?: these will be called multiple times, move to focus service. + // TODO: these will be called multiple times, move to focus service. self.try_unhide(ctx); + // TODO: move to timer service. if self.components.active_timer.duration() > Duration::from_secs(15) { self.components.active_timer.refresh(); @@ -102,16 +108,16 @@ impl App for AiR { } fn save(&mut self, _: &mut dyn Storage) { - self.components.setting.save().expect("setting must be saved"); + self.components.setting.save().unwrap(); } } #[derive(Debug)] pub struct AiRContext<'a> { pub egui_ctx: &'a Context, - pub runtime: &'a Runtime, pub components: &'a mut Components, - pub services: &'a mut Services, + pub state: &'a State, + pub services: &'a Services, } pub fn launch() -> Result<()> { @@ -121,15 +127,14 @@ pub fn launch() -> Result<()> { viewport: ViewportBuilder::default() .with_icon( icon_data::from_png_bytes(include_bytes!("../asset/icon.png").as_slice()) - .expect("icon must be valid"), + .unwrap(), ) .with_inner_size((720., 360.)) .with_min_inner_size((720., 360.)) .with_transparent(true), - follow_system_theme: true, ..Default::default() }, - Box::new(|c| Box::new(AiR::init(&c.egui_ctx))), + Box::new(|c| Box::new(AiR::init(c.egui_ctx.clone()))), )?; Ok(()) diff --git a/src/component.rs b/src/component.rs index 1bd661f..ef38b44 100644 --- a/src/component.rs +++ b/src/component.rs @@ -1,5 +1,8 @@ // TODO?: refresh trait. +pub mod tokenizer; +use tokenizer::Tokenizer; + pub mod function; pub mod keyboard; @@ -20,20 +23,28 @@ use timer::Timer; pub mod util; +// std +use std::sync::Arc; +// self +use crate::prelude::*; + #[derive(Debug)] pub struct Components { pub active_timer: Timer, pub setting: Setting, pub quote: Quoter, - pub openai: OpenAi, + pub tokenizer: Tokenizer, + pub openai: Arc, } impl Components { - pub fn init() -> Self { + pub fn init() -> Result { let active_timer = Timer::default(); - let setting = Setting::load().expect("setting must be loaded"); + let setting = Setting::load()?; let quote = Quoter::default(); - let openai = OpenAi::new(setting.ai.clone()); + let tokenizer = Tokenizer::new(setting.ai.model.as_str()); + // TODO: no clone. + let openai = Arc::new(OpenAi::new(setting.ai.clone())); - Self { active_timer, setting, quote, openai } + Ok(Self { active_timer, setting, quote, tokenizer, openai }) } } diff --git a/src/component/function.rs b/src/component/function.rs index ffc7b40..e6b219e 100644 --- a/src/component/function.rs +++ b/src/component/function.rs @@ -1,20 +1,28 @@ -// TODO:detect input language. +// self +use super::setting::Translation; #[derive(Debug)] pub enum Function { - Polish, - // Translate, + Rewrite, + RewriteDirectly, + Translate, + TranslateDirectly, } impl Function { - pub fn prompt(&self) -> &'static str { + pub fn prompt(&self, setting: &Translation) -> String { match self { - Self::Polish => + Self::Rewrite | Self::RewriteDirectly => "As an English professor, assist me in refining this text. \ Amend any grammatical errors and enhance the language to sound more like a native speaker.\ - Provide the refined text only, without any other things.", - // Self::Translate => "\ - // Translate the following text into English.\ - // ", + Provide the refined text only, without any other things." + .into(), + Self::Translate | Self::TranslateDirectly => format!( + "As a language professor, assist me in translate this text from {} to {}. \ + Amend any grammatical errors and enhance the language to sound more like a native speaker.\ + Provide the translated text only, without any other things.", + setting.source.as_str(), + setting.target.as_str() + ), } } } diff --git a/src/component/keyboard.rs b/src/component/keyboard.rs index 7089cca..907bccb 100644 --- a/src/component/keyboard.rs +++ b/src/component/keyboard.rs @@ -1,15 +1,17 @@ // crates.io -use enigo::{Enigo, Settings}; +use enigo::{Enigo, Keyboard as _, Settings}; // self use crate::prelude::*; #[derive(Debug)] pub struct Keyboard { - enigo: Enigo, + pub enigo: Enigo, } impl Keyboard { pub fn init() -> Result { - Ok(Self { enigo: Enigo::new(&Settings::default()).map_err(EnigoError::NewCon)? }) + let enigo = Enigo::new(&Settings::default()).map_err(EnigoError::NewCon)?; + + Ok(Self { enigo }) } // pub fn copy(&mut self) -> Result<()> { @@ -19,4 +21,8 @@ impl Keyboard { // // Ok(()) // } + + pub fn text(&mut self, text: &str) -> Result<()> { + Ok(self.enigo.text(text).map_err(EnigoError::Input)?) + } } diff --git a/src/component/openai.rs b/src/component/openai.rs index 55c44e0..350e647 100644 --- a/src/component/openai.rs +++ b/src/component/openai.rs @@ -1,44 +1,43 @@ // std -use std::sync::{Arc, Mutex}; +use std::sync::Arc; // crates.io use async_openai::{ config::OpenAIConfig, types::{ - // ChatCompletionRequestAssistantMessageArgs, ChatCompletionRequestMessage, - ChatCompletionRequestSystemMessageArgs, - ChatCompletionRequestUserMessageArgs, - CreateChatCompletionRequestArgs, + ChatCompletionRequestSystemMessageArgs, ChatCompletionRequestUserMessageArgs, + ChatCompletionResponseStream, CreateChatCompletionRequestArgs, }, Client, }; use eframe::egui::WidgetText; -use futures::StreamExt; use serde::{Deserialize, Serialize}; -use tokio::runtime::Runtime; +use tokio::sync::RwLock as TokioRwLock; // self -use crate::{component::setting::Ai, prelude::*}; +use super::setting::Ai; +use crate::prelude::*; -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct OpenAi { - pub client: Arc>, - // TODO: use Mutex. + pub client: Arc>>, pub setting: Ai, - pub output: Arc>, } impl OpenAi { pub fn new(setting: Ai) -> Self { - Self { - client: Arc::new(Client::with_config( - OpenAIConfig::new() - .with_api_base("https://aihubmix.com/v1") - .with_api_key(&setting.api_key), - )), - setting, - output: Arc::new(Mutex::new(Default::default())), - } + let client = Arc::new(TokioRwLock::new(Client::with_config( + OpenAIConfig::new().with_api_base(&setting.api_base).with_api_key(&setting.api_key), + ))); + + Self { client, setting } + } + + pub fn reload(&mut self, setting: Ai) { + *self.client.blocking_write() = Client::with_config( + OpenAIConfig::new().with_api_base(&setting.api_base).with_api_key(&setting.api_key), + ); + self.setting = setting; } - pub fn chat(&self, runtime: &Runtime, prompt: &str, content: &str) -> Result<()> { + pub async fn chat(&self, prompt: &str, content: &str) -> Result { let msg = [ ChatCompletionRequestSystemMessageArgs::default().content(prompt).build()?.into(), ChatCompletionRequestUserMessageArgs::default().content(content).build()?.into(), @@ -49,34 +48,9 @@ impl OpenAi { .max_tokens(4_096_u16) .messages(&msg) .build()?; - let c = self.client.clone(); - let o = self.output.clone(); - - runtime.spawn(async move { - match c.chat().create_stream(req).await { - Ok(mut s) => { - o.lock().expect("output must be available").clear(); - - while let Some(r) = s.next().await { - match r { - Ok(resp) => { - resp.choices.iter().for_each(|c| { - if let Some(c) = &c.delta.content { - o.lock().expect("output must be available").push_str(c); - } - }); - }, - Err(e) => println!("failed to receive chat response: {e}"), - } - } - }, - Err(e) => { - tracing::error!("failed to create chat stream: {e}"); - }, - } - }); + let stream = self.client.read().await.chat().create_stream(req).await?; - Ok(()) + Ok(stream) } } diff --git a/src/component/setting.rs b/src/component/setting.rs index 5f8e70a..8f04e39 100644 --- a/src/component/setting.rs +++ b/src/component/setting.rs @@ -2,16 +2,21 @@ use std::{fs, path::PathBuf}; // crates.io use app_dirs2::{AppDataType, AppInfo}; +use async_openai::config::OPENAI_API_BASE; +use eframe::egui::WidgetText; use serde::{Deserialize, Serialize}; // self -use crate::{component::openai::Model, prelude::*}; +use super::openai::Model; +use crate::prelude::*; const APP: AppInfo = AppInfo { name: "AiR", author: "xavier@inv.cafe" }; #[derive(Debug, Default, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] pub struct Setting { pub general: General, pub ai: Ai, + pub translation: Translation, } impl Setting { pub fn path() -> Result { @@ -23,7 +28,12 @@ impl Setting { tracing::info!("loading from {}", p.display()); - Ok(toml::from_str(&fs::read_to_string(p)?)?) + // TODO: log the error. + let Ok(s) = fs::read_to_string(p) else { + return Ok(Default::default()); + }; + + Ok(toml::from_str(&s)?) } pub fn save(&self) -> Result<()> { @@ -36,6 +46,7 @@ impl Setting { } #[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] pub struct General { pub font_size: f32, pub hide_on_lost_focus: bool, @@ -46,10 +57,11 @@ impl Default for General { } } -// TODO: Support Google Gemini. +// TODO: support Google Gemini. #[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] pub struct Ai { - // TODO: custom API endpoint. + pub api_base: String, pub api_key: String, pub model: Model, pub temperature: f32, @@ -61,6 +73,51 @@ impl Ai { } impl Default for Ai { fn default() -> Self { - Self { api_key: Default::default(), model: Model::default(), temperature: 0.7 } + Self { + api_base: OPENAI_API_BASE.into(), + api_key: Default::default(), + model: Model::default(), + temperature: 0.7, + } + } +} + +// TODO: add a super type for all the settings. +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub struct Translation { + pub source: Language, + pub target: Language, +} +impl Default for Translation { + fn default() -> Self { + Self { source: Language::ZhCn, target: Language::EnGb } + } +} +// https://www.alchemysoftware.com/livedocs/ezscript/Topics/Catalyst/Language.htm +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum Language { + // Chinese (Simplified, People's Republic of China). + ZhCn, + // English (United Kingdom). + EnGb, +} +impl Language { + pub fn all() -> [Self; 2] { + [Self::ZhCn, Self::EnGb] + } + + pub fn as_str(&self) -> &'static str { + match self { + Self::ZhCn => "zh-CN", + Self::EnGb => "en-GB", + } + } +} +#[allow(clippy::from_over_into)] +impl Into for &Language { + fn into(self) -> WidgetText { + self.as_str().into() } } diff --git a/src/component/tokenizer.rs b/src/component/tokenizer.rs new file mode 100644 index 0000000..b204cfb --- /dev/null +++ b/src/component/tokenizer.rs @@ -0,0 +1,19 @@ +// std +use std::sync::{Arc, RwLock}; +// crates.io +use llm_utils::tokenizer::LlmTokenizer; + +#[derive(Debug)] +pub struct Tokenizer(Arc>); +impl Tokenizer { + pub fn new(model_id: &str) -> Self { + Self(Arc::new(RwLock::new(LlmTokenizer::new_tiktoken(model_id)))) + } + + pub fn count_token(&self, input: &str, output: &str) -> (u32, u32) { + // TODO: handle the error. + let t = self.0.read().unwrap(); + + (t.count_tokens(input), t.count_tokens(output)) + } +} diff --git a/src/error.rs b/src/error.rs index bc79071..2c87e4d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,3 +1,5 @@ +// TODO: Some errors are not used since we use `.unwrap()`. + #[derive(Debug, thiserror::Error)] pub enum Error { #[error(transparent)] @@ -8,15 +10,18 @@ pub enum Error { #[error(transparent)] AppDirs2(#[from] app_dirs2::AppDirsError), #[error(transparent)] - Eframe(#[from] eframe::Error), + Arboard(#[from] arboard::Error), #[error(transparent)] - Enigo(#[from] EnigoError), + Eframe(#[from] eframe::Error), #[error(transparent)] GlobalHotKey(#[from] global_hotkey::Error), #[error(transparent)] OpenAi(#[from] async_openai::error::OpenAIError), #[error(transparent)] Toml(#[from] toml::de::Error), + + #[error(transparent)] + Enigo(#[from] EnigoError), } #[derive(Debug, thiserror::Error)] diff --git a/src/main.rs b/src/main.rs index 90bf0a2..99ee901 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,7 @@ mod error; mod os; mod service; mod ui; +mod state; mod prelude { pub type Result = std::result::Result; @@ -23,6 +24,9 @@ mod prelude { } use prelude::*; +// Only used for enable the svg support. +use egui_extras as _; + fn main() -> Result<()> { color_eyre::install().unwrap(); tracing_subscriber::fmt::init(); diff --git a/src/os/macos.rs b/src/os/macos.rs index f4a3aef..321c7e1 100644 --- a/src/os/macos.rs +++ b/src/os/macos.rs @@ -77,7 +77,7 @@ impl AppKit for Os { NSApplication::sharedApplication(MainThreadMarker::new_unchecked()) .mainWindow() - .expect("main window must be available") + .unwrap() .setCollectionBehavior(NSWindowCollectionBehavior::MoveToActiveSpace); } } diff --git a/src/service.rs b/src/service.rs index d11f008..e3eb2d7 100644 --- a/src/service.rs +++ b/src/service.rs @@ -1,45 +1,25 @@ mod hotkey; use hotkey::Hotkey; -// TODO?: Init trait. - -// std -use std::{ - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, - }, - thread, - time::Duration, -}; // crates.io use eframe::egui::Context; +use tokio::runtime::Runtime; +// self +use crate::{component::Components, prelude::*, state::State}; #[derive(Debug)] pub struct Services { - // TODO: https://github.com/emilk/egui/issues/4468. - pub to_hidden: Arc, pub hotkey: Hotkey, } impl Services { - pub fn init(ctx: &Context) -> Self { - let to_hidden = { - let ctx: Context = ctx.to_owned(); - let to_hidden = Arc::new(AtomicBool::new(false)); - let to_hidden_ = to_hidden.clone(); - - thread::spawn(move || { - while !ctx.input(|i| i.focused) { - thread::sleep(Duration::from_millis(50)); - } - - to_hidden_.store(false, Ordering::SeqCst); - }); - - to_hidden - }; - let hotkey = Hotkey::init(ctx, to_hidden.clone()); + pub fn init( + ctx: &Context, + runtime: &Runtime, + components: &mut Components, + state: &State, + ) -> Result { + let hotkey = Hotkey::init(ctx, runtime, components, state)?; - Self { to_hidden, hotkey } + Ok(Self { hotkey }) } } diff --git a/src/service/hotkey.rs b/src/service/hotkey.rs index 5c440e8..8881b0c 100644 --- a/src/service/hotkey.rs +++ b/src/service/hotkey.rs @@ -1,46 +1,60 @@ // std -use std::{ - fmt::{Debug, Formatter, Result as FmtResult}, - sync::{ - atomic::{AtomicBool, Ordering}, - mpsc::{self, Receiver}, - Arc, - }, - thread, +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, }; // crates.io use arboard::Clipboard; use eframe::egui::{Context, ViewportCommand}; +use futures::StreamExt; use global_hotkey::{ hotkey::{Code, HotKey, Modifiers}, GlobalHotKeyEvent, GlobalHotKeyManager, HotKeyState, }; +use tokio::{runtime::Runtime, task}; // self -use crate::{component::function::Function, os::*}; +use crate::{ + component::{function::Function, keyboard::Keyboard, Components}, + os::*, + prelude::*, + state::State, +}; +#[derive(Debug)] pub struct Hotkey { - pub clipboard: Clipboard, - pub rx: Receiver, + pub is_running: Arc, } impl Hotkey { - pub fn init(ctx: &Context, to_hidden: Arc) -> Self { - let ctx = ctx.to_owned(); - let clipboard = Clipboard::new().expect("clipboard must be available"); - let (tx, rx) = mpsc::channel(); - let manager = GlobalHotKeyManager::new().expect("hotkey manager must be created"); - let receiver = GlobalHotKeyEvent::receiver(); - // Hotkeys. - let hk_polish = HotKey::new(Some(Modifiers::CONTROL), Code::KeyU); - let hk_polish_id = hk_polish.id(); + pub fn is_running(&self) -> bool { + self.is_running.load(Ordering::SeqCst) + } - manager.register_all(&[hk_polish]).expect("hotkey must be registered"); + pub fn init( + ctx: &Context, + runtime: &Runtime, + components: &mut Components, + state: &State, + ) -> Result { + // The manager need to be kept alive during the whole program life. + let (manager, hotkeys) = init_inner()?; + let mut clipboard = Clipboard::new()?; + let is_running = Arc::new(AtomicBool::new(false)); + let is_running_ = is_running.clone(); + let receiver = GlobalHotKeyEvent::receiver(); + let ctx = ctx.to_owned(); + let openai = components.openai.to_owned(); + let to_hide = state.to_hide.to_owned(); + let input = state.chat.input.to_owned(); + let output = state.chat.output.to_owned(); + let translation = state.setting.translation.to_owned(); - thread::spawn(move || { + runtime.spawn(async move { // The manager need to be kept alive during the whole program life. let _manager = manager; - let mut clipboard = Clipboard::new().expect("clipboard must be available"); loop { + is_running_.store(false, Ordering::SeqCst); + // Block the thread until a hotkey event is received. match receiver.recv() { Ok(e) => { @@ -48,27 +62,95 @@ impl Hotkey { if let HotKeyState::Pressed = e.state { tracing::info!("receive hotkey event {e:?}"); - to_hidden.store(false, Ordering::SeqCst); - // TODO: https://github.com/emilk/egui/discussions/4635. - // ctx.send_viewport_cmd(ViewportCommand::Minimized(false)); - Os::unhide(); + is_running_.store(true, Ordering::SeqCst); - match e.id { - i if i == hk_polish_id => { - if let Some(t) = Os::get_selected_text() { - clipboard.set_text(t).expect("clipboard must be set"); - } + let (func, to_get_selected_text) = match e.id { + i if i == hotkeys[0] => (Function::Rewrite, true), + i if i == hotkeys[1] => (Function::RewriteDirectly, true), + i if i == hotkeys[2] => (Function::Translate, true), + i if i == hotkeys[3] => (Function::TranslateDirectly, true), + _ => unreachable!(), + }; + let to_unhide = !matches!( + func, + Function::RewriteDirectly | Function::TranslateDirectly + ); - tx.send(Function::Polish).expect("hotkey event must be sent"); - }, - _ => tracing::error!("unknown hotkey id {e:?}"), + if to_unhide { + to_hide.store(false, Ordering::SeqCst); + // TODO: https://github.com/emilk/egui/discussions/4635. + // ctx.send_viewport_cmd(ViewportCommand::Minimized(false)); + Os::unhide(); + } + if to_get_selected_text { + // TODO?: this might fail, not sure. + if let Some(t) = Os::get_selected_text() { + clipboard.set_text(t).unwrap(); + } } + if to_unhide { + // Give some time for the system to unhide and then focus. + // Since `get_selected_text` is slow, we don't need this for now. + // thread::sleep(Duration::from_millis(50)); + + ctx.send_viewport_cmd(ViewportCommand::Focus); + } + + let content = match clipboard.get_text() { + Ok(c) if !c.is_empty() => c, + _ => continue, + }; - // Give some time for the system to unhide and then focus. - // Since `get_selected_text`` is slow, we don't need this for now. - // thread::sleep(Duration::from_millis(50)); + // TODO: handle the error. + input.write().unwrap().clone_from(&content); + output.write().unwrap().clear(); - ctx.send_viewport_cmd(ViewportCommand::Focus); + let openai = openai.clone(); + let output = output.clone(); + // TODO: sometimes, we don't need this. + let translation = translation.read().unwrap().to_owned(); + + // TODO?: task spawn. + // TODO: handle the error. + let mut stream = + openai.chat(&func.prompt(&translation), &content).await.unwrap(); + + // TODO: handle the error. + task::spawn_blocking(move || { + // TODO: handle the error. + // TODO: do not init this if not needed. + let mut keyboard = Keyboard::init().unwrap(); + + // TODO: handle the error. + tokio::runtime::Handle::current() + .block_on(async { + while let Some(r) = stream.next().await { + for s in r? + .choices + .into_iter() + .filter_map(|c| c.delta.content) + { + // TODO?: handle the error. + output.write().unwrap().push_str(&s); + + // TODO: move to outside of the loop. + if matches!( + func, + Function::RewriteDirectly + | Function::TranslateDirectly + ) { + // TODO?: handle the error. + keyboard.text(&s)?; + } + } + } + + Ok::<_, Error>(()) + }) + .unwrap(); + }) + .await + .unwrap(); } }, Err(e) => panic!("failed to receive hotkey event {e:?}"), @@ -76,15 +158,31 @@ impl Hotkey { } }); - Self { clipboard, rx } - } - - pub fn try_recv(&mut self) -> Option<(Function, String)> { - self.rx.try_recv().ok().map(|f| (f, self.clipboard.get_text().unwrap_or_default())) + Ok(Self { is_running }) } } -impl Debug for Hotkey { - fn fmt(&self, f: &mut Formatter) -> FmtResult { - write!(f, "Hotkey {{ clipboard: .., rx: {:?} }}", self.rx) - } + +// TODO: make into a struct. +fn init_inner() -> Result<(GlobalHotKeyManager, [u32; 4])> { + let manager = GlobalHotKeyManager::new()?; + let hk_rewrite = HotKey::new(Some(Modifiers::CONTROL), Code::KeyT); + let hk_rewrite_id = hk_rewrite.id(); + let hk_rewrite_directly = HotKey::new(Some(Modifiers::CONTROL), Code::KeyY); + let hk_rewrite_directly_id = hk_rewrite_directly.id(); + let hk_translate = HotKey::new(Some(Modifiers::CONTROL), Code::KeyU); + let hk_translate_id = hk_translate.id(); + let hk_translate_directly = HotKey::new(Some(Modifiers::CONTROL), Code::KeyI); + let hk_translate_directly_id = hk_translate_directly.id(); + + manager.register_all(&[ + hk_rewrite, + hk_rewrite_directly, + hk_translate, + hk_translate_directly, + ])?; + + Ok(( + manager, + [hk_rewrite_id, hk_rewrite_directly_id, hk_translate_id, hk_translate_directly_id], + )) } diff --git a/src/state.rs b/src/state.rs new file mode 100644 index 0000000..7ef0df8 --- /dev/null +++ b/src/state.rs @@ -0,0 +1,23 @@ +// std +use std::sync::{atomic::AtomicBool, Arc, RwLock}; +// self +use crate::component::setting::Translation; + +#[derive(Debug, Default)] +pub struct State { + // TODO: https://github.com/emilk/egui/issues/4468. + pub to_hide: Arc, + pub chat: Chat, + pub setting: Setting, +} + +#[derive(Debug, Default)] +pub struct Chat { + pub input: Arc>, + pub output: Arc>, +} + +#[derive(Debug, Default)] +pub struct Setting { + pub translation: Arc>, +} diff --git a/src/ui/panel/chat.rs b/src/ui/panel/chat.rs index 83c896b..baa8fc1 100644 --- a/src/ui/panel/chat.rs +++ b/src/ui/panel/chat.rs @@ -9,39 +9,29 @@ use crate::{air::AiRContext, component::util}; pub struct Chat { // TODO: use widgets instead. pub input: String, - pub output: String, + pub output: OutputWidget, } impl UiT for Chat { fn draw(&mut self, ui: &mut Ui, ctx: &mut AiRContext) { - if let Some((func, input)) = ctx.services.hotkey.try_recv() { - // TODO: focus on the chat panel. - - self.input = input; - - ctx.components - .openai - .chat(ctx.runtime, func.prompt(), &self.input) - .expect("chat must succeed"); - } - if let Ok(output) = ctx.components.openai.output.try_lock() { - output.clone_into(&mut self.output); - } - let size = ui.available_size(); - // Input. ScrollArea::vertical().id_source("Input").max_height((size.y - 50.) / 2.).show(ui, |ui| { ui.add_sized( (size.x, ui.available_height()), - TextEdit::multiline(&mut self.input).hint_text(ctx.components.quote.get()), + TextEdit::multiline({ + if ctx.services.hotkey.is_running() { + if let Ok(i) = ctx.state.chat.input.try_read() { + i.clone_into(&mut self.input); + } + } + + &mut self.input + }) + .hint_text(ctx.components.quote.get()), ); }); - // Separator. - ui.add_space(20.); - ui.separator(); - - // Usage. + // Indicators. ui.horizontal(|ui| { ui.with_layout(Layout::right_to_left(Align::Center), |ui| { // TODO: when to show the spinner. @@ -49,25 +39,69 @@ impl UiT for Chat { ui.vertical(|ui| { ui.add_space(4.5); ui.with_layout(Layout::right_to_left(Align::Center), |ui| { - // let (i, o) = self.token_count.lock().unwrap().to_owned(); - let (i, o) = (0, 0); + let (ic, oc) = + ctx.components.tokenizer.count_token(&self.input, &self.output.value); let (ip, op) = ctx.components.setting.ai.model.prices(); ui.label(format!( "{} tokens (${:.6})", - i + o, - util::price_rounded(i as f32 * ip + o as f32 * op) + ic + oc, + util::price_rounded(ic as f32 * ip + oc as f32 * op) )); }); }); }); }); - // Output. - CommonMarkViewer::new("Output").show_scrollable( - ui, - &mut CommonMarkCache::default(), - &self.output, - ); + ui.separator(); + + // Shortcuts. + ui.horizontal(|ui| { + ui.with_layout(Layout::right_to_left(Align::Center), |ui| { + if !self.output.widget.triggered { + if ui.add(self.output.widget.copy.clone()).clicked() { + self.output.widget.triggered = true; + } + } else { + ui.add(self.output.widget.copied.clone()); + } + }); + }); + + // TODO?: use markdown. + CommonMarkViewer::new("Output").show_scrollable(ui, &mut CommonMarkCache::default(), { + if ctx.services.hotkey.is_running() { + if let Ok(o) = ctx.state.chat.output.try_read() { + o.clone_into(&mut self.output.value); + } + } + + &self.output.value + }); + } +} + +#[derive(Debug, Default)] +pub struct OutputWidget { + value: String, + widget: CopyWidget, +} +// TODO: https://github.com/emilk/egui/issues/3453. +#[derive(Debug)] +pub struct CopyWidget { + copy: Image<'static>, + copied: Image<'static>, + triggered: bool, +} +impl Default for CopyWidget { + fn default() -> Self { + Self { + copy: Image::new(include_image!("../../../asset/copy.svg")) + .max_size((16., 16.).into()) + .sense(Sense::click()), + copied: Image::new(include_image!("../../../asset/check.svg")) + .max_size((16., 16.).into()), + triggered: false, + } } } diff --git a/src/ui/panel/setting.rs b/src/ui/panel/setting.rs index 97d0d38..712aaff 100644 --- a/src/ui/panel/setting.rs +++ b/src/ui/panel/setting.rs @@ -2,11 +2,15 @@ use eframe::egui::*; // self use super::super::UiT; -use crate::{air::AiRContext, component::openai::Model}; +use crate::{ + air::AiRContext, + component::{openai::Model, setting::Language}, +}; +// TODO: when to reload the API client. #[derive(Debug, Default)] pub struct Setting { - pub api_key_widget: ApiKeyWidget, + pub api_key: ApiKeyWidget, } impl Setting { fn set_font_sizes(&self, ctx: &AiRContext) { @@ -20,49 +24,59 @@ impl Setting { impl UiT for Setting { fn draw(&mut self, ui: &mut Ui, ctx: &mut AiRContext) { ui.collapsing("General", |ui| { - Grid::new("General").show(ui, |ui| { - // Font size. - // TODO: adjust api_key_widget's length. + Grid::new("General").num_columns(2).striped(true).show(ui, |ui| { ui.label("Font Size"); - if ui - .add( - Slider::new(&mut ctx.components.setting.general.font_size, 9_f32..=16.) - .step_by(1.) - .fixed_decimals(0), - ) - .changed() - { - self.set_font_sizes(ctx); - } + ui.horizontal(|ui| { + ui.spacing_mut().slider_width = ui.available_width() - 56.; + + if ui + .add( + Slider::new(&mut ctx.components.setting.general.font_size, 9_f32..=16.) + .step_by(1.) + .fixed_decimals(0), + ) + .changed() + { + self.set_font_sizes(ctx); + } + }); ui.end_row(); }); }); + ui.collapsing("AI", |ui| { Grid::new("AI").num_columns(2).striped(true).show(ui, |ui| { - // API key. - ui.label("API Key"); - let width = ui + ui.label("API Base"); + let size = ui .horizontal(|ui| { - let size = ui.available_size(); - let w_text = ui.add_sized( - (size.x - 56., size.y), - TextEdit::singleline(&mut ctx.components.setting.ai.api_key) - .password(self.api_key_widget.visibility), - ); + let mut size = ui.available_size(); - // TODO?: persistent OpenAI client. - // if w_text.changed() {} - if ui.button(&self.api_key_widget.label).clicked() { - self.api_key_widget.clicked(); - } + size.x -= 56.; - w_text.rect.width() + ui.add_sized( + size, + TextEdit::singleline(&mut ctx.components.setting.ai.api_base), + ); + + size }) .inner; - ui.spacing_mut().slider_width = width; ui.end_row(); - // Model. + ui.label("API Key"); + ui.horizontal(|ui| { + ui.add_sized( + size, + TextEdit::singleline(&mut ctx.components.setting.ai.api_key) + .password(self.api_key.visibility), + ); + + if ui.button(&self.api_key.label).clicked() { + self.api_key.clicked(); + } + }); + ui.end_row(); + ui.label("Model"); ComboBox::from_id_source("Model") .selected_text(&ctx.components.setting.ai.model) @@ -77,8 +91,8 @@ impl UiT for Setting { }); ui.end_row(); - // Temperature. ui.label("Temperature"); + ui.spacing_mut().slider_width = size.x; ui.add( Slider::new(&mut ctx.components.setting.ai.temperature, 0_f32..=2.) .fixed_decimals(1) @@ -87,7 +101,38 @@ impl UiT for Setting { ui.end_row(); }); }); - // ui.collapsing("Hotkey", |_ui| {}); + + ui.collapsing("Translation", |ui| { + Grid::new("Translation").num_columns(2).striped(true).show(ui, |ui| { + ui.label("Source"); + ComboBox::from_id_source("Source") + .selected_text(&ctx.components.setting.translation.source) + .show_ui(ui, |ui| { + Language::all().iter().for_each(|l| { + ui.selectable_value( + &mut ctx.components.setting.translation.source, + l.to_owned(), + l.as_str(), + ); + }); + }); + ui.end_row(); + + ui.label("Target"); + ComboBox::from_id_source("Target") + .selected_text(&ctx.components.setting.translation.target) + .show_ui(ui, |ui| { + Language::all().iter().for_each(|l| { + ui.selectable_value( + &mut ctx.components.setting.translation.target, + l.to_owned(), + l.as_str(), + ); + }); + }); + ui.end_row(); + }); + }); } }