From c50394a437249eabf4f8f819ddf4b19f513c6850 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Tue, 24 Sep 2024 22:52:26 +0200 Subject: [PATCH 01/47] Add egui testing library --- .gitignore | 2 + Cargo.lock | 220 +++++++++++++++++- Cargo.toml | 4 +- crates/accesskit_query/Cargo.toml | 16 ++ crates/accesskit_query/src/lib.rs | 67 ++++++ crates/egui_demo_lib/Cargo.toml | 4 +- .../egui_demo_lib/src/demo/widget_gallery.rs | 29 +++ .../tests/snapshots/widget_gallery.new.webp | Bin 0 -> 113456 bytes .../tests/snapshots/widget_gallery.png | Bin 0 -> 166348 bytes crates/etest/Cargo.toml | 35 +++ crates/etest/etest.png | Bin 0 -> 4430 bytes crates/etest/examples/etest.rs | 48 ++++ crates/etest/src/lib.rs | 141 +++++++++++ crates/etest/src/snapshot.rs | 42 ++++ crates/etest/src/texture_to_bytes.rs | 85 +++++++ crates/etest/src/wgpu.rs | 130 +++++++++++ 16 files changed, 812 insertions(+), 11 deletions(-) create mode 100644 crates/accesskit_query/Cargo.toml create mode 100644 crates/accesskit_query/src/lib.rs create mode 100644 crates/egui_demo_lib/tests/snapshots/widget_gallery.new.webp create mode 100644 crates/egui_demo_lib/tests/snapshots/widget_gallery.png create mode 100644 crates/etest/Cargo.toml create mode 100644 crates/etest/etest.png create mode 100644 crates/etest/examples/etest.rs create mode 100644 crates/etest/src/lib.rs create mode 100644 crates/etest/src/snapshot.rs create mode 100644 crates/etest/src/texture_to_bytes.rs create mode 100644 crates/etest/src/wgpu.rs diff --git a/.gitignore b/.gitignore index 7db0b9d06fb..4a635412479 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ /.vscode /media/* .idea/ +**/tests/snapshots/*.new.png +**/tests/snapshots/*.diff.png diff --git a/Cargo.lock b/Cargo.lock index 47d5d30b6b8..cb169078597 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,6 +66,15 @@ dependencies = [ "once_cell", ] +[[package]] +name = "accesskit_query" +version = "0.28.1" +dependencies = [ + "accesskit", + "accesskit_consumer", + "extension-traits", +] + [[package]] name = "accesskit_unix" version = "0.12.0" @@ -530,6 +539,12 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22" +[[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" @@ -753,7 +768,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" dependencies = [ "ciborium-io", - "half", + "half 1.8.2", ] [[package]] @@ -818,6 +833,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[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" @@ -1003,6 +1028,12 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +[[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" @@ -1060,7 +1091,7 @@ dependencies = [ "egui_demo_lib", "egui_extras", "env_logger", - "image", + "image 0.25.0", ] [[package]] @@ -1097,6 +1128,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "dify" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0037c927ecea762372f44d75b7477c62a76f91932bfe85a52095b6e837c4390" +dependencies = [ + "anyhow", + "colored", + "getopts", + "image 0.24.9", + "rayon", +] + [[package]] name = "digest" version = "0.10.7" @@ -1192,7 +1236,7 @@ dependencies = [ "glutin", "glutin-winit", "home", - "image", + "image 0.25.0", "js-sys", "log", "objc2", @@ -1283,7 +1327,7 @@ dependencies = [ "egui_extras", "ehttp", "env_logger", - "image", + "image 0.25.0", "log", "poll-promise", "puffin", @@ -1305,8 +1349,11 @@ dependencies = [ "document-features", "egui", "egui_extras", + "etest", + "log", "serde", "unicode_names2", + "wgpu", ] [[package]] @@ -1319,7 +1366,7 @@ dependencies = [ "egui", "ehttp", "enum-map", - "image", + "image 0.25.0", "log", "mime_guess2", "puffin", @@ -1501,6 +1548,21 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "281e452d3bad4005426416cdba5ccfd4f5c1280e10099e21db27f7c1c28347fc" +[[package]] +name = "etest" +version = "0.28.1" +dependencies = [ + "accesskit_consumer", + "accesskit_query", + "dify", + "egui", + "egui-wgpu", + "image 0.24.9", + "image 0.25.0", + "pollster", + "wgpu", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -1539,6 +1601,51 @@ 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 2.4.1", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] +name = "ext-trait" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703090345f7d5de48379b391c9dfe69967a3c1694730a3e53bf4c905f71069c0" +dependencies = [ + "ext-trait-proc_macros", +] + +[[package]] +name = "ext-trait-proc_macros" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9f3f15f123dee4e8a6b14f033ba22904a48c5935505dc07225ce440e640d8b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "extension-traits" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "360cbc11ebc403c8ebb731dfb4d3950835d40d3d9a20f0e89a27b17e991d0863" +dependencies = [ + "ext-trait", +] + [[package]] name = "fancy-regex" version = "0.11.0" @@ -1598,6 +1705,15 @@ 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" @@ -1767,6 +1883,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + [[package]] name = "getrandom" version = "0.2.10" @@ -2005,6 +2130,16 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +[[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.3" @@ -2128,6 +2263,24 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "image" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-traits", + "png", + "qoi", + "tiff", +] + [[package]] name = "image" version = "0.25.0" @@ -2151,7 +2304,7 @@ dependencies = [ "eframe", "egui_extras", "env_logger", - "image", + "image 0.25.0", ] [[package]] @@ -2256,6 +2409,15 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" +dependencies = [ + "rayon", +] + [[package]] name = "js-sys" version = "0.3.70" @@ -2299,6 +2461,18 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[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" @@ -3158,6 +3332,15 @@ dependencies = [ "puffin_http", ] +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + [[package]] name = "quick-xml" version = "0.31.0" @@ -3499,7 +3682,7 @@ version = "0.1.0" dependencies = [ "eframe", "env_logger", - "image", + "image 0.25.0", ] [[package]] @@ -3710,6 +3893,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" @@ -3890,6 +4076,17 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "time" version = "0.3.30" @@ -5129,6 +5326,15 @@ 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" diff --git a/Cargo.toml b/Cargo.toml index 9e2fac41cf8..58fc162029c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,11 +12,9 @@ members = [ "crates/emath", "crates/epaint", "crates/epaint_default_fonts", - "examples/*", "tests/*", - - "xtask", + "xtask", "crates/etest", "crates/accesskit_query", ] [workspace.package] diff --git a/crates/accesskit_query/Cargo.toml b/crates/accesskit_query/Cargo.toml new file mode 100644 index 00000000000..9640027e1b9 --- /dev/null +++ b/crates/accesskit_query/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "accesskit_query" +edition.workspace = true +license.workspace = true +rust-version.workspace = true +version.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +accesskit_consumer = "0.24.0" +accesskit = "0.16.0" +extension-traits = "2" + +[lints] +workspace = true diff --git a/crates/accesskit_query/src/lib.rs b/crates/accesskit_query/src/lib.rs new file mode 100644 index 00000000000..046adf66cc9 --- /dev/null +++ b/crates/accesskit_query/src/lib.rs @@ -0,0 +1,67 @@ +use accesskit_consumer::{FilterResult, Node}; +use extension_traits::extension; +use std::fmt::Debug; + +struct DebugNode<'a>(&'a Node<'a>); + +impl Debug for DebugNode<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let node = self.0; + + let mut tuple = f.debug_tuple("Node"); + tuple.field(&node.id()).field(&node.role()); + + if let Some(name) = node.name() { + tuple.field(&name); + } + + tuple.finish() + } +} + +#[extension(pub trait NodeExt)] +impl<'a> Node<'a> { + fn query_by<'b>(&'b self, f: impl Fn(&Node<'_>) -> bool + 'a) -> Option> { + let mut iter = self.filtered_children(move |node: &Node<'_>| { + if f(node) { + FilterResult::Include + } else { + FilterResult::ExcludeNode + } + }); + let result = iter.next(); + + if let Some(second) = iter.next() { + let first = result?; + panic!( + "Found two or more nodes matching the query: {:?} {:?}", + DebugNode(&first), + DebugNode(&second) + ); + } + + result + } + + fn get_by<'b>(&'b self, f: impl Fn(&Node<'_>) -> bool + 'a) -> Node<'a> { + self.query_by(f).expect("No node found matching the query") + } + + fn query_by_name<'b>(&'b self, name: &'a str) -> Option> { + self.query_by(move |node| node.name().as_deref() == Some(name)) + } + + fn get_by_name<'b>(&'b self, name: &'a str) -> Node<'a> { + self.query_by_name(name) + .expect("No node found with the given name") + } + + fn query_by_role<'b>(&'b self, role: accesskit::Role) -> Option> { + self.query_by(move |node| node.role() == role) + } + + fn get_by_role<'b>(&'b self, role: accesskit::Role) -> Node<'a> { + self.query_by_role(role) + .expect("No node found with the given role") + } +} diff --git a/crates/egui_demo_lib/Cargo.toml b/crates/egui_demo_lib/Cargo.toml index 28b0592c228..c41000986ed 100644 --- a/crates/egui_demo_lib/Cargo.toml +++ b/crates/egui_demo_lib/Cargo.toml @@ -56,7 +56,9 @@ serde = { workspace = true, optional = true } [dev-dependencies] criterion.workspace = true - +etest = { path = "../etest", features = ["wgpu", "snapshot"] } +wgpu = { workspace = true, features = ["metal"] } +egui = { workspace = true, features = ["default_fonts"] } [[bench]] name = "benchmark" diff --git a/crates/egui_demo_lib/src/demo/widget_gallery.rs b/crates/egui_demo_lib/src/demo/widget_gallery.rs index 7be6e20c040..a39c5d5da36 100644 --- a/crates/egui_demo_lib/src/demo/widget_gallery.rs +++ b/crates/egui_demo_lib/src/demo/widget_gallery.rs @@ -285,3 +285,32 @@ fn doc_link_label_with_crate<'a>( }) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::View; + use egui::{CentralPanel, Context, Vec2}; + use etest::snapshot::image_snapshot; + use etest::wgpu::TestRenderer; + use etest::Harness; + + #[test] + pub fn should_match_screenshot() { + let mut demo = WidgetGallery::default(); + let app = |ctx: &Context| { + CentralPanel::default().show(ctx, |ui| { + demo.ui(ui); + }); + }; + let mut harness = Harness::new() + .with_size(Vec2::new(380.0, 550.0)) + .with_dpi(2.0); + + harness.run(app); + + let image = TestRenderer::new().render(&harness); + + image_snapshot(image, "widget_gallery"); + } +} diff --git a/crates/egui_demo_lib/tests/snapshots/widget_gallery.new.webp b/crates/egui_demo_lib/tests/snapshots/widget_gallery.new.webp new file mode 100644 index 0000000000000000000000000000000000000000..c4f58f5e1296e19c1af3210038d6a48b111eb1d4 GIT binary patch literal 113456 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�)$z^=Xa{P6<|t2FX0i_z)i5>44Nui5Ti)C?Zrf%5=OU24bi%51%*3`tX zMCJ`&OIZ(nBso=+k}iv?JQb|f*%!^m5W0Oh1rU^FBgwaQc$U^Wz+tQfI zC&>E*DzdYLiZ&YvM%vGLqID1zHjGG^PphknK{pD0G8M5^d`ekc5v?cM`Ap9c2xeHG zuy+Q}D$4j*=rOz^dnkCYE(t3r@196G@pbgDmG**C*WiZUNb5vHf(kTivR(v5_u1;u zA7rIe*JQt!Z=(6OkcyEiZ^daJ$H)#D$C#f!R#g-Ee(;ph)EL>qlIMPD6H2am&lFng zw@M1G*;!_Tf?3&eJbgI4MeQN3-7M}7hApMXm?dgLFc&qrPu4G)0#XfjLTo7!Xb)%O|wzAzy%;u+D;U&U7P) zJx|;W>RHZxO6c#>9$$f20;Cts<`k>LcZM)}hJ@k69^4!IHYcQE2e{%KcG(eD=VPvM z>zki>`gQ4b&4TftF|i^Y;qAJuVE#6F!247h-`0krnRNGC_)t?C-7mLF(bDj{MOAWI zK2V6^<@aXh%ASBAyP;zuk8bpX(pQpPF4#shKgGIW2|t}3Qi-_MFQh~nT*c%pfrJbc zKPy4-YzwG%>uvAeJ4x+~Zwfb%>SN6-aX!m-!Edgu`E5*+onn; zUf-u7t=vt&2CjPzc}}kE#h|+GRoz}%e+E4+hbzB?*VO&b*G3`Pn-BKcu2Rh%9RMA&h*pP5PQ*7k|3K%jS%etZGs`z*UCcGTNr zRwtT&H!a<3xMuFPe*p<>w|lGnd7hfKPsWtCFbtN$Wzg|pJ;SheQOlQ*<%-X7t9NiZ zg%81a7V>r-SmZg^2(&wXp4a5K`;k*u=D=4DvN@nA+8J%`av0+D;Sl{i(q(_6k~h;5Ct4h_UC7()F|cQR z8X*<46Gm^MS$z>>ZXLaZ1Yj<8XEJli#Irwe-fzMW6x#K*y5@zP-Ah$>w`gqWPb+M+ z(;Efv!=uUtl>>YAGfv=7?tXiwD2H$Rf{I(3-85yA$=n&jwX3Kzb(2)Rc5WnFif21x zF+N+Y`A$*{_c2E^pM+rSbaKM#MHAtW=a{ceGY)_F}>yEx;frKTx{^CxKxoVEnfDQv97ew*w^df;rB3Yw^cChhYC!%M-w=_P`*B>5M~=36Ec zHIVGtBwOKjz+D9+GUr57L6>(Rq=pV~BJ#^tnk{&rn*{w-U@_LDM#$~k+vw^|$J56| z2UuEW0J_q+V}^O$YDjdKknja0q{TZ=&m)6ax0lM9qSDLBLpP5B-una+OxTwuT3k+t z@0PrFhBYs46Mx&8G9_ua>b~?e0K>k{cLO#*9{7rU@jPf1-fNxpc^q>}FMQ>S?^DcnGffz$_Y@DreWNU&KGh|OB@K~xcgCf$U& zs_LBJM`fkCx9m{X)Dlb${gB;jyqnWp`^0+t7G{%xd_tWJV8CkzIR1t5 zh~{qgymCP^k^PPhsH6aJg6mfBoyg%DDyHZsm0Vr$j}{w7pSycOnrd2di92@0LDfii zO<3W1Ep^gr=Z-v8E7Yzp{X`oME_F_Bg#n zQJnD-@{bfxRT*o~HQ6#-;R=hh&jdST%&)Ng{b&0{y5RdY9au(OJC1CAWm%kMtCFBR zF_aj`as}vEKK;m^KdvD?2&vf-$P&)}zD@HZFR6s@;_cbJ3Uc4%uI3E6OSqe6?}H8c z7raXM_L6?OXUrQuWmPSXc%3qIjxqiXx{xRUeJ%QXj0!QQ-(zTOFoJPrhl(`RZm*dG zojB00P&OV0Ty5YrYX!+TXrU+*z{CU6UP3VD*@1;~IZAj(H zhjnp>2Y=_D6P3rh3Z|cZq6{wcDW(JXT{#&3kucE@^sWaEdCoyri%y*H#rPmVz=YYJ8x&Oz)f+>tBx{HV@w^K1XV$ecO7J3@nXK749p@yo|U zE{%e5O#pH{M~h+PgN_?mmBn2p?U?w;N*hFzqzNu+Rta05DR>CKXOmws(+@${)C(s! z2`7;y%lc7MN(Ht!O2qB=8B0Qt<&BqI0x1--OP=3?q>AS>Oz$pHwFoVKwz0a2iAv2*Kgv{8wL-Q?ckIP1A2bvKJ7>|kcfsEXtF-7Z^}(I zJZ5zFF|;Nia}$p*!xmATypW@7Pm&EK2#!D``eB`8;A{}Uuz8~m=@nq4=VZ&u&2muk zLec+0d*3RE3g+t8r5XS$Z~(ARK-5D8q3Mg(MA^@PZ1E*LkG3&sGkD((g_>9b*eqhI zlSwz)0a_lz=QwrBQJ>(g)tV1I&(nMXq@U>PZV_#yik=K)Zd@-Vb`CACA|%n|hG=6& zS=&IIgZePjCBcU$S29Wv#>YwO#o90J+SDs>@8clXx76erR`r_Y9kNkg%6p)@ktFS* zE1L-_>4qam+6x8?20YL*w%@8GK5N9N-DF~YWj^<+zA0p`(j`<6EVZISe108OxvzG2 z%hQep+^Pqm)T58Kw>p$cY9Z-o@1C^C^V>YbGxvueUV|$pPLB7nDs2M_ET5Zz_W*!6 z1+2D+tJqAiC!P?tx6E>n0SODYQwoTavkH|(p4wB~Ygo>hJ}~BSrbrX>cCUHWwRFy8 zxYV=0pyfe+e-9Mlb19?88Bd!9`VDV`lJw=fe8t+ANV)#H!%e-JbZ(}>IaF7Vi*7sL z@YkYCKP>tMlYkoU7m;FQ|M;Ye_0EGky|?x8&%KersWs;h?7@6F>SVa#ou)ZbGDtK( z{goT9m4DHS7a0KQYTpBzZOFP1{@M)!?RNmJfzrB@%K1I7ozrkE9ro3Ns0_$tlG&U% z8;&6wW3aUcv>jt2N&dVq{WiE8S(P2NwqKyn#c)aFvdjSeAomJn3^fbO%@$7~%@9^E z-M&>BCF6>zVa&G-VO526#;yPI{xX#MaQ=ZdFw!J%40h%n% z$DxJ}6@)WT$JTw^y>sdse%Jc9T2xK)%@lE}aI!Bl1 z?K!@xpeKZWSu;)JoxDI0rI~UF6XjXLL+pVbn*MQHVs!C{3~#_ubcV*cBa2K!^~P{q zru%u3pW#T1#-jJ(3YYrI@h5&Q`d&s&vp|da&mV>)qSUGX7_`uWC%4*k77in`m{0a{ z`ex@33b`j`vX7mWLZI06iXEPD`lb;}?$|x>aXi3-Sevt5MU~&Y25UM3^#};|=S^M*az~$xILdZ=Ev`JO#(ze z1?nHF(r(6)FU;4YFSR&hEZxg-bs*G0;zS1)9f-FO{ zu?`U0+ML<;Gh0(Zu!IRD7637tL2tyrR}{70BEEhNzbRTf`Cf3IB9EcD%3qi@l+69o zA_3@B&MG{Wd!FCg7Y#%Qy}#X-T9F(Ld1paEJVt$)eq2@{%`3iOSdN~YI$BCU8QdwP z4_+baM}_at23i)p|NgF)eB)(@-Gm3=<)w$1n$uhQp~P04X1;qeQOO<23d9T*qt`>= z^;08;dx2p3ZRPQwYMj75HAPC8!7y?|Js8jmH8?b4xm-|foCZLpyBoTf3+raLs72!1 zzly>|q;K`6te!;u#IJ9BI$V`yn&QaqO>xk;(`#U84Z_=h7(S^120u;ZoNU;BKYT=W zNP0aQTIZgQ7&U+SOft9iaJ27inPDJ_T?sgx_zfUPCVZ{7YHuH?%5fN37<3>QhKU3T zt#qVtH^W~2QqxfFstqf#)C(h;AU2GJ9jA2P1 z1@AY^(5^VT>|YDP(h7Z(SJ3O=8ww^Aqi1f~vXE#l_}6b`9ZspWhF@fVt+s!*^FQAb z+P$a#Kc0y-PWPWX33@R=|Mb_+7#d#f2WbU#j&VsJ-qsKeO4P%IS{wI0{n+(o&|d}O z7-&LM4t|gojBsCt6;*yXc6b^=lpnmQVYdnKj0V?fWhH;@yN5j_1hDzQ=h zL%eL{uGaCO>g?cCKna^p7y;k7kavnyb{g0p$QLrS?tAB?Lc=C8eX8zKi`xW?k`wvj zfBo2Jp3()Fma|FY53Dk#MQbaPie>^I27*Wj3*00wALLP}7KC14RID33Q5^^xB2?0X zj>vNk^yKj+D~cCqt_MAv{zRZ9d*OB%k7SsC@j;#05hy`|?vH5og-KP|oD65g#TKs* zTkuTKfP1yuc|2F$crD?0!SJ8-F2TzcoVSDPC!9%NUsryQw)0(b47VsDU{F(T_c2w+hK6K_xu24XA}whaxA zV7mcyFA^%tn{S(%ZVZO|=6tsjR1KPEyN|tBU6d~V!H5H?qL|714C|tL0Kr*67~%ev`*}#gMR)j z76)1hHZMO7qeMPvGvTh5V(JSmApJkPNx5r91bJoiwc2f=-j673FSt2+AmRzL;mi`f zbn*le(fkyk0%S|_b?Q173kDX0I%`_Mlw3!Xqrwf~# zn>XPw7*vGbJYNnipXbX9f@MEt%5S0?6+Rk*D|A;uLw}2PAhgjgJ_!w9FZbg~h85q{ z+So#pwso!J@l|9l)D?unQ#2k zBr^wxwx)&+`^*NNfd3L8WFK;?#KEVbMQ*r<`}9xHB^CEgV=XlDu&14IH(a!ds?+`b z7Dm^A7{NhY8N+5gEwngPfQA4aPn~6MCL$1A&QBn9m^d2JNan>y$mr^}A3GI#KK%WZ$^o%c^UP*oED~ zCMW!GcmdAD0Q>l>EAjJPTKG_B@-U7P0WIuXF&hVdWLd+b5oNG^a|k|4r~L!_8v8aVWO7@`sr`J`N+j9NG{om zn$18k@L-rP6}|>LJ0hHI7Uzp$P8|;9%3P0Q01_knj-YNdcOT5x!q&_DDyIY(pnz8x zG<@_+W9F-%M4L2rW6(SB{iZ%AX%=v(Sx*BiFk^~!<$a?R?m;$R${}-8gom&OJpg64)j*lC?bcCJy;aM(CJ-M%s=q0sp4i-KTa$EMjYjKv{GC_Fw8-k*z834yPQpXM73 zN>9o==!Lj-`3VlX3oG)vz6^u?Pnkwve^m-|H*BXugBt~V;=z-k73T@7^-D)Mu|Tt zbHNOV(Mm9c2?%uLW|B-EWE@SzQn%aT3luxr~|DfnR6=< zy1K{KvcnS8Z*%&{+P9La$bF z#nH+yV!4-0i{w=g9h6@WXll~Cr_hJ?I9R}-jy%1ue^{o=eui+z)NpUMRu$<$ zeF}=5iTBybc?%0Cs&pelOk;Gt2MT|Q1^qd|D3}-#Z@Te=+!|%gh;{M!WVmG@A_u1m zb0gp{ICDmh`~&o65xtbuS{zpj)`HVAV5H!fDdinb8z_K=b2d&z!m)R9Dz@uq*I^H4 zFzmj5DUN)>fdq&%u%Gzp&Vf)Ir!Wg9uo81XKvRz+Ok|Hdv(z}7g>v`JvlYdX6^I1} z@}<+kr1S}<*M&0vlNJ04c;?V$hSF_Q7%4}o06RbtJ!Y#16XAP<<10?kr-Si$)ZB6#fTpuO8f#{1V1MNvO>#aVLL zrisl=e+5IBY4-#_hiGCWp8lR-e1+$E>{-Ekg3YQp)Qa{T$591iFCX@a6W0de!zZ5^ zruYIe{6$*Cuurg}!V`oCymG?){M|GKR0+x!ko|($M*3mzY~}eR+3*hjltzK#anLA} z!;3Di$dLHbM!f0fZpOm8YupQq3VH7OKDz4(Bj58SlVTqmhBWNTEY5nBBeZ^WmM>vk z>MHPtYK10%m;PGqJv1TK{3#Sjo9HzRE{x$qQxmO9+5r-N^flP8r*edw1FjLfE}FbT zLz8^&7o34{R#y?&YH-fvHy`2HpMvcY#^P8YLaBiDyb(X(I1(#;hZV~o8_ozsf!$Mk zemUssh29lL7{I7K@Xtq}IT_>akITrvU?T}Oyb=chqg|vzgI361D5B9JMTK)jxM?kK z0YiWgc?9}zaKZq#C<}0G4d64JG=!$j6JbLeHVI*atsvTum!1Lm0ee0W%HQwBL}dFH zvkddG?>!%;!=SIaJ!iiUF@Oc161+PO@U)!@dus<%f7u-DkNe+vd-Jd+&vxrOh>Bxz zs%TYk9%>b5M5EDGOVuj1wzYL2&bC!SMJo|VKASx&-LTs&~ zf`l0rA%w^fNOFH`UBUL*`}yAezQ;bk@BO1bj{+gXeP7pko#$G=wUQ_`6s(ueVOf{) z!Rf+;H%45*{((3P+#+U!UMXz;E(Lf$xcg)O#hYOZEv};5L%fUl9o)~*4p`a>{o@z- za9d9wHBkP%IzavN16L>rPGyc11DKDd_3*BHuIrZarn5RfESH5KL{{HlQA?1wC+qX$ zCUx~0mcA(1IPEhR1OMmYm30>|Ku16Lb7lNKsHB}nnNMeQ|5}I1aeHZqG3(nwm>G%> zeCcSpykQO*k8BHW?a6gmM%IFi)=SrCxLHL7s3h#OTX(wtb-H0wQE7u5ivn458-BEt z?Sv%~-e7+GTbt04GYo25@4zSbakNAI4tf(@Z79gz2*FX;6de=eG)@mICRrX6R${M? zhy+0h=1pI9j1Wh^%WE>xRGp!a^g zL$}Lk?{~dmI(D$|CB|6Cc6i$y%Pa|oJmUPgMlUct*QDQ9+nQt4FEhHgiJfYBkP-i; z`>(c|ma@)It3MI*x(K&!5eH@B%`Sd|of@Y$qC1>M;nqSyk%j$L_y)1)gb{l&q2b}C zS5YO%h~|P|2~Kj&86r^Nmg4@uQGixH03*_2C9Xu2AMST)z6Pp*CPh!w05nw5^$rhh z@g>4w@EN&(umpre7}*w#jRXxQfOi$nbD7{PsR7(L_WgCo0qvX1_?{DdAS2D?Uw;X< z70tF4J&hYayblfY&BlCom<_3WLQjC^jSN*l91uA&)Dz-@*#H*Bdu{dxjQ{zo2J^5v z0f^~{3Rwo=P%d|UJF+I^@$$x3aU=v_CjK-&c^RBpzy-#)umfeb{qtp>UJp(;doMD* zyB|v7vz?SJhM*M#noiHbuB9I@=_FS;tsC=3@wdnK-rw$W6U(84G3rl$)ve{0Kq{9oOX7|m9H|q`6(TQ$e~gwf8X#qGB!QsF_Y(++y#e#_YBf8+ zkHOOLwZ8OsosJJ`!8N)kYMg&nI~=h?}!on`m$V+%s=e$CTES zSnOem*#S2hDIYlc%DQiGdi$j8e02226=i*z0>IMQ3+OBl8barXyDY+bgYVe;ZO;g| z%=oUrm$ho06$NJS=J`2<4eVdxv-_(bWLuk*&0N-K9!|sfCh_D#@%S!3ecyoB&n1u! zA~Hwr0^AE-$q4vM8Z4Bxa{nt}P3w?TlEr0phFg%EG>iI*dmd6d;T(v(YV?X9<*bVK z&U>yc?gR2JqYE;|{!ZAP+?FuxJWPf|Q+~$J@Dqt>n69ovH#!C9r zX-n6^0}Du#>^m^M7F@{L^!)N00$oKi6}w^}LpX>-8=2hFFfJwLjJHx+hp<})cGL%X zid5jO#CeQneO$1YRO5-C;W3QXL~%&|E=LjCN|v{2w(_!5$c^F7#rnKlziL)R2-!`!d$(l&)Db^^%qF(Y zR9af#U3vSjCgCFE-$B<+i2Vl%v>_)_m>ruQc0-dKzzK ztMTlI%d$IL3R$t&C$V8h$ ztU>SN_Vm3!43Pnwh>*KPin{d0tYt)HHJ*oqMIG=>4w=}D8w1or@CurA>}~jU+lEU| zr$b-jLK>(E=8Ug#o+v~;qiIe^7HC%s$U`#Ny`Qi5d`&|%VC&g8sFauclk5x5&2@Z+ ztuskEc>Oko4tC!jt*MND`Lwopxli>6uC_~&DLa16lwX?~Ro4v)G1VRK;P%y5>cTX; z{WaD7#ay_yedJ9}E)SQ^N!sR>(A)jHnv5&h>(_nFm%Z zPAHIp)i)mm?Ev>N$cX~P#99#4A*_bRM=4_uNbjI0N=CSqJ3V~8Xkg^r04)TkT2yu9 z79PG$@`8}J;hy8U5BT22xOmtPu`ENujaCJ{tNNr7y0D(hO;NqJ6<@+K3R?a4o}!!} z`Ha;Xj`O5kic=>mCu#YAc{=Fn#t-^0|Hcg3yef-zXg&a6L zphRohEh6)=*1Fi$ax<(DW#5ggYE0My0`}baCHyg@$IyA#HQ?y+2&$2STtAbitZ%az zTg6Nvh0o+_!U~y|egJ5O?Bg~=7zS2g=c|N*phFE#_utNZGCz_AaXCT}L9mA>mLeIe zI9TOjBIa=m=YO!HuwOq~f?b_cAky=&aRO$$X=Xs9o2%Gxeem_fv-|OTNdmM})t%7v zh)70V!}A?3A3iypQ}GYLk^odn;tgA7{`-P-IieSdlI#-i2v*fZx1iN0 zbe!)NDnbMPm>ZDght`34p6jd4ZfWTol?O`0eKt6~RaLg|o0qf7*1;!1&J3JTwwNpq z0sLpf;!liCKzVpj10DhL-4aV29b&B>T3iXUV~ZB+f0*qfCB^B_YYyPjjf)(-{mx;S zWql5P6_?UhQ8yb{>D82kemqB3WI@OFAL+=eh)y&4*I__x+UMb4 znwrouCf>HiUkjdwsjWwYdj|qXcG^B~R+;^X2;xI9xjl<|v&MA4%Y!k_JX?CAr!*GZ z>IZq7F6;!xQS9&NH-J7ND4f>K^XH9?^w(l72m^sxTSTZ3`$MdTXGLWYZPX5I8V)&# zk{O3BOprslHHTtcU}oZiU=pD#$5R-$rT|O6n~r@r+W;0)P@&wyf+S!Xf{Tl9V@-Rk za{W{sIAWL#f%y$7F(my$p|(B^rGpyOIPC;5H#<#2#U*4L%`1NDGiKYBvdcSI(4j{@ zxgSas9*yWh=jmwHviQC|jedfEK#sE5c=4g*Fj77a8#Aa0cw@E17Kk1OyBaLdQ5wnb zp&<#%JI>r=oYv&;^!P#Q2ApgG9csQN=maOeQ5HnGQ%h-25k>?s`fc+q>FKm??5?M$ zEQ4c>ZlyJF{$S~PXZxMl_~hK9VfkFXG&>-w9toxAao>o7@^dK{>i$w}UY=!0KH;

M@M&ZrnjfCyjzAFE02*iC1+!O9N6fuAf;621~YE@_M z5ol`WD^d31L$p<~LP`q3Nu6UsGMe{5a;aqHWh zFJreyJ5TxpB@H0eQQxjm1DGZT@0x@BHHLAo{p2&PQEbG3eVtLB#ihyT#Yvy-i3VaR zL`kOqhizbuGI5BBO7Z8fSfry>IyYm_;VggM7(1N+Ckf4#zk{MGwdq_6NJIf$tz?u8 zCswrHc)H_>l-rTi>z_%zGzvG63;*NC@u_ap-w!182}qpc;S_q*=@&o4kD?sHq<)~$2 zXysSQ3?Twm5zYm1r_HSd(-seIe>Kv49wS;``&0_V%7a(T69p~`yQ}$E&6^07qD0^X z&M4cO0PEYYJF8&()A>(d1+_2+zp?(^nrXj=Dm9gqSE%7UF?00pF_SF%O>-}geBWW3t=IMq(OiG#R$dp4Tmp2l z)nQVP$p^5)D85DS78{z+A!`z1n`GJL-vna z`Vmh;Rd6M^3mnb4ja2u-gWqy-t1h8EWS{hbd)*{$8Wg;Cr@ZPh9EuQnSxPgs1MIhh zj=4U-G6i$k(zf-Y-T>B4!l%SuYz5yN3vuWq>Hy#xk%{ldDH31DDuodQQ?jJvUSliv z5axPg1h*;sRc76SG^q(&k2H<|JnAYO(Qx4W7F*PsP8RCfrpaGij4k_AzY#iGd2Zm? ztx{j>g_5t%1lxL{<{os`SzKf5)!aU^U!2X}&I20XC{7B|YL4p7U4ZrD0{UyQu3j-?-EyMB?as@w&)3E2X{F_VbSn`T;941>zY9Ox zd*?J4tMkefHLkW3k1RXBYi)m@&XkN2ksWv%MvnOiLMn_qiar;~TtzX!N~wHtE)uLN z?ZFi`cSt(wDI&GbUcxGQmx|IdIGL9zbGtmgY(5!k$W?3r<9J+1O~w=a{fi^&RxrR{ z;YnpWG?T;#yvXbDxc6s}T+t$mE3Y>4`KREwiOz3e)jOo1k>$GF-v8h)sVLH=j}qQiGbVR8uzfT0-CMXNI1HJ-W^ z#Xm+(SmO^Js7FWV^r2_pIK86_KpS^){OV3?WzH{1dpJ^;smxKQxLGd~sx70e^l@;7 zLCnfB;=owt;ehNPa_G!qXjJQT#36zTxQs({j_?^11nBCav?Uy$S*-*)6n}$4tYQi1 znSaePGipQ3uX=erUDFnuD62tmng_K2CT#WV=pX_GPZl&#RuP(y<;EWeY0HY^NB&54G(v6L7&PQA~hF#GmvOPX#D>lqPs zbW36zT7NH4_6{L(&N-OqT|cO|s_hG@v<1tbJ1Nlm+zj`Dx9vyRYvT%cDqx^=P1>ZD z-i&zlp4(Jm;JuL@vL&I^1w0e2yNjDNn|AVmX-nksSKB5QZw&DD(AvC&;UFUs2i`J2 zO=#UwmVn?Ty(fn(Vq5XN?*jhlV7d)(4Z9HE?S0 z#Cw^V=2!klmZh=V?fgV*Lcp{J;l;&ON(pA#8|&u5UgZUg@5&}uAw|_nKd%#OqXGGV zGG-+y_M-dBW|laaUd%*U*pku%_+d*|qvVK&ASEHy13H`A>^ z4bAfl`>JAhV}OgAH?SDs;JytE7BuyE_^RAh+G(@h$}L&u zaQ&@-m4u}vX&+W(pK5b)DP$n5WojdTeAw(NRE)4)p{o;-Npd%u*r4cB{DmGUCyQdq z!U%zfz;xa=Xf>KPupz~MyV1f%pXgnVBNwpm$#TvFi$O7_AOLj_3$@VA^JUCd`R68a zE*L=`#`|&wtYBwjbK&mZ2jBLc(e5={{DM6qZdi6KAJ|qmDP*wJrqehu(f4^co*%WY zzxxN5_P~(713r(JHI@Id&QSCi7Qe4cf@SSbx!%o&hm^lVih0ht39G-$gD#S%Lk zTC74cwrA?s-dwD`gNrtKLRFna2g;P7N8aa6=VumiQv%hYi|Yq%r0&Ke4f7^0yxaV~ zU!=o4%>H0m{qo?>zRR;;?G>*D4D%0WyE(w)#FwGrB$BflbJ!xVE#l&u5(Db~YoY-K zl#D$V(Ncc+R%;CD<_vV$o$N^DKHBv=Fke7dheJC=_h5d?&OXaW$X7?cEsg*7YWznK zrLA0}YwMZl-!j}Ip&^Y_vPbklHgew`d$-8*kql#Eqx%nUxHlLy`kOB9AI^OllJ>__ zZ~F2Z(d)@alUk4rr=s)<9<0u+|LJv#$+g%_N zZoGWp7z}}rp`8fp9}Tv);pmFP@UHzy5K4RwL0`D=HxM6Rm4v{su{k411J}e<&nY*bY>8g zU&If(f6eo9=};oH$~Vw71-F4=kfO4yYt<#?RsT$Nd8#l2dA1ZQi)mpvhb8k|pViLP zxcRQPhW(TtBTnZfsBWztMHC!{h>&qS6(K*(sm{RhRgIPlz>=(Y*}EiZnv8YAu-~6h z9z~?Sx@xKB0J;f2wnAmZ!S%l!%+sc_m&dDvm4UdPqKpg$6zo)r%IjbK%1>;LzqE6; z?NZ+SJ$}NjWp|c?@3RD^h6}M}dw}C4He#PTr$>PAf3j@7LQ{vXyGK_JKJ$1s!h49q z+G^lXUG8;-7o(GZ3^b2CB#V6Gf3$S5%7bwoQ6m==G6h7KE68X_%Sc{|bw zt1QGu-pE;%s%to|HC?PiUad4RzCo256EubWEs>x>HZvPwK;BO7hg-~_If$&0pt0Cu zc^+x&C&N@gNM(qpGz;kk;vh`dE!W&E4ix){U}v&((e-1CX>JBP$dmh75Leohd4e2T ziCE0p2@hr)5h?eC*=f}G0;nQ&wBarir_a^k9+MBs28>u+dGx~U)<_8|V~OPVM8F~> zBAgZ^BH%*k1u140W^%=HX{Hln|VN+%31H9g){;`v7`eKf05RrOo{C`f`@gMF_(_UnqwJhT_ z1E;LPb`#ao$aHLGn=_M}4;iiQ0mxgg%RAfB<5dOY^~g@T6|bFGv+2Y#(#x}PU-7BC zBRq}IGJaHi13y=t-Oq&;CHV|&l>)BAg4C@Tp-OrB7v!w6&Ok5O-ms*ng4daDK=)Y4 z-5f*`)Q%Srg!9^^AOeFYf?AE7zG;!#YI$i56t#bZ=5}Lm-oi@rY86EqFa4VjKa{Rw_?*8|m*aqpn^!Qh^;d2iXbT3yqexIFUxHU72}^1RZqVI|7aG4_^bSjE;D>0RG|{p<4M9_(C*c89@u z9xxN%fQ!}j{m3&mM=Wxy?=RDIeVW(7TRQ2U4_G0PoWD3rgE4f})@=7!GU`d8-dkJ@ z)+y8E6~jkbKlZx=yu*pRBR~@q+~~04Y(?E*I32H98$Ob6LC@sIl;B5U_cy<1%S+AP zO5kQ&qvlTzmoE7Ry+e}-mEXdYha$Nh5P=@?F9HXRRy)=|iIJvOm(%tELIbblkS?Va zhQ*z_iPszvxf4vWr0m*gPskG|OkX(-xR}N-HeT{X*j{p46d+oKrxaVLVvLJS_W%5d zs_)aAt6nS!=Y%8H)JAImZU>Vl?fJog9_Lh#V;YB}Bo@)&IEJ`SWNQoQOmQSvRhg6% z-tYpj(b?j)+up%Tgs*pqymm}tCi&%l6EvYvw1iO{yY| zGqZH^D1S}e6uH$U@z7Vnx2_$Pu4?zM__juS6Cr%BUwvl+62VurVQ8m$XTIGm>9}9L z(JL|k;Q5hYa{=dJ68g(b8bdH7-Xt$APTcL(W}ZpzTes6MM?cjP`MN*nH=$6m*X;ah z(QKw(086wg{PXN;kSSH&-M6l&=Z7Afot*;|TCRwla+QMJ(zOQw1EG{3sG0d7VQw5P zg;oND8!208I{|;|qs!)A&)cVTcq2W!t^m2oX^^qNC%rku%5Q|wZF=8keO#@h;2?#c z8cf-EcoXW|_|^=xDkp~2%v7E9mfm}^GC5N7yu>t)xgASz1YD%HH2&mmU0wl%{-(bo zt#bN#RjzsFQ52v~H&pD0BgWERJX@Q}x6fWR?3gh!RL4O*=d{Mt94WO7u zS(UJ;YY(VwKF{wF26mcL$UeMcnXHiNuIXkGun zuPPW;{;iv(FM3nDfcdU+fq!{9W79!Jq4b$E33$Vw?g7`G zgWn4DmWIlvB|IvL2FA}}s`J#x5w+7|0p56?lHa#zGl^5qcx3SO{(w?8U+*MQp=QG zV_xp>7u_;lN}{^!)LG}}m!?Gro2IO;7#x+9s>zF*Q8b&99yF)FxM_{X!HB?71hIm% zlVFH3Whkq^0n*{{mhv`kudMG(8?%)GPGGsc>3I$z4JSQ~0J8KN`^>4PBuXZ7>M4-rAe#!gsh&E0m5DR^_Ft$gNUcwmrP@G4EQ|Hdy)tE%0C z72dUfAhFNY{Dv~QGOE@UuW0OnK9-!6@^PML9aeVwdkMLwX$P`Tc(GT5g%OcUEq7*8 z$P1!`3b00}-_opHb;E)Uen0zm=56y86(K1U3Yqbqj-G;5eEM1vK<|& zbgKzo@;Ck7c;2YX^_#g=*u)-n-{w(~YMV<@d3K++7njz-I~3Y;(2|nPDHRaOw6854 zDlhD#*oefRQ(UHPnzyZ;L&%^0{Q4mwVSX1pwtV%*zVrt)D-dfuTTt27Q#6PN2cd{1si$F%kwFHeV-?D7dyt^hg87}n$ zR(9#ACykEXy@V_2zZW6L>A`;kLMphKy$llf%tUlml197>Xx_UQD_hI{pkn?n^N4qL z{n!LgTyz4Y%-TQ4$dGV~solxOcT+)G?6D2qr6HL)p|IOe>vW*=)4D}sGsl*TY0`Gc z`g%mTcSC&c%Z4&!ea{;?GG&IQ)}P+%H=Nfeg)R8z<@yNNH#lFYl~2}dJP`E%F)~MV^|?xG%f?V zrZF%+JH1>S(8<+wTW7siZHywDFuMAc!fv_!RchZ*+Oym?9J2Sg$L|B!lI1P$$oD!~iRYdgyj;GbT@_R4xy2uEd z-tlgOOaaI-XiF1DUar19r@EQp>WS>e39aXQKmf zFEoLxmI-Rzd`32vCHtS>*-8dc*&eNQshUZ%{?`5pU=Qu^<_o~H!F4u$xo{cr8e29A ziFooD-seYllCS17tih_s%)&M#mX7g^$8)KhYygq5;=bySrpe7AYKb3oQ+|)ZR_XMC zY_u2Pwwc{(oEJFeDZZ60q#SmhX&mlP^_d;(%41;?;SEnoYlimD72~*iMPY4+7xwHn z>D*{_apvRTKMg}huj=7$%~f2($g92k2QjL>qx3~;B%%(zspm3e=nk&1%v z&WY^8{?mVnAB1~EeWv-k@^1~&%FR!BOcN6A|_S2Z2)3*=uA{U`g6B2faz#q^@J zVbHhL#aWh-l8Nfq_Rb|gRlk3^_O{9<7G5w^PJPrhv}GGz?j>d2tT)Qm%VljkFvn3^ z-@w@U4a0g2Mz(q9l<9fnU@DsUjTT$4Plrje5ZD8n7_(Rj_*c83 zrcbn_{^0en3%u;I*0#gpOOx-ka!`S7D^vo&FI9z{li#Dye+(Tb8Eq)M+{|%Hve}|C@(09GV>LQ$r#{1R$fmgry zapLn{0mneBS(0+DFs|@?gRU7~ub1~Xo}!CXB>mDhEU4v+n}gGB^)5SUb!{*Gw>a^< z7o$SV16Y+htogfHJ{SMow{zg5GhOfA=p(_jj0$HZs=LWCtByPKG*dMu4^Qfgq*0>4fkv|#&Av;0}BU_mE>kab^SwqPYI4zI-%^9^aTc1%l zb>D0mWp;=^JuRUi97}9)SAO~$Ei^>kH%QA{UjqR{def(BvGRcELTio-fe&num8$6p zbjL(hua9~?qW`f8P&|a_XC&OYVp9C^UiJ%rXjrn3x;%JKU+W)Rg&Yd5_gXz4_EXM& zqRMv}YIeonTo&J0YMYQWI^K~8iS!*WC_@mFm-=he8RzKR7hnlLrL35G82GZamnMck zgb>6tzRq~Wx+9VmPQ=tEMn(N-q`9YMivuww0^&3 zimw7vQB8Lw5pSrDM* z;>f6gvz>fe?B4~RCXx$g1nlWM5)Ih#Cs#k8r1e6>d^#l|%jZZPa1vx|rA1&h3BfK$ z$IDZRUBmfv-rC#|goE3LW3T=Sqze(40GK?VveZ( zVEBWrpDO1#syzgPh z?<3`SU8pP2gKpN_)#{^1KSHpup-~DGOG0{TLRM;hY_oDo8)$-pik7N-!gyT5;$RI4Ck^4_~Ya7h0G}kbrPT>@DH7vkt1|KRI#~V7iUr<&`aA%I8 z0uze^g;LzUF};gn9^+NOMcMQKO_XYH^;XUB_g?v9&T7)sHOIvaNE|yDe0lsLg8lP3$J{u9GX~9)uN0>Afr0;jmsXC;%0q1Esns@|SjT?+z z$#PE_P6%B2)^+BueO0g$AWSC&g;H7d?ikC5BmCAkEwk=(TLi(HlZdOpjIw=5ewexo zLGRqsq~Sum0>=>L{$l>58IXxj2;3BA5<|ef5XKO4Gw6567_K_sNuA?VgF(|2*Jsd- z=f0g_Jlwlg>qm+=1T;U8T~Q;Sr|?sjaa0unc6WTowTBd z;<`Uw?rt@qZnwA^G0>728gg7{BG_K3zAqs?LP=Hz4^+ zP|LNKZp=_yX2g~|Ywtjox5XvEvM$lhDMtDyT473T*}p_9$nOmxGu}t)kSO$BIy zuAZ|>ixZ}!YgLu`QcXado=K>KO{LYm6mD)EZ>e8j}suAlbCUN1axurD`3$ z)+s_yS&@6AMTo_eBM6x}@v8YiOR2j+hGnR*612Pu(S-CFrFs;GseJuvfA+f*p7=bx z;;ks-TNbF9dO5#3;AcKSD}adT<>Xm)Y~A`(>++~K3!tt7y1B$Kr}g(ef@g48DS}b? zabkVKu~vR>s>jo0T!w)|BXwrRkqTsk(_Y4V(&B%Yx@E^P4E=nXUHUZO;>*)K`dZEPo>? zWnGYyOu%2L7Fk(*bX^6UEcv29w7S1v?uMPm;p+KyZqkxG^JQyB;ty!UQwi{~$1Z9S?bLue*(E2YdpxVE5MqgYZ+V3CNbrcOu9yNj!$p&$lB z%qV2k_e8F%<%aSIZDzpRSz$fg@q+j>Yqr5kRX$;IcKAp53J9*K_|}!u#0znN7U~ZU zxaIfA>+q>Psr&(&_C%>p8wpMEF(KQoM#wa@pd$EKSK3FN*GEKMlMv!l`KfY0)XKB9 zm9y{9%0C6oA|{ohgCgAkm;7|P1F{=xVu1UucsXPG^GCS6t6DP1&;-&32VZ3NIQ#%LS<5BK4Dn+ zT6nAgQH}63VMoL3aNT!sIqtn;rSMR1T6+>vK7IyaoXU`nojk34(4s)amjDOjwUel0e>N*;@u7# z9UL~J7rU1c&_G?Z4S|Hl;q$q%M_oSst7Dj2=XV^S*87^;=vZV3?sb_Q|55%mNH)%K zH(re`Rdy)ya-)z!^K8}ltoMktq@&Rckao=XaX)s4)%sAruvW zeB%(Zua9>FLN9#UUHau>1@p~m8RNz!FjJB%?cZ>|GK?0}_~vvJIIe`xz-RZvx5!(e zE{R67va*VC{PfH;7G#&V)bAFtG!b>yI$^C zJ;TFkUjF8k4f~whT<_2Vjs8Cd#45GHZ-rp(37EeBaqqPk92+7pDR0xzcOl_g?c8&O zZvg9yrXjv1Eo7i@o38(UV(v%hIUutAiNi+Hm57k&ANv;kE+`9;L{iE4y8IS{UXbA9 z_|dXLb+F!XCDu~7{k_`2m;>LD^-@fXLoDh&^i>vIgDQ0INdKZ1k`KQ6fsjYz9MvEP zXKIo6>QV%^z*gZfrt&C;A@6s4c846%ena*^Pb;=OR#|+&!xjK-PS?p^m-cA7Yzzop zgsbnwT$yhjKEDWs&B5mrcDSKSi$9HGDXZ2$QukhV#n3q8TE!9Y!nw)rDfWI;gye^X zkBX4|uu^M$)-wSTqD2}LeMDC7pG}+1Zr$jc3ElmE)R9SM-e{f zAbgX;eQQr2GBssF!xN*`I$wnhHDEsK6+J*-F@U}^G$2GhH6S~0Kuug^ zou@d_+Ya`qab_*aXHQV~&5XL0wn}J3cQ=%6t=kz`?QlM}Xg>Ve>kJJs6KL-g^!wt93iY8|609yJzXygn$S_$Ay=R=h_IfFr;$ybDATZ{}n%`4jSWuVp zw6ypeOJiSYXB1{tRohTiQ*-W2RiG#(hteL$|9G)`tUuwAr+>E%UZy+iMge1_X?xHfBR`dGp*sI*FAW>V>R7R=Tsm#R9sBYnicaZsO(JgLq zq;p`+84egQB3ll8e~IyU>qDss_2?cZrB{m_g;I2PnK_V)SdQjv7)feRZ~z>x`Y*-J z6?x!9cA5wtdG2t1By0S#;32xw+L^)L)8ruDp`(s?S9K@AqE~|?KK$3Au9l+6#-g(& zwV;!y#Z@klu+`N_r$xZn7>eU=Cbp8?Ee?EqJ)CdD5% z*0C>6jNP6hFB%-*6-Q+-D)7dg}<;xOz#k<5OF>{%Q}s`AlpX@)!VO zmlMf-#uPK(12LLQ$W`E8`zWwB(l`#M%#3Jo?|2(A2&*86*%MX2Owi6#*It8$>05)j z>$yQ&i&q9z=c}IRg4&C~zyls;u;lCd^Ny-M(1urdHsFwMNk-u$kG>C z_f^N1TCTfXU^d2+nd_HgUgO4r_9`Y9i6-RX4S)-u5%S|@)~n7InZY#Hkd)+FH3*ew zc37XW#%(k%yfheQEGvYdkXUXQ~Tl*6>CFNr^ZE+1`L-O7nhYZbEiRLI4j9 z%w%5;q2?-70z>xEG)UdCoAnR3!e6|D-*$dQY33Yw=fpx6gH(ADHxC_Su-+ew+t+7< zGGl@};embEWvlw2dQjY{!&#_;2PQr#ZUR|;aFnpy%PS5A8MX{kqEs&zx=oo-&Qp<~ zpvGA(I!R7LY*g*9QFrizDeTP97f$;=nk;1W;!La6@rrbPb{6(WuBD>Pps&x-`j@x0 zoiL;D03~$0R}6`Ea=5e!`|?|8cI0C~i7HjG85tZ8MGQ{C4sC1QZ9oVb`^tAS;YJps zI`*`WWrVjS(YX*gf_>SP9pM)=*!9aS1wvB?=t|ME*s7I^))jU0vwAY0;I~yzd&EWh zFTj#=gHx=`8!3pr!uc5xM=eq&Qtc@dvXPe!{gAQou}D;O^z4KxW>p=sXO>D3f~a?u zsT*jdsfJs~vNJta;bGymY9zah*?CrNv@(r7IUbahd+xhi4{+`ynE3v)QE;+Yk1d3# zBV3=e5NS%mO;*Hhi4NUx>4~TVqGGOGNzDj;nqj29OrQ{j+JUsEt=J388H38rPl zu7pxvYGh?B4kOO$@{Iz~cnq?2HZ=SL$q*MW#MG+&7`}v$CZi7{rJ( zjWe1v0i_x06{42FavtTF!=5Uc7Ff=sZaXgSP1Ni`_49)@IB*S(h-5j%3m}hMWdM71 z6ug$LgYQOImFOoZ3}pkzB=p$8lUpF!eoI$sF`FzPJq{G@knn`Z;l@&I*7bYpx14mD zqOeuC|GLlJ_WtsxaD;I6?hpQh5T%7&}q4+bD7`5d;@?EGGRt@h8SFQJ*oDHz57Kj{xRfl>Ka zZSfjqyOnY5ZVb=C5VBg8YbhRAK8GJ7M-L3Zi<2zb!8eAq86H*Ib%h}^>>KFSDX)&c zc<}~=v%J;VxI*#}xPG)@k@ko}f&ddXOl@OO(W;VrxL(6K0L%oOH6v=0`>X~g!RHeg zfq4F9@lG&N5z!W6#J{++7nqQO1fkhaQL+=o=rVRdk{jc z;w6fO1%Er}6@S9Zg^C+iJ^Mrm4x%RY!2l@~82>E_o@rJ5Pezv;G`$3uT(soHSfC-~ zl>f_!g#V?mxKKZ@v)6ym8~Fb4Yd_#?d9l>No<#8arTyR22G_rZVVIU-D2Ha|$IVW* z>j`2y(DOb~gqC+`3{ag%cp5H9;7TU<`~KtI$-|~%q&4s$=(-q!%(O}X1Hb)JQYIa}?f=`j>HJj-u`V3rrmH;#YKeM7(F(qRyJAL4R zXm6mOj3z$>^O}p|Pzw;11&!gir5W@;lFmcWkodV@B~uey*eEOJa!L9se^2wXjJ&u9 zHwGh%jT&-^Oml2wK#EvqBdv$-eSmOlqJ9VP{Oo>d3aPmN@^v;5`A;ttda*uFGrXE6 z>SE~&{xh~unC1R{Ba9Z zc#%!XD7pC<=3KrpxZS3&F6si-?7^w~Dg&f!(S4hx-_(B4C<|+Y6ozL-Ql8X$az6pa zMv2e%PgEs4VQ^V?1Kkk`pXcF2G^OBB!TC)V*oR_b0wa}s%?9_J^77r%hpopisfhdv zFNzI!smaN9^yqV;L&HdF&ogJGkD-#o%|}n3yvyr^s6Wxj5PXv{;VW!IaSijwY&|A4 z$u{GstM?FFM_r}qlutP zqgyUTLVWvO7F8aIyawsWTi!OKcfP_Nhtb6+$6Z^CI1C@-eRU+Zp?bxPRf8E7NL9It zC+PFg&4hurW~cbbInz)IMgb2?^|T;-031B=Eqo`kS`|s&y|SX0^19}L{dSQ4AfJ|p zc`WJ5d@1=-GB@J@H!%H5iD#Wh9KVf-Z_SzDs2`U>*} z%I2BMz7HB0R_P>V??8tHO5S)kX*y1W^JbNr++mE0xHJlOVVhzUmIY8uPVE1f3j_x| z&~JWq)|i0VptwBK9G}8uBeTGb|0aieY1ogdGX07b_rd%i+Is2hhnU!qG&#~XCRUPB z7Za2k)3duUMB`AU-bvpp7bjkE6(6Jc68rD3(i}1DtO@&Ua_+0=_eEc!ulNBnERsfm zRly?J-;hvU!5IaqpAG_{U0qY6wJj44b}*z!nAEhNG^bK(uwNRNUO>`P_3Vf%`>E0^ zGe^7S6XBE+U+jTY)a)bS%HpUvYfR!M=@W#<6@OFb7vw1Awip?QV{EQEP*>BxDgw3x z1fkuiN^`%lP+vS-km7bm*|M|DP{wN-0>jzuJ8bWgA3j?yZA-B#;m&42z>djn4&N3) z(&M$bC>GoL!xnqrzSV%~Wj=yspI69qQHi1`;T)uZt?htgP-Ym}ez&~T+1{CHEq;=f zwFnxD$i=Wpfv?WOVlUC-@)#`Bd~bkzLib%ml%zBZM;7f}P5VrW;w6{U7O&Rse?fQH zbe*Ltru;m@BB`YluiWWZ(+ZUKlYqTCwsRTAi*+1PO@~PJk*YlP$J2Cv4eorTSbftn zn|k#}BdzlW%5&Gjj9c#hn`%50$HY*w8d^tS)OL;5NLS2Z^JD;dfn1WQx|hmHKH>`2 zb#xwBe*83ko!hG+Yv7}p))}#%IANlvQmM~H2PFQq7ziL20IAyL}! z4LRbt-Oj@%M%o#INJ7QwjcgO(g={6KQ(3o-?{COHK06w; zTyB8(K^yPZCZf8;hpst5;$37ZYD;YHG^zuPC_LTl+|TOI+lvdYhlxzTljQ_mzbCVehPTDnx+q%rJU@Ox>>6kB&yEv4iuV|5 zZoogi46*TzyPg`3CdR6gsGv8ON-vhG)UVwl6VVSjz9vie7`~f!5w$}jQ#RpX>O2fq zPxq=s{dmYJDCoAQsZ_cx9ubbr8TSt-2ur#+nPGMQph1pU!pW!LM^(XD)uP_+ALy$= zETWvH8B%hBuek&{VBghQvvh@_*`-gjcd{u-M?Ovidfau975yTwWBHq^e>GKTw1^Zz z+z6rRjg;k$0HtOGW7TutV?I?IQ)F@RfPFdli<5QzVWU!u7Uer%4|wn}id z2+4*>c%i7HvzHKca1hVcP_6(0#^Jq3!iS1AL1O?Sdl|XB45OZ#suAtmqE% z%L{(!{kk_;zEo4SRIU)C^^IVEG3# zk>OVsuW)-D*(DGP(w5*gQk?{v;|B4G?mMT2c)Pb8hN*AQ8=EwY|EudLamyoD0d zUs3Ikc`=w(g@eOXEeNMN1?VZ@{sOH(>)M4;u7? zPbK${fJ!i3hkr&kQgsYy6}Fc!+unoPV6CZPCO8KoG_@)r@vye0!eh}R_%T-KEqmof zPqn*13(iNlq5sN^eB1^bed}64_uB&bj%ji4%41*@8lhXEe$n3NWw7?>S-?eT3!}pU z555ELIHs|Ltv?vG09J0(D`icah%F9A!gxNGz0@14V%bmXB)y zeQ;4v?A8=IK->?Q zjrcHL1QJ5#KM;pwkG?ur0)~kY@u9orcN^@U8n$M^%kVzCpOjNO+78|aE`FeP26~G`X7o&p3KCLZa`5;)eJ2L`W+Av_=K*E_=sNE{3yWQXzkD?UfD^Zz|aT5kH zW6iTL+n0$iQxm`A204zcGI3p#W=#PbujG|Dw!3;139Tlq-zO>sw)R zXhyZ7G`1LGvZ1>UXk0Y z@ovc+g;x}7Y{l}A^wq!sC*U=|gPWXd00xeL$bTWC(YS<&=YXDLDjS9r&KzBreH(WV zg0*rP#s|;7yHm&tAOu72Xxd>tFZuz_Q5j+i3PQ`QrpTOZh14`6b78i%B(|t9dow7e zJxD|D?fmMPNA2ebW&ciiv@F${cCp5BOdQI+nGvLDrQ0%2jy(9=ea^2?CuqqA*kL)LG;1@{unhMu~lA~SnPc|{qvuCQqpKGx>i@d8sVb>JHN0%IskH6vrNML5Hz+8`@Q$r&~+i(Xy7BJc-RyGfoipIdwmegokzh zOv;2_-P5_}JVa?If{N?VsDJgoTk1xA%|ekD6RokD7$9S5u+-;88d8cy%FE>!ia*5- za@uRmcH9QdaZD9gg&XJz<=1g!Vm$yPEtGjW9ePsC+`3~jf$deXsJHkFk&{S3@vY7TX)ad3Sm zmO+A7vQZA&m-o=@iUIn))J+LZ9d&e2Ke!Z-_rS}#hKQBK{LzUU5tU{?E~5=t7GGA9 zI8d;h*hY@Xq}1lsR6V?R9ED;gnY}?Aok)5LI2IGIBPQp`vZz9#m&I-}aL7KV^^nbY z;biIKoN4jmfqN$Z5Tq$=4nf>6b)_6{is`Bt6q8(vU%;;L!Ep~R){RSXicT@eamW|`W63hFnAe+ zb?uzjacROEQncCb~2>vtA+{isxR!`nJ{x#O|Z-#>1Q^XW$`ZL0tfRp$-8N=go` z4Mju3i+g@&KG@NCy-VP;{+LK)e-9gP0ATa)te9gQS1j3P#+h!qe@`c#*T{c0Pf=YDOGO<0c>wmIb2|39Q1T9e?Wg2Lx z7#I(+#4rJQ5;PePjmg7;w!%9@9l#@lX&!nFi;&*Ts1>cIV1kBDGBz7EJsA> zgh85;*Na#hy=ja-Y1q{Gu7p7aFq?vfO@zVhiq$z3>O0%!aKFUE;u=cBImV2J^emrG zcrED8Bs@7IWQe#U0I$zs2@r;xVkG9l;)XH#lirB)XH67#7z3cVC|sSxvwlUKavz zsF6Um{B6!al^R_`H4iC7)rdR{9&9dt#=zFHYQ_zM;71w_7RQ<}e6rff{WbyTkHiP& z6ctee_3#cu1a{m3Fq$G!{4yxZ#z1)`1HwXTPTbEY=Yq{Kh3fRCt+rpc_m)n&7c;Bc zB692C#OM`$bXi|hm#p_;mUB4P7qr9VoigM$zg3^I6Waciufx2xWzXZgBC|0e@Ns>Cif9maPartEH_EHZ^Y8mYVE8sA%Hi zyUm%3ECZV%y?Ne<-?FcSorS2k9$BV_&27VXsbgdiCpScPJX+e?@Se6Sm=iAzez?>a zg~Q<4NZa$sBF>6LpXk|pZg<2TPvoRX&GBj@eSu-6)C|P_^~7q67(-+nm0)IRBz83( z=i*TuNty3NStg@{;J{ByM$QR0EjU^e5_a|!$6Ay^vS|_WrVLCJvy#RksDQ#;e!58R zBHOLZykMC$aqXHl4X<)g&KMgRjx`Qf31bnl3l^_E$(lDOiFH2-9~Ff%EUR8$hM39= zUZ_ti_FkHSz|eU0ER$EHd5G*0lyabNsGEp@Hx#D}XO$tx)0k(F#!$I|H&Lz`?b*4_ z(+vxqgC`yj?-4O0M%65&^5hlO_~rhakQM?TFWO=)#kMvrN@| zXpkV8N}Upo2U*${+#k=*4N$>TBl+V+2o*PQXd9nACB7ljW|pHVTU~zr_lGqGC|nBC zM;q)qS%NHuiA30g9{7|#s9~`zdQnsuC{OaC@PNo$B@7+OQ}ZDuQg3vwJMWy&nbKS| ztZUFg`9@Zo=#*0w?spR$3$Plybm@YrLaZL$02yb4%HN`+9Yql9d^8TXHW42!rhyzY z#&-pkHw5%-J=2OXQi$)0n{C9@wsSL#%K6B19<$u!4$z&??#lHo$7QTV3p+czF=q^j zKkJR=ZStE?Mmk-FT6A0KY#)q-D}M(0L>r>1Nv|$Og9ZJD+bM|yNkOOKHy{4Tm5K)u zGwUqc8;6|Ua@IKxQmBTyZ>`BdgGWZoip$Rfzd65;j!wsp8v}l%&mGfz2DE0vZs`(H zo+%sIXXVGWjQ}`ozUZztxp6D^y8%$-JvKtt^+L$HN{pOC4+GG~*8lg1sFhs=M^wd~ zhi4a`LqNY(koO)x2yx8A(O_L1uGv9x>lo}+)Xa#FrO>CWFyO|_pox6XOlV*};7ukq zJ3IXHxqK~h{4`N~Aj(;TAnK8``x3{4z6_h8;)Y;29v?Moln}pJrl1ie;~nFEcfp0L zBi3cDa&qp8Mma?#uUne{*h|xAEyD>yL!DXsOE|#d-`tx`!Ye}j7O?inq?9pa3ZtB% ztu0f-N%Ar+P*DqCNpV0?@w|P$lwfJJW z8Hb*U!+A92d=5c^c|UjJfnwjn&~F2#|6b`JD|&on=c+ibqki`FYi0P>)0Qbm+D^#b z^udktCT?Y5CM6KuUOEYP$> z9f-DuPdh3gDI+y!>8x{v)P?v=kHBb;d|*Gn|F}j6Zj(6*8-+Qn{QFb#P1q%|0~FvaiAJeYzii~#lUeY#UIy3 z*#AjH>O4f3#7V4Qfcdv2$ghhB>K!1bgS2hq!+~IR$+# z2l!BJ1D%I;DgCo_PAVH;n=Yu{SP?w#sT~pcy#46-L07!3J+gXF8(XyYqjnLI;mSJ4 z!|<{v1xDUA(KO2q;!pH3m7*PGF-Jy&lj+Z6`2su22?Yq@rn# zZUMhDS-Y8;WJJoM0-cgrFy%M&s6UcBu2GAw=f;5K(Lt?s zrD)>s>7>jLzWr5BM{U(w;`AEL0w0_H_jH8AKMK65jF!IB@^iE}eeat-AWF&wqF|i- zlrg6>0CXUX4_D2H)cDotjMaJ5qi#1}&EJ5&Vtb&{iwNVO8p++b&ggFq3rB8O`i9u>Q;DgcY@5p z1dv1gd{PN<^!StcW+>6r4uEj}aNphdKCCe4rkTTtcX+h(^2l_i0AXCyJ9IFt5X#!s zI2jIOkjif==#NkeEX`7+LW)-OYKM00;>4tYa2aX zumzn#0vc!3w&WlpOv-jHjHAHrE`U}G3A9?G&g)&}D|Nb=5V%dvP!RBY@`o5Zr(2&! zl^;X@u17Yy>;xqI69`oPDzfg~fn&|iGNL2zKHM2rh(>p>tm=b`q%~{yfG#q!D(7JS zFZJm}vVdCmpniO{B}(&L)TVpptgnq6iXf?cpd(*gi1LOEGQ&-+;La)cXo~%OaFIGA z{^e{E7?#U+2i$bm^g`|8_8ekw>S0`Nh?3He6AccXfZITj4@sxL%{m*4o+{(iF@K^q zk*4OwC=*bI9B``T2kCqHdGBmAzmAH7Jf;&A#qHiA|5h}1w|NJ3mt0Y2P!nfa$}Gi+ z{K%a&b`h(PB6|(0=Ef0@_ zmzdDZgceaPMUY}S4nSG$|3lonheciP@4us{m?umvEDbyrnJJb_K}AM0BQqtlq&zUG zshJ`o%a{?F@sOc;z(b0Ng4r@HzlLTCC@>%>qT*y8P&o|eQBhzRVHoD{+4ud7_N}$n z@4EK2uYK+PN39hKGtB4nd7k(4e&6@&Cj0iX7#fx$4us^%gL=YHE6|3Mn>Mj#1 zINFS8`Vk3&d^n)k;^FWf><}L(ai-J!tEMR_5JNL?eF(hX zf{^;Ll!PvJzp-f_z%^9cvaYTwE41O6qK1{8m$?3!9hN}c{?*8D^ZX?$HF-^JWG|0b zbBAXiic~E<3ZZ|j!ctBCO7wMa%PX^_*Xk~X_iEDp>IWn)wye~biW+?(iYVC~kcQY~ z^hvH_9Oofpf_)jDk`A>tJ5t*}oh|y`1?hi`Hd2ZYj#)Q%(8r6=69JyhFS#o9uqi^{ zlE4~p8`PyBaH^gXIP2neNBaF9qBV8~{xpa2NJR}To>%EMB4JgXY`@_1=4jQhf{dcV zWtVF-zUE#4psLH?L95?f0X9YA_*z=d6HN}z22i}^t5e`R$$tEZ%GUF2X z92UB?4LJn{vprz6ukUB@y0E3jI9T+spejJd&?`7WGQ=42hP0x~>Al_l2?ZzQp6c~Z zeVmZ*(f}!rOvYZ?H_Tv}S5Uwbi7gCIf*9Aroz7PELHd{S0@ZKw=2PLP%nyc4G|u(X z`(h5m)0v=wuMwUaHowb6*NdiRo?u;O!vxI$h$1mv;@J*f*|d&awt37-Q7jPJ1Zy#5 z8LMz^9*9Xx-Gv`K?O!+(kYJ*O3$mfV4G$vfngKXU`N>)QZ_2p0NqIP8rI+XxaeX(W z;%ra7s-ypZ{vx3-bKq#3`Q)j;!h;{$>vK!WUMg852nH;IRZCgELD|Dm`5EJdUip&j z+jES#!}@mUaYw*UQCR+p+@hDE;@D9EcN#94)e1B!c7e~kQ^bEn_GglE>s&06N z!{~dbrz~G)s7OI(!G$}*O}pGSC+U4)Y^ZUlohJ2MSYbgz{gg3HjeEd!WehB^$Di|*zSiyM9O0hbv^S$aU0?AO5if*X39CV>NCU| z4=MA9RCsFNUeMr)C^YJiK*$aF@>m#ZGK|+H;J7E@P{{OQu6Vv%8K5mfGl+m!EXOIB zu`$Qf)AP|MrbLkrIB5s#;wORB$00!F?3!JA6T;a=q8kqAc{J5?*>nsN6HB)35A~o* zq+;u6B_$-9Z!m$xjkE#37)E!(N<-Tv{^JBznqEy8bvIW9DGh=D@S4C~2_85`SEL3nI9 z{Ezs2P`ZH}HE%>b!Uv!d{O-e756OO?@xv*I7d}s&g((h|p<{hYls`O`hzbYQQHS^c zb6$$`C!j8sI{YUJ245ClXy?EF8-~^5^KJWnttSf6@KcSZ=DEVpiG9_ryQCd=?74sY z!{HOZ`*1^hiVVq??eXlpPcXDkewEP^`yoY&YSIZ#D((}RY2y$s6 z0twg%zLsKyUK?{PGU3Xt^gyS1Lh6X_Qt$sI9gE*V({^KF@csRHqbj7Gd$1pQ$vZg{ zeI!pO=JzRXH*2_?SIuTA^w+DtDb;1pU$0T>=9KhGQ~9z|Qd3gYllN%XK8@=-!gr%N zRpLwv#}cDB_#b52dhPF6(>pFz=9>)?s@BE@G`VDI&)<(-$*;PVYU2O=s^$=s>(3X} z@AY)zn>D9kMQk8+JB?F5DMoLG&vtkHAa>Ku({TVG3z*VoO-zgpbFvlnN`S7c;|Xj^vK4Bg(c1)T&i zrMT`TxNdw;pOCfbIbdj?%+EG=)wZBZJ?v^iMPIZbgS2&#Cthq$oWM;^I)WYavN{^@t}PIjDg zU#|01do%l7Up8NUKlud+q9PR1Y1=~P`?ku_>{*Ozp7`-Xb>kq5Zb7{CVYfc`;MJj) z4&J)Sho>}nTcR-qe_^36?D|hTAHM$llB)X(R}$-UHXH3?WE{{RrivkT%~F0 zoaBW*eg`R~)vsVxn{fjr_@AbY`K50pUkuqx~oBHW4t`9 z?HqX> z^&5eyhG3bx&KOu)sJ8ojy2S-w@Nf*99saOq^wHtcv@z9h#FXWiJj~zFUL2gkSW+13 z>$|RI{U($P?8OGEE=^16Fu*9!r?Jb#={SXe8{3Q13j5l$_GAe?t=LP)h`AI6D)Z8V z!@>Wq$I11{C6)mbKls&?lWQI8>Z(sGT0Zpn0-&6w)?G=Jrxlj>9ND+uwI#n%Enh!w zgJw{nExMaz>GT#pDvkH{Me3>~=^OW(ZjO>V6JD>IG!Fom^xjnPVKjm>4lq9l;C?hQ zAj(EhPtX{ziMBuyBV#~9qY8(R2n^16@ZgL`QNy~9TYzKQ2Nt*E95GN;XPY^Y6yUqB zj-r6>;+#C>X}iBO)z@*Ppx>7|o*G8>HXdX=*zGjOH8?xNP-k=aX-B(z?M0Eg(E&4i7&YXmJ5g9>_oeXw51|=0e6YSL$%QUlZTF>Bty_8=S3NhSYED#kz^M z=*S#M^LTTk!v5FU+UjNLaMnbcCi^vCd7&wGQo_o*^r97I{dAMt$4e*hw7O)9M&q%5 zYjY9Bhbb249~7oEvUcP7il;ef^r%SbC>{VFPQUi@TZ8s%a1Ux*040JKWLq5llujWj zlSeO(_jv2=r)@~_d`w#6vJ5Igo_4=HCWP0hgKUvSt4#SkL*wW19>O-R3jvCrY?HU! zPz;UcZRXQ;LKgB#>!AqXaGb(`LPh)+g}V>|t=@+oV~e}s0sX*k-!_@ihGtU(S8Mh` zHah>#7`raDaiKg~{GDm;qx~L-_$M+04>s3HV~8=AV9M_2J>Xq|8fO0P>P@>028#`!SGr zA=O|9Sd!|c-FX1eHLv&nyzai{f~or{!_+#y10X0GFu`rbVM z9aTdcGW7M6{eI8QI3I8P)h()hLGRJ;CPusYit(~F1e_h^I)~Wr~M~_S%3TvY+0z7>gT@IRKJhhP!f|W96 z&WQL{L$~%9#HtgX);FlIPe??=O*lU(5kdAstq-)eFo))$g<%eZuR<9cp>h|c|EW{! z2mCu1$z&oLMdWj!!TQ~YI0`Q3L`kTPYQthGEZE1&=`|C6K)qS^+bvr0IbDzn-kpoA z9i8opt`frNx7*0#@;H^FM8m|aK||BXMAJx=nHlJkY;y&XWhEAjdja9NwK3sPLwY4( zQXCTDt(SmN5XWchag-av%}DOCK1ycKpCGPf$^!W^8`_~O;PBli#Vep!h;=^?=a=e) zSqcU_Y=LxITV2|uMPSuTA8ikqC|>hxa>CR}O}VW*R`xDIu+&mRLXk3i&AiGo)zB{!rpGzL{jM zAN%)gJC`l4hTDKKEmxYmqx1lg{mz;DFEeMedTO1cv#l{GeIWF93F{D3@sii`xwo~C zl6*mJxlNn%=k&n#4Yho_WR~^agr;eU==mdo$=BZ1!{pHC+bRe5E^_!ViVZA&u+%GW zBj4BEy1K5SPJ90)+S&{YOi6Eg>=VA}vf{wcM%_KMv^TA_rRYk>1*BUGK;Uj%0D!%6 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

-6-VsE98qcIul=cN8m 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, + output: Option, + texture_deltas: Vec, +} + +impl Default for Harness { + fn default() -> Self { + Self::new() + } +} + +impl Harness { + pub fn new() -> Self { + let ctx = egui::Context::default(); + ctx.enable_accesskit(); + + Self { + ctx, + input: egui::RawInput { + screen_rect: Some(Rect::from_min_size(Pos2::ZERO, Vec2::new(800.0, 600.0))), + ..Default::default() + }, + tree: None, + output: None, + texture_deltas: Vec::new(), + } + } + + pub fn with_size(mut self, size: Vec2) -> Self { + self.input.screen_rect = Some(Rect::from_min_size(Pos2::ZERO, size)); + self + } + + pub fn with_dpi(mut self, dpi: f32) -> Self { + self.input + .viewports + .get_mut(&self.input.viewport_id) + .unwrap() + .native_pixels_per_point = Some(dpi); + self + } + + pub fn run(&mut self, app: impl FnMut(&egui::Context)) { + let mut output = self.ctx.run(self.input.take(), app); + if let Some(tree) = &mut self.tree { + tree.update( + output + .platform_output + .accesskit_update + .take() + .expect("AccessKit was disabled"), + ); + } else { + self.tree = Some(Tree::new( + output + .platform_output + .accesskit_update + .take() + .expect("AccessKit was disabled"), + true, + )); + } + self.output = Some(output); + self.texture_deltas + .push(self.output().textures_delta.clone()); + } + + pub fn click(&mut self, id: NodeId) { + let action = egui::accesskit::ActionRequest { + target: id, + action: egui::accesskit::Action::Default, + data: None, + }; + self.input + .events + .push(egui::Event::AccessKitActionRequest(action)); + } + + pub fn focus(&mut self, id: NodeId) { + let action = egui::accesskit::ActionRequest { + target: id, + action: egui::accesskit::Action::Focus, + data: None, + }; + self.input + .events + .push(egui::Event::AccessKitActionRequest(action)); + } + + // TODO: SetValue is currently not supported by egui + // pub fn set_text(&mut self, id: NodeId, text: &str) { + // let action = egui::accesskit::ActionRequest { + // target: id, + // action: egui::accesskit::Action::SetValue, + // data: Some(ActionData::Value(Box::from(text))), + // }; + // self.input + // .events + // .push(egui::Event::AccessKitActionRequest(action)); + // } + + pub fn type_text(&mut self, id: NodeId, text: &str) { + self.focus(id); + self.input.events.push(egui::Event::Text(text.to_owned())); + } + + pub fn input(&self) -> &egui::RawInput { + &self.input + } + + pub fn input_mut(&mut self) -> &mut egui::RawInput { + &mut self.input + } + + pub fn output(&self) -> &egui::FullOutput { + self.output.as_ref().expect("Not initialized") + } + + pub fn tree(&self) -> &Tree { + self.tree.as_ref().expect("Not initialized") + } + + pub fn root(&self) -> Node<'_> { + self.tree().state().root() + } +} diff --git a/crates/etest/src/snapshot.rs b/crates/etest/src/snapshot.rs new file mode 100644 index 00000000000..c7b9d8d53b0 --- /dev/null +++ b/crates/etest/src/snapshot.rs @@ -0,0 +1,42 @@ +pub fn image_snapshot(current: image::RgbaImage, name: &str) { + let current = + dify_image::RgbaImage::from_raw(current.width(), current.height(), current.into_raw()) + .unwrap(); + + let path = format!("tests/snapshots/{name}.png"); + let diff_path = format!("tests/snapshots/{name}.diff.webp"); + let current_path = format!("tests/snapshots/{name}.new.webp"); + + std::fs::create_dir_all("tests/snapshots").ok(); + + current.save(¤t_path).unwrap(); + + let previous = match dify_image::open(&path) { + Ok(image) => image.to_rgba8(), + Err(err) => { + println!("Error opening image: {err}"); + println!("Saving current image as {path}"); + current.save(&path).unwrap(); + + current.clone() + } + }; + + let result = dify::diff::get_results(previous, current.clone(), 0.1, true, None, &None, &None); + + if let Some((diff, result_image)) = result { + result_image.save(diff_path.clone()).unwrap(); + + if std::env::var("UPDATE_SNAPSHOTS").is_ok() { + current.save(&path).unwrap(); + println!("Updated snapshot: {path}"); + } else { + panic!( + "Image did not match snapshot. Diff: {diff}, {diff_path}" + ); + } + } else { + // Delete old diff if it exists + std::fs::remove_file(diff_path).ok(); + } +} diff --git a/crates/etest/src/texture_to_bytes.rs b/crates/etest/src/texture_to_bytes.rs new file mode 100644 index 00000000000..5022b9bc15c --- /dev/null +++ b/crates/etest/src/texture_to_bytes.rs @@ -0,0 +1,85 @@ +use egui_wgpu::wgpu; +use egui_wgpu::wgpu::{Device, Extent3d, Queue, Texture}; +use image::RgbaImage; +use std::iter; +use std::mem::size_of; +use std::sync::mpsc::channel; + +pub fn texture_to_bytes(device: &Device, queue: &Queue, texture: &Texture) -> RgbaImage { + let buffer_dimensions = + BufferDimensions::new(texture.width() as usize, texture.height() as usize); + + let output_buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: Some("Texture to bytes output buffer"), + size: (buffer_dimensions.padded_bytes_per_row * buffer_dimensions.height) as u64, + usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }); + + let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: Some("Texture to bytes encoder"), + }); + + // Copy the data from the texture to the buffer + encoder.copy_texture_to_buffer( + texture.as_image_copy(), + wgpu::ImageCopyBuffer { + buffer: &output_buffer, + layout: wgpu::ImageDataLayout { + offset: 0, + bytes_per_row: Some(buffer_dimensions.padded_bytes_per_row as u32), + rows_per_image: None, + }, + }, + Extent3d { + width: texture.width(), + height: texture.height(), + depth_or_array_layers: 1, + }, + ); + + let submission_index = queue.submit(iter::once(encoder.finish())); + + // Note that we're not calling `.await` here. + let buffer_slice = output_buffer.slice(..); + // Sets the buffer up for mapping, sending over the result of the mapping back to us when it is finished. + let (sender, receiver) = channel(); + buffer_slice.map_async(wgpu::MapMode::Read, move |v| drop(sender.send(v))); + + // Poll the device in a blocking manner so that our future resolves. + device.poll(wgpu::Maintain::WaitForSubmissionIndex(submission_index)); + + receiver.recv().unwrap().unwrap(); + let buffer_slice = output_buffer.slice(..); + let data = buffer_slice.get_mapped_range(); + let data = data + .chunks_exact(buffer_dimensions.padded_bytes_per_row) + .flat_map(|row| row.iter().take(buffer_dimensions.unpadded_bytes_per_row)) + .copied() + .collect::>(); + + RgbaImage::from_raw(texture.width(), texture.height(), data).expect("Failed to create image") +} + +struct BufferDimensions { + width: usize, + height: usize, + unpadded_bytes_per_row: usize, + padded_bytes_per_row: usize, +} + +impl BufferDimensions { + fn new(width: usize, height: usize) -> Self { + let bytes_per_pixel = size_of::(); + let unpadded_bytes_per_row = width * bytes_per_pixel; + let align = wgpu::COPY_BYTES_PER_ROW_ALIGNMENT as usize; + let padded_bytes_per_row_padding = (align - unpadded_bytes_per_row % align) % align; + let padded_bytes_per_row = unpadded_bytes_per_row + padded_bytes_per_row_padding; + Self { + width, + height, + unpadded_bytes_per_row, + padded_bytes_per_row, + } + } +} diff --git a/crates/etest/src/wgpu.rs b/crates/etest/src/wgpu.rs new file mode 100644 index 00000000000..68a31ffc9f6 --- /dev/null +++ b/crates/etest/src/wgpu.rs @@ -0,0 +1,130 @@ +use crate::texture_to_bytes::texture_to_bytes; +use crate::Harness; +use egui_wgpu::wgpu::{Backends, InstanceDescriptor, StoreOp, TextureFormat}; +use egui_wgpu::{wgpu, ScreenDescriptor}; +use image::RgbaImage; +use std::iter::once; +use wgpu::Maintain; + +impl Harness { + pub fn image(&self, _renderer: TestRenderer) {} +} + +pub struct TestRenderer { + renderer: egui_wgpu::Renderer, + device: wgpu::Device, + queue: wgpu::Queue, +} + +impl Default for TestRenderer { + fn default() -> Self { + Self::new() + } +} + +impl TestRenderer { + pub fn new() -> Self { + let instance = wgpu::Instance::new(InstanceDescriptor::default()); + + let adapters = instance.enumerate_adapters(Backends::all()); + let adapter = adapters.first().expect("No adapter found"); + + let (device, queue) = pollster::block_on(adapter.request_device( + &wgpu::DeviceDescriptor { + label: Some("Egui Device"), + memory_hints: Default::default(), + required_limits: Default::default(), + required_features: Default::default(), + }, + None, + )) + .expect("Failed to create device"); + + let renderer = egui_wgpu::Renderer::new(&device, TextureFormat::Rgba8Unorm, None, 1, true); + + Self { + renderer, + device, + queue, + } + } + + pub fn render(&mut self, harness: &Harness) -> RgbaImage { + for delta in &harness.texture_deltas { + for (id, image_delta) in &delta.set { + self.renderer + .update_texture(&self.device, &self.queue, *id, image_delta); + } + } + + let mut encoder = self + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: Some("Egui Command Encoder"), + }); + + let size = harness.ctx.screen_rect().size() * harness.ctx.pixels_per_point(); + let screen = ScreenDescriptor { + pixels_per_point: harness.ctx.pixels_per_point(), + size_in_pixels: [size.x as u32, size.y as u32], + }; + + let tesselated = harness.ctx.tessellate( + harness.output().shapes.clone(), + harness.ctx.pixels_per_point(), + ); + + let user_buffers = self.renderer.update_buffers( + &self.device, + &self.queue, + &mut encoder, + &tesselated, + &screen, + ); + + let texture = self.device.create_texture(&wgpu::TextureDescriptor { + label: Some("Egui Texture"), + size: wgpu::Extent3d { + width: size.x as u32, + height: size.y as u32, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: TextureFormat::Rgba8Unorm, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_SRC, + view_formats: &[], + }); + + let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default()); + + { + let mut pass = encoder + .begin_render_pass(&wgpu::RenderPassDescriptor { + label: Some("Egui Render Pass"), + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: &texture_view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color::BLACK), + store: StoreOp::Store, + }, + })], + depth_stencil_attachment: None, + occlusion_query_set: None, + timestamp_writes: None, + }) + .forget_lifetime(); + + self.renderer.render(&mut pass, &tesselated, &screen); + } + + self.queue + .submit(user_buffers.into_iter().chain(once(encoder.finish()))); + + self.device.poll(Maintain::Wait); + + texture_to_bytes(&self.device, &self.queue, &texture) + } +} From d5dedbac73304ab5172ae293d86b5719aed74746 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Wed, 25 Sep 2024 15:43:08 +0200 Subject: [PATCH 02/47] Improved usability --- crates/accesskit_query/src/event.rs | 11 +++ crates/accesskit_query/src/lib.rs | 76 ++--------------- crates/accesskit_query/src/node.rs | 105 ++++++++++++++++++++++++ crates/accesskit_query/src/query.rs | 123 ++++++++++++++++++++++++++++ crates/accesskit_query/src/tree.rs | 41 ++++++++++ crates/etest/examples/etest.rs | 18 ++-- crates/etest/src/lib.rs | 45 +++++++++- crates/etest/src/utils.rs | 12 +++ 8 files changed, 352 insertions(+), 79 deletions(-) create mode 100644 crates/accesskit_query/src/event.rs create mode 100644 crates/accesskit_query/src/node.rs create mode 100644 crates/accesskit_query/src/query.rs create mode 100644 crates/accesskit_query/src/tree.rs create mode 100644 crates/etest/src/utils.rs diff --git a/crates/accesskit_query/src/event.rs b/crates/accesskit_query/src/event.rs new file mode 100644 index 00000000000..f037e529bab --- /dev/null +++ b/crates/accesskit_query/src/event.rs @@ -0,0 +1,11 @@ +use accesskit::Vec2; + +pub enum AKEvent { + ActionRequest(accesskit::ActionRequest), + Simulated(SimulatedEvent), +} + +pub enum SimulatedEvent { + Click { position: Vec2 }, + Type { text: String }, +} diff --git a/crates/accesskit_query/src/lib.rs b/crates/accesskit_query/src/lib.rs index 046adf66cc9..66b78dda11a 100644 --- a/crates/accesskit_query/src/lib.rs +++ b/crates/accesskit_query/src/lib.rs @@ -1,67 +1,9 @@ -use accesskit_consumer::{FilterResult, Node}; -use extension_traits::extension; -use std::fmt::Debug; - -struct DebugNode<'a>(&'a Node<'a>); - -impl Debug for DebugNode<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let node = self.0; - - let mut tuple = f.debug_tuple("Node"); - tuple.field(&node.id()).field(&node.role()); - - if let Some(name) = node.name() { - tuple.field(&name); - } - - tuple.finish() - } -} - -#[extension(pub trait NodeExt)] -impl<'a> Node<'a> { - fn query_by<'b>(&'b self, f: impl Fn(&Node<'_>) -> bool + 'a) -> Option> { - let mut iter = self.filtered_children(move |node: &Node<'_>| { - if f(node) { - FilterResult::Include - } else { - FilterResult::ExcludeNode - } - }); - let result = iter.next(); - - if let Some(second) = iter.next() { - let first = result?; - panic!( - "Found two or more nodes matching the query: {:?} {:?}", - DebugNode(&first), - DebugNode(&second) - ); - } - - result - } - - fn get_by<'b>(&'b self, f: impl Fn(&Node<'_>) -> bool + 'a) -> Node<'a> { - self.query_by(f).expect("No node found matching the query") - } - - fn query_by_name<'b>(&'b self, name: &'a str) -> Option> { - self.query_by(move |node| node.name().as_deref() == Some(name)) - } - - fn get_by_name<'b>(&'b self, name: &'a str) -> Node<'a> { - self.query_by_name(name) - .expect("No node found with the given name") - } - - fn query_by_role<'b>(&'b self, role: accesskit::Role) -> Option> { - self.query_by(move |node| node.role() == role) - } - - fn get_by_role<'b>(&'b self, role: accesskit::Role) -> Node<'a> { - self.query_by_role(role) - .expect("No node found with the given role") - } -} +mod event; +mod node; +mod query; +mod tree; + +pub use event::*; +pub use node::*; +pub use query::*; +pub use tree::*; diff --git a/crates/accesskit_query/src/node.rs b/crates/accesskit_query/src/node.rs new file mode 100644 index 00000000000..8352cd9153a --- /dev/null +++ b/crates/accesskit_query/src/node.rs @@ -0,0 +1,105 @@ +use crate::event::{AKEvent, SimulatedEvent}; +use crate::query::Queryable; +use accesskit::{ActionRequest, Vec2}; +use std::fmt::{Debug, Formatter}; +use std::ops::Deref; +use std::sync::Mutex; + +pub struct Node<'tree> { + node: accesskit_consumer::Node<'tree>, + pub(crate) queue: &'tree Mutex>, +} + +impl<'a> Debug for Node<'a> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut s = f.debug_struct("Node"); + s.field("id", &self.node.id()); + s.field("role", &self.node.role()); + s.field("focused", &self.node.is_focused()); + s.field("hidden", &self.node.is_hidden()); + s.field("disabled", &self.node.is_disabled()); + if let Some(name) = self.node.name() { + s.field("name", &name); + } + if let Some(value) = self.node.value() { + s.field("value", &value); + } + if let Some(toggled) = self.node.toggled() { + s.field("toggled", &toggled); + } + if let Some(numeric) = self.node.numeric_value() { + s.field("numeric_value", &numeric); + } + s.finish() + } +} + +/// We should probably add our own methods to query the node state but for now this should work +impl<'tree> Deref for Node<'tree> { + type Target = accesskit_consumer::Node<'tree>; + + fn deref(&self) -> &Self::Target { + &self.node + } +} + +impl<'tree> Node<'tree> { + pub fn new(node: accesskit_consumer::Node<'tree>, queue: &'tree Mutex>) -> Self { + Self { node, queue } + } + + pub fn queue<'node>(&'node self) -> &'tree Mutex> { + self.queue + } + + pub fn focus(&self) { + self.queue + .lock() + .unwrap() + .push(AKEvent::ActionRequest(ActionRequest { + data: None, + action: accesskit::Action::Focus, + target: self.node.id(), + })); + } + + /// Click the node via accesskit + pub fn click(&self) { + self.queue + .lock() + .unwrap() + .push(AKEvent::ActionRequest(ActionRequest { + data: None, + action: accesskit::Action::Default, + target: self.node.id(), + })); + } + + /// Simulate a click event on the node center + pub fn simulate_click(&self) { + let rect = self.node.raw_bounds().expect("Node has no bounds"); + let center = Vec2::new(rect.x0 + rect.x1 / 2.0, rect.y0 + rect.y1 / 2.0); + self.queue + .lock() + .unwrap() + .push(AKEvent::Simulated(SimulatedEvent::Click { + position: center, + })); + } + + pub fn type_text(&self, text: &str) { + self.focus(); + self.queue + .lock() + .unwrap() + .push(AKEvent::Simulated(SimulatedEvent::Type { + text: text.to_owned(), + })); + } +} + +impl<'t, 'n> Queryable<'t, 'n> for Node<'t> { + fn node(&'n self) -> Node<'t> { + Node::new(self.node, self.queue) + } +} diff --git a/crates/accesskit_query/src/query.rs b/crates/accesskit_query/src/query.rs new file mode 100644 index 00000000000..671a8445717 --- /dev/null +++ b/crates/accesskit_query/src/query.rs @@ -0,0 +1,123 @@ +use crate::Node; +use accesskit_consumer::{FilterResult, Node as AKNode}; +use std::iter::{FusedIterator, Peekable}; + +fn query_by_impl<'tree>(mut iter: impl Iterator>) -> Option> { + let result = iter.next(); + + if let Some(second) = iter.next() { + let first = result?; + panic!( + "Found two or more nodes matching the query: {:?} {:?}", + first.node().id(), + second.node().id(), + ); + } + result +} + +pub trait Queryable<'tree, 'node> { + fn node(&'node self) -> crate::Node<'tree>; + + fn query_all_by( + &'node self, + f: impl Fn(&Node<'_>) -> bool + 'tree, + ) -> impl Iterator> + + DoubleEndedIterator> + + FusedIterator> + + 'tree { + let root = self.node(); + let queue = root.queue(); + root.filtered_children(move |node: &AKNode<'_>| { + if f(&Node::new(*node, queue)) { + FilterResult::Include + } else { + FilterResult::ExcludeNode + } + }) + .map(|node| Node::new(node, queue)) + } + + fn query_by(&'node self, f: impl Fn(&Node<'_>) -> bool + 'tree) -> Option> { + query_by_impl(self.query_all_by(f)) + } + + fn get_by(&'node self, f: impl Fn(&Node<'_>) -> bool + 'tree) -> Node<'tree> { + self.query_by(f).expect("No node found matching the query") + } + + fn query_all_by_name(&'node self, name: &'tree str) -> impl IterType<'tree> + 'tree { + self.query_all_by(move |node| node.name().as_deref() == Some(name)) + } + + fn query_by_name(&'node self, name: &'tree str) -> Option> { + query_by_impl(self.query_all_by_name(name)) + } + + fn get_by_name(&'node self, name: &'tree str) -> Node<'tree> { + self.query_by_name(name) + .expect("No node found with the given name") + } + + fn query_all_by_role(&'node self, role: accesskit::Role) -> impl IterType<'tree> + 'tree { + self.query_all_by(move |node| node.role() == role) + } + + fn query_by_role(&'node self, role: accesskit::Role) -> Option> { + query_by_impl(self.query_all_by_role(role)) + } + + fn get_by_role(&'node self, role: accesskit::Role) -> Node<'tree> { + self.query_by_role(role) + .expect("No node found with the given role") + } +} + +trait IterType<'tree>: + Iterator> + + DoubleEndedIterator> + + FusedIterator> +{ +} + +impl<'tree, T> IterType<'tree> for T where + T: Iterator> + + DoubleEndedIterator> + + FusedIterator> +{ +} + +// pub trait Findable<'tree, 'node, 's>: Queryable<'tree, 'node> { +// fn run(&mut self); +// +// fn find_timeout(&self) -> std::time::Duration { +// std::time::Duration::from_secs(5) +// } +// +// fn find_all_by( +// &'node mut self, +// f: impl Fn(&Node<'_>) -> bool + Copy + 'tree, +// ) -> impl IterType<'tree> + 'tree { +// let timeout = self.find_timeout(); +// let step = timeout / 10; +// +// let mut start_time = std::time::Instant::now(); +// +// loop { +// { +// let node = self.node(); +// let iter = node.query_all_by(f); +// let mut peekable = iter.peekable(); +// if !peekable.peek().is_none() { +// return peekable; +// } +// +// if start_time.elapsed() > timeout { +// panic!("Timeout exceeded while waiting for node"); +// } +// } +// +// std::thread::sleep(step); +// } +// } +// } diff --git a/crates/accesskit_query/src/tree.rs b/crates/accesskit_query/src/tree.rs new file mode 100644 index 00000000000..7f6d98f21bb --- /dev/null +++ b/crates/accesskit_query/src/tree.rs @@ -0,0 +1,41 @@ +use crate::event::AKEvent; +use crate::query::Queryable; +use crate::Node; +use std::ops::Deref; +use std::sync::Mutex; + +pub struct Tree { + tree: accesskit_consumer::Tree, + queued_events: Mutex>, +} + +impl Tree { + pub fn new(update: accesskit::TreeUpdate) -> Tree { + Self { + tree: accesskit_consumer::Tree::new(update, true), + queued_events: Mutex::new(Vec::new()), + } + } + + pub fn update(&mut self, update: accesskit::TreeUpdate) { + self.tree.update(update); + } + + pub fn root(&self) -> Node<'_> { + self.node() + } + + pub fn take_events(&self) -> Vec { + self.queued_events.lock().unwrap().drain(..).collect() + } +} + +impl<'tree, 'node> Queryable<'tree, 'node> for Tree +where + 'node: 'tree, +{ + /// Return the root node + fn node(&'node self) -> Node<'tree> where { + Node::new(self.tree.state().root(), &self.queued_events) + } +} diff --git a/crates/etest/examples/etest.rs b/crates/etest/examples/etest.rs index 7095e4730f5..b102bbf2129 100644 --- a/crates/etest/examples/etest.rs +++ b/crates/etest/examples/etest.rs @@ -1,4 +1,4 @@ -use accesskit_query::NodeExt; +use accesskit_query::Queryable; use egui::accesskit::{Role, Toggled}; use egui::{CentralPanel, Context, TextEdit, Vec2}; use etest::Harness; @@ -20,23 +20,25 @@ fn main() { harness.run(&mut app); - let checkbox = harness.root().get_by_name("Check me!"); - harness.click(checkbox.id()); + harness.get_by_name("Check me!").click(); harness.run(&mut app); assert!(*checked.borrow()); - let checkbox = harness.root().get_by_name("Check me!"); + let checkbox = harness.get_by_name("Check me!"); assert_eq!(checkbox.toggled(), Some(Toggled::True)); - let text_edit = harness.root().get_by_role(Role::TextInput); - harness.type_text(text_edit.id(), "Hello, World!"); + harness + .get_by_role(Role::TextInput) + .type_text("Hello, World!"); harness.run(&mut app); assert_eq!(&*text.borrow_mut(), "Hello, World!"); - let text_edit = harness.root().get_by_role(Role::TextInput); - assert_eq!(text_edit.value().as_deref(), Some("Hello, World!")); + assert_eq!( + harness.get_by_role(Role::TextInput).value().as_deref(), + Some("Hello, World!") + ); #[cfg(feature = "wgpu")] { diff --git a/crates/etest/src/lib.rs b/crates/etest/src/lib.rs index 38a4f53477b..206bbf4b2dc 100644 --- a/crates/etest/src/lib.rs +++ b/crates/etest/src/lib.rs @@ -2,11 +2,13 @@ pub mod snapshot; #[cfg(feature = "wgpu")] mod texture_to_bytes; +mod utils; #[cfg(feature = "wgpu")] pub mod wgpu; +use crate::utils::egui_vec2; pub use accesskit_consumer; -use accesskit_consumer::{Node, Tree}; +use accesskit_query::{AKEvent, Node, Queryable, SimulatedEvent, Tree}; use egui::accesskit::NodeId; use egui::{Pos2, Rect, TexturesDelta, Vec2}; @@ -56,6 +58,37 @@ impl Harness { } pub fn run(&mut self, app: impl FnMut(&egui::Context)) { + if let Some(tree) = &mut self.tree { + for event in tree.take_events() { + match event { + AKEvent::ActionRequest(e) => { + self.input + .events + .push(egui::Event::AccessKitActionRequest(e)); + } + AKEvent::Simulated(e) => match e { + SimulatedEvent::Click { position } => { + let position = egui_vec2(position).to_pos2(); + self.input.events.push(egui::Event::PointerButton { + pos: position, + button: egui::PointerButton::Primary, + pressed: true, + modifiers: Default::default(), + }); + self.input.events.push(egui::Event::PointerButton { + pos: position, + button: egui::PointerButton::Primary, + pressed: false, + modifiers: Default::default(), + }); + } + SimulatedEvent::Type { text } => { + self.input.events.push(egui::Event::Text(text)); + } + }, + } + } + } let mut output = self.ctx.run(self.input.take(), app); if let Some(tree) = &mut self.tree { tree.update( @@ -72,7 +105,6 @@ impl Harness { .accesskit_update .take() .expect("AccessKit was disabled"), - true, )); } self.output = Some(output); @@ -134,8 +166,13 @@ impl Harness { pub fn tree(&self) -> &Tree { self.tree.as_ref().expect("Not initialized") } +} - pub fn root(&self) -> Node<'_> { - self.tree().state().root() +impl<'t, 'n> Queryable<'t, 'n> for Harness +where + 'n: 't, +{ + fn node(&'n self) -> Node<'t> { + self.tree().node() } } diff --git a/crates/etest/src/utils.rs b/crates/etest/src/utils.rs new file mode 100644 index 00000000000..fe190dac82e --- /dev/null +++ b/crates/etest/src/utils.rs @@ -0,0 +1,12 @@ +use egui::accesskit; + +pub fn egui_vec2(vec: accesskit::Vec2) -> egui::Vec2 { + egui::Vec2::new(vec.x as f32, vec.y as f32) +} + +pub fn accesskit_vec2(vec: egui::Vec2) -> accesskit::Vec2 { + accesskit::Vec2 { + x: vec.x as f64, + y: vec.y as f64, + } +} From 608e4df7d9329cc34557b2a80fa375b0759f3726 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Wed, 25 Sep 2024 22:32:53 +0200 Subject: [PATCH 03/47] Rename and move kittest to external crate --- Cargo.lock | 80 ++++-------- Cargo.toml | 3 +- crates/accesskit_query/Cargo.toml | 16 --- crates/accesskit_query/src/event.rs | 11 -- crates/accesskit_query/src/lib.rs | 9 -- crates/accesskit_query/src/node.rs | 105 --------------- crates/accesskit_query/src/query.rs | 123 ------------------ crates/accesskit_query/src/tree.rs | 41 ------ crates/egui_demo_lib/Cargo.toml | 2 +- .../egui_demo_lib/src/demo/widget_gallery.rs | 10 +- .../tests/snapshots/widget_gallery.new.webp | Bin 113456 -> 0 bytes .../tests/snapshots/widget_gallery.png | Bin 166348 -> 0 bytes crates/{etest => egui_kittest}/Cargo.toml | 4 +- .../examples/kittest.rs} | 16 +-- .../etest.png => egui_kittest/kittest.png} | Bin crates/{etest => egui_kittest}/src/lib.rs | 28 ++-- .../{etest => egui_kittest}/src/snapshot.rs | 8 +- .../src/texture_to_bytes.rs | 0 crates/{etest => egui_kittest}/src/utils.rs | 0 crates/{etest => egui_kittest}/src/wgpu.rs | 2 +- 20 files changed, 61 insertions(+), 397 deletions(-) delete mode 100644 crates/accesskit_query/Cargo.toml delete mode 100644 crates/accesskit_query/src/event.rs delete mode 100644 crates/accesskit_query/src/lib.rs delete mode 100644 crates/accesskit_query/src/node.rs delete mode 100644 crates/accesskit_query/src/query.rs delete mode 100644 crates/accesskit_query/src/tree.rs delete mode 100644 crates/egui_demo_lib/tests/snapshots/widget_gallery.new.webp delete mode 100644 crates/egui_demo_lib/tests/snapshots/widget_gallery.png rename crates/{etest => egui_kittest}/Cargo.toml (90%) rename crates/{etest/examples/etest.rs => egui_kittest/examples/kittest.rs} (76%) rename crates/{etest/etest.png => egui_kittest/kittest.png} (100%) rename crates/{etest => egui_kittest}/src/lib.rs (89%) rename crates/{etest => egui_kittest}/src/snapshot.rs (82%) rename crates/{etest => egui_kittest}/src/texture_to_bytes.rs (100%) rename crates/{etest => egui_kittest}/src/utils.rs (100%) rename crates/{etest => egui_kittest}/src/wgpu.rs (99%) diff --git a/Cargo.lock b/Cargo.lock index cb169078597..4996331920f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,15 +66,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "accesskit_query" -version = "0.28.1" -dependencies = [ - "accesskit", - "accesskit_consumer", - "extension-traits", -] - [[package]] name = "accesskit_unix" version = "0.12.0" @@ -1349,7 +1340,7 @@ dependencies = [ "document-features", "egui", "egui_extras", - "etest", + "egui_kittest", "log", "serde", "unicode_names2", @@ -1395,6 +1386,21 @@ dependencies = [ "winit", ] +[[package]] +name = "egui_kittest" +version = "0.28.1" +dependencies = [ + "accesskit_consumer", + "dify", + "egui", + "egui-wgpu", + "image 0.24.9", + "image 0.25.0", + "kittest", + "pollster", + "wgpu", +] + [[package]] name = "ehttp" version = "0.5.0" @@ -1548,21 +1554,6 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "281e452d3bad4005426416cdba5ccfd4f5c1280e10099e21db27f7c1c28347fc" -[[package]] -name = "etest" -version = "0.28.1" -dependencies = [ - "accesskit_consumer", - "accesskit_query", - "dify", - "egui", - "egui-wgpu", - "image 0.24.9", - "image 0.25.0", - "pollster", - "wgpu", -] - [[package]] name = "event-listener" version = "2.5.3" @@ -1617,35 +1608,6 @@ dependencies = [ "zune-inflate", ] -[[package]] -name = "ext-trait" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703090345f7d5de48379b391c9dfe69967a3c1694730a3e53bf4c905f71069c0" -dependencies = [ - "ext-trait-proc_macros", -] - -[[package]] -name = "ext-trait-proc_macros" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9f3f15f123dee4e8a6b14f033ba22904a48c5935505dc07225ce440e640d8b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "extension-traits" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360cbc11ebc403c8ebb731dfb4d3950835d40d3d9a20f0e89a27b17e991d0863" -dependencies = [ - "ext-trait", -] - [[package]] name = "fancy-regex" version = "0.11.0" @@ -2452,6 +2414,16 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" +[[package]] +name = "kittest" +version = "0.1.0" +source = "git+https://github.com/rerun-io/kittest?branch=kittest#be12a16312993bd614f7291470c588e906908cc8" +dependencies = [ + "accesskit", + "accesskit_consumer", + "parking_lot", +] + [[package]] name = "kurbo" version = "0.9.5" diff --git a/Cargo.toml b/Cargo.toml index 58fc162029c..be92bc5bf96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ members = [ "crates/egui_demo_lib", "crates/egui_extras", "crates/egui_glow", + "crates/egui_kittest", "crates/egui-wgpu", "crates/egui-winit", "crates/egui", @@ -14,7 +15,7 @@ members = [ "crates/epaint_default_fonts", "examples/*", "tests/*", - "xtask", "crates/etest", "crates/accesskit_query", + "xtask", ] [workspace.package] diff --git a/crates/accesskit_query/Cargo.toml b/crates/accesskit_query/Cargo.toml deleted file mode 100644 index 9640027e1b9..00000000000 --- a/crates/accesskit_query/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "accesskit_query" -edition.workspace = true -license.workspace = true -rust-version.workspace = true -version.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -accesskit_consumer = "0.24.0" -accesskit = "0.16.0" -extension-traits = "2" - -[lints] -workspace = true diff --git a/crates/accesskit_query/src/event.rs b/crates/accesskit_query/src/event.rs deleted file mode 100644 index f037e529bab..00000000000 --- a/crates/accesskit_query/src/event.rs +++ /dev/null @@ -1,11 +0,0 @@ -use accesskit::Vec2; - -pub enum AKEvent { - ActionRequest(accesskit::ActionRequest), - Simulated(SimulatedEvent), -} - -pub enum SimulatedEvent { - Click { position: Vec2 }, - Type { text: String }, -} diff --git a/crates/accesskit_query/src/lib.rs b/crates/accesskit_query/src/lib.rs deleted file mode 100644 index 66b78dda11a..00000000000 --- a/crates/accesskit_query/src/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -mod event; -mod node; -mod query; -mod tree; - -pub use event::*; -pub use node::*; -pub use query::*; -pub use tree::*; diff --git a/crates/accesskit_query/src/node.rs b/crates/accesskit_query/src/node.rs deleted file mode 100644 index 8352cd9153a..00000000000 --- a/crates/accesskit_query/src/node.rs +++ /dev/null @@ -1,105 +0,0 @@ -use crate::event::{AKEvent, SimulatedEvent}; -use crate::query::Queryable; -use accesskit::{ActionRequest, Vec2}; -use std::fmt::{Debug, Formatter}; -use std::ops::Deref; -use std::sync::Mutex; - -pub struct Node<'tree> { - node: accesskit_consumer::Node<'tree>, - pub(crate) queue: &'tree Mutex>, -} - -impl<'a> Debug for Node<'a> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let mut s = f.debug_struct("Node"); - s.field("id", &self.node.id()); - s.field("role", &self.node.role()); - s.field("focused", &self.node.is_focused()); - s.field("hidden", &self.node.is_hidden()); - s.field("disabled", &self.node.is_disabled()); - if let Some(name) = self.node.name() { - s.field("name", &name); - } - if let Some(value) = self.node.value() { - s.field("value", &value); - } - if let Some(toggled) = self.node.toggled() { - s.field("toggled", &toggled); - } - if let Some(numeric) = self.node.numeric_value() { - s.field("numeric_value", &numeric); - } - s.finish() - } -} - -/// We should probably add our own methods to query the node state but for now this should work -impl<'tree> Deref for Node<'tree> { - type Target = accesskit_consumer::Node<'tree>; - - fn deref(&self) -> &Self::Target { - &self.node - } -} - -impl<'tree> Node<'tree> { - pub fn new(node: accesskit_consumer::Node<'tree>, queue: &'tree Mutex>) -> Self { - Self { node, queue } - } - - pub fn queue<'node>(&'node self) -> &'tree Mutex> { - self.queue - } - - pub fn focus(&self) { - self.queue - .lock() - .unwrap() - .push(AKEvent::ActionRequest(ActionRequest { - data: None, - action: accesskit::Action::Focus, - target: self.node.id(), - })); - } - - /// Click the node via accesskit - pub fn click(&self) { - self.queue - .lock() - .unwrap() - .push(AKEvent::ActionRequest(ActionRequest { - data: None, - action: accesskit::Action::Default, - target: self.node.id(), - })); - } - - /// Simulate a click event on the node center - pub fn simulate_click(&self) { - let rect = self.node.raw_bounds().expect("Node has no bounds"); - let center = Vec2::new(rect.x0 + rect.x1 / 2.0, rect.y0 + rect.y1 / 2.0); - self.queue - .lock() - .unwrap() - .push(AKEvent::Simulated(SimulatedEvent::Click { - position: center, - })); - } - - pub fn type_text(&self, text: &str) { - self.focus(); - self.queue - .lock() - .unwrap() - .push(AKEvent::Simulated(SimulatedEvent::Type { - text: text.to_owned(), - })); - } -} - -impl<'t, 'n> Queryable<'t, 'n> for Node<'t> { - fn node(&'n self) -> Node<'t> { - Node::new(self.node, self.queue) - } -} diff --git a/crates/accesskit_query/src/query.rs b/crates/accesskit_query/src/query.rs deleted file mode 100644 index 671a8445717..00000000000 --- a/crates/accesskit_query/src/query.rs +++ /dev/null @@ -1,123 +0,0 @@ -use crate::Node; -use accesskit_consumer::{FilterResult, Node as AKNode}; -use std::iter::{FusedIterator, Peekable}; - -fn query_by_impl<'tree>(mut iter: impl Iterator>) -> Option> { - let result = iter.next(); - - if let Some(second) = iter.next() { - let first = result?; - panic!( - "Found two or more nodes matching the query: {:?} {:?}", - first.node().id(), - second.node().id(), - ); - } - result -} - -pub trait Queryable<'tree, 'node> { - fn node(&'node self) -> crate::Node<'tree>; - - fn query_all_by( - &'node self, - f: impl Fn(&Node<'_>) -> bool + 'tree, - ) -> impl Iterator> - + DoubleEndedIterator> - + FusedIterator> - + 'tree { - let root = self.node(); - let queue = root.queue(); - root.filtered_children(move |node: &AKNode<'_>| { - if f(&Node::new(*node, queue)) { - FilterResult::Include - } else { - FilterResult::ExcludeNode - } - }) - .map(|node| Node::new(node, queue)) - } - - fn query_by(&'node self, f: impl Fn(&Node<'_>) -> bool + 'tree) -> Option> { - query_by_impl(self.query_all_by(f)) - } - - fn get_by(&'node self, f: impl Fn(&Node<'_>) -> bool + 'tree) -> Node<'tree> { - self.query_by(f).expect("No node found matching the query") - } - - fn query_all_by_name(&'node self, name: &'tree str) -> impl IterType<'tree> + 'tree { - self.query_all_by(move |node| node.name().as_deref() == Some(name)) - } - - fn query_by_name(&'node self, name: &'tree str) -> Option> { - query_by_impl(self.query_all_by_name(name)) - } - - fn get_by_name(&'node self, name: &'tree str) -> Node<'tree> { - self.query_by_name(name) - .expect("No node found with the given name") - } - - fn query_all_by_role(&'node self, role: accesskit::Role) -> impl IterType<'tree> + 'tree { - self.query_all_by(move |node| node.role() == role) - } - - fn query_by_role(&'node self, role: accesskit::Role) -> Option> { - query_by_impl(self.query_all_by_role(role)) - } - - fn get_by_role(&'node self, role: accesskit::Role) -> Node<'tree> { - self.query_by_role(role) - .expect("No node found with the given role") - } -} - -trait IterType<'tree>: - Iterator> - + DoubleEndedIterator> - + FusedIterator> -{ -} - -impl<'tree, T> IterType<'tree> for T where - T: Iterator> - + DoubleEndedIterator> - + FusedIterator> -{ -} - -// pub trait Findable<'tree, 'node, 's>: Queryable<'tree, 'node> { -// fn run(&mut self); -// -// fn find_timeout(&self) -> std::time::Duration { -// std::time::Duration::from_secs(5) -// } -// -// fn find_all_by( -// &'node mut self, -// f: impl Fn(&Node<'_>) -> bool + Copy + 'tree, -// ) -> impl IterType<'tree> + 'tree { -// let timeout = self.find_timeout(); -// let step = timeout / 10; -// -// let mut start_time = std::time::Instant::now(); -// -// loop { -// { -// let node = self.node(); -// let iter = node.query_all_by(f); -// let mut peekable = iter.peekable(); -// if !peekable.peek().is_none() { -// return peekable; -// } -// -// if start_time.elapsed() > timeout { -// panic!("Timeout exceeded while waiting for node"); -// } -// } -// -// std::thread::sleep(step); -// } -// } -// } diff --git a/crates/accesskit_query/src/tree.rs b/crates/accesskit_query/src/tree.rs deleted file mode 100644 index 7f6d98f21bb..00000000000 --- a/crates/accesskit_query/src/tree.rs +++ /dev/null @@ -1,41 +0,0 @@ -use crate::event::AKEvent; -use crate::query::Queryable; -use crate::Node; -use std::ops::Deref; -use std::sync::Mutex; - -pub struct Tree { - tree: accesskit_consumer::Tree, - queued_events: Mutex>, -} - -impl Tree { - pub fn new(update: accesskit::TreeUpdate) -> Tree { - Self { - tree: accesskit_consumer::Tree::new(update, true), - queued_events: Mutex::new(Vec::new()), - } - } - - pub fn update(&mut self, update: accesskit::TreeUpdate) { - self.tree.update(update); - } - - pub fn root(&self) -> Node<'_> { - self.node() - } - - pub fn take_events(&self) -> Vec { - self.queued_events.lock().unwrap().drain(..).collect() - } -} - -impl<'tree, 'node> Queryable<'tree, 'node> for Tree -where - 'node: 'tree, -{ - /// Return the root node - fn node(&'node self) -> Node<'tree> where { - Node::new(self.tree.state().root(), &self.queued_events) - } -} diff --git a/crates/egui_demo_lib/Cargo.toml b/crates/egui_demo_lib/Cargo.toml index c41000986ed..2f19c6cb9a6 100644 --- a/crates/egui_demo_lib/Cargo.toml +++ b/crates/egui_demo_lib/Cargo.toml @@ -56,7 +56,7 @@ serde = { workspace = true, optional = true } [dev-dependencies] criterion.workspace = true -etest = { path = "../etest", features = ["wgpu", "snapshot"] } +egui_kittest = { path = "../egui_kittest", features = ["wgpu", "snapshot"] } wgpu = { workspace = true, features = ["metal"] } egui = { workspace = true, features = ["default_fonts"] } diff --git a/crates/egui_demo_lib/src/demo/widget_gallery.rs b/crates/egui_demo_lib/src/demo/widget_gallery.rs index a39c5d5da36..85b9e3a4fa6 100644 --- a/crates/egui_demo_lib/src/demo/widget_gallery.rs +++ b/crates/egui_demo_lib/src/demo/widget_gallery.rs @@ -291,9 +291,9 @@ mod tests { use super::*; use crate::View; use egui::{CentralPanel, Context, Vec2}; - use etest::snapshot::image_snapshot; - use etest::wgpu::TestRenderer; - use etest::Harness; + use egui_kittest::snapshot::image_snapshot; + use egui_kittest::wgpu::TestRenderer; + use egui_kittest::Harness; #[test] pub fn should_match_screenshot() { @@ -303,11 +303,11 @@ mod tests { demo.ui(ui); }); }; - let mut harness = Harness::new() + let mut harness = Harness::new(app) .with_size(Vec2::new(380.0, 550.0)) .with_dpi(2.0); - harness.run(app); + harness.run(); let image = TestRenderer::new().render(&harness); diff --git a/crates/egui_demo_lib/tests/snapshots/widget_gallery.new.webp b/crates/egui_demo_lib/tests/snapshots/widget_gallery.new.webp deleted file mode 100644 index c4f58f5e1296e19c1af3210038d6a48b111eb1d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113456 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�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%0D!%6 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

-6-VsE98qcIul=cN8m z&B{F2bxE^HK7Zyx6vSnPfsX%uU;n@8W? zK4H&o%=0r?f9B7BZRDRYA^$y_|9`8UuT^ZjE6auINzc&7Z*j-}*o^M~N!-!%kUhcF zza7E(-GEtMxLZcvg?w5R{P~v-M6Gz5|+8w zJ`~i?6-|Sb6a5-n(kPpL>^c1xBnqy}>%b6Ve?H2;G}BlfK}6)>b#tf(+e>wIV^S@FrNjH z9j^_ye7xso!rRNc6i+~Ver&bcU!}kA+|Xw>xD3~U|03Gl?gi!TzBxzF`lkolN54em zl@gwQs5z}H(|j+p_Ke9XwQHhmF_^_=_4E;-jZRm3i@##)>9D<;E&syL9A7nG@o%~> zk|vpNOKbUUd!(I)%yuv1SW9_|5Da4A%z&KLgiIGwE;uI5JO-Nc{@gdhcceevF&leO zVys_EY!O|G&%(QJfIb2&O{+z<*?O6fPw>xJX@>Pv^`8yD{#YAIY$Q}zyjTZ29*jI^972!490tPfVgKn( z%KO<&oh$P2b_mOBN zgyP16Xe=J=tx&~i4ZRq9e=)d81M+jVkR?p}>7kANPavybtL^rh=Hy=wfy4_SzT_5l zq#CDyIR&)l#(vygC&SvNrN+Hi08+KV;BsB~Fj(5ymFqt;C@{8WOQ*Uk+I)7^bMIii zGefP}N7VBE*UlZni8N0EyXD)L@P?={Lt2eewH8AH=cEMxF-~Y!b_i!Dj5E2_mHh%=n-7hnFgOs)_x;34kWHa zp=g<`%W?Gtok{QAwmn6palN@rWzb6NGdBC4fgOk$IsxQb3uHE1%kywDNMZ;?Zc;GB zwvEm{Iy_Mn+}*NbYwKIIY9t0!lPxoj^gnQ|tmdG)_0}kH-r41@-mmrFn)0YZ=ff); zE^ZCvK;)_pbF*ugLhL{yUBNZKTU}oz>slo71!EXlDP`U%|3lNud%K*O z2_f8 zLpFm4XCvKaC?0OUm#zCzwJ1gHK*2vFt#c@lpGqTwQk2O*@21QC-woLP9M2Qkh1#)06zt z7@m`Hyt6z??WrX-?bCmZB}^ zS3@JT24dE;!N8lQ|G^iBOuq%6|0ewyh^z+X=MI1h;|S)Gp03K?Q{3!ad|zC%SP+s7 zZnuJLohz|oxq(ZJM6xbthuN*oCV7hyThx84zoXY_&v!0J7ay4`R$u>wpFaBGNXJt5 zy|6E!!u5YK2taVo%yhXo8OCt0;M*rJ2WYoHpe29O;C4;@1C#Y2yab(6R_k$acZaIdc*`fVzr5u} zs4?9A$v)4Wj{Yqka08+vcEhGVlQw7+y49IsYs%&p*2&bl!kRomm_*!FqN~fO?0Q9= z8>grrp5D;GOG)rHdZ4MsQ59JXFSDhsORW!>0^crNU1BcghBcn9+6z`CRjBx&QrYbz za(!Amf{5-k+es4V-BqLNNQjJhV7mfo^L3^MZ|zskU9YF?vx_S870+_bdSnZ`#Mc zDd{Vbg2d;@R(-tM?9v%x8el%RVFpAtCGb}VX0O`uL zRyY|OrA64WijH^%=%$|?B7RzvLwN4lEW5PKnu69m=k5_sPyQZio=7r2IA!YAe>j`n za9nD(Icc5vatP77NQxV$YkG~eb&(wEouBDKdTt=|BSoScEIh#sa8KBPTHhnS`2`Sm z27oSdahh;Dacq9Rm%2&%WN3BS3B>X^@$zJ+w(q33Z68AM@|DN3I<-D&Aar(1`Ib&> zZT3VMrZb4tppgrTH`4^(%>f(XXcEfvD#dMM+<)Hfl{KD7W#5#0#1)7Y@kA;MHsmmn zF4oycuPw=}PoC~~Eq;Re=YoTEd+g?riYjQxV!wIZ*Islgu?Ez$wGZ7o%1Q%a0VG{< z&T(h9IsBvCZGSna&=Ttu3p3xZ%n!e`Z&a1u9^GJ3&zcVf*HQLV#Yj3b} z(cS{Nhu(nok-^Ii37pdjnU!)+Y>Pl)(^b` z=}A$7_*`9L)Y6m5;VNg*iL1XV^}_tr*wJ-2ghc#ozo~6`>W(kv;K1(t_+9^_^hK51 zy<~+xVB$9V_NNEDrvBm^(Ty<*{iN3~PxgNiw4N718NU(yVvl8}P~o>LKm_>xhg+mZ zgF6o-+@~&kLtnH61g{lp3ar2PP?}Xf#4K+d$w{^w0%GVToUIVN%5>@ZD9Gc~mEog$ z0tTy&M%2OnulgUbO4Gl*1uH)la%8r<#K$N-@Hkg=*ST`S zHYrv>5h-Ga@Y`EI_(Fv+dJcD2`RypRKO`()gof7T>`ksjXKHg{j@Z%iwXayS_;Dtf z25}ibBeRKh7ze3ObpQ^Sc{6SKef$VSIPdvsr-$AtiQ|JZ-mthre_c`X^yX-~Q+Kap zohv6;JmtZnr|UT6hMWwZiakT@KU*S;?K`9#qP`zHs5t@QPv>(+Rq9?eFRXpMfwLFS zX}h)978*3#2-75)3 zAl@=T#kiNa<4R~TV#`wx9*-ygply@3HoG@g%JxH0w5!w&`N%)^O;YI(IpYL8_m_+g zUq)*i?|^1YZyBhnn+HU;-dy69^!|%iLxmGn5C-TQAjCS1Bbi2-`PZ}>3D30r?uJ98 zfFsQC?)r#X8Zg&oeh+>br|YZs(EWg02#GqUQ#SBwN`>v$#iKz~*J?}=JXrsA z-5%(q#S21C^Enqb*CmA44o%G`zPkcv&5y)*w$V5=_3myk@K!#W_}!_+II$+ktaA3o zI|y#%LBQ8xLG23~zq|n(L4LYu|0I?9kh7HujK9qa;3xd8SD^n?90GO?w{|5h3P^VN zu4tAG&O=}Ow?M2rT>Km3~5e=g~fH{-b?~ zYt>g}>mV}V4%+eT5x%aTN3zPz$8o!~6^OYxbb(2jSrBHk6^Uu))Xf*;PS8rITqkpF zkcMK0G%J$pZG;eKQ+ZH&(-q!<-!$cl>E^K|z z4E_A4+HMuTe7$A^m@)^9M|l=P)O0?HY}Jl*EiZdprBe9YdK|%c{}C7+E$M%zEZ$r zs18?+JiI@_y9?bMFe7#WNG3@E5%l3llv0}<+;-vW?w0$|rNFH}Y&bWi3jg?EvT^-D zLy+)Sd901td^%O0A+vl$(${f{C#Qt>`n~G^Vs6#So(H(oyb+AIhi^5-x00fr)01mH zF%wR9rihK98Y8?C(_7Y;x@9VNb2e1Aeu8Va5=6saN{J@oEhBWn7~ zthz0-VLhJlHiT{&-Szvv&c96F(v^hhYwg8c=u6|@OEaJO&X_Blf%U87|MDolqI)sl zCZ}cNt&EVub&okQiA0QM1-+0~JY9|m8*L3)@l&FiPXF^h{^+SDjDK~+XcyBqm zl_`5}Y9sEi7rOwaAS2=Q{q}1Vq%kJ!kn1tmO3MQsHwU86eMFUcxgr_ks@w#5Le^o&v#9Xa% z)$$e?_rq7`RG;T{+gJ-+hkt`dhLLn+k?o-9peC?2QwHL&4*bj;l&=u@A^dyqdjJvA zcPp<7O{bWSdH@CJ^$RaMuj zC1+g%`N(jAk{6Inxr!!U_6A5}-AJndt|QR>=fyEU+yDGAN$%=!cb2d7-B8s!f&#Jw z!SzO-@fF>5_~SkCSsg(U$MR-~^pkATI~x>E6WtJ_x3X+*J4&$QD5*cOgt&{|kcPaLb$E#y)Rs?8w7Hn)Br}!$RZ;8c}x>2^CU(+)0hF;t?)Bk9>*aWKG($vQMQh_sa)dmWj zR>G}px#YHa0HsKhZfNxaxxnlqqO(DuxUP9v6_?Cc#--~wd-hBDHs|q(PEgfu8NEvx zW(bX)frMgTItiXWzLN~$o6wbD1fElVGDH#pu?tRsXnCu+rc zaYJN7#vnt`N~!FGa!XigT~~8zv@cUkhryZyfJ?}^KnsB5F)3Y(1XoF*!EJtQWw~Zo znxz-1M?VHNbcK9&cvF+uW}es>waia<93n!l%55YE(5WzvSD8;aSBvi78yD6KYNi-# z7+Tv0X6hjFWM$Fftl9QIAtO(-G`fcCz*4Q73;2RiH`vd2GN&q?b&l@lXwRd*RZjv* zS^WZ&Nys&?ymn%}P$V%Y@NZ^`HN#VccU;$sx^Fztzudf7hqEu*(d^%_3g~6ko>BW* zq_5Q}%>GQRHqc%)n?W1jUiGX7${Fx!i+0}IAYg~#d1J4gL%JbRWYu30+cK#)2J2dS z;og(@^^!E<*SW|DaIQuK)nycWSLH$Ta#-b~MT1o_qpo}F1H&x;>whl3UvI)jMK z_Co%^;3~WQQzk+t(&<6uxbQ^qv?<(+b99?Zcq&(5W-#VIB#bUGcgStSx^ea$qNSk? zxHGRk@L0sckW#00#c~9e2vWe=`DY$*~({pNo-KGo%|Hy zXJleGIToyJsVb(#1^`tf%x>p<&}H}lXhJYBtH);|YBaJt+KA^gG|gAY%sKK#SojiNyRQib5c1MVHi;e5SwtWYwb*?cw*iZL2Vq}N>5pH#+OOnK_^o#12YD2+) zpE=Hjd@6W_sTZe*z)ZG(NUiKwI!1JS)sVYnLaM+2&Bx?5Y_5ImLV^?!_fIolCiEnq zQeb&Y`{L~Wi9%f}^1~Y*;?6*blmdTWgQQudzwB)FY>Hhy{WR0B>QlEsXJUp45jUZx z10c7-{+41oD{c7E@(GZMxiiW$ju7FzG3Z*;l`84J_0BhbssOro`-^{sKwkvb!R-vsNQ4g`>bK|I_L_;?uBt>5!3SXpjGa-~I+rb>jK%#F+>%NP$LW z0yxaOKSR{Ao{BMRA?tcK#&O|=O!W@~4Z3i()Y2Op1pyxjX5BswSumaXmbbOZOTCpQ z$XLeq8wD?DbN??==wt!LZ~y0CNrhU2-H*5r2BmhZGM^Qgdsz-Ib8nj|_`x1r{F?ig z13ukFyvAv2%^>4?kNRTXj-;*}b%Xe9Gryry_&CwD(3}bx#h6#P8XHBftw;N0&wWW< zTh%q}OL?5bv^AEWfPW7M z9~PXrD9jBcF{FGdB|fP-6ZSA6zfo3nCAGce`%a@NGMh&-+pCfCD*l!xOp$dTPixG0 z{H{@6x1sEgY>6=_swg^UOl4y@<-o@+@74CXVD;Aa>_l|)nh`VbAs6J@6|asFJADqx znp*ZfmL)LP(^ZuPVNFivaeHza^}}7v1wx}v+?)GKT$lHlKC>(h16?F>oF4wD-t4Gb z76H)sB@{Us^oS!c#TzOJDRAn15BkRIp}=raT&}>iwz!p5sOh?XfRItN&2A1N)CCV9 zKlxOduDFBCT<$6xi%ff?UpQ>SC?Ec`u`9sn6Ts>nt^KNsHsRc z@S~7UdI@+u;EUI|x9_0p3smswx7A2_zJZ-g0JjHt^4;`L{`q%x2_b!#BZIDzPRfIF zb9L<@QKIrpNm@qJ6;IC8S*U-NQia#%LJdG)A6Ub&A!FUq@<0{KbM%_6~g zA%IHpO9VrHuMMWM7pGPj42^aw3|+?Yy#Hn5!&}!Wt}a59Wj6=HR}Fb%_@iI+i~3c% zks;D9_)W^~IeP~g(kwHvkP-d|&N=e;(k)pxA@tY|?Z(+h9i9Q#Ou{eDe1EmNNu2*!rU&=If7#WAX~JGZf-K!i z!MDiQHsU$UT^vN^SN zFe_IP9PO6gtl?C&eyQH^nj3aO*&v7LD4$xKghLyff$Q zp#Zb$!)N}P<) zn{_hi4Xt)E&yp6y(}et+4|d|b3iZWw1o#8SawvET*T7jvTrNfty`uH0`j$!6ZBoO)XtkFw*y+5o?oLmFEQ4?(~U`gwIaK z8(R8Fq=ynklb2}1i@lOD_lH3 z=9Xi`|KkIJet_I*%|k_kp|ZoEV7(SfP5aS)1FnvKix}dhWVqa!&DBn z2@n~hLWEiNsQ1|`^C+vJlR$`DC49ngj!mt8s=RKwx_zymc4KI6Tg8m9WmNbrA>_iz zVsgG=a_U&d&&S(zj)JzDpYu>t%2iJ!z4IyWi0DK+f!(#vwTj~qo6O1pWW0~LpRrbJ zxsp-Rkv207axvP=KF|4Lre{+)mQnJIUEW(fm(`Y+Q*)i z*Awo>Il$3o=0)rh#WkR^DwjPQBnY7jP#A5Zw*_lYiHBq z$P&#-CzzTbi;WsoJZes^K7YTEUXm=0Ydp*`+(rP+hG1|kG=>Nw9Y z&aHYnLth>m<-iGvYO$}!UGS2a7xPP6Wcqyoh&A6w>R+IKm2?QC>P3DAXyvXDcVEtE zw$FChO8#1qS03wm-P>$Sh-srfqvj*U2^8S6(jm0!qA`^S(Uws5#A*Rz@O7h<2oJ`i-j_lsJ%(MGShGI~vxe92mb54t_ zquAY~lS#fo8s-?zVU*Oq?W4lY~A}J-PiR6j_*fd5^ zrPhwNV3n||Jl3Yv13IHhZ_$XYPh3$eooLi2W!up+ZxxxJ#KD zt5qjJ2JBVI!k&`Dq$ElAgbH)AA}?Y(7NqTZ7|fS^mCSCd+fw8vO*u z&`VX<6Yq2N<15r?OL__YGmwpJN{Sh-ibT=u&W%d%&)hTnZ5`sGimZg+$FdaAvfMUp z^t(LAGH|S<0TA7HNBQg&yY5M2JH@w5O3MR~-!+TGqHQ z+;ld3F6{t2J$9GoX9mFCPo{VTNLGq+tkZ44f($rhPYy$oZhdk{egb%N)V|p(Ss9M} z29mk%gg9&G(Jz`H@59X6n^v>-MWj&`8CIYc+0hQ-9AuA4j49wY)}P`h7sSf#Y^MSR zisYd)CM42)L)Z3mTK7O|K%#pX5SOQ2TV(obNUi?ZiS%s)yt^j*A264742%vEmX*g0 z?lrLA`%P%f&~8Wald}T~jNIFhvwY^+qytq6RD3lT(u@Q5dvvWO?>?0$@=#jLrO=|@ z9dyiDCPA@)JZKz9*(~+M$VA0&uu3K6Sf-+xGUqTR2akK-t|JK!mg6yw` z$k(GG?pBjsgiNn#hUjZuO{f<5>9D>hKkROq0j9M`&;7ttgsMm?6q#GZ1<$%RQ*=ia z|NdKBeEpACo-w|vySz_u6&m1fmUO;Se^Gcuf5$PS6_Sg>k(v$Ky3!e_15rmGBrpap z_@N!O8ENoX|FI;f1VAB9IeuGl1j(G%VdQjZWq$vZ;gya3Q}!tXv=tj9xeQoQ3c9dL zy30$y*&ovUmTvgl?%Z+;^unI4PAxJ)*l#bq zFr#6g=ka8|?j68g*$LOm07Tu^hM}m?J~v1(OT)!D^zh0Q2ocl2uedgQb2ep6D8kv@ zU45s`80^lwSB$!Rer^K&2_O!tgYK?Drv}AuDi7KfvaCIM$ypDHb8_LykXM^_SuwHrEz+~l_L5n|}11tOcuh|65 zo9B205^4Z^aXX99z_c8tghIrJ8x(CHRA_t^H*1f_hr@vN&Vfv232eFWskeBR{Iz+0 zFVjnWHV1Qu!)rzNikCNi(QNz2W9_HM`s4FWUvV_tiIpi&8kgXwxSBU9{Hwj@6E$J5 ziiz4yG>xZf?lr*#`IC_bUoul#`rRR8ygrO5UZiU*=v$ zjXwh3<)y-iw2frpFZWL_q{s3PfDW7_dD^g~hV(V=ZUshcS9adoKOX1-J&>FBt5#6F!;LnmW_TFMz5V0K+^9kGqKMc+ICOf~51Q^R64tfpC=c z)-FZ;>@r9LU(-#bynJh3#AV?T*zhChwdmfUFn;YG|N5>V-xJY&3!J)NFfN9AF=_O! zv0RnaJV?m$^mWbZZT}*A`p{##=z(Ohw`n+b42Qlr;=)DYVA@h#w;b65*v|u$)VpbJ zm!fj;clvDVp``+EH*cTS0yUv&_8>)~7dPhyX7JNukN?&zjq~KhNweg;UI;JF6#&Vw z#r?8@@@%HPYv!-f8woo=iNt9uiu+y@FE4fKn8Ke=O#{n=7PQQBPu?dm<2-~0HFp=Z zu2CCCZ$MJaK~E<#Y(?*_)aF)pt?8EVS+rW4gM1eYHZgMGar$e+% z9nk!pgI&OuXP+YKNalov*=g@rZ zY=n|{>nEx+-3KuOax5EpVM`s;EYYwFwn!x&-Lv+)2&qc&t?rRDLtf^lRxCH&1)k#|xerVkRXD6GN-l@;V*dpfdSY z@mhkQzdMycug}_RlZVJ>ja~&4w-b&tT>|}{ z3(~f7fFG#!x&PWgJI6MXSn0R_ZeD90uzmYqwIx;5|wLts-(})dc6Plk~9=57geaM zc$WS+C&fq<&^v7$eE;dz>E!`)*!Leo0ZmSwTjRaW8t;brXphWn3o=d%_8WS7BQpMh z-sauj4J*;Z_qwVJMwdXJf=s1r>+MM6n!6hk2s2Bu#Pe;pO_RUlB58U4yKdsUf;Z1Q z7EFBrsHWZu3zIn18&M90jhxWkhqB_0G8Qz>zTGypUiW{j#Z^?qc~-9z7tiI8>N z^9p0PbIGKbw$S^J?7k5l3ePAcDQ~z|&U5clP^$e;?^2gB8C`<1u05_;kM?_1P{#5B z_WKO&q0h>$_^s2n^SfVgYTxO6Ym(@x`u@&${_%Fvtn~J8c(tNP(>?o*ZGgE7#kHy0 z0;#s`r;ed4|EJPalHn_ULn2T45)#ed9L-~#%RmGPu|7EDKQ)$Z-WE}VSUGt>i zs@Bi9ga}8%Hx(Kr`P8e(Z~MTxGZ6i->TKX_Aqnf9@=GwWfR?ytygKfkS#7`d8NFzS zXq~_US^nbKuEayRU&{=Sbk!onQ=0hf*RUEtHHN{yP&0r0}8o zecN>EBo>6A29VN%w#W`ZvYVRu)w9}C!&&_=v%s}AQqirVA0xQk?EMaLJ}~5+K+T%Q zGtNtVRaBG~Q81*XoL{0j%P$U=nKv7QRziXnpsl95m+m^6mUdH@Z5!l`-=Gv)DgIHU ze8s=kRwnIGtumU@WUkh&w~9RiH5G45_OFYjKExduY4|+%>uVR^N!xrpLTs5-(b>!| z5P#>$$A4EHRvfGOCF`fvi_*gPhBUuOy5s3Br80?Sw|{4#c<5BPu*=y32XFmuZz`U3 zi*4AXJu9Q&rQ#FjAPvc$Mm-QuUPglki!|uGh_60bM=2$f zA07ExQ&VIKqOKKmfcLVzanK+2W%@h&3QNx@54|1h47R-V`zu { pub ctx: egui::Context, input: egui::RawInput, tree: Option, output: Option, texture_deltas: Vec, + update_fn: Box, } -impl Default for Harness { - fn default() -> Self { - Self::new() - } -} - -impl Harness { - pub fn new() -> Self { +impl<'a> Harness<'a> { + pub fn new(app: impl FnMut(&egui::Context) + 'a) -> Self { let ctx = egui::Context::default(); ctx.enable_accesskit(); Self { + update_fn: Box::new(app), ctx, input: egui::RawInput { screen_rect: Some(Rect::from_min_size(Pos2::ZERO, Vec2::new(800.0, 600.0))), @@ -57,16 +55,16 @@ impl Harness { self } - pub fn run(&mut self, app: impl FnMut(&egui::Context)) { + pub fn run(&mut self) { if let Some(tree) = &mut self.tree { for event in tree.take_events() { match event { - AKEvent::ActionRequest(e) => { + kittest::Event::ActionRequest(e) => { self.input .events .push(egui::Event::AccessKitActionRequest(e)); } - AKEvent::Simulated(e) => match e { + kittest::Event::Simulated(e) => match e { SimulatedEvent::Click { position } => { let position = egui_vec2(position).to_pos2(); self.input.events.push(egui::Event::PointerButton { @@ -89,7 +87,7 @@ impl Harness { } } } - let mut output = self.ctx.run(self.input.take(), app); + let mut output = self.ctx.run(self.input.take(), self.update_fn.as_mut()); if let Some(tree) = &mut self.tree { tree.update( output @@ -168,7 +166,7 @@ impl Harness { } } -impl<'t, 'n> Queryable<'t, 'n> for Harness +impl<'t, 'n, 'h> Queryable<'t, 'n> for Harness<'h> where 'n: 't, { diff --git a/crates/etest/src/snapshot.rs b/crates/egui_kittest/src/snapshot.rs similarity index 82% rename from crates/etest/src/snapshot.rs rename to crates/egui_kittest/src/snapshot.rs index c7b9d8d53b0..ff76fe69c33 100644 --- a/crates/etest/src/snapshot.rs +++ b/crates/egui_kittest/src/snapshot.rs @@ -4,8 +4,8 @@ pub fn image_snapshot(current: image::RgbaImage, name: &str) { .unwrap(); let path = format!("tests/snapshots/{name}.png"); - let diff_path = format!("tests/snapshots/{name}.diff.webp"); - let current_path = format!("tests/snapshots/{name}.new.webp"); + let diff_path = format!("tests/snapshots/{name}.diff.png"); + let current_path = format!("tests/snapshots/{name}.new.png"); std::fs::create_dir_all("tests/snapshots").ok(); @@ -31,9 +31,7 @@ pub fn image_snapshot(current: image::RgbaImage, name: &str) { current.save(&path).unwrap(); println!("Updated snapshot: {path}"); } else { - panic!( - "Image did not match snapshot. Diff: {diff}, {diff_path}" - ); + panic!("Image did not match snapshot. Diff: {diff}, {diff_path}"); } } else { // Delete old diff if it exists diff --git a/crates/etest/src/texture_to_bytes.rs b/crates/egui_kittest/src/texture_to_bytes.rs similarity index 100% rename from crates/etest/src/texture_to_bytes.rs rename to crates/egui_kittest/src/texture_to_bytes.rs diff --git a/crates/etest/src/utils.rs b/crates/egui_kittest/src/utils.rs similarity index 100% rename from crates/etest/src/utils.rs rename to crates/egui_kittest/src/utils.rs diff --git a/crates/etest/src/wgpu.rs b/crates/egui_kittest/src/wgpu.rs similarity index 99% rename from crates/etest/src/wgpu.rs rename to crates/egui_kittest/src/wgpu.rs index 68a31ffc9f6..8dcf51500c7 100644 --- a/crates/etest/src/wgpu.rs +++ b/crates/egui_kittest/src/wgpu.rs @@ -6,7 +6,7 @@ use image::RgbaImage; use std::iter::once; use wgpu::Maintain; -impl Harness { +impl<'a> Harness<'a> { pub fn image(&self, _renderer: TestRenderer) {} } From 6f2691f9df0425d4ff846aee336ea2321c0c7efb Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Wed, 25 Sep 2024 22:41:42 +0200 Subject: [PATCH 04/47] Enable git lfs for snapshots files --- .gitattributes | 1 + .gitignore | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitattributes b/.gitattributes index b1f5e1192e4..bffb89d4ad0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ * text=auto eol=lf Cargo.lock linguist-generated=false +**/tests/snapshots/**/*.png filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore index 4a635412479..fab7870a6e8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,5 @@ /.vscode /media/* .idea/ -**/tests/snapshots/*.new.png -**/tests/snapshots/*.diff.png +**/tests/snapshots/**/*.new.png +**/tests/snapshots/**/*.diff.png From e791a7451ae7f0993fe2b543402736f1425a5ba7 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Wed, 25 Sep 2024 23:05:08 +0200 Subject: [PATCH 05/47] Add widget_gallery.png --- crates/egui_demo_lib/tests/snapshots/widget_gallery.png | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 crates/egui_demo_lib/tests/snapshots/widget_gallery.png diff --git a/crates/egui_demo_lib/tests/snapshots/widget_gallery.png b/crates/egui_demo_lib/tests/snapshots/widget_gallery.png new file mode 100644 index 00000000000..88b0bccb38b --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/widget_gallery.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bceac96a5fb9eaf4660e7d646f3694955aa31f63004966789a032f0a606bd644 +size 166348 From 0853a52e3d8e682289dc279399126e362520f594 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Wed, 25 Sep 2024 23:25:13 +0200 Subject: [PATCH 06/47] Fix Cargo.toml formatting --- Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index be92bc5bf96..aec446d822a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,8 +13,10 @@ members = [ "crates/emath", "crates/epaint", "crates/epaint_default_fonts", + "examples/*", "tests/*", + "xtask", ] From 661bc3ea37261f5aa83e24ce6190bfa13d46247a Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Thu, 26 Sep 2024 00:24:24 +0200 Subject: [PATCH 07/47] Add snapshot tests for all demos --- .../src/demo/demo_app_windows.rs | 55 +++++++++++++++++++ .../tests/snapshots/B\303\251zier Curve.png" | 3 + .../tests/snapshots/Code Editor.png | 3 + .../tests/snapshots/Code Example.png | 3 + .../tests/snapshots/Context Menus.png | 3 + .../tests/snapshots/Dancing Strings.png | 3 + .../tests/snapshots/Drag and Drop.png | 3 + .../tests/snapshots/Extra Viewport.png | 3 + .../tests/snapshots/Font Book.png | 3 + .../egui_demo_lib/tests/snapshots/Frame.png | 3 + .../tests/snapshots/Highlighting.png | 3 + .../tests/snapshots/Interactive Container.png | 3 + .../tests/snapshots/Misc Demos.png | 3 + .../tests/snapshots/Multi Touch.png | 3 + .../tests/snapshots/Painting.png | 3 + .../tests/snapshots/Pan Zoom.png | 3 + .../egui_demo_lib/tests/snapshots/Panels.png | 3 + .../tests/snapshots/Scrolling.png | 3 + .../egui_demo_lib/tests/snapshots/Sliders.png | 3 + .../egui_demo_lib/tests/snapshots/Strip.png | 3 + .../egui_demo_lib/tests/snapshots/Table.png | 3 + .../tests/snapshots/Text Layout.png | 3 + .../tests/snapshots/TextEdit.png | 3 + .../tests/snapshots/Tooltips.png | 3 + .../tests/snapshots/Undo Redo.png | 3 + .../tests/snapshots/Widget Gallery.png | 3 + .../tests/snapshots/Window Options.png | 3 + crates/egui_kittest/src/lib.rs | 2 + crates/egui_kittest/src/snapshot.rs | 40 +++++++++++--- 29 files changed, 168 insertions(+), 7 deletions(-) create mode 100644 "crates/egui_demo_lib/tests/snapshots/B\303\251zier Curve.png" create mode 100644 crates/egui_demo_lib/tests/snapshots/Code Editor.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Code Example.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Context Menus.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Dancing Strings.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Drag and Drop.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Extra Viewport.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Font Book.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Frame.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Highlighting.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Interactive Container.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Misc Demos.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Multi Touch.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Painting.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Pan Zoom.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Panels.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Scrolling.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Sliders.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Strip.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Table.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Text Layout.png create mode 100644 crates/egui_demo_lib/tests/snapshots/TextEdit.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Tooltips.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Undo Redo.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Widget Gallery.png create mode 100644 crates/egui_demo_lib/tests/snapshots/Window Options.png diff --git a/crates/egui_demo_lib/src/demo/demo_app_windows.rs b/crates/egui_demo_lib/src/demo/demo_app_windows.rs index d55cc6aff3f..0b1a74ce8a0 100644 --- a/crates/egui_demo_lib/src/demo/demo_app_windows.rs +++ b/crates/egui_demo_lib/src/demo/demo_app_windows.rs @@ -377,3 +377,58 @@ fn file_menu_button(ui: &mut Ui) { } }); } + +#[cfg(test)] +mod tests { + use crate::demo::demo_app_windows::Demos; + use egui::Vec2; + use egui_kittest::kittest::Queryable; + use egui_kittest::snapshot::try_image_snapshot; + use egui_kittest::wgpu::TestRenderer; + use egui_kittest::Harness; + + #[test] + fn demos_should_match_snapshot() { + let demos = Demos::default(); + + let mut errors = Vec::new(); + + for mut demo in demos.demos { + let name = demo + .name() + .split_once(" ") + .map(|(_, name)| name) + .unwrap_or(demo.name()); + + let mut harness = Harness::new(|ctx| { + demo.show(ctx, &mut true); + }); + + // We need to run the app for multiple frames before all windows have the right size + harness.run(); + harness.run(); + harness.run(); + + let window = harness.node().children().next().unwrap(); + // TODO: Windows should probably have a label? + //let window = harness.get_by_name(name); + + let size = window.raw_bounds().expect("window bounds").size(); + harness = harness.with_size(Vec2::new(size.width as f32, size.height as f32)); + + // We need to run the app for some more frames... + harness.run(); + harness.run(); + + let image = TestRenderer::new().render(&harness); + let result = try_image_snapshot(image, &format!("{}", name)); + if let Err(err) = result { + errors.push(err); + } + } + + if !errors.is_empty() { + panic!("Errors: {:#?}", errors); + } + } +} diff --git "a/crates/egui_demo_lib/tests/snapshots/B\303\251zier Curve.png" "b/crates/egui_demo_lib/tests/snapshots/B\303\251zier Curve.png" new file mode 100644 index 00000000000..73a3fd5afe6 --- /dev/null +++ "b/crates/egui_demo_lib/tests/snapshots/B\303\251zier Curve.png" @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:baa595e6d1f67e09bb9303b925ae7e8bfcb1095869dedd15980f2da553286a51 +size 153229 diff --git a/crates/egui_demo_lib/tests/snapshots/Code Editor.png b/crates/egui_demo_lib/tests/snapshots/Code Editor.png new file mode 100644 index 00000000000..a472ee0ded8 --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Code Editor.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4116ee3996fab18e591e8f82023f9a3aa6c7c8f4081cf33b34596f952f637e4c +size 88807 diff --git a/crates/egui_demo_lib/tests/snapshots/Code Example.png b/crates/egui_demo_lib/tests/snapshots/Code Example.png new file mode 100644 index 00000000000..23eaa8fcf42 --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Code Example.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a2a0b05229f926cf60dea21a37a9980af4a8aac8fba32a948143d5d78e55ed3 +size 97752 diff --git a/crates/egui_demo_lib/tests/snapshots/Context Menus.png b/crates/egui_demo_lib/tests/snapshots/Context Menus.png new file mode 100644 index 00000000000..54dd2634a4a --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Context Menus.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2077c0047e00e61983090268768a298bda1a6d3ae12312f58bdbe401725d03c +size 25151 diff --git a/crates/egui_demo_lib/tests/snapshots/Dancing Strings.png b/crates/egui_demo_lib/tests/snapshots/Dancing Strings.png new file mode 100644 index 00000000000..048bbdcfe4c --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Dancing Strings.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6dad3634f4792d04351e2146e17f6aec3736d2ca11a6d3f524acba501114fe0 +size 144784 diff --git a/crates/egui_demo_lib/tests/snapshots/Drag and Drop.png b/crates/egui_demo_lib/tests/snapshots/Drag and Drop.png new file mode 100644 index 00000000000..c78be16618c --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Drag and Drop.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9466eaad8b642daf4b1ec07e9311294aacd8384c2ea657c24157b4a5efa59e4 +size 57546 diff --git a/crates/egui_demo_lib/tests/snapshots/Extra Viewport.png b/crates/egui_demo_lib/tests/snapshots/Extra Viewport.png new file mode 100644 index 00000000000..53f5dfe1896 --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Extra Viewport.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dbd2677a131cc8b1d4b2ebac547bcd907375dcdf90d26245be8a2f121bf5d74f +size 20333 diff --git a/crates/egui_demo_lib/tests/snapshots/Font Book.png b/crates/egui_demo_lib/tests/snapshots/Font Book.png new file mode 100644 index 00000000000..97b9f11c229 --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Font Book.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e8731835a1ece9f3e5a97ba40b297c68a0d9a4061319e67878e7b6fe200ad24 +size 153264 diff --git a/crates/egui_demo_lib/tests/snapshots/Frame.png b/crates/egui_demo_lib/tests/snapshots/Frame.png new file mode 100644 index 00000000000..12277d7e5ba --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Frame.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cdae677c8366af17eeb38445b5babee544bfc5070abaa7cfb48e42f41824fa56 +size 51884 diff --git a/crates/egui_demo_lib/tests/snapshots/Highlighting.png b/crates/egui_demo_lib/tests/snapshots/Highlighting.png new file mode 100644 index 00000000000..2e3df16ed60 --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Highlighting.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5534494c0b8372639e9d24acc5f5c1e15ef5987a0820ca1e244c22e74e0f18bf +size 31102 diff --git a/crates/egui_demo_lib/tests/snapshots/Interactive Container.png b/crates/egui_demo_lib/tests/snapshots/Interactive Container.png new file mode 100644 index 00000000000..fa4fda5c871 --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Interactive Container.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfc85be4e113fb986157435d7acfb3381a56b21921317224abe649b4da36e798 +size 36819 diff --git a/crates/egui_demo_lib/tests/snapshots/Misc Demos.png b/crates/egui_demo_lib/tests/snapshots/Misc Demos.png new file mode 100644 index 00000000000..39074b780bd --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Misc Demos.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e5ecc6c377e16bec5228859c839b661f456db224b4b329f4bae932ffff1624f7 +size 75710 diff --git a/crates/egui_demo_lib/tests/snapshots/Multi Touch.png b/crates/egui_demo_lib/tests/snapshots/Multi Touch.png new file mode 100644 index 00000000000..1c47a0c41c1 --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Multi Touch.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b74dcf0b119e03b231a4a288639c035021324bb9d8014c1f5228956d14f58b1 +size 324143 diff --git a/crates/egui_demo_lib/tests/snapshots/Painting.png b/crates/egui_demo_lib/tests/snapshots/Painting.png new file mode 100644 index 00000000000..0f1c6d36246 --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Painting.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:912b1d3c06864261d3a084de6e7cee9464841b6d54fd74699fb1541a39298bba +size 323025 diff --git a/crates/egui_demo_lib/tests/snapshots/Pan Zoom.png b/crates/egui_demo_lib/tests/snapshots/Pan Zoom.png new file mode 100644 index 00000000000..84a8362c4de --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Pan Zoom.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ebe157e8a32125aaa6691d7fb231b1c557f2b30c261205579a605c25720bb73 +size 39762 diff --git a/crates/egui_demo_lib/tests/snapshots/Panels.png b/crates/egui_demo_lib/tests/snapshots/Panels.png new file mode 100644 index 00000000000..6e6d658970c --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Panels.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:394837e1331cf3b0640d21201a121080fa78f3290d8f1a942104e63fee68fe4e +size 456632 diff --git a/crates/egui_demo_lib/tests/snapshots/Scrolling.png b/crates/egui_demo_lib/tests/snapshots/Scrolling.png new file mode 100644 index 00000000000..28154c31919 --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Scrolling.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05e081870e934880dd1efcd479cfb5a07d5ccc40b4c773e1458b88c50b654a01 +size 210058 diff --git a/crates/egui_demo_lib/tests/snapshots/Sliders.png b/crates/egui_demo_lib/tests/snapshots/Sliders.png new file mode 100644 index 00000000000..240fac5b5aa --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Sliders.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78a8fbe91614e4ea481cf2b773a7e881a3b64becdcad162ed3383af2d8a30960 +size 138692 diff --git a/crates/egui_demo_lib/tests/snapshots/Strip.png b/crates/egui_demo_lib/tests/snapshots/Strip.png new file mode 100644 index 00000000000..8edd42a1fff --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Strip.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3eb0943dd207a3ae8c20f503a5046351d1268d612e8a2230a199c70971ec0b58 +size 123211 diff --git a/crates/egui_demo_lib/tests/snapshots/Table.png b/crates/egui_demo_lib/tests/snapshots/Table.png new file mode 100644 index 00000000000..194d0a33a88 --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Table.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7268ac64bfd6128f8f4ee5aee1d80a2612536550f3158f895d39af39b5f07cb0 +size 95381 diff --git a/crates/egui_demo_lib/tests/snapshots/Text Layout.png b/crates/egui_demo_lib/tests/snapshots/Text Layout.png new file mode 100644 index 00000000000..d0875f7db84 --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Text Layout.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4cd97103a9b536779fe7b86e940e82f0574bf774f6883f7d38c38dc880b4cddf +size 83206 diff --git a/crates/egui_demo_lib/tests/snapshots/TextEdit.png b/crates/egui_demo_lib/tests/snapshots/TextEdit.png new file mode 100644 index 00000000000..ceeb5082b3d --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/TextEdit.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7bd317d11a0f7e7b548736b93e24f421d18061394f1dcacfa0ab2774551109b7 +size 53625 diff --git a/crates/egui_demo_lib/tests/snapshots/Tooltips.png b/crates/egui_demo_lib/tests/snapshots/Tooltips.png new file mode 100644 index 00000000000..1749b834d1f --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Tooltips.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b12673d58ff153449777baf01d183ab73a311c74f82c79c6c292f05752b72b92 +size 195954 diff --git a/crates/egui_demo_lib/tests/snapshots/Undo Redo.png b/crates/egui_demo_lib/tests/snapshots/Undo Redo.png new file mode 100644 index 00000000000..c441c93d104 --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Undo Redo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96f65efbb8a5a4a33454a7bf5f2a679cce078df9405c18207dddbcaace5a7553 +size 31041 diff --git a/crates/egui_demo_lib/tests/snapshots/Widget Gallery.png b/crates/egui_demo_lib/tests/snapshots/Widget Gallery.png new file mode 100644 index 00000000000..f1b29751af8 --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Widget Gallery.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e376aaa97574d8c0fca3b331a39dcaadbc463ef06026512e71e93d559539d9d +size 101513 diff --git a/crates/egui_demo_lib/tests/snapshots/Window Options.png b/crates/egui_demo_lib/tests/snapshots/Window Options.png new file mode 100644 index 00000000000..c37be4216ed --- /dev/null +++ b/crates/egui_demo_lib/tests/snapshots/Window Options.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71d56fa2d6ee4a7cfba57d1a186e1496046c4cb7509d7bb0d20d6446360bc93c +size 59316 diff --git a/crates/egui_kittest/src/lib.rs b/crates/egui_kittest/src/lib.rs index a29cb9924db..19aeb31a69d 100644 --- a/crates/egui_kittest/src/lib.rs +++ b/crates/egui_kittest/src/lib.rs @@ -6,6 +6,8 @@ mod utils; #[cfg(feature = "wgpu")] pub mod wgpu; +pub use kittest; + use crate::utils::egui_vec2; pub use accesskit_consumer; use egui::accesskit::NodeId; diff --git a/crates/egui_kittest/src/snapshot.rs b/crates/egui_kittest/src/snapshot.rs index ff76fe69c33..289cdca1f4d 100644 --- a/crates/egui_kittest/src/snapshot.rs +++ b/crates/egui_kittest/src/snapshot.rs @@ -1,11 +1,23 @@ -pub fn image_snapshot(current: image::RgbaImage, name: &str) { +use std::path::{Path, PathBuf}; + +#[derive(Debug)] +pub struct SnapshotError { + pub diff: i32, + pub diff_path: PathBuf, +} + +pub fn try_image_snapshot(current: image::RgbaImage, name: &str) -> Result<(), SnapshotError> { let current = dify_image::RgbaImage::from_raw(current.width(), current.height(), current.into_raw()) .unwrap(); - let path = format!("tests/snapshots/{name}.png"); - let diff_path = format!("tests/snapshots/{name}.diff.png"); - let current_path = format!("tests/snapshots/{name}.new.png"); + let snapshots_path = Path::new("tests/snapshots"); + + let path = snapshots_path.join(format!("{name}.png")); + std::fs::create_dir_all(path.parent().unwrap()).ok(); + + let diff_path = snapshots_path.join(format!("{name}.diff.png")); + let current_path = snapshots_path.join(format!("{name}.new.png")); std::fs::create_dir_all("tests/snapshots").ok(); @@ -15,7 +27,7 @@ pub fn image_snapshot(current: image::RgbaImage, name: &str) { Ok(image) => image.to_rgba8(), Err(err) => { println!("Error opening image: {err}"); - println!("Saving current image as {path}"); + println!("Saving current image as {path:?}"); current.save(&path).unwrap(); current.clone() @@ -29,12 +41,26 @@ pub fn image_snapshot(current: image::RgbaImage, name: &str) { if std::env::var("UPDATE_SNAPSHOTS").is_ok() { current.save(&path).unwrap(); - println!("Updated snapshot: {path}"); + println!("Updated snapshot: {path:?}"); } else { - panic!("Image did not match snapshot. Diff: {diff}, {diff_path}"); + return Err(SnapshotError { diff, diff_path }); } } else { // Delete old diff if it exists std::fs::remove_file(diff_path).ok(); } + + Ok(()) +} + +pub fn image_snapshot(current: image::RgbaImage, name: &str) { + match try_image_snapshot(current, name) { + Ok(_) => {} + Err(err) => { + panic!( + "{name} failed. Image did not match snapshot. Diff: {}, {:?}", + err.diff, err.diff_path + ); + } + } } From 87cdb1742d42ea5d711df5d24bbe9939d342edb1 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Fri, 27 Sep 2024 00:53:48 +0200 Subject: [PATCH 08/47] Move demo snapshots --- crates/egui_demo_lib/src/demo/demo_app_windows.rs | 2 +- .../tests/snapshots/demos/B\303\251zier Curve.png" | 0 .../egui_demo_lib/tests/snapshots/{ => demos}/Code Editor.png | 0 .../egui_demo_lib/tests/snapshots/{ => demos}/Code Example.png | 0 .../egui_demo_lib/tests/snapshots/{ => demos}/Context Menus.png | 0 .../tests/snapshots/{ => demos}/Dancing Strings.png | 0 .../egui_demo_lib/tests/snapshots/{ => demos}/Drag and Drop.png | 0 .../tests/snapshots/{ => demos}/Extra Viewport.png | 0 crates/egui_demo_lib/tests/snapshots/{ => demos}/Font Book.png | 0 crates/egui_demo_lib/tests/snapshots/{ => demos}/Frame.png | 0 .../egui_demo_lib/tests/snapshots/{ => demos}/Highlighting.png | 0 .../tests/snapshots/{ => demos}/Interactive Container.png | 0 crates/egui_demo_lib/tests/snapshots/{ => demos}/Misc Demos.png | 0 .../egui_demo_lib/tests/snapshots/{ => demos}/Multi Touch.png | 0 crates/egui_demo_lib/tests/snapshots/{ => demos}/Painting.png | 0 crates/egui_demo_lib/tests/snapshots/{ => demos}/Pan Zoom.png | 0 crates/egui_demo_lib/tests/snapshots/{ => demos}/Panels.png | 0 crates/egui_demo_lib/tests/snapshots/{ => demos}/Scrolling.png | 0 crates/egui_demo_lib/tests/snapshots/{ => demos}/Sliders.png | 0 crates/egui_demo_lib/tests/snapshots/{ => demos}/Strip.png | 0 crates/egui_demo_lib/tests/snapshots/{ => demos}/Table.png | 0 .../egui_demo_lib/tests/snapshots/{ => demos}/Text Layout.png | 0 crates/egui_demo_lib/tests/snapshots/{ => demos}/TextEdit.png | 0 crates/egui_demo_lib/tests/snapshots/{ => demos}/Tooltips.png | 0 crates/egui_demo_lib/tests/snapshots/{ => demos}/Undo Redo.png | 0 .../tests/snapshots/{ => demos}/Widget Gallery.png | 0 .../tests/snapshots/{ => demos}/Window Options.png | 0 27 files changed, 1 insertion(+), 1 deletion(-) rename "crates/egui_demo_lib/tests/snapshots/B\303\251zier Curve.png" => "crates/egui_demo_lib/tests/snapshots/demos/B\303\251zier Curve.png" (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Code Editor.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Code Example.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Context Menus.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Dancing Strings.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Drag and Drop.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Extra Viewport.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Font Book.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Frame.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Highlighting.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Interactive Container.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Misc Demos.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Multi Touch.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Painting.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Pan Zoom.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Panels.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Scrolling.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Sliders.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Strip.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Table.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Text Layout.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/TextEdit.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Tooltips.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Undo Redo.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Widget Gallery.png (100%) rename crates/egui_demo_lib/tests/snapshots/{ => demos}/Window Options.png (100%) diff --git a/crates/egui_demo_lib/src/demo/demo_app_windows.rs b/crates/egui_demo_lib/src/demo/demo_app_windows.rs index 0b1a74ce8a0..7767a5deaf0 100644 --- a/crates/egui_demo_lib/src/demo/demo_app_windows.rs +++ b/crates/egui_demo_lib/src/demo/demo_app_windows.rs @@ -421,7 +421,7 @@ mod tests { harness.run(); let image = TestRenderer::new().render(&harness); - let result = try_image_snapshot(image, &format!("{}", name)); + let result = try_image_snapshot(image, &format!("demos/{}", name)); if let Err(err) = result { errors.push(err); } diff --git "a/crates/egui_demo_lib/tests/snapshots/B\303\251zier Curve.png" "b/crates/egui_demo_lib/tests/snapshots/demos/B\303\251zier Curve.png" similarity index 100% rename from "crates/egui_demo_lib/tests/snapshots/B\303\251zier Curve.png" rename to "crates/egui_demo_lib/tests/snapshots/demos/B\303\251zier Curve.png" diff --git a/crates/egui_demo_lib/tests/snapshots/Code Editor.png b/crates/egui_demo_lib/tests/snapshots/demos/Code Editor.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Code Editor.png rename to crates/egui_demo_lib/tests/snapshots/demos/Code Editor.png diff --git a/crates/egui_demo_lib/tests/snapshots/Code Example.png b/crates/egui_demo_lib/tests/snapshots/demos/Code Example.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Code Example.png rename to crates/egui_demo_lib/tests/snapshots/demos/Code Example.png diff --git a/crates/egui_demo_lib/tests/snapshots/Context Menus.png b/crates/egui_demo_lib/tests/snapshots/demos/Context Menus.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Context Menus.png rename to crates/egui_demo_lib/tests/snapshots/demos/Context Menus.png diff --git a/crates/egui_demo_lib/tests/snapshots/Dancing Strings.png b/crates/egui_demo_lib/tests/snapshots/demos/Dancing Strings.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Dancing Strings.png rename to crates/egui_demo_lib/tests/snapshots/demos/Dancing Strings.png diff --git a/crates/egui_demo_lib/tests/snapshots/Drag and Drop.png b/crates/egui_demo_lib/tests/snapshots/demos/Drag and Drop.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Drag and Drop.png rename to crates/egui_demo_lib/tests/snapshots/demos/Drag and Drop.png diff --git a/crates/egui_demo_lib/tests/snapshots/Extra Viewport.png b/crates/egui_demo_lib/tests/snapshots/demos/Extra Viewport.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Extra Viewport.png rename to crates/egui_demo_lib/tests/snapshots/demos/Extra Viewport.png diff --git a/crates/egui_demo_lib/tests/snapshots/Font Book.png b/crates/egui_demo_lib/tests/snapshots/demos/Font Book.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Font Book.png rename to crates/egui_demo_lib/tests/snapshots/demos/Font Book.png diff --git a/crates/egui_demo_lib/tests/snapshots/Frame.png b/crates/egui_demo_lib/tests/snapshots/demos/Frame.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Frame.png rename to crates/egui_demo_lib/tests/snapshots/demos/Frame.png diff --git a/crates/egui_demo_lib/tests/snapshots/Highlighting.png b/crates/egui_demo_lib/tests/snapshots/demos/Highlighting.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Highlighting.png rename to crates/egui_demo_lib/tests/snapshots/demos/Highlighting.png diff --git a/crates/egui_demo_lib/tests/snapshots/Interactive Container.png b/crates/egui_demo_lib/tests/snapshots/demos/Interactive Container.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Interactive Container.png rename to crates/egui_demo_lib/tests/snapshots/demos/Interactive Container.png diff --git a/crates/egui_demo_lib/tests/snapshots/Misc Demos.png b/crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Misc Demos.png rename to crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png diff --git a/crates/egui_demo_lib/tests/snapshots/Multi Touch.png b/crates/egui_demo_lib/tests/snapshots/demos/Multi Touch.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Multi Touch.png rename to crates/egui_demo_lib/tests/snapshots/demos/Multi Touch.png diff --git a/crates/egui_demo_lib/tests/snapshots/Painting.png b/crates/egui_demo_lib/tests/snapshots/demos/Painting.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Painting.png rename to crates/egui_demo_lib/tests/snapshots/demos/Painting.png diff --git a/crates/egui_demo_lib/tests/snapshots/Pan Zoom.png b/crates/egui_demo_lib/tests/snapshots/demos/Pan Zoom.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Pan Zoom.png rename to crates/egui_demo_lib/tests/snapshots/demos/Pan Zoom.png diff --git a/crates/egui_demo_lib/tests/snapshots/Panels.png b/crates/egui_demo_lib/tests/snapshots/demos/Panels.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Panels.png rename to crates/egui_demo_lib/tests/snapshots/demos/Panels.png diff --git a/crates/egui_demo_lib/tests/snapshots/Scrolling.png b/crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Scrolling.png rename to crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png diff --git a/crates/egui_demo_lib/tests/snapshots/Sliders.png b/crates/egui_demo_lib/tests/snapshots/demos/Sliders.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Sliders.png rename to crates/egui_demo_lib/tests/snapshots/demos/Sliders.png diff --git a/crates/egui_demo_lib/tests/snapshots/Strip.png b/crates/egui_demo_lib/tests/snapshots/demos/Strip.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Strip.png rename to crates/egui_demo_lib/tests/snapshots/demos/Strip.png diff --git a/crates/egui_demo_lib/tests/snapshots/Table.png b/crates/egui_demo_lib/tests/snapshots/demos/Table.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Table.png rename to crates/egui_demo_lib/tests/snapshots/demos/Table.png diff --git a/crates/egui_demo_lib/tests/snapshots/Text Layout.png b/crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Text Layout.png rename to crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png diff --git a/crates/egui_demo_lib/tests/snapshots/TextEdit.png b/crates/egui_demo_lib/tests/snapshots/demos/TextEdit.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/TextEdit.png rename to crates/egui_demo_lib/tests/snapshots/demos/TextEdit.png diff --git a/crates/egui_demo_lib/tests/snapshots/Tooltips.png b/crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Tooltips.png rename to crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png diff --git a/crates/egui_demo_lib/tests/snapshots/Undo Redo.png b/crates/egui_demo_lib/tests/snapshots/demos/Undo Redo.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Undo Redo.png rename to crates/egui_demo_lib/tests/snapshots/demos/Undo Redo.png diff --git a/crates/egui_demo_lib/tests/snapshots/Widget Gallery.png b/crates/egui_demo_lib/tests/snapshots/demos/Widget Gallery.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Widget Gallery.png rename to crates/egui_demo_lib/tests/snapshots/demos/Widget Gallery.png diff --git a/crates/egui_demo_lib/tests/snapshots/Window Options.png b/crates/egui_demo_lib/tests/snapshots/demos/Window Options.png similarity index 100% rename from crates/egui_demo_lib/tests/snapshots/Window Options.png rename to crates/egui_demo_lib/tests/snapshots/demos/Window Options.png From ee3e766c84bb210c1e790dfee50cdd79190743b5 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Fri, 27 Sep 2024 01:11:16 +0200 Subject: [PATCH 09/47] Update kittest --- Cargo.lock | 2 +- crates/egui_kittest/examples/kittest.rs | 2 +- crates/egui_kittest/src/event.rs | 122 ++++++++++++++++++++ crates/egui_kittest/src/lib.rs | 91 ++++++++++----- crates/egui_kittest/src/snapshot.rs | 8 ++ crates/egui_kittest/src/texture_to_bytes.rs | 4 +- crates/egui_kittest/src/utils.rs | 12 -- crates/egui_kittest/src/wgpu.rs | 2 +- 8 files changed, 195 insertions(+), 48 deletions(-) create mode 100644 crates/egui_kittest/src/event.rs delete mode 100644 crates/egui_kittest/src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index 4996331920f..a77d39d3a1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2417,7 +2417,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "kittest" version = "0.1.0" -source = "git+https://github.com/rerun-io/kittest?branch=kittest#be12a16312993bd614f7291470c588e906908cc8" +source = "git+https://github.com/rerun-io/kittest?branch=kittest#9fd3c6258b1570b5944ce681ec648ef3b0711b59" dependencies = [ "accesskit", "accesskit_consumer", diff --git a/crates/egui_kittest/examples/kittest.rs b/crates/egui_kittest/examples/kittest.rs index bd46d798473..6fd3e412ea3 100644 --- a/crates/egui_kittest/examples/kittest.rs +++ b/crates/egui_kittest/examples/kittest.rs @@ -7,7 +7,7 @@ use std::cell::RefCell; fn main() { let checked = RefCell::new(false); let text = RefCell::new(String::new()); - let mut app = |ctx: &Context| { + let app = |ctx: &Context| { CentralPanel::default().show(ctx, |ui| { ui.checkbox(&mut checked.borrow_mut(), "Check me!"); TextEdit::singleline(&mut *text.borrow_mut()) diff --git a/crates/egui_kittest/src/event.rs b/crates/egui_kittest/src/event.rs new file mode 100644 index 00000000000..5c06342f034 --- /dev/null +++ b/crates/egui_kittest/src/event.rs @@ -0,0 +1,122 @@ +use kittest::{Key, MouseButton}; + +pub fn kittest_key_to_egui(value: Key) -> Option { + match value { + Key::ArrowDown => Some(egui::Key::ArrowDown), + Key::ArrowLeft => Some(egui::Key::ArrowLeft), + Key::ArrowRight => Some(egui::Key::ArrowRight), + Key::ArrowUp => Some(egui::Key::ArrowUp), + Key::Escape => Some(egui::Key::Escape), + Key::Tab => Some(egui::Key::Tab), + Key::Backspace => Some(egui::Key::Backspace), + Key::Enter => Some(egui::Key::Enter), + Key::Space => Some(egui::Key::Space), + Key::Insert => Some(egui::Key::Insert), + Key::Delete => Some(egui::Key::Delete), + Key::Home => Some(egui::Key::Home), + Key::End => Some(egui::Key::End), + Key::PageUp => Some(egui::Key::PageUp), + Key::PageDown => Some(egui::Key::PageDown), + Key::Copy => Some(egui::Key::Copy), + Key::Cut => Some(egui::Key::Cut), + Key::Paste => Some(egui::Key::Paste), + Key::Colon => Some(egui::Key::Colon), + Key::Comma => Some(egui::Key::Comma), + Key::Backslash => Some(egui::Key::Backslash), + Key::Slash => Some(egui::Key::Slash), + Key::Pipe => Some(egui::Key::Pipe), + Key::Questionmark => Some(egui::Key::Questionmark), + Key::OpenBracket => Some(egui::Key::OpenBracket), + Key::CloseBracket => Some(egui::Key::CloseBracket), + Key::Backtick => Some(egui::Key::Backtick), + Key::Minus => Some(egui::Key::Minus), + Key::Period => Some(egui::Key::Period), + Key::Plus => Some(egui::Key::Plus), + Key::Equals => Some(egui::Key::Equals), + Key::Semicolon => Some(egui::Key::Semicolon), + Key::Quote => Some(egui::Key::Quote), + Key::Num0 => Some(egui::Key::Num0), + Key::Num1 => Some(egui::Key::Num1), + Key::Num2 => Some(egui::Key::Num2), + Key::Num3 => Some(egui::Key::Num3), + Key::Num4 => Some(egui::Key::Num4), + Key::Num5 => Some(egui::Key::Num5), + Key::Num6 => Some(egui::Key::Num6), + Key::Num7 => Some(egui::Key::Num7), + Key::Num8 => Some(egui::Key::Num8), + Key::Num9 => Some(egui::Key::Num9), + Key::A => Some(egui::Key::A), + Key::B => Some(egui::Key::B), + Key::C => Some(egui::Key::C), + Key::D => Some(egui::Key::D), + Key::E => Some(egui::Key::E), + Key::F => Some(egui::Key::F), + Key::G => Some(egui::Key::G), + Key::H => Some(egui::Key::H), + Key::I => Some(egui::Key::I), + Key::J => Some(egui::Key::J), + Key::K => Some(egui::Key::K), + Key::L => Some(egui::Key::L), + Key::M => Some(egui::Key::M), + Key::N => Some(egui::Key::N), + Key::O => Some(egui::Key::O), + Key::P => Some(egui::Key::P), + Key::Q => Some(egui::Key::Q), + Key::R => Some(egui::Key::R), + Key::S => Some(egui::Key::S), + Key::T => Some(egui::Key::T), + Key::U => Some(egui::Key::U), + Key::V => Some(egui::Key::V), + Key::W => Some(egui::Key::W), + Key::X => Some(egui::Key::X), + Key::Y => Some(egui::Key::Y), + Key::Z => Some(egui::Key::Z), + Key::F1 => Some(egui::Key::F1), + Key::F2 => Some(egui::Key::F2), + Key::F3 => Some(egui::Key::F3), + Key::F4 => Some(egui::Key::F4), + Key::F5 => Some(egui::Key::F5), + Key::F6 => Some(egui::Key::F6), + Key::F7 => Some(egui::Key::F7), + Key::F8 => Some(egui::Key::F8), + Key::F9 => Some(egui::Key::F9), + Key::F10 => Some(egui::Key::F10), + Key::F11 => Some(egui::Key::F11), + Key::F12 => Some(egui::Key::F12), + Key::F13 => Some(egui::Key::F13), + Key::F14 => Some(egui::Key::F14), + Key::F15 => Some(egui::Key::F15), + Key::F16 => Some(egui::Key::F16), + Key::F17 => Some(egui::Key::F17), + Key::F18 => Some(egui::Key::F18), + Key::F19 => Some(egui::Key::F19), + Key::F20 => Some(egui::Key::F20), + Key::F21 => Some(egui::Key::F21), + Key::F22 => Some(egui::Key::F22), + Key::F23 => Some(egui::Key::F23), + Key::F24 => Some(egui::Key::F24), + Key::F25 => Some(egui::Key::F25), + Key::F26 => Some(egui::Key::F26), + Key::F27 => Some(egui::Key::F27), + Key::F28 => Some(egui::Key::F28), + Key::F29 => Some(egui::Key::F29), + Key::F30 => Some(egui::Key::F30), + Key::F31 => Some(egui::Key::F31), + Key::F32 => Some(egui::Key::F32), + Key::F33 => Some(egui::Key::F33), + Key::F34 => Some(egui::Key::F34), + Key::F35 => Some(egui::Key::F35), + _ => None, + } +} + +pub fn pointer_button_to_egui(value: MouseButton) -> Option { + match value { + MouseButton::Left => Some(egui::PointerButton::Primary), + MouseButton::Right => Some(egui::PointerButton::Secondary), + MouseButton::Middle => Some(egui::PointerButton::Middle), + MouseButton::Back => Some(egui::PointerButton::Extra1), + MouseButton::Forward => Some(egui::PointerButton::Extra2), + MouseButton::Other(_) => None, + } +} diff --git a/crates/egui_kittest/src/lib.rs b/crates/egui_kittest/src/lib.rs index 19aeb31a69d..e906e300b86 100644 --- a/crates/egui_kittest/src/lib.rs +++ b/crates/egui_kittest/src/lib.rs @@ -1,28 +1,29 @@ +mod event; #[cfg(feature = "snapshot")] pub mod snapshot; #[cfg(feature = "wgpu")] mod texture_to_bytes; -mod utils; #[cfg(feature = "wgpu")] pub mod wgpu; pub use kittest; -use crate::utils::egui_vec2; +use crate::event::{kittest_key_to_egui, pointer_button_to_egui}; pub use accesskit_consumer; use egui::accesskit::NodeId; -use egui::{Pos2, Rect, TexturesDelta, Vec2}; -use kittest::{Node, Queryable, SimulatedEvent, Tree}; -use std::iter; -use std::time::Duration; +use egui::{Event, ImeEvent, Modifiers, Pos2, Rect, TexturesDelta, Vec2}; +use kittest::{ElementState, Node, Queryable, SimulatedEvent, State}; pub struct Harness<'a> { pub ctx: egui::Context, input: egui::RawInput, - tree: Option, + tree: Option, output: Option, texture_deltas: Vec, update_fn: Box, + + last_mouse_pos: Pos2, + modifiers: Modifiers, } impl<'a> Harness<'a> { @@ -40,6 +41,9 @@ impl<'a> Harness<'a> { tree: None, output: None, texture_deltas: Vec::new(), + + last_mouse_pos: Pos2::ZERO, + modifiers: Modifiers::NONE, } } @@ -62,28 +66,55 @@ impl<'a> Harness<'a> { for event in tree.take_events() { match event { kittest::Event::ActionRequest(e) => { - self.input - .events - .push(egui::Event::AccessKitActionRequest(e)); + self.input.events.push(Event::AccessKitActionRequest(e)); } kittest::Event::Simulated(e) => match e { - SimulatedEvent::Click { position } => { - let position = egui_vec2(position).to_pos2(); - self.input.events.push(egui::Event::PointerButton { - pos: position, - button: egui::PointerButton::Primary, - pressed: true, - modifiers: Default::default(), - }); - self.input.events.push(egui::Event::PointerButton { - pos: position, - button: egui::PointerButton::Primary, - pressed: false, - modifiers: Default::default(), - }); + SimulatedEvent::CursorMoved { position } => { + self.input.events.push(Event::PointerMoved(Pos2::new( + position.x as f32, + position.y as f32, + ))); + } + SimulatedEvent::MouseInput { state, button } => { + let button = pointer_button_to_egui(button); + if let Some(button) = button { + self.input.events.push(Event::PointerButton { + button, + modifiers: self.modifiers, + pos: self.last_mouse_pos, + pressed: matches!(state, ElementState::Pressed), + }); + } } - SimulatedEvent::Type { text } => { - self.input.events.push(egui::Event::Text(text)); + SimulatedEvent::Ime(text) => { + self.input.events.push(Event::Ime(ImeEvent::Commit(text))); + } + SimulatedEvent::KeyInput { state, key } => { + match key { + kittest::Key::Alt => { + self.modifiers.alt = matches!(state, ElementState::Pressed); + } + kittest::Key::Command => { + self.modifiers.command = matches!(state, ElementState::Pressed); + } + kittest::Key::Control => { + self.modifiers.ctrl = matches!(state, ElementState::Pressed); + } + kittest::Key::Shift => { + self.modifiers.shift = matches!(state, ElementState::Pressed); + } + _ => {} + } + let key = kittest_key_to_egui(key); + if let Some(key) = key { + self.input.events.push(Event::Key { + key, + modifiers: self.modifiers, + pressed: matches!(state, ElementState::Pressed), + repeat: false, + physical_key: None, + }); + } } }, } @@ -99,7 +130,7 @@ impl<'a> Harness<'a> { .expect("AccessKit was disabled"), ); } else { - self.tree = Some(Tree::new( + self.tree = Some(State::new( output .platform_output .accesskit_update @@ -131,7 +162,7 @@ impl<'a> Harness<'a> { }; self.input .events - .push(egui::Event::AccessKitActionRequest(action)); + .push(Event::AccessKitActionRequest(action)); } // TODO: SetValue is currently not supported by egui @@ -163,7 +194,7 @@ impl<'a> Harness<'a> { self.output.as_ref().expect("Not initialized") } - pub fn tree(&self) -> &Tree { + pub fn kittest_state(&self) -> &State { self.tree.as_ref().expect("Not initialized") } } @@ -173,6 +204,6 @@ where 'n: 't, { fn node(&'n self) -> Node<'t> { - self.tree().node() + self.kittest_state().node() } } diff --git a/crates/egui_kittest/src/snapshot.rs b/crates/egui_kittest/src/snapshot.rs index 289cdca1f4d..f93868bfb76 100644 --- a/crates/egui_kittest/src/snapshot.rs +++ b/crates/egui_kittest/src/snapshot.rs @@ -6,6 +6,10 @@ pub struct SnapshotError { pub diff_path: PathBuf, } +/// Image snapshot test. +/// +/// # Errors +/// Returns a [`SnapshotError`] if the image does not match the snapshot. pub fn try_image_snapshot(current: image::RgbaImage, name: &str) -> Result<(), SnapshotError> { let current = dify_image::RgbaImage::from_raw(current.width(), current.height(), current.into_raw()) @@ -53,6 +57,10 @@ pub fn try_image_snapshot(current: image::RgbaImage, name: &str) -> Result<(), S Ok(()) } +/// Image snapshot test. +/// +/// # Panics +/// Panics if the image does not match the snapshot. pub fn image_snapshot(current: image::RgbaImage, name: &str) { match try_image_snapshot(current, name) { Ok(_) => {} diff --git a/crates/egui_kittest/src/texture_to_bytes.rs b/crates/egui_kittest/src/texture_to_bytes.rs index 5022b9bc15c..63335b09a7e 100644 --- a/crates/egui_kittest/src/texture_to_bytes.rs +++ b/crates/egui_kittest/src/texture_to_bytes.rs @@ -5,7 +5,7 @@ use std::iter; use std::mem::size_of; use std::sync::mpsc::channel; -pub fn texture_to_bytes(device: &Device, queue: &Queue, texture: &Texture) -> RgbaImage { +pub(crate) fn texture_to_bytes(device: &Device, queue: &Queue, texture: &Texture) -> RgbaImage { let buffer_dimensions = BufferDimensions::new(texture.width() as usize, texture.height() as usize); @@ -62,7 +62,6 @@ pub fn texture_to_bytes(device: &Device, queue: &Queue, texture: &Texture) -> Rg } struct BufferDimensions { - width: usize, height: usize, unpadded_bytes_per_row: usize, padded_bytes_per_row: usize, @@ -76,7 +75,6 @@ impl BufferDimensions { let padded_bytes_per_row_padding = (align - unpadded_bytes_per_row % align) % align; let padded_bytes_per_row = unpadded_bytes_per_row + padded_bytes_per_row_padding; Self { - width, height, unpadded_bytes_per_row, padded_bytes_per_row, diff --git a/crates/egui_kittest/src/utils.rs b/crates/egui_kittest/src/utils.rs deleted file mode 100644 index fe190dac82e..00000000000 --- a/crates/egui_kittest/src/utils.rs +++ /dev/null @@ -1,12 +0,0 @@ -use egui::accesskit; - -pub fn egui_vec2(vec: accesskit::Vec2) -> egui::Vec2 { - egui::Vec2::new(vec.x as f32, vec.y as f32) -} - -pub fn accesskit_vec2(vec: egui::Vec2) -> accesskit::Vec2 { - accesskit::Vec2 { - x: vec.x as f64, - y: vec.y as f64, - } -} diff --git a/crates/egui_kittest/src/wgpu.rs b/crates/egui_kittest/src/wgpu.rs index 8dcf51500c7..385efc002b6 100644 --- a/crates/egui_kittest/src/wgpu.rs +++ b/crates/egui_kittest/src/wgpu.rs @@ -49,7 +49,7 @@ impl TestRenderer { } } - pub fn render(&mut self, harness: &Harness) -> RgbaImage { + pub fn render(&mut self, harness: &Harness<'_>) -> RgbaImage { for delta in &harness.texture_deltas { for (id, image_delta) in &delta.set { self.renderer From e63ffa3a16e9f4d7de9a8e19f298e2e60ce6fcd8 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 28 Sep 2024 23:41:48 +0200 Subject: [PATCH 10/47] Add text_edit.rs test and fix ime input --- Cargo.lock | 2 +- crates/egui_demo_lib/src/demo/text_edit.rs | 34 ++++++++++++++++++++++ crates/egui_kittest/src/lib.rs | 4 +-- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a77d39d3a1e..be745cb6a59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2417,7 +2417,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "kittest" version = "0.1.0" -source = "git+https://github.com/rerun-io/kittest?branch=kittest#9fd3c6258b1570b5944ce681ec648ef3b0711b59" +source = "git+https://github.com/rerun-io/kittest?branch=kittest#526e8469d266cc7e6d9a941f8ddd27248cf819b4" dependencies = [ "accesskit", "accesskit_consumer", diff --git a/crates/egui_demo_lib/src/demo/text_edit.rs b/crates/egui_demo_lib/src/demo/text_edit.rs index 9743306c746..96763625fca 100644 --- a/crates/egui_demo_lib/src/demo/text_edit.rs +++ b/crates/egui_demo_lib/src/demo/text_edit.rs @@ -112,3 +112,37 @@ impl crate::View for TextEditDemo { }); } } + +#[cfg(test)] +mod tests { + use egui::{accesskit, CentralPanel}; + use egui_kittest::kittest::{Key, Queryable}; + use egui_kittest::Harness; + + #[test] + pub fn should_type() { + let mut text = "Hello, world!".to_owned(); + let mut harness = Harness::new(move |ctx| { + CentralPanel::default().show(ctx, |ui| { + ui.text_edit_singleline(&mut text); + }); + }); + + harness.run(); + + let text_edit = harness.get_by_role(accesskit::Role::TextInput); + assert_eq!(text_edit.value().as_deref(), Some("Hello, world!")); + + text_edit.key_combination(&[Key::Command, Key::A]); + text_edit.type_text("Hi "); + + harness.run(); + harness + .get_by_role(accesskit::Role::TextInput) + .type_text("there!"); + + harness.run(); + let text_edit = harness.get_by_role(accesskit::Role::TextInput); + assert_eq!(text_edit.value().as_deref(), Some("Hi there!")); + } +} diff --git a/crates/egui_kittest/src/lib.rs b/crates/egui_kittest/src/lib.rs index e906e300b86..2e99bf45fc1 100644 --- a/crates/egui_kittest/src/lib.rs +++ b/crates/egui_kittest/src/lib.rs @@ -11,7 +11,7 @@ pub use kittest; use crate::event::{kittest_key_to_egui, pointer_button_to_egui}; pub use accesskit_consumer; use egui::accesskit::NodeId; -use egui::{Event, ImeEvent, Modifiers, Pos2, Rect, TexturesDelta, Vec2}; +use egui::{Event, Modifiers, Pos2, Rect, TexturesDelta, Vec2}; use kittest::{ElementState, Node, Queryable, SimulatedEvent, State}; pub struct Harness<'a> { @@ -87,7 +87,7 @@ impl<'a> Harness<'a> { } } SimulatedEvent::Ime(text) => { - self.input.events.push(Event::Ime(ImeEvent::Commit(text))); + self.input.events.push(Event::Text(text)); } SimulatedEvent::KeyInput { state, key } => { match key { From bba834bada4afe4fab4d54a462459001fab7bde6 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sun, 29 Sep 2024 01:00:31 +0200 Subject: [PATCH 11/47] Typo --- crates/egui_kittest/src/wgpu.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/crates/egui_kittest/src/wgpu.rs b/crates/egui_kittest/src/wgpu.rs index 385efc002b6..ef3d8f6cdd2 100644 --- a/crates/egui_kittest/src/wgpu.rs +++ b/crates/egui_kittest/src/wgpu.rs @@ -6,10 +6,6 @@ use image::RgbaImage; use std::iter::once; use wgpu::Maintain; -impl<'a> Harness<'a> { - pub fn image(&self, _renderer: TestRenderer) {} -} - pub struct TestRenderer { renderer: egui_wgpu::Renderer, device: wgpu::Device, @@ -69,7 +65,7 @@ impl TestRenderer { size_in_pixels: [size.x as u32, size.y as u32], }; - let tesselated = harness.ctx.tessellate( + let tessellated = harness.ctx.tessellate( harness.output().shapes.clone(), harness.ctx.pixels_per_point(), ); @@ -78,7 +74,7 @@ impl TestRenderer { &self.device, &self.queue, &mut encoder, - &tesselated, + &tessellated, &screen, ); @@ -117,7 +113,7 @@ impl TestRenderer { }) .forget_lifetime(); - self.renderer.render(&mut pass, &tesselated, &screen); + self.renderer.render(&mut pass, &tessellated, &screen); } self.queue From b2db13d8b93495a78e31d99389d6073fb4f66e39 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sun, 29 Sep 2024 01:01:03 +0200 Subject: [PATCH 12/47] Run tests with gpu --- .github/workflows/rust.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 1e8e31bbcf1..b0989617fcb 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -222,3 +222,23 @@ jobs: - name: Check hello_world run: cargo check -p hello_world + + # --------------------------------------------------------------------------- + + tests: + name: Run tests + # We run the tests on macOS because it will run with a actual GPU + runs-on: macos-latest + + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: 1.76.0 + + - name: Set up cargo cache + uses: Swatinem/rust-cache@v2 + + - name: Run tests + # TODO: Enable --all-features (currently this breaks the rendering in the tests) + run: cargo test From 94d0b84ed16c0baf4ac759b2feaefd358d8e76b4 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sun, 29 Sep 2024 01:20:29 +0200 Subject: [PATCH 13/47] Improve snapshot error --- crates/egui_kittest/src/snapshot.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/crates/egui_kittest/src/snapshot.rs b/crates/egui_kittest/src/snapshot.rs index f93868bfb76..80cc78b947b 100644 --- a/crates/egui_kittest/src/snapshot.rs +++ b/crates/egui_kittest/src/snapshot.rs @@ -1,3 +1,4 @@ +use std::fmt::Display; use std::path::{Path, PathBuf}; #[derive(Debug)] @@ -6,6 +7,16 @@ pub struct SnapshotError { pub diff_path: PathBuf, } +impl Display for SnapshotError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Image did not match snapshot. Diff: {}, {:?}", + self.diff, self.diff_path + ) + } +} + /// Image snapshot test. /// /// # Errors @@ -65,10 +76,7 @@ pub fn image_snapshot(current: image::RgbaImage, name: &str) { match try_image_snapshot(current, name) { Ok(_) => {} Err(err) => { - panic!( - "{name} failed. Image did not match snapshot. Diff: {}, {:?}", - err.diff, err.diff_path - ); + panic!("{}", err); } } } From f26e98d485dd4c16e54fd398decaab23569d4851 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sun, 29 Sep 2024 01:20:42 +0200 Subject: [PATCH 14/47] Test if snapshots fail in ci --- crates/egui_demo_lib/src/demo/widget_gallery.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/egui_demo_lib/src/demo/widget_gallery.rs b/crates/egui_demo_lib/src/demo/widget_gallery.rs index 85b9e3a4fa6..b21425f0ce6 100644 --- a/crates/egui_demo_lib/src/demo/widget_gallery.rs +++ b/crates/egui_demo_lib/src/demo/widget_gallery.rs @@ -61,6 +61,8 @@ impl crate::Demo for WidgetGallery { impl crate::View for WidgetGallery { fn ui(&mut self, ui: &mut egui::Ui) { + ui.visuals_mut().widgets.inactive.rounding = 0.0.into(); + let mut ui_builder = egui::UiBuilder::new(); if !self.enabled { ui_builder = ui_builder.disabled(); From 02f734ca121b32ea861d35f240f42173ad0f52c4 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Fri, 4 Oct 2024 16:55:14 +0200 Subject: [PATCH 15/47] Update dify --- Cargo.lock | 1467 ++++++++++++++------------- Cargo.toml | 4 + crates/egui_kittest/Cargo.toml | 8 +- crates/egui_kittest/src/snapshot.rs | 6 +- 4 files changed, 754 insertions(+), 731 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be745cb6a59..4e59b5c976c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ab_glyph" -version = "0.2.21" +version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5110f1c78cf582855d895ecd0746b653db010cec6d9f5575293f27934d980a39" +checksum = "79faae4620f45232f599d9bc7b290f88247a0834162c4495ab2f02d60004adfb" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -20,9 +20,9 @@ checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" [[package]] name = "accesskit" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4700bdc115b306d6c43381c344dc307f03b7f0460c304e4892c309930322bd7" +checksum = "ef7442f1f520649b8e11ee3af6caeec24123fed4b63bc36a85b67308d8514fdf" dependencies = [ "enumn", "serde", @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "accesskit_atspi_common" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1de72dc7093910a1284cef784b6b143bab0a34d67f6178e4fc3aaaf29a09f8b" +checksum = "ab9d2b364833ae6e2eae9359a374108b1c5488877a9f43d26f0cb700560af9ae" dependencies = [ "accesskit", "accesskit_consumer", @@ -44,9 +44,9 @@ dependencies = [ [[package]] name = "accesskit_consumer" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe3a07a32ab5837ad83db3230ac490c8504c2cd5b90ac8c00db6535f6ed65d0b" +checksum = "7072a4f17b8e7440a88ce08eb657d1ec84be061b1a94be78f9699aa18e583885" dependencies = [ "accesskit", "immutable-chunkmap", @@ -54,9 +54,9 @@ dependencies = [ [[package]] name = "accesskit_macos" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a189d159c153ae0fce5f9eefdcfec4a27885f453ce5ef0ccf078f72a73c39d34" +checksum = "716698a26b5113812348a9f99ec250cb7b4154c89a83bc55a8b7d8678a1ecf02" dependencies = [ "accesskit", "accesskit_consumer", @@ -68,9 +68,9 @@ dependencies = [ [[package]] name = "accesskit_unix" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b76c448cfd96d16131a9ad3ab786d06951eb341cdac1db908978ab010245a19d" +checksum = "fd552c7bae0cd2ba1131fb0cedad32f8915743e0ed086f989fd706431641f56e" dependencies = [ "accesskit", "accesskit_atspi_common", @@ -86,22 +86,23 @@ dependencies = [ [[package]] name = "accesskit_windows" -version = "0.22.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "682d8c4fb425606f97408e7577793f32e96310b646fa77662eb4216293eddc7f" +checksum = "4d134e9eb16c98b35d1ff7056a027d7482968bcab0d8b625e7e72895b748d705" dependencies = [ "accesskit", "accesskit_consumer", "paste", "static_assertions", - "windows 0.54.0", + "windows 0.58.0", + "windows-core 0.58.0", ] [[package]] name = "accesskit_winit" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afbd6d598b7c035639ad2b664aa0edc94c93dc1fc3ebb4b40d8a95fcd43ffac" +checksum = "156c5066e7b3ac9a82fb80fc18dcee42f79967c47e0ff431bae23e7ee8412a83" dependencies = [ "accesskit", "accesskit_macos", @@ -113,18 +114,18 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" @@ -142,18 +143,18 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "android-activity" @@ -205,21 +206,21 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "arboard" -version = "3.4.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb4009533e8ff8f1450a5bcbc30f4242a1d34442221f72314bea1f5dc9c7f89" +checksum = "df099ccb16cd014ff054ac1bf392c67feeef57164b05c42f037cd40f5d4357f4" dependencies = [ "clipboard-win", "log", @@ -232,21 +233,21 @@ dependencies = [ [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "as-raw-xcb-connection" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d5f312b0a56c5cdf967c0aeb67f6289603354951683bc97ddc595ab974ba9aa" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" [[package]] name = "ash" @@ -281,15 +282,14 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.5.3" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78f2db9467baa66a700abce2a18c5ad793f6f83310aca1284796fc3921d113fd" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" dependencies = [ - "async-lock", "async-task", "concurrent-queue", - "fastrand 2.0.1", - "futures-lite 1.13.0", + "fastrand 2.1.1", + "futures-lite 2.3.0", "slab", ] @@ -299,7 +299,7 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" dependencies = [ - "async-lock", + "async-lock 2.8.0", "autocfg", "blocking", "futures-lite 1.13.0", @@ -311,7 +311,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" dependencies = [ - "async-lock", + "async-lock 2.8.0", "autocfg", "cfg-if", "concurrent-queue", @@ -319,12 +319,31 @@ dependencies = [ "log", "parking", "polling 2.8.0", - "rustix 0.37.25", + "rustix 0.37.27", "slab", "socket2", "waker-fn", ] +[[package]] +name = "async-io" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" +dependencies = [ + "async-lock 3.4.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.3.0", + "parking", + "polling 3.7.3", + "rustix 0.38.37", + "slab", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "async-lock" version = "2.8.0" @@ -334,68 +353,78 @@ dependencies = [ "event-listener 2.5.3", ] +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener 5.3.1", + "event-listener-strategy", + "pin-project-lite", +] + [[package]] name = "async-process" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf012553ce51eb7aa6dc2143804cc8252bd1cb681a1c5cb7fa94ca88682dee1d" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" dependencies = [ - "async-io", - "async-lock", + "async-io 1.13.0", + "async-lock 2.8.0", "async-signal", "blocking", "cfg-if", - "event-listener 3.0.0", + "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.38.21", + "rustix 0.38.37", "windows-sys 0.48.0", ] [[package]] name = "async-recursion" -version = "1.0.5" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] name = "async-signal" -version = "0.2.1" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4af361a844928cb7d36590d406709473a1b574f443094422ef166daa3b493208" +checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" dependencies = [ - "async-io", - "async-lock", + "async-io 2.3.4", + "async-lock 3.4.0", "atomic-waker", "cfg-if", - "concurrent-queue", "futures-core", "futures-io", - "libc", + "rustix 0.38.37", "signal-hook-registry", "slab", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "async-task" -version = "4.4.1" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9441c6b2fe128a7c2bf680a44c34d0df31ce09e5b7e401fcca3faa483dbc921" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] @@ -466,30 +495,36 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] name = "base64" -version = "0.21.4" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bincode" @@ -530,12 +565,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22" -[[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" @@ -590,41 +619,47 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.5.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" +checksum = "0cc8b54b395f2fcfbb3d90c47b01c7f444d94d05bdeb775811dec868ac3bbc26" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] name = "byteorder" -version = "1.4.3" +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 = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.5.0" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "cairo-sys-rs" @@ -644,8 +679,8 @@ checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ "bitflags 2.6.0", "log", - "polling 3.3.0", - "rustix 0.38.21", + "polling 3.7.3", + "rustix 0.38.37", "slab", "thiserror", ] @@ -657,7 +692,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" dependencies = [ "calloop", - "rustix 0.38.21", + "rustix 0.38.37", "wayland-backend", "wayland-client", ] @@ -670,12 +705,13 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.83" +version = "1.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" dependencies = [ "jobserver", "libc", + "shlex", ] [[package]] @@ -686,9 +722,9 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfg-expr" -version = "0.15.5" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03915af431787e6ffdcc74c645077518c6b6e01f80b761e0fbbfa288536311b3" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" dependencies = [ "smallvec", "target-lexicon", @@ -723,23 +759,23 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] name = "ciborium" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" dependencies = [ "ciborium-io", "ciborium-ll", @@ -748,18 +784,18 @@ dependencies = [ [[package]] name = "ciborium-io" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" [[package]] name = "ciborium-ll" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", - "half 1.8.2", + "half", ] [[package]] @@ -770,18 +806,18 @@ checksum = "7a0e87cdf78571d9fbeff16861c37a006cd718d2433dc6d5b80beaae367d899a" [[package]] name = "clap" -version = "4.4.11" +version = "4.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" +checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.4.11" +version = "4.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" +checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" dependencies = [ "anstyle", "clap_lex", @@ -789,15 +825,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "clipboard-win" -version = "5.3.1" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79f4473f5144e20d9aceaf2972478f06ddf687831eafeeb434fbaf0acc4144ad" +checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" dependencies = [ "error-code", ] @@ -867,9 +903,9 @@ dependencies = [ [[package]] name = "combine" -version = "4.6.6" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ "bytes", "memchr", @@ -902,20 +938,30 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "core-graphics" -version = "0.23.1" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "core-graphics-types", "foreign-types", "libc", @@ -928,24 +974,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "libc", ] [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -986,11 +1032,10 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ - "cfg-if", "crossbeam-utils", ] @@ -1015,9 +1060,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -1082,7 +1127,7 @@ dependencies = [ "egui_demo_lib", "egui_extras", "env_logger", - "image 0.25.0", + "image", ] [[package]] @@ -1101,9 +1146,9 @@ checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" [[package]] name = "deranged" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", ] @@ -1122,13 +1167,12 @@ dependencies = [ [[package]] name = "dify" version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0037c927ecea762372f44d75b7477c62a76f91932bfe85a52095b6e837c4390" +source = "git+https://github.com/jihchi/dify#fc4739edf4cf56534e3fc1b5b96d4cc599060d2b" dependencies = [ "anyhow", "colored", "getopts", - "image 0.24.9", + "image", "rayon", ] @@ -1189,9 +1233,9 @@ dependencies = [ [[package]] name = "downcast-rs" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dpi" @@ -1223,11 +1267,11 @@ dependencies = [ "egui-wgpu", "egui-winit", "egui_glow", - "glow 0.14.0", + "glow 0.14.1", "glutin", "glutin-winit", "home", - "image 0.25.0", + "image", "js-sys", "log", "objc2", @@ -1318,7 +1362,7 @@ dependencies = [ "egui_extras", "ehttp", "env_logger", - "image 0.25.0", + "image", "log", "poll-promise", "puffin", @@ -1357,7 +1401,7 @@ dependencies = [ "egui", "ehttp", "enum-map", - "image 0.25.0", + "image", "log", "mime_guess2", "puffin", @@ -1375,11 +1419,11 @@ dependencies = [ "document-features", "egui", "egui-winit", - "glow 0.14.0", + "glow 0.14.1", "glutin", "glutin-winit", "log", - "memoffset 0.9.0", + "memoffset 0.9.1", "puffin", "wasm-bindgen", "web-sys", @@ -1394,8 +1438,7 @@ dependencies = [ "dify", "egui", "egui-wgpu", - "image 0.24.9", - "image 0.25.0", + "image", "kittest", "pollster", "wgpu", @@ -1417,9 +1460,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "emath" @@ -1433,9 +1476,9 @@ dependencies = [ [[package]] name = "enum-map" -version = "2.6.3" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c188012f8542dee7b3996e44dd89461d64aa471b0a7c71a1ae2f595d259e96e5" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" dependencies = [ "enum-map-derive", "serde", @@ -1443,20 +1486,20 @@ dependencies = [ [[package]] name = "enum-map-derive" -version = "0.14.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04d0b288e3bb1d861c4403c1774a6f7a798781dfc519b3647df2a3dd4ae95f25" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] name = "enumflags2" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5998b4f30320c9d93aed72f63af821bfdac50465b75428fce77b48ec482c3939" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" dependencies = [ "enumflags2_derive", "serde", @@ -1464,31 +1507,31 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] name = "enumn" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ad8cef1d801a4686bfd8919f0b30eac4c8e48968c437a6405ded4fb5272d2b" +checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -1529,30 +1572,19 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] name = "error-code" -version = "3.0.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "281e452d3bad4005426416cdba5ccfd4f5c1280e10099e21db27f7c1c28347fc" +checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f" [[package]] name = "event-listener" @@ -1562,9 +1594,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e56284f00d94c1bc7fd3c77027b4623c88c1f53d8d2394c6199f2921dea325" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" dependencies = [ "concurrent-queue", "parking", @@ -1592,22 +1624,6 @@ 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 2.4.1", - "lebe", - "miniz_oxide", - "rayon-core", - "smallvec", - "zune-inflate", -] - [[package]] name = "fancy-regex" version = "0.11.0" @@ -1629,15 +1645,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fdeflate" -version = "0.3.0" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" +checksum = "d8090f921a24b04994d9929e204f50b498a33ea6ba559ffaa05e04f7ee7fb5ab" dependencies = [ "simd-adler32", ] @@ -1653,9 +1669,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.27" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ "crc32fast", "miniz_oxide", @@ -1667,15 +1683,6 @@ 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" @@ -1700,7 +1707,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] @@ -1711,24 +1718,24 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" @@ -1751,38 +1758,41 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ + "fastrand 2.1.1", "futures-core", + "futures-io", + "parking", "pin-project-lite", ] [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", "futures-io", @@ -1856,9 +1866,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -1877,9 +1887,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "gio-sys" @@ -1929,9 +1939,9 @@ dependencies = [ [[package]] name = "glow" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f865cbd94bd355b89611211e49508da98a1fce0ad755c1e8448fb96711b24528" +checksum = "2f4a888dbe8181a7535853469c21c67ca9a1cea9460b16808fc018ea9e55d248" dependencies = [ "js-sys", "slotmap", @@ -1941,14 +1951,14 @@ dependencies = [ [[package]] name = "glutin" -version = "0.32.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2491aa3090f682ddd920b184491844440fdd14379c7eef8f5bc10ef7fb3242fd" +checksum = "ec69412a0bf07ea7607e638b415447857a808846c2b685a43c8aa18bc6d5e499" dependencies = [ "bitflags 2.6.0", "cfg_aliases 0.2.1", "cgl", - "core-foundation", + "core-foundation 0.9.4", "dispatch", "glutin_egl_sys", "glutin_glx_sys", @@ -2045,7 +2055,7 @@ dependencies = [ "presser", "thiserror", "winapi", - "windows 0.51.1", + "windows 0.52.0", ] [[package]] @@ -2056,7 +2066,7 @@ checksum = "9c08c1f623a8d0b722b8b99f821eb0ba672a1618f0d3b16ddbee1cedd2dd8557" dependencies = [ "bitflags 2.6.0", "gpu-descriptor-types", - "hashbrown", + "hashbrown 0.14.5", ] [[package]] @@ -2086,12 +2096,6 @@ dependencies = [ "system-deps", ] -[[package]] -name = "half" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - [[package]] name = "half" version = "2.4.1" @@ -2104,14 +2108,20 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", ] +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + [[package]] name = "hassle-rs" version = "0.11.0" @@ -2129,9 +2139,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hello_world" @@ -2161,9 +2171,15 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "hex" @@ -2194,16 +2210,16 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core 0.51.1", + "windows-core 0.52.0", ] [[package]] @@ -2217,9 +2233,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -2227,30 +2243,12 @@ dependencies = [ [[package]] name = "image" -version = "0.24.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" -dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "exr", - "gif", - "jpeg-decoder", - "num-traits", - "png", - "qoi", - "tiff", -] - -[[package]] -name = "image" -version = "0.25.0" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9b4f005360d32e9325029b38ba47ebd7a56f3316df09249368939562d518645" +checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10" dependencies = [ "bytemuck", - "byteorder", + "byteorder-lite", "color_quant", "gif", "num-traits", @@ -2266,7 +2264,7 @@ dependencies = [ "eframe", "egui_extras", "env_logger", - "image 0.25.0", + "image", ] [[package]] @@ -2286,19 +2284,19 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.0", ] [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -2309,20 +2307,20 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "windows-sys 0.48.0", ] [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" dependencies = [ - "hermit-abi", - "rustix 0.38.21", - "windows-sys 0.48.0", + "hermit-abi 0.4.0", + "libc", + "windows-sys 0.52.0", ] [[package]] @@ -2336,9 +2334,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jni" @@ -2364,22 +2362,13 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] -[[package]] -name = "jpeg-decoder" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" -dependencies = [ - "rayon", -] - [[package]] name = "js-sys" version = "0.3.70" @@ -2439,26 +2428,20 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[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" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libloading" -version = "0.8.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-sys 0.48.0", + "windows-targets 0.52.6", ] [[package]] @@ -2473,10 +2456,14 @@ dependencies = [ ] [[package]] -name = "line-wrap" -version = "0.2.0" +name = "libredox" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd1bc4d24ad230d21fb898d1116b1801d7adfc449d42026475862ab48b11e70e" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", +] [[package]] name = "linked-hash-map" @@ -2492,9 +2479,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.11" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "litrs" @@ -2504,9 +2491,9 @@ checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2514,15 +2501,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lz4_flex" -version = "0.11.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea9b256699eda7b0387ffbc776dd625e28bde3918446381781245b7a50349d8" +checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5" [[package]] name = "malloc_buf" @@ -2535,15 +2522,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.3" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" -version = "0.9.0" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deaba38d7abf1d4cca21cc89e932e542ba2b9258664d2a9ef0e61512039c9375" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" dependencies = [ "libc", ] @@ -2559,9 +2546,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ "autocfg", ] @@ -2597,19 +2584,13 @@ dependencies = [ "unicase", ] -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", "simd-adler32", ] @@ -2629,9 +2610,9 @@ dependencies = [ [[package]] name = "naga" -version = "22.0.0" +version = "22.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09eeccb9b50f4f7839b214aa3e08be467159506a986c18e0702170ccf720a453" +checksum = "8bd5a652b6faf21496f2cfd88fc49989c8db0825d1f6746b1a71a6ede24a63ad" dependencies = [ "arrayvec", "bit-set 0.6.0", @@ -2706,43 +2687,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" [[package]] -name = "nom" -version = "7.1.3" +name = "num-conv" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "num_enum" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683751d591e6d81200c39fb0d1032608b77724f34114db54f571ff1317b337c0" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] @@ -2979,24 +2956,27 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" +dependencies = [ + "portable-atomic", +] [[package]] name = "oorandom" -version = "11.1.3" +version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "option-ext" @@ -3010,7 +2990,7 @@ version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" dependencies = [ - "libredox", + "libredox 0.0.2", ] [[package]] @@ -3025,9 +3005,9 @@ dependencies = [ [[package]] name = "owned_ttf_parser" -version = "0.19.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "706de7e2214113d63a8238d1910463cfce781129a6f263d13fdb09ff64355ba4" +checksum = "490d3a563d3122bf7c911a59b0add9389e5ec0f5f0c3ac6b91ff235a0e6a7f90" dependencies = [ "ttf-parser", ] @@ -3046,15 +3026,15 @@ dependencies = [ [[package]] name = "parking" -version = "2.1.1" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e52c774a4c39359c1d1c52e43f73dd91a75a614652c825408eec30c95a9b2067" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -3062,28 +3042,28 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall 0.5.7", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pico-args" @@ -3108,14 +3088,14 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -3125,40 +3105,39 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.1" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", - "fastrand 2.0.1", + "fastrand 2.1.1", "futures-io", ] [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "plist" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9d34169e64b3c7a80c8621a48adaf44e0cf62c78a9b25dd9dd35f1881a17cf9" +checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" dependencies = [ - "base64", + "base64 0.22.1", "indexmap", - "line-wrap", - "quick-xml 0.31.0", + "quick-xml 0.32.0", "serde", "time", ] [[package]] name = "png" -version = "0.17.10" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" +checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -3195,16 +3174,17 @@ dependencies = [ [[package]] name = "polling" -version = "3.3.0" +version = "3.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53b6af1f60f36f8c2ac2aad5459d75a5a9b4be1e8cdd40264f315d78193e531" +checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" dependencies = [ "cfg-if", "concurrent-queue", + "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.21", + "rustix 0.38.37", "tracing", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -3221,6 +3201,12 @@ dependencies = [ "env_logger", ] +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + [[package]] name = "powerfmt" version = "0.2.0" @@ -3229,9 +3215,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "presser" @@ -3246,34 +3235,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit 0.22.22", ] [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "profiling" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f0f7f43585c34e4fdd7497d746bc32e14458cf11c69341cc0587b1d825dde42" +checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" [[package]] name = "puffin" -version = "0.19.0" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f76ad4bb049fded4e572df72cbb6381ff5d1f41f85c3a04b56e4eca287a02f" +checksum = "fa9dae7b05c02ec1a6bc9bcf20d8bc64a7dcbf57934107902a872014899b741f" dependencies = [ "anyhow", "bincode", "byteorder", "cfg-if", + "itertools", "lz4_flex", "once_cell", "parking_lot", @@ -3282,9 +3281,9 @@ dependencies = [ [[package]] name = "puffin_http" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4936c085e48efc86f6d96609dc5086d1d236afe3ec4676f09b157a4f4be83ff6" +checksum = "739a3c7f56604713b553d7addd7718c226e88d598979ae3450320800bd0e9810" dependencies = [ "anyhow", "crossbeam-channel", @@ -3304,38 +3303,29 @@ dependencies = [ "puffin_http", ] -[[package]] -name = "qoi" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" -dependencies = [ - "bytemuck", -] - [[package]] name = "quick-xml" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" dependencies = [ "memchr", ] [[package]] name = "quick-xml" -version = "0.34.0" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f24d770aeca0eacb81ac29dfbc55ebcc09312fdd1f8bbecdc7e4a84e000e3b4" +checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" dependencies = [ "memchr", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -3384,9 +3374,9 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "rayon" -version = "1.8.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -3410,47 +3400,38 @@ checksum = "3b42e27ef78c35d3998403c1d26f3efd9e135d3e5121b0a4845cc5cc27547f4f" [[package]] name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", - "redox_syscall 0.2.16", + "libredox 0.1.3", "thiserror", ] [[package]] name = "regex" -version = "1.9.5" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -3460,9 +3441,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -3471,9 +3452,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "renderdoc-sys" @@ -3520,9 +3501,9 @@ dependencies = [ [[package]] name = "rgb" -version = "0.8.36" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20ec2d3e3fc7a92ced357df9cebd5a10b6fb2aa1ee797bf7e9ce2f17dffc8f59" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" dependencies = [ "bytemuck", ] @@ -3548,7 +3529,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ - "base64", + "base64 0.21.7", "bitflags 2.6.0", "serde", "serde_derive", @@ -3562,9 +3543,9 @@ checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -3574,9 +3555,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.37.25" +version = "0.37.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4eb579851244c2c03e7c24f501c3432bed80b8f720af1d6e5b0e0f01555a035" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" dependencies = [ "bitflags 1.3.2", "errno", @@ -3588,44 +3569,54 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys 0.4.11", - "windows-sys 0.48.0", + "linux-raw-sys 0.4.14", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.21.11" +version = "0.23.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" +checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" dependencies = [ "log", + "once_cell", "ring", + "rustls-pki-types", "rustls-webpki", - "sct", + "subtle", + "zeroize", ] +[[package]] +name = "rustls-pki-types" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" + [[package]] name = "rustls-webpki" -version = "0.101.7" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", + "rustls-pki-types", "untrusted", ] [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -3654,17 +3645,7 @@ version = "0.1.0" dependencies = [ "eframe", "env_logger", - "image 0.25.0", -] - -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", + "image", ] [[package]] @@ -3682,51 +3663,52 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.188" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_repr" -version = "0.1.16" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -3751,11 +3733,17 @@ dependencies = [ "digest", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -3792,18 +3780,18 @@ dependencies = [ [[package]] name = "slotmap" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" dependencies = [ "version_check", ] [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "smithay-client-toolkit" @@ -3818,7 +3806,7 @@ dependencies = [ "libc", "log", "memmap2", - "rustix 0.38.21", + "rustix 0.38.37", "thiserror", "wayland-backend", "wayland-client", @@ -3843,18 +3831,18 @@ dependencies = [ [[package]] name = "smol_str" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" dependencies = [ "serde", ] [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", @@ -3865,9 +3853,6 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] [[package]] name = "spirv" @@ -3893,6 +3878,12 @@ dependencies = [ "float-cmp", ] +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "svgtypes" version = "0.13.0" @@ -3916,9 +3907,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -3927,9 +3918,9 @@ dependencies = [ [[package]] name = "syntect" -version = "5.1.0" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02b4b303bf8d08bfeb0445cba5068a3d306b6baece1d5582171a9bf49188f91" +checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1" dependencies = [ "bincode", "bitflags 1.3.2", @@ -3940,6 +3931,7 @@ dependencies = [ "plist", "regex-syntax", "serde", + "serde_derive", "serde_json", "thiserror", "walkdir", @@ -3948,9 +3940,9 @@ dependencies = [ [[package]] name = "system-deps" -version = "6.1.1" +version = "6.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30c2de8a4d8f4b823d634affc9cd2a74ec98c53a756f317e529a48046cbf71f3" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" dependencies = [ "cfg-expr", "heck", @@ -3961,21 +3953,21 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.11" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.8.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", - "fastrand 2.0.1", - "redox_syscall 0.3.5", - "rustix 0.38.21", - "windows-sys 0.48.0", + "fastrand 2.1.1", + "once_cell", + "rustix 0.38.37", + "windows-sys 0.59.0", ] [[package]] @@ -4030,43 +4022,33 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", -] - -[[package]] -name = "tiff" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" -dependencies = [ - "flate2", - "jpeg-decoder", - "weezl", + "syn 2.0.79", ] [[package]] name = "time" -version = "0.3.30" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -4081,18 +4063,19 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] [[package]] name = "tiny-skia" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a067b809476893fce6a254cf285850ff69c847e6cfbade6a20b655b6c7e80d" +checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" dependencies = [ "arrayref", "arrayvec", @@ -4105,9 +4088,9 @@ dependencies = [ [[package]] name = "tiny-skia-path" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de35e8a90052baaaf61f171680ac2f8e925a1e43ea9d2e3a00514772250e541" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" dependencies = [ "arrayref", "bytemuck", @@ -4126,9 +4109,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -4141,21 +4124,21 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "toml" -version = "0.7.8" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.22.22", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -4165,12 +4148,23 @@ name = "toml_edit" version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.20", ] [[package]] @@ -4192,7 +4186,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] @@ -4206,9 +4200,9 @@ dependencies = [ [[package]] name = "ttf-parser" -version = "0.19.1" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a464a4b34948a5f67fddd2b823c62d9d92e44be75058b99939eae6c5b6960b33" +checksum = "5be21190ff5d38e8b4a2d3b6a3ae57f612cc39c96e83cedeaf7abc338a8bac4a" [[package]] name = "type-map" @@ -4227,10 +4221,11 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "uds_windows" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce65604324d3cce9b966701489fbd0cf318cb1f7bd9dd07ac9a4ee6fb791930d" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" dependencies = [ + "memoffset 0.9.1", "tempfile", "winapi", ] @@ -4246,42 +4241,42 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "unicode_names2" @@ -4297,25 +4292,25 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.8.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3" +checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a" dependencies = [ - "base64", + "base64 0.22.1", "flate2", "log", "once_cell", "rustls", - "rustls-webpki", + "rustls-pki-types", "url", "webpki-roots", ] [[package]] name = "url" -version = "2.4.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -4336,7 +4331,7 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b0a51b72ab80ca511d126b77feeeb4fb1e972764653e61feac30adc161a756" dependencies = [ - "base64", + "base64 0.21.7", "log", "pico-args", "usvg-parser", @@ -4376,27 +4371,27 @@ dependencies = [ [[package]] name = "version-compare" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "waker-fn" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -4430,15 +4425,15 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" dependencies = [ "cfg-if", "js-sys", @@ -4464,7 +4459,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4477,13 +4472,13 @@ checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "wayland-backend" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90e11ce2ca99c97b940ee83edbae9da2d56a08f9ea8158550fd77fa31722993" +checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" dependencies = [ "cc", "downcast-rs", - "rustix 0.38.21", + "rustix 0.38.37", "scoped-tls", "smallvec", "wayland-sys", @@ -4491,12 +4486,12 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.5" +version = "0.31.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e321577a0a165911bdcfb39cf029302479d7527b517ee58ab0f6ad09edf0943" +checksum = "e3f45d1222915ef1fd2057220c1d9d9624b7654443ea35c3877f7a52bd0a5a2d" dependencies = [ "bitflags 2.6.0", - "rustix 0.38.21", + "rustix 0.38.37", "wayland-backend", "wayland-scanner", ] @@ -4514,20 +4509,20 @@ dependencies = [ [[package]] name = "wayland-cursor" -version = "0.31.5" +version = "0.31.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef9489a8df197ebf3a8ce8a7a7f0a2320035c3743f3c1bd0bdbccf07ce64f95" +checksum = "3a94697e66e76c85923b0d28a0c251e8f0666f58fc47d316c0f4da6da75d37cb" dependencies = [ - "rustix 0.38.21", + "rustix 0.38.37", "wayland-client", "xcursor", ] [[package]] name = "wayland-protocols" -version = "0.32.3" +version = "0.32.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62989625a776e827cc0f15d41444a3cea5205b963c3a25be48ae1b52d6b4daaa" +checksum = "2b5755d77ae9040bb872a25026555ce4cb0ae75fd923e90d25fba07d81057de0" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -4537,9 +4532,9 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f79f2d57c7fcc6ab4d602adba364bf59a5c24de57bd194486bf9b8360e06bfc4" +checksum = "8a0a41a6875e585172495f7a96dfa42ca7e0213868f4f15c313f7c33221a7eff" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -4550,9 +4545,9 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd993de54a40a40fbe5601d9f1fbcaef0aebcc5fda447d7dc8f6dcbaae4f8953" +checksum = "dad87b5fd1b1d3ca2f792df8f686a2a11e3fe1077b71096f7a175ab699f89109" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -4563,20 +4558,20 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.4" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7b56f89937f1cf2ee1f1259cf2936a17a1f45d8f0aa1019fae6d470d304cfa6" +checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" dependencies = [ "proc-macro2", - "quick-xml 0.34.0", + "quick-xml 0.36.2", "quote", ] [[package]] name = "wayland-sys" -version = "0.31.4" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43676fe2daf68754ecf1d72026e4e6c15483198b5d24e888b74d3f22f887a148" +checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" dependencies = [ "dlib", "log", @@ -4606,26 +4601,30 @@ dependencies = [ [[package]] name = "webbrowser" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b6f804e41d0852e16d2eaee61c7e4f7d3e8ffdb7b8ed85886aeb0791fe9fcd" +checksum = "2e5f07fb9bc8de2ddfe6b24a71a75430673fd679e568c48b52716cef1cfae923" dependencies = [ - "core-foundation", + "block2", + "core-foundation 0.10.0", "home", "jni", "log", "ndk-context", - "objc", - "raw-window-handle 0.5.2", + "objc2", + "objc2-foundation", "url", "web-sys", ] [[package]] name = "webpki-roots" -version = "0.25.2" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +dependencies = [ + "rustls-pki-types", +] [[package]] name = "weezl" @@ -4738,9 +4737,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" [[package]] name = "winapi" @@ -4760,11 +4759,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -4775,74 +4774,85 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.51.1" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ - "windows-core 0.51.1", - "windows-targets 0.48.5", + "windows-core 0.52.0", + "windows-targets 0.52.6", ] [[package]] name = "windows" -version = "0.54.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-core 0.54.0", - "windows-implement", - "windows-interface", - "windows-targets 0.52.5", + "windows-core 0.58.0", + "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.51.1" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.54.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ + "windows-implement", + "windows-interface", "windows-result", - "windows-targets 0.52.5", + "windows-strings", + "windows-targets 0.52.6", ] [[package]] name = "windows-implement" -version = "0.53.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942ac266be9249c84ca862f0a164a39533dc2f6f33dc98ec89c8da99b82ea0bd" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] name = "windows-interface" -version = "0.53.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da33557140a288fae4e1d5f8873aaf9eb6613a9cf82c3e070223ff177f598b60" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] name = "windows-result" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", ] [[package]] @@ -4869,7 +4879,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -4904,18 +4923,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -4932,9 +4951,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -4950,9 +4969,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -4968,15 +4987,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -4992,9 +5011,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -5010,9 +5029,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -5028,9 +5047,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -5046,9 +5065,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winit" @@ -5065,7 +5084,7 @@ dependencies = [ "calloop", "cfg_aliases 0.2.1", "concurrent-queue", - "core-foundation", + "core-foundation 0.9.4", "core-graphics", "cursor-icon", "dpi", @@ -5082,7 +5101,7 @@ dependencies = [ "pin-project", "raw-window-handle 0.6.2", "redox_syscall 0.4.1", - "rustix 0.38.21", + "rustix 0.38.37", "sctk-adwaita", "smithay-client-toolkit", "smol_str", @@ -5104,9 +5123,18 @@ dependencies = [ [[package]] name = "winnow" -version = "0.5.15" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -5124,42 +5152,39 @@ dependencies = [ [[package]] name = "x11rb" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a" +checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" dependencies = [ "as-raw-xcb-connection", "gethostname", "libc", "libloading", "once_cell", - "rustix 0.38.21", + "rustix 0.38.37", "x11rb-protocol", ] [[package]] name = "x11rb-protocol" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34" +checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" [[package]] name = "xcursor" -version = "0.3.4" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" -dependencies = [ - "nom", -] +checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" [[package]] name = "xdg-home" -version = "1.0.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2769203cd13a0c6015d515be729c526d041e9cf2c0cc478d57faee85f40c6dcd" +checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" dependencies = [ - "nix", - "winapi", + "libc", + "windows-sys 0.59.0", ] [[package]] @@ -5177,15 +5202,15 @@ 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" -version = "0.8.19" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" +checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26" [[package]] name = "xmlwriter" @@ -5208,15 +5233,15 @@ dependencies = [ [[package]] name = "zbus" -version = "3.14.1" +version = "3.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31de390a2d872e4cd04edd71b425e29853f786dc99317ed72d73d6fcf5ebb948" +checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" dependencies = [ "async-broadcast", "async-executor", "async-fs", - "async-io", - "async-lock", + "async-io 1.13.0", + "async-lock 2.8.0", "async-process", "async-recursion", "async-task", @@ -5249,11 +5274,11 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "3.14.1" +version = "3.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d1794a946878c0e807f55a397187c11fc7a038ba5d868e7db4f3bd7760bc9d" +checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "regex", @@ -5263,9 +5288,9 @@ dependencies = [ [[package]] name = "zbus_names" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb80bb776dbda6e23d705cf0123c3b95df99c4ebeaec6c2599d4a5419902b4a9" +checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d" dependencies = [ "serde", "static_assertions", @@ -5274,53 +5299,51 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.31" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.31" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.79", ] [[package]] -name = "zune-core" -version = "0.4.12" +name = "zeroize" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] -name = "zune-inflate" -version = "0.2.54" +name = "zune-core" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" -dependencies = [ - "simd-adler32", -] +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" [[package]] name = "zune-jpeg" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448" +checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768" dependencies = [ "zune-core", ] [[package]] name = "zvariant" -version = "3.15.0" +version = "3.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44b291bee0d960c53170780af148dca5fa260a63cdd24f1962fa82e03e53338c" +checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" dependencies = [ "byteorder", "enumflags2", @@ -5332,11 +5355,11 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "3.15.0" +version = "3.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934d7a7dfc310d6ee06c87ffe88ef4eca7d3e37bb251dece2ef93da8f17d8ecd" +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 aec446d822a..0bd817bf367 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -265,3 +265,7 @@ unwrap_used = "allow" # TODO(emilk): We really wanna warn on thi manual_range_contains = "allow" # this one is just worse imho self_named_module_files = "allow" # Disabled waiting on https://github.com/rust-lang/rust-clippy/issues/9602 significant_drop_tightening = "allow" # Too many false positives + +[patch.crates-io] +# TODO(lucasmerlin): Remove once dify releases a new version +dify = { git = "https://github.com/jihchi/dify"} diff --git a/crates/egui_kittest/Cargo.toml b/crates/egui_kittest/Cargo.toml index 75185b4ae74..da07f5f2ad4 100644 --- a/crates/egui_kittest/Cargo.toml +++ b/crates/egui_kittest/Cargo.toml @@ -9,7 +9,9 @@ version.workspace = true [features] wgpu = ["dep:egui-wgpu", "dep:pollster", "dep:image"] -snapshot = ["dep:dify", "dep:dify_image"] +snapshot = ["dep:dify"] + +default = ["image?/png"] [dependencies] accesskit_consumer = "0.24.0" @@ -22,9 +24,7 @@ pollster = { version = "0.3", optional = true } image = { workspace = true, optional = true } # snapshot dependencies -dify = { version = "0.6.0", optional = true } -# unfortunately dify hasn't been updated image to 0.25 yet -dify_image = { version = "0.24", package = "image", optional = true } +dify = { version = "0.6.0", optional = true, default-features = false } [dev-dependencies] wgpu = { workspace = true, features = ["metal"] } diff --git a/crates/egui_kittest/src/snapshot.rs b/crates/egui_kittest/src/snapshot.rs index 80cc78b947b..62b8cdeddc9 100644 --- a/crates/egui_kittest/src/snapshot.rs +++ b/crates/egui_kittest/src/snapshot.rs @@ -22,10 +22,6 @@ impl Display for SnapshotError { /// # Errors /// Returns a [`SnapshotError`] if the image does not match the snapshot. pub fn try_image_snapshot(current: image::RgbaImage, name: &str) -> Result<(), SnapshotError> { - let current = - dify_image::RgbaImage::from_raw(current.width(), current.height(), current.into_raw()) - .unwrap(); - let snapshots_path = Path::new("tests/snapshots"); let path = snapshots_path.join(format!("{name}.png")); @@ -38,7 +34,7 @@ pub fn try_image_snapshot(current: image::RgbaImage, name: &str) -> Result<(), S current.save(¤t_path).unwrap(); - let previous = match dify_image::open(&path) { + let previous = match image::open(&path) { Ok(image) => image.to_rgba8(), Err(err) => { println!("Error opening image: {err}"); From 80381ab75faf8c446d9a612b528957b1b252de77 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Fri, 4 Oct 2024 17:13:53 +0200 Subject: [PATCH 16/47] Fix lints --- crates/egui_demo_lib/src/demo/demo_app_windows.rs | 13 +++++-------- crates/egui_kittest/src/lib.rs | 4 +++- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/crates/egui_demo_lib/src/demo/demo_app_windows.rs b/crates/egui_demo_lib/src/demo/demo_app_windows.rs index 7767a5deaf0..54996b10da7 100644 --- a/crates/egui_demo_lib/src/demo/demo_app_windows.rs +++ b/crates/egui_demo_lib/src/demo/demo_app_windows.rs @@ -396,9 +396,8 @@ mod tests { for mut demo in demos.demos { let name = demo .name() - .split_once(" ") - .map(|(_, name)| name) - .unwrap_or(demo.name()); + .split_once(' ') + .map_or(demo.name(), |(_, name)| name); let mut harness = Harness::new(|ctx| { demo.show(ctx, &mut true); @@ -410,7 +409,7 @@ mod tests { harness.run(); let window = harness.node().children().next().unwrap(); - // TODO: Windows should probably have a label? + // TODO(lucasmerlin): Windows should probably have a label? //let window = harness.get_by_name(name); let size = window.raw_bounds().expect("window bounds").size(); @@ -421,14 +420,12 @@ mod tests { harness.run(); let image = TestRenderer::new().render(&harness); - let result = try_image_snapshot(image, &format!("demos/{}", name)); + let result = try_image_snapshot(image, &format!("demos/{name}")); if let Err(err) = result { errors.push(err); } } - if !errors.is_empty() { - panic!("Errors: {:#?}", errors); - } + assert!(errors.is_empty(), "Errors: {errors:#?}"); } } diff --git a/crates/egui_kittest/src/lib.rs b/crates/egui_kittest/src/lib.rs index 2e99bf45fc1..f4afb7b6313 100644 --- a/crates/egui_kittest/src/lib.rs +++ b/crates/egui_kittest/src/lib.rs @@ -47,11 +47,13 @@ impl<'a> Harness<'a> { } } + #[inline] pub fn with_size(mut self, size: Vec2) -> Self { self.input.screen_rect = Some(Rect::from_min_size(Pos2::ZERO, size)); self } + #[inline] pub fn with_dpi(mut self, dpi: f32) -> Self { self.input .viewports @@ -165,7 +167,7 @@ impl<'a> Harness<'a> { .push(Event::AccessKitActionRequest(action)); } - // TODO: SetValue is currently not supported by egui + // TODO(lucasmerlin): SetValue is currently not supported by egui // pub fn set_text(&mut self, id: NodeId, text: &str) { // let action = egui::accesskit::ActionRequest { // target: id, From 7cbf5571000b3052c5103f2fb0253f9734ecc955 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Fri, 4 Oct 2024 17:14:07 +0200 Subject: [PATCH 17/47] Try if tests fail on style change --- crates/egui_demo_lib/src/demo/widget_gallery.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/egui_demo_lib/src/demo/widget_gallery.rs b/crates/egui_demo_lib/src/demo/widget_gallery.rs index b21425f0ce6..1f1f161dab9 100644 --- a/crates/egui_demo_lib/src/demo/widget_gallery.rs +++ b/crates/egui_demo_lib/src/demo/widget_gallery.rs @@ -62,6 +62,7 @@ impl crate::Demo for WidgetGallery { impl crate::View for WidgetGallery { fn ui(&mut self, ui: &mut egui::Ui) { ui.visuals_mut().widgets.inactive.rounding = 0.0.into(); + ui.visuals_mut().extreme_bg_color = egui::Color32::RED; let mut ui_builder = egui::UiBuilder::new(); if !self.enabled { From d478162354cf25ac31994df7f844d5c4fd01a57b Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Fri, 4 Oct 2024 17:20:21 +0200 Subject: [PATCH 18/47] Upload snapshots as artifacts --- .github/workflows/rust.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index b0989617fcb..945d0b37f4d 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -242,3 +242,9 @@ jobs: - name: Run tests # TODO: Enable --all-features (currently this breaks the rendering in the tests) run: cargo test + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: test-results + path: "**/tests/snapshots" From 10c076767adf6c87c1160c70189b390e45d29906 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Fri, 4 Oct 2024 17:37:05 +0200 Subject: [PATCH 19/47] Fail tests on missing snapshot --- .../src/demo/demo_app_windows.rs | 2 +- .../egui_demo_lib/src/demo/widget_gallery.rs | 2 +- crates/egui_kittest/src/snapshot.rs | 33 ++++++++++--------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/crates/egui_demo_lib/src/demo/demo_app_windows.rs b/crates/egui_demo_lib/src/demo/demo_app_windows.rs index 54996b10da7..621471ab45e 100644 --- a/crates/egui_demo_lib/src/demo/demo_app_windows.rs +++ b/crates/egui_demo_lib/src/demo/demo_app_windows.rs @@ -420,7 +420,7 @@ mod tests { harness.run(); let image = TestRenderer::new().render(&harness); - let result = try_image_snapshot(image, &format!("demos/{name}")); + let result = try_image_snapshot(&image, &format!("demos/{name}")); if let Err(err) = result { errors.push(err); } diff --git a/crates/egui_demo_lib/src/demo/widget_gallery.rs b/crates/egui_demo_lib/src/demo/widget_gallery.rs index 1f1f161dab9..6ac28fcd5b0 100644 --- a/crates/egui_demo_lib/src/demo/widget_gallery.rs +++ b/crates/egui_demo_lib/src/demo/widget_gallery.rs @@ -314,6 +314,6 @@ mod tests { let image = TestRenderer::new().render(&harness); - image_snapshot(image, "widget_gallery"); + image_snapshot(&image, "widget_gallery"); } } diff --git a/crates/egui_kittest/src/snapshot.rs b/crates/egui_kittest/src/snapshot.rs index 62b8cdeddc9..6fd1372e00e 100644 --- a/crates/egui_kittest/src/snapshot.rs +++ b/crates/egui_kittest/src/snapshot.rs @@ -2,18 +2,23 @@ use std::fmt::Display; use std::path::{Path, PathBuf}; #[derive(Debug)] -pub struct SnapshotError { - pub diff: i32, - pub diff_path: PathBuf, +pub enum SnapshotError { + Diff { diff: i32, diff_path: PathBuf }, + MissingSnapshot { path: PathBuf }, } - impl Display for SnapshotError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "Image did not match snapshot. Diff: {}, {:?}", - self.diff, self.diff_path - ) + match self { + Self::Diff { diff, diff_path } => { + write!( + f, + "Image did not match snapshot. Diff: {diff}, {diff_path:?}" + ) + } + Self::MissingSnapshot { path } => { + write!(f, "Missing snapshot: {path:?}") + } + } } } @@ -21,7 +26,7 @@ impl Display for SnapshotError { /// /// # Errors /// Returns a [`SnapshotError`] if the image does not match the snapshot. -pub fn try_image_snapshot(current: image::RgbaImage, name: &str) -> Result<(), SnapshotError> { +pub fn try_image_snapshot(current: &image::RgbaImage, name: &str) -> Result<(), SnapshotError> { let snapshots_path = Path::new("tests/snapshots"); let path = snapshots_path.join(format!("{name}.png")); @@ -30,8 +35,6 @@ pub fn try_image_snapshot(current: image::RgbaImage, name: &str) -> Result<(), S let diff_path = snapshots_path.join(format!("{name}.diff.png")); let current_path = snapshots_path.join(format!("{name}.new.png")); - std::fs::create_dir_all("tests/snapshots").ok(); - current.save(¤t_path).unwrap(); let previous = match image::open(&path) { @@ -41,7 +44,7 @@ pub fn try_image_snapshot(current: image::RgbaImage, name: &str) -> Result<(), S println!("Saving current image as {path:?}"); current.save(&path).unwrap(); - current.clone() + return Err(SnapshotError::MissingSnapshot { path }); } }; @@ -54,7 +57,7 @@ pub fn try_image_snapshot(current: image::RgbaImage, name: &str) -> Result<(), S current.save(&path).unwrap(); println!("Updated snapshot: {path:?}"); } else { - return Err(SnapshotError { diff, diff_path }); + return Err(SnapshotError::Diff { diff, diff_path }); } } else { // Delete old diff if it exists @@ -68,7 +71,7 @@ pub fn try_image_snapshot(current: image::RgbaImage, name: &str) -> Result<(), S /// /// # Panics /// Panics if the image does not match the snapshot. -pub fn image_snapshot(current: image::RgbaImage, name: &str) { +pub fn image_snapshot(current: &image::RgbaImage, name: &str) { match try_image_snapshot(current, name) { Ok(_) => {} Err(err) => { From b4f7129864103f5df06d0da6b8428f7e167ec475 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Fri, 4 Oct 2024 17:47:51 +0200 Subject: [PATCH 20/47] Checkout with lfs --- .github/workflows/rust.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 945d0b37f4d..0f048894d01 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -232,6 +232,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + lfs: 'true' - uses: dtolnay/rust-toolchain@master with: toolchain: 1.76.0 From b00315bf025e1f546d3fc72b993cbd3f52b3ffa4 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Fri, 4 Oct 2024 17:54:30 +0200 Subject: [PATCH 21/47] Always upload artifacts --- .github/workflows/rust.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 0f048894d01..8837442cdcf 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -247,6 +247,7 @@ jobs: - name: Upload artifacts uses: actions/upload-artifact@v4 + if: always() with: name: test-results path: "**/tests/snapshots" From 2ac2d85ae34d0e2795d3a2f4b84df41bd476f327 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Fri, 4 Oct 2024 18:31:16 +0200 Subject: [PATCH 22/47] Update dify --- Cargo.lock | 1350 +++++++++++++++----------------- Cargo.toml | 4 - crates/egui_kittest/Cargo.toml | 2 +- 3 files changed, 611 insertions(+), 745 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4e59b5c976c..21fa0094360 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ab_glyph" -version = "0.2.28" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79faae4620f45232f599d9bc7b290f88247a0834162c4495ab2f02d60004adfb" +checksum = "5110f1c78cf582855d895ecd0746b653db010cec6d9f5575293f27934d980a39" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -20,9 +20,9 @@ checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" [[package]] name = "accesskit" -version = "0.16.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef7442f1f520649b8e11ee3af6caeec24123fed4b63bc36a85b67308d8514fdf" +checksum = "e4700bdc115b306d6c43381c344dc307f03b7f0460c304e4892c309930322bd7" dependencies = [ "enumn", "serde", @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "accesskit_atspi_common" -version = "0.9.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab9d2b364833ae6e2eae9359a374108b1c5488877a9f43d26f0cb700560af9ae" +checksum = "a1de72dc7093910a1284cef784b6b143bab0a34d67f6178e4fc3aaaf29a09f8b" dependencies = [ "accesskit", "accesskit_consumer", @@ -44,9 +44,9 @@ dependencies = [ [[package]] name = "accesskit_consumer" -version = "0.24.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7072a4f17b8e7440a88ce08eb657d1ec84be061b1a94be78f9699aa18e583885" +checksum = "fe3a07a32ab5837ad83db3230ac490c8504c2cd5b90ac8c00db6535f6ed65d0b" dependencies = [ "accesskit", "immutable-chunkmap", @@ -54,9 +54,9 @@ dependencies = [ [[package]] name = "accesskit_macos" -version = "0.17.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "716698a26b5113812348a9f99ec250cb7b4154c89a83bc55a8b7d8678a1ecf02" +checksum = "a189d159c153ae0fce5f9eefdcfec4a27885f453ce5ef0ccf078f72a73c39d34" dependencies = [ "accesskit", "accesskit_consumer", @@ -68,9 +68,9 @@ dependencies = [ [[package]] name = "accesskit_unix" -version = "0.12.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd552c7bae0cd2ba1131fb0cedad32f8915743e0ed086f989fd706431641f56e" +checksum = "b76c448cfd96d16131a9ad3ab786d06951eb341cdac1db908978ab010245a19d" dependencies = [ "accesskit", "accesskit_atspi_common", @@ -86,23 +86,22 @@ dependencies = [ [[package]] name = "accesskit_windows" -version = "0.23.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d134e9eb16c98b35d1ff7056a027d7482968bcab0d8b625e7e72895b748d705" +checksum = "682d8c4fb425606f97408e7577793f32e96310b646fa77662eb4216293eddc7f" dependencies = [ "accesskit", "accesskit_consumer", "paste", "static_assertions", - "windows 0.58.0", - "windows-core 0.58.0", + "windows 0.54.0", ] [[package]] name = "accesskit_winit" -version = "0.22.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "156c5066e7b3ac9a82fb80fc18dcee42f79967c47e0ff431bae23e7ee8412a83" +checksum = "9afbd6d598b7c035639ad2b664aa0edc94c93dc1fc3ebb4b40d8a95fcd43ffac" dependencies = [ "accesskit", "accesskit_macos", @@ -114,18 +113,18 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.24.2" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] [[package]] -name = "adler2" -version = "2.0.0" +name = "adler" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" @@ -143,18 +142,18 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" dependencies = [ "memchr", ] [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "android-activity" @@ -206,21 +205,21 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "arboard" -version = "3.4.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df099ccb16cd014ff054ac1bf392c67feeef57164b05c42f037cd40f5d4357f4" +checksum = "9fb4009533e8ff8f1450a5bcbc30f4242a1d34442221f72314bea1f5dc9c7f89" dependencies = [ "clipboard-win", "log", @@ -233,21 +232,21 @@ dependencies = [ [[package]] name = "arrayref" -version = "0.3.9" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "as-raw-xcb-connection" -version = "1.0.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" +checksum = "2d5f312b0a56c5cdf967c0aeb67f6289603354951683bc97ddc595ab974ba9aa" [[package]] name = "ash" @@ -282,14 +281,15 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.13.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +checksum = "78f2db9467baa66a700abce2a18c5ad793f6f83310aca1284796fc3921d113fd" dependencies = [ + "async-lock", "async-task", "concurrent-queue", - "fastrand 2.1.1", - "futures-lite 2.3.0", + "fastrand 2.0.1", + "futures-lite 1.13.0", "slab", ] @@ -299,7 +299,7 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" dependencies = [ - "async-lock 2.8.0", + "async-lock", "autocfg", "blocking", "futures-lite 1.13.0", @@ -311,7 +311,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" dependencies = [ - "async-lock 2.8.0", + "async-lock", "autocfg", "cfg-if", "concurrent-queue", @@ -319,31 +319,12 @@ dependencies = [ "log", "parking", "polling 2.8.0", - "rustix 0.37.27", + "rustix 0.37.25", "slab", "socket2", "waker-fn", ] -[[package]] -name = "async-io" -version = "2.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" -dependencies = [ - "async-lock 3.4.0", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite 2.3.0", - "parking", - "polling 3.7.3", - "rustix 0.38.37", - "slab", - "tracing", - "windows-sys 0.59.0", -] - [[package]] name = "async-lock" version = "2.8.0" @@ -353,78 +334,68 @@ dependencies = [ "event-listener 2.5.3", ] -[[package]] -name = "async-lock" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" -dependencies = [ - "event-listener 5.3.1", - "event-listener-strategy", - "pin-project-lite", -] - [[package]] name = "async-process" -version = "1.8.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +checksum = "bf012553ce51eb7aa6dc2143804cc8252bd1cb681a1c5cb7fa94ca88682dee1d" dependencies = [ - "async-io 1.13.0", - "async-lock 2.8.0", + "async-io", + "async-lock", "async-signal", "blocking", "cfg-if", - "event-listener 3.1.0", + "event-listener 3.0.0", "futures-lite 1.13.0", - "rustix 0.38.37", + "rustix 0.38.21", "windows-sys 0.48.0", ] [[package]] name = "async-recursion" -version = "1.1.1" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] name = "async-signal" -version = "0.2.10" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" +checksum = "4af361a844928cb7d36590d406709473a1b574f443094422ef166daa3b493208" dependencies = [ - "async-io 2.3.4", - "async-lock 3.4.0", + "async-io", + "async-lock", "atomic-waker", "cfg-if", + "concurrent-queue", "futures-core", "futures-io", - "rustix 0.38.37", + "libc", "signal-hook-registry", "slab", - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] name = "async-task" -version = "4.7.1" +version = "4.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" +checksum = "b9441c6b2fe128a7c2bf680a44c34d0df31ce09e5b7e401fcca3faa483dbc921" [[package]] name = "async-trait" -version = "0.1.83" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] @@ -495,36 +466,30 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.4.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", + "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", ] [[package]] name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64" -version = "0.22.1" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "bincode" @@ -619,35 +584,35 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytemuck" -version = "1.18.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.7.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc8b54b395f2fcfbb3d90c47b01c7f444d94d05bdeb775811dec868ac3bbc26" +checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] name = "byteorder" -version = "1.5.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "byteorder-lite" @@ -657,9 +622,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.7.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cairo-sys-rs" @@ -679,8 +644,8 @@ checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ "bitflags 2.6.0", "log", - "polling 3.7.3", - "rustix 0.38.37", + "polling 3.3.0", + "rustix 0.38.21", "slab", "thiserror", ] @@ -692,7 +657,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" dependencies = [ "calloop", - "rustix 0.38.37", + "rustix 0.38.21", "wayland-backend", "wayland-client", ] @@ -705,13 +670,12 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.24" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", "libc", - "shlex", ] [[package]] @@ -722,9 +686,9 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfg-expr" -version = "0.15.8" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +checksum = "03915af431787e6ffdcc74c645077518c6b6e01f80b761e0fbbfa288536311b3" dependencies = [ "smallvec", "target-lexicon", @@ -759,23 +723,23 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] name = "ciborium" -version = "0.2.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" dependencies = [ "ciborium-io", "ciborium-ll", @@ -784,15 +748,15 @@ dependencies = [ [[package]] name = "ciborium-io" -version = "0.2.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" +checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" [[package]] name = "ciborium-ll" -version = "0.2.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" dependencies = [ "ciborium-io", "half", @@ -806,18 +770,18 @@ checksum = "7a0e87cdf78571d9fbeff16861c37a006cd718d2433dc6d5b80beaae367d899a" [[package]] name = "clap" -version = "4.5.19" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" +checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.19" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" +checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" dependencies = [ "anstyle", "clap_lex", @@ -825,15 +789,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "clipboard-win" -version = "5.4.0" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" +checksum = "79f4473f5144e20d9aceaf2972478f06ddf687831eafeeb434fbaf0acc4144ad" dependencies = [ "error-code", ] @@ -903,9 +867,9 @@ dependencies = [ [[package]] name = "combine" -version = "4.6.7" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" dependencies = [ "bytes", "memchr", @@ -938,30 +902,20 @@ dependencies = [ "libc", ] -[[package]] -name = "core-foundation" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" -version = "0.8.7" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core-graphics" -version = "0.23.2" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212" dependencies = [ "bitflags 1.3.2", - "core-foundation 0.9.4", + "core-foundation", "core-graphics-types", "foreign-types", "libc", @@ -974,24 +928,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", - "core-foundation 0.9.4", + "core-foundation", "libc", ] [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", ] @@ -1032,10 +986,11 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ + "cfg-if", "crossbeam-utils", ] @@ -1060,15 +1015,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "crunchy" -version = "0.2.2" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crypto-common" @@ -1146,9 +1095,9 @@ checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" [[package]] name = "deranged" -version = "0.3.11" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" dependencies = [ "powerfmt", ] @@ -1166,8 +1115,9 @@ dependencies = [ [[package]] name = "dify" -version = "0.6.0" -source = "git+https://github.com/jihchi/dify#fc4739edf4cf56534e3fc1b5b96d4cc599060d2b" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11217d469eafa3b809ad84651eb9797ccbb440b4a916d5d85cb1b994e89787f6" dependencies = [ "anyhow", "colored", @@ -1233,9 +1183,9 @@ dependencies = [ [[package]] name = "downcast-rs" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "dpi" @@ -1267,7 +1217,7 @@ dependencies = [ "egui-wgpu", "egui-winit", "egui_glow", - "glow 0.14.1", + "glow 0.14.0", "glutin", "glutin-winit", "home", @@ -1419,11 +1369,11 @@ dependencies = [ "document-features", "egui", "egui-winit", - "glow 0.14.1", + "glow 0.14.0", "glutin", "glutin-winit", "log", - "memoffset 0.9.1", + "memoffset 0.9.0", "puffin", "wasm-bindgen", "web-sys", @@ -1460,9 +1410,9 @@ dependencies = [ [[package]] name = "either" -version = "1.13.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "emath" @@ -1476,9 +1426,9 @@ dependencies = [ [[package]] name = "enum-map" -version = "2.7.3" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" +checksum = "c188012f8542dee7b3996e44dd89461d64aa471b0a7c71a1ae2f595d259e96e5" dependencies = [ "enum-map-derive", "serde", @@ -1486,20 +1436,20 @@ dependencies = [ [[package]] name = "enum-map-derive" -version = "0.17.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" +checksum = "04d0b288e3bb1d861c4403c1774a6f7a798781dfc519b3647df2a3dd4ae95f25" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] name = "enumflags2" -version = "0.7.10" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" +checksum = "5998b4f30320c9d93aed72f63af821bfdac50465b75428fce77b48ec482c3939" dependencies = [ "enumflags2_derive", "serde", @@ -1507,31 +1457,31 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.10" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" +checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] name = "enumn" -version = "0.1.14" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" +checksum = "c2ad8cef1d801a4686bfd8919f0b30eac4c8e48968c437a6405ded4fb5272d2b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] name = "env_logger" -version = "0.10.2" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ "humantime", "is-terminal", @@ -1572,19 +1522,30 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", "libc", - "windows-sys 0.52.0", ] [[package]] name = "error-code" -version = "3.3.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f" +checksum = "281e452d3bad4005426416cdba5ccfd4f5c1280e10099e21db27f7c1c28347fc" [[package]] name = "event-listener" @@ -1594,9 +1555,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "3.1.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +checksum = "29e56284f00d94c1bc7fd3c77027b4623c88c1f53d8d2394c6199f2921dea325" dependencies = [ "concurrent-queue", "parking", @@ -1645,15 +1606,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "fdeflate" -version = "0.3.5" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8090f921a24b04994d9929e204f50b498a33ea6ba559ffaa05e04f7ee7fb5ab" +checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" dependencies = [ "simd-adler32", ] @@ -1669,9 +1630,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.34" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" dependencies = [ "crc32fast", "miniz_oxide", @@ -1707,7 +1668,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] @@ -1718,24 +1679,24 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-lite" @@ -1758,41 +1719,38 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand 2.1.1", "futures-core", - "futures-io", - "parking", "pin-project-lite", ] [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", "futures-io", @@ -1866,9 +1824,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -1887,9 +1845,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.31.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "gio-sys" @@ -1939,9 +1897,9 @@ dependencies = [ [[package]] name = "glow" -version = "0.14.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4a888dbe8181a7535853469c21c67ca9a1cea9460b16808fc018ea9e55d248" +checksum = "f865cbd94bd355b89611211e49508da98a1fce0ad755c1e8448fb96711b24528" dependencies = [ "js-sys", "slotmap", @@ -1951,14 +1909,14 @@ dependencies = [ [[package]] name = "glutin" -version = "0.32.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec69412a0bf07ea7607e638b415447857a808846c2b685a43c8aa18bc6d5e499" +checksum = "2491aa3090f682ddd920b184491844440fdd14379c7eef8f5bc10ef7fb3242fd" dependencies = [ "bitflags 2.6.0", "cfg_aliases 0.2.1", "cgl", - "core-foundation 0.9.4", + "core-foundation", "dispatch", "glutin_egl_sys", "glutin_glx_sys", @@ -2055,7 +2013,7 @@ dependencies = [ "presser", "thiserror", "winapi", - "windows 0.52.0", + "windows 0.51.1", ] [[package]] @@ -2066,7 +2024,7 @@ checksum = "9c08c1f623a8d0b722b8b99f821eb0ba672a1618f0d3b16ddbee1cedd2dd8557" dependencies = [ "bitflags 2.6.0", "gpu-descriptor-types", - "hashbrown 0.14.5", + "hashbrown", ] [[package]] @@ -2098,30 +2056,20 @@ dependencies = [ [[package]] name = "half" -version = "2.4.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" -dependencies = [ - "cfg-if", - "crunchy", -] +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", "allocator-api2", ] -[[package]] -name = "hashbrown" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" - [[package]] name = "hassle-rs" version = "0.11.0" @@ -2139,9 +2087,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.5.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hello_world" @@ -2171,15 +2119,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.9" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hex" @@ -2210,16 +2152,16 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.61" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core 0.52.0", + "windows-core 0.51.1", ] [[package]] @@ -2233,9 +2175,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.5.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -2284,19 +2226,19 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.6.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown", ] [[package]] name = "instant" -version = "0.1.13" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", ] @@ -2307,20 +2249,20 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", "windows-sys 0.48.0", ] [[package]] name = "is-terminal" -version = "0.4.13" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "hermit-abi 0.4.0", - "libc", - "windows-sys 0.52.0", + "hermit-abi", + "rustix 0.38.21", + "windows-sys 0.48.0", ] [[package]] @@ -2334,9 +2276,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jni" @@ -2362,9 +2304,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" dependencies = [ "libc", ] @@ -2430,18 +2372,18 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.159" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-sys 0.48.0", ] [[package]] @@ -2456,14 +2398,10 @@ dependencies = [ ] [[package]] -name = "libredox" -version = "0.1.3" +name = "line-wrap" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags 2.6.0", - "libc", -] +checksum = "dd1bc4d24ad230d21fb898d1116b1801d7adfc449d42026475862ab48b11e70e" [[package]] name = "linked-hash-map" @@ -2479,9 +2417,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" [[package]] name = "litrs" @@ -2491,9 +2429,9 @@ checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", @@ -2501,15 +2439,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "lz4_flex" -version = "0.11.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5" +checksum = "3ea9b256699eda7b0387ffbc776dd625e28bde3918446381781245b7a50349d8" [[package]] name = "malloc_buf" @@ -2522,15 +2460,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.4" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "memmap2" -version = "0.9.5" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +checksum = "deaba38d7abf1d4cca21cc89e932e542ba2b9258664d2a9ef0e61512039c9375" dependencies = [ "libc", ] @@ -2546,9 +2484,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.9.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] @@ -2584,13 +2522,19 @@ dependencies = [ "unicase", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" -version = "0.8.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ - "adler2", + "adler", "simd-adler32", ] @@ -2610,9 +2554,9 @@ dependencies = [ [[package]] name = "naga" -version = "22.1.0" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bd5a652b6faf21496f2cfd88fc49989c8db0825d1f6746b1a71a6ede24a63ad" +checksum = "09eeccb9b50f4f7839b214aa3e08be467159506a986c18e0702170ccf720a453" dependencies = [ "arrayvec", "bit-set 0.6.0", @@ -2687,39 +2631,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" [[package]] -name = "num-conv" -version = "0.1.0" +name = "nom" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] [[package]] name = "num-traits" -version = "0.2.19" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] [[package]] name = "num_enum" -version = "0.7.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +checksum = "683751d591e6d81200c39fb0d1032608b77724f34114db54f571ff1317b337c0" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e" dependencies = [ - "proc-macro-crate 3.2.0", + "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] @@ -2956,27 +2904,24 @@ dependencies = [ [[package]] name = "object" -version = "0.36.5" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.20.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oorandom" -version = "11.1.4" +version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "option-ext" @@ -2990,7 +2935,7 @@ version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" dependencies = [ - "libredox 0.0.2", + "libredox", ] [[package]] @@ -3005,9 +2950,9 @@ dependencies = [ [[package]] name = "owned_ttf_parser" -version = "0.24.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490d3a563d3122bf7c911a59b0add9389e5ec0f5f0c3ac6b91ff235a0e6a7f90" +checksum = "706de7e2214113d63a8238d1910463cfce781129a6f263d13fdb09ff64355ba4" dependencies = [ "ttf-parser", ] @@ -3026,15 +2971,15 @@ dependencies = [ [[package]] name = "parking" -version = "2.2.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" +checksum = "e52c774a4c39359c1d1c52e43f73dd91a75a614652c825408eec30c95a9b2067" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", "parking_lot_core", @@ -3042,28 +2987,28 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.7", + "redox_syscall 0.3.5", "smallvec", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] name = "paste" -version = "1.0.15" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pico-args" @@ -3088,14 +3033,14 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -3105,39 +3050,40 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.4" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" dependencies = [ "atomic-waker", - "fastrand 2.1.1", + "fastrand 2.0.1", "futures-io", ] [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "plist" -version = "1.7.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" +checksum = "d9d34169e64b3c7a80c8621a48adaf44e0cf62c78a9b25dd9dd35f1881a17cf9" dependencies = [ - "base64 0.22.1", + "base64", "indexmap", - "quick-xml 0.32.0", + "line-wrap", + "quick-xml 0.31.0", "serde", "time", ] [[package]] name = "png" -version = "0.17.14" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" +checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -3174,17 +3120,16 @@ dependencies = [ [[package]] name = "polling" -version = "3.7.3" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" +checksum = "e53b6af1f60f36f8c2ac2aad5459d75a5a9b4be1e8cdd40264f315d78193e531" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.37", + "rustix 0.38.21", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] @@ -3201,12 +3146,6 @@ dependencies = [ "env_logger", ] -[[package]] -name = "portable-atomic" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" - [[package]] name = "powerfmt" version = "0.2.0" @@ -3215,12 +3154,9 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "presser" @@ -3235,44 +3171,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit 0.19.15", -] - -[[package]] -name = "proc-macro-crate" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" -dependencies = [ - "toml_edit 0.22.22", + "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] [[package]] name = "profiling" -version = "1.0.15" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" +checksum = "0f0f7f43585c34e4fdd7497d746bc32e14458cf11c69341cc0587b1d825dde42" [[package]] name = "puffin" -version = "0.19.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa9dae7b05c02ec1a6bc9bcf20d8bc64a7dcbf57934107902a872014899b741f" +checksum = "b9f76ad4bb049fded4e572df72cbb6381ff5d1f41f85c3a04b56e4eca287a02f" dependencies = [ "anyhow", "bincode", "byteorder", "cfg-if", - "itertools", "lz4_flex", "once_cell", "parking_lot", @@ -3281,9 +3207,9 @@ dependencies = [ [[package]] name = "puffin_http" -version = "0.16.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739a3c7f56604713b553d7addd7718c226e88d598979ae3450320800bd0e9810" +checksum = "4936c085e48efc86f6d96609dc5086d1d236afe3ec4676f09b157a4f4be83ff6" dependencies = [ "anyhow", "crossbeam-channel", @@ -3305,27 +3231,27 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.32.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" dependencies = [ "memchr", ] [[package]] name = "quick-xml" -version = "0.36.2" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" +checksum = "6f24d770aeca0eacb81ac29dfbc55ebcc09312fdd1f8bbecdc7e4a84e000e3b4" dependencies = [ "memchr", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -3374,9 +3300,9 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "rayon" -version = "1.10.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" dependencies = [ "either", "rayon-core", @@ -3400,38 +3326,47 @@ checksum = "3b42e27ef78c35d3998403c1d26f3efd9e135d3e5121b0a4845cc5cc27547f4f" [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags 2.6.0", + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", ] [[package]] name = "redox_users" -version = "0.4.6" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", - "libredox 0.1.3", + "redox_syscall 0.2.16", "thiserror", ] [[package]] name = "regex" -version = "1.11.0" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", @@ -3441,9 +3376,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", @@ -3452,9 +3387,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "renderdoc-sys" @@ -3501,9 +3436,9 @@ dependencies = [ [[package]] name = "rgb" -version = "0.8.50" +version = "0.8.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" +checksum = "20ec2d3e3fc7a92ced357df9cebd5a10b6fb2aa1ee797bf7e9ce2f17dffc8f59" dependencies = [ "bytemuck", ] @@ -3529,7 +3464,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ - "base64 0.21.7", + "base64", "bitflags 2.6.0", "serde", "serde_derive", @@ -3543,9 +3478,9 @@ checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustc-hash" @@ -3555,9 +3490,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.37.27" +version = "0.37.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +checksum = "d4eb579851244c2c03e7c24f501c3432bed80b8f720af1d6e5b0e0f01555a035" dependencies = [ "bitflags 1.3.2", "errno", @@ -3569,54 +3504,44 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" dependencies = [ "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys 0.4.14", - "windows-sys 0.52.0", + "linux-raw-sys 0.4.11", + "windows-sys 0.48.0", ] [[package]] name = "rustls" -version = "0.23.13" +version = "0.21.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" +checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" dependencies = [ "log", - "once_cell", "ring", - "rustls-pki-types", "rustls-webpki", - "subtle", - "zeroize", + "sct", ] -[[package]] -name = "rustls-pki-types" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" - [[package]] name = "rustls-webpki" -version = "0.102.8" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ "ring", - "rustls-pki-types", "untrusted", ] [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "same-file" @@ -3648,6 +3573,16 @@ dependencies = [ "image", ] +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "sctk-adwaita" version = "0.10.1" @@ -3663,52 +3598,51 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.210" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", - "memchr", "ryu", "serde", ] [[package]] name = "serde_repr" -version = "0.1.19" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] name = "serde_spanned" -version = "0.6.8" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" dependencies = [ "serde", ] @@ -3733,17 +3667,11 @@ dependencies = [ "digest", ] -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] @@ -3780,18 +3708,18 @@ dependencies = [ [[package]] name = "slotmap" -version = "1.0.7" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" dependencies = [ "version_check", ] [[package]] name = "smallvec" -version = "1.13.2" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "smithay-client-toolkit" @@ -3806,7 +3734,7 @@ dependencies = [ "libc", "log", "memmap2", - "rustix 0.38.37", + "rustix 0.38.21", "thiserror", "wayland-backend", "wayland-client", @@ -3831,18 +3759,18 @@ dependencies = [ [[package]] name = "smol_str" -version = "0.2.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" dependencies = [ "serde", ] [[package]] name = "socket2" -version = "0.4.10" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -3878,12 +3806,6 @@ dependencies = [ "float-cmp", ] -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - [[package]] name = "svgtypes" version = "0.13.0" @@ -3907,9 +3829,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -3918,9 +3840,9 @@ dependencies = [ [[package]] name = "syntect" -version = "5.2.0" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1" +checksum = "e02b4b303bf8d08bfeb0445cba5068a3d306b6baece1d5582171a9bf49188f91" dependencies = [ "bincode", "bitflags 1.3.2", @@ -3931,7 +3853,6 @@ dependencies = [ "plist", "regex-syntax", "serde", - "serde_derive", "serde_json", "thiserror", "walkdir", @@ -3940,9 +3861,9 @@ dependencies = [ [[package]] name = "system-deps" -version = "6.2.2" +version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +checksum = "30c2de8a4d8f4b823d634affc9cd2a74ec98c53a756f317e529a48046cbf71f3" dependencies = [ "cfg-expr", "heck", @@ -3953,21 +3874,21 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.16" +version = "0.12.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" [[package]] name = "tempfile" -version = "3.13.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", - "fastrand 2.1.1", - "once_cell", - "rustix 0.38.37", - "windows-sys 0.59.0", + "fastrand 2.0.1", + "redox_syscall 0.3.5", + "rustix 0.38.21", + "windows-sys 0.48.0", ] [[package]] @@ -4022,33 +3943,32 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] name = "time" -version = "0.3.36" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" dependencies = [ "deranged", "itoa", - "num-conv", "powerfmt", "serde", "time-core", @@ -4063,19 +3983,18 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" dependencies = [ - "num-conv", "time-core", ] [[package]] name = "tiny-skia" -version = "0.11.4" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" +checksum = "b6a067b809476893fce6a254cf285850ff69c847e6cfbade6a20b655b6c7e80d" dependencies = [ "arrayref", "arrayvec", @@ -4088,9 +4007,9 @@ dependencies = [ [[package]] name = "tiny-skia-path" -version = "0.11.4" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" +checksum = "5de35e8a90052baaaf61f171680ac2f8e925a1e43ea9d2e3a00514772250e541" dependencies = [ "arrayref", "bytemuck", @@ -4109,9 +4028,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.8.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] @@ -4124,21 +4043,21 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "toml" -version = "0.8.19" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.22", + "toml_edit", ] [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" dependencies = [ "serde", ] @@ -4148,23 +4067,12 @@ name = "toml_edit" version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.20", + "winnow", ] [[package]] @@ -4186,7 +4094,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] @@ -4200,9 +4108,9 @@ dependencies = [ [[package]] name = "ttf-parser" -version = "0.24.1" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be21190ff5d38e8b4a2d3b6a3ae57f612cc39c96e83cedeaf7abc338a8bac4a" +checksum = "a464a4b34948a5f67fddd2b823c62d9d92e44be75058b99939eae6c5b6960b33" [[package]] name = "type-map" @@ -4221,11 +4129,10 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "uds_windows" -version = "1.1.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" +checksum = "ce65604324d3cce9b966701489fbd0cf318cb1f7bd9dd07ac9a4ee6fb791930d" dependencies = [ - "memoffset 0.9.1", "tempfile", "winapi", ] @@ -4241,42 +4148,42 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.17" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.24" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" -version = "0.1.14" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "unicode-xid" -version = "0.2.6" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "unicode_names2" @@ -4292,25 +4199,25 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.10.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a" +checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3" dependencies = [ - "base64 0.22.1", + "base64", "flate2", "log", "once_cell", "rustls", - "rustls-pki-types", + "rustls-webpki", "url", "webpki-roots", ] [[package]] name = "url" -version = "2.5.2" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", @@ -4331,7 +4238,7 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b0a51b72ab80ca511d126b77feeeb4fb1e972764653e61feac30adc161a756" dependencies = [ - "base64 0.21.7", + "base64", "log", "pico-args", "usvg-parser", @@ -4371,27 +4278,27 @@ dependencies = [ [[package]] name = "version-compare" -version = "0.2.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" +checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" [[package]] name = "version_check" -version = "0.9.5" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "waker-fn" -version = "1.2.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" +checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" [[package]] name = "walkdir" -version = "2.5.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", @@ -4425,15 +4332,15 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -4459,7 +4366,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4472,13 +4379,13 @@ checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "wayland-backend" -version = "0.3.7" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" +checksum = "f90e11ce2ca99c97b940ee83edbae9da2d56a08f9ea8158550fd77fa31722993" dependencies = [ "cc", "downcast-rs", - "rustix 0.38.37", + "rustix 0.38.21", "scoped-tls", "smallvec", "wayland-sys", @@ -4486,12 +4393,12 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.6" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3f45d1222915ef1fd2057220c1d9d9624b7654443ea35c3877f7a52bd0a5a2d" +checksum = "7e321577a0a165911bdcfb39cf029302479d7527b517ee58ab0f6ad09edf0943" dependencies = [ "bitflags 2.6.0", - "rustix 0.38.37", + "rustix 0.38.21", "wayland-backend", "wayland-scanner", ] @@ -4509,20 +4416,20 @@ dependencies = [ [[package]] name = "wayland-cursor" -version = "0.31.6" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a94697e66e76c85923b0d28a0c251e8f0666f58fc47d316c0f4da6da75d37cb" +checksum = "6ef9489a8df197ebf3a8ce8a7a7f0a2320035c3743f3c1bd0bdbccf07ce64f95" dependencies = [ - "rustix 0.38.37", + "rustix 0.38.21", "wayland-client", "xcursor", ] [[package]] name = "wayland-protocols" -version = "0.32.4" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b5755d77ae9040bb872a25026555ce4cb0ae75fd923e90d25fba07d81057de0" +checksum = "62989625a776e827cc0f15d41444a3cea5205b963c3a25be48ae1b52d6b4daaa" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -4532,9 +4439,9 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.3.4" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0a41a6875e585172495f7a96dfa42ca7e0213868f4f15c313f7c33221a7eff" +checksum = "f79f2d57c7fcc6ab4d602adba364bf59a5c24de57bd194486bf9b8360e06bfc4" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -4545,9 +4452,9 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.4" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad87b5fd1b1d3ca2f792df8f686a2a11e3fe1077b71096f7a175ab699f89109" +checksum = "fd993de54a40a40fbe5601d9f1fbcaef0aebcc5fda447d7dc8f6dcbaae4f8953" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -4558,20 +4465,20 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.5" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" +checksum = "d7b56f89937f1cf2ee1f1259cf2936a17a1f45d8f0aa1019fae6d470d304cfa6" dependencies = [ "proc-macro2", - "quick-xml 0.36.2", + "quick-xml 0.34.0", "quote", ] [[package]] name = "wayland-sys" -version = "0.31.5" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" +checksum = "43676fe2daf68754ecf1d72026e4e6c15483198b5d24e888b74d3f22f887a148" dependencies = [ "dlib", "log", @@ -4601,30 +4508,26 @@ dependencies = [ [[package]] name = "webbrowser" -version = "1.0.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5f07fb9bc8de2ddfe6b24a71a75430673fd679e568c48b52716cef1cfae923" +checksum = "60b6f804e41d0852e16d2eaee61c7e4f7d3e8ffdb7b8ed85886aeb0791fe9fcd" dependencies = [ - "block2", - "core-foundation 0.10.0", + "core-foundation", "home", "jni", "log", "ndk-context", - "objc2", - "objc2-foundation", + "objc", + "raw-window-handle 0.5.2", "url", "web-sys", ] [[package]] name = "webpki-roots" -version = "0.26.6" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" -dependencies = [ - "rustls-pki-types", -] +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "weezl" @@ -4737,9 +4640,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.1.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" +checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" [[package]] name = "winapi" @@ -4759,11 +4662,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ - "windows-sys 0.59.0", + "winapi", ] [[package]] @@ -4774,85 +4677,74 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.52.0" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" dependencies = [ - "windows-core 0.52.0", - "windows-targets 0.52.6", + "windows-core 0.51.1", + "windows-targets 0.48.5", ] [[package]] name = "windows" -version = "0.58.0" +version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" dependencies = [ - "windows-core 0.58.0", - "windows-targets 0.52.6", + "windows-core 0.54.0", + "windows-implement", + "windows-interface", + "windows-targets 0.52.5", ] [[package]] name = "windows-core" -version = "0.52.0" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] name = "windows-core" -version = "0.58.0" +version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" dependencies = [ - "windows-implement", - "windows-interface", "windows-result", - "windows-strings", - "windows-targets 0.52.6", + "windows-targets 0.52.5", ] [[package]] name = "windows-implement" -version = "0.58.0" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +checksum = "942ac266be9249c84ca862f0a164a39533dc2f6f33dc98ec89c8da99b82ea0bd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] name = "windows-interface" -version = "0.58.0" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +checksum = "da33557140a288fae4e1d5f8873aaf9eb6613a9cf82c3e070223ff177f598b60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] [[package]] name = "windows-result" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-strings" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" dependencies = [ - "windows-result", - "windows-targets 0.52.6", + "windows-targets 0.52.5", ] [[package]] @@ -4879,16 +4771,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", + "windows-targets 0.52.5", ] [[package]] @@ -4923,18 +4806,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -4951,9 +4834,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -4969,9 +4852,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -4987,15 +4870,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" [[package]] name = "windows_i686_gnullvm" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -5011,9 +4894,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -5029,9 +4912,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -5047,9 +4930,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -5065,9 +4948,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winit" @@ -5084,7 +4967,7 @@ dependencies = [ "calloop", "cfg_aliases 0.2.1", "concurrent-queue", - "core-foundation 0.9.4", + "core-foundation", "core-graphics", "cursor-icon", "dpi", @@ -5101,7 +4984,7 @@ dependencies = [ "pin-project", "raw-window-handle 0.6.2", "redox_syscall 0.4.1", - "rustix 0.38.37", + "rustix 0.38.21", "sctk-adwaita", "smithay-client-toolkit", "smol_str", @@ -5123,18 +5006,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.5.40" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" dependencies = [ "memchr", ] @@ -5152,39 +5026,42 @@ dependencies = [ [[package]] name = "x11rb" -version = "0.13.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" +checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a" dependencies = [ "as-raw-xcb-connection", "gethostname", "libc", "libloading", "once_cell", - "rustix 0.38.37", + "rustix 0.38.21", "x11rb-protocol", ] [[package]] name = "x11rb-protocol" -version = "0.13.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" +checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34" [[package]] name = "xcursor" -version = "0.3.8" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" +checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" +dependencies = [ + "nom", +] [[package]] name = "xdg-home" -version = "1.3.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" +checksum = "2769203cd13a0c6015d515be729c526d041e9cf2c0cc478d57faee85f40c6dcd" dependencies = [ - "libc", - "windows-sys 0.59.0", + "nix", + "winapi", ] [[package]] @@ -5202,15 +5079,15 @@ dependencies = [ [[package]] name = "xkeysym" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" +checksum = "054a8e68b76250b253f671d1268cb7f1ae089ec35e195b2efb2a4e9a836d0621" [[package]] name = "xml-rs" -version = "0.8.22" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26" +checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" [[package]] name = "xmlwriter" @@ -5233,15 +5110,15 @@ dependencies = [ [[package]] name = "zbus" -version = "3.15.2" +version = "3.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" +checksum = "31de390a2d872e4cd04edd71b425e29853f786dc99317ed72d73d6fcf5ebb948" dependencies = [ "async-broadcast", "async-executor", "async-fs", - "async-io 1.13.0", - "async-lock 2.8.0", + "async-io", + "async-lock", "async-process", "async-recursion", "async-task", @@ -5274,11 +5151,11 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "3.15.2" +version = "3.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" +checksum = "41d1794a946878c0e807f55a397187c11fc7a038ba5d868e7db4f3bd7760bc9d" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate", "proc-macro2", "quote", "regex", @@ -5288,9 +5165,9 @@ dependencies = [ [[package]] name = "zbus_names" -version = "2.6.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d" +checksum = "fb80bb776dbda6e23d705cf0123c3b95df99c4ebeaec6c2599d4a5419902b4a9" dependencies = [ "serde", "static_assertions", @@ -5299,31 +5176,24 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.7.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" dependencies = [ - "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.7.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.48", ] -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" - [[package]] name = "zune-core" version = "0.4.12" @@ -5332,18 +5202,18 @@ checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" [[package]] name = "zune-jpeg" -version = "0.4.13" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768" +checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448" dependencies = [ "zune-core", ] [[package]] name = "zvariant" -version = "3.15.2" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" +checksum = "44b291bee0d960c53170780af148dca5fa260a63cdd24f1962fa82e03e53338c" dependencies = [ "byteorder", "enumflags2", @@ -5355,11 +5225,11 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "3.15.2" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" +checksum = "934d7a7dfc310d6ee06c87ffe88ef4eca7d3e37bb251dece2ef93da8f17d8ecd" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", diff --git a/Cargo.toml b/Cargo.toml index 0bd817bf367..aec446d822a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -265,7 +265,3 @@ unwrap_used = "allow" # TODO(emilk): We really wanna warn on thi manual_range_contains = "allow" # this one is just worse imho self_named_module_files = "allow" # Disabled waiting on https://github.com/rust-lang/rust-clippy/issues/9602 significant_drop_tightening = "allow" # Too many false positives - -[patch.crates-io] -# TODO(lucasmerlin): Remove once dify releases a new version -dify = { git = "https://github.com/jihchi/dify"} diff --git a/crates/egui_kittest/Cargo.toml b/crates/egui_kittest/Cargo.toml index da07f5f2ad4..03a78a5556b 100644 --- a/crates/egui_kittest/Cargo.toml +++ b/crates/egui_kittest/Cargo.toml @@ -24,7 +24,7 @@ pollster = { version = "0.3", optional = true } image = { workspace = true, optional = true } # snapshot dependencies -dify = { version = "0.6.0", optional = true, default-features = false } +dify = { version = "0.7.0", optional = true, default-features = false } [dev-dependencies] wgpu = { workspace = true, features = ["metal"] } From d7b874e8333386867454351c95f4f0121c9cd393 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Fri, 4 Oct 2024 18:37:39 +0200 Subject: [PATCH 23/47] "un-break" tests --- crates/egui_demo_lib/src/demo/widget_gallery.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/egui_demo_lib/src/demo/widget_gallery.rs b/crates/egui_demo_lib/src/demo/widget_gallery.rs index 6ac28fcd5b0..2dfcd35820e 100644 --- a/crates/egui_demo_lib/src/demo/widget_gallery.rs +++ b/crates/egui_demo_lib/src/demo/widget_gallery.rs @@ -61,9 +61,6 @@ impl crate::Demo for WidgetGallery { impl crate::View for WidgetGallery { fn ui(&mut self, ui: &mut egui::Ui) { - ui.visuals_mut().widgets.inactive.rounding = 0.0.into(); - ui.visuals_mut().extreme_bg_color = egui::Color32::RED; - let mut ui_builder = egui::UiBuilder::new(); if !self.enabled { ui_builder = ui_builder.disabled(); From 66a6c00ff6ec470066974f9bc963862d9d1ea231 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Fri, 4 Oct 2024 21:24:58 +0200 Subject: [PATCH 24/47] Fix lint --- crates/egui_kittest/src/snapshot.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/egui_kittest/src/snapshot.rs b/crates/egui_kittest/src/snapshot.rs index 6fd1372e00e..e67a8a3cf04 100644 --- a/crates/egui_kittest/src/snapshot.rs +++ b/crates/egui_kittest/src/snapshot.rs @@ -6,6 +6,7 @@ pub enum SnapshotError { Diff { diff: i32, diff_path: PathBuf }, MissingSnapshot { path: PathBuf }, } + impl Display for SnapshotError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { From e0d82635f547787d23e989e4f96ab31605422db8 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 5 Oct 2024 13:13:16 +0200 Subject: [PATCH 25/47] Always run egui_demo_lib tests with chrono feature --- Cargo.lock | 1 + crates/egui_demo_lib/Cargo.toml | 3 +++ crates/egui_demo_lib/tests/snapshots/demos/Widget Gallery.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/widget_gallery.png | 4 ++-- crates/egui_kittest/src/snapshot.rs | 1 + 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 21fa0094360..c4e9c569aaf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1333,6 +1333,7 @@ dependencies = [ "criterion", "document-features", "egui", + "egui_demo_lib", "egui_extras", "egui_kittest", "log", diff --git a/crates/egui_demo_lib/Cargo.toml b/crates/egui_demo_lib/Cargo.toml index 2f19c6cb9a6..a00657ea1f0 100644 --- a/crates/egui_demo_lib/Cargo.toml +++ b/crates/egui_demo_lib/Cargo.toml @@ -55,6 +55,9 @@ serde = { workspace = true, optional = true } [dev-dependencies] +# when running tests we always want to use the `chrono` feature +egui_demo_lib = { features = ["chrono"], workspace = true } + criterion.workspace = true egui_kittest = { path = "../egui_kittest", features = ["wgpu", "snapshot"] } wgpu = { workspace = true, features = ["metal"] } diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Widget Gallery.png b/crates/egui_demo_lib/tests/snapshots/demos/Widget Gallery.png index f1b29751af8..da7f58d44f4 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Widget Gallery.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Widget Gallery.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8e376aaa97574d8c0fca3b331a39dcaadbc463ef06026512e71e93d559539d9d -size 101513 +oid sha256:c3b604629cdb4f9d48c2bb1b30e0650da38a50f130ac10b64defb5334e8a2b90 +size 106900 diff --git a/crates/egui_demo_lib/tests/snapshots/widget_gallery.png b/crates/egui_demo_lib/tests/snapshots/widget_gallery.png index 88b0bccb38b..29574beb03e 100644 --- a/crates/egui_demo_lib/tests/snapshots/widget_gallery.png +++ b/crates/egui_demo_lib/tests/snapshots/widget_gallery.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bceac96a5fb9eaf4660e7d646f3694955aa31f63004966789a032f0a606bd644 -size 166348 +oid sha256:1e3c37b58611bf14983b87320a220a8befa81273c05cbcb073399c13f6d5b630 +size 177431 diff --git a/crates/egui_kittest/src/snapshot.rs b/crates/egui_kittest/src/snapshot.rs index e67a8a3cf04..7afd7b65e64 100644 --- a/crates/egui_kittest/src/snapshot.rs +++ b/crates/egui_kittest/src/snapshot.rs @@ -72,6 +72,7 @@ pub fn try_image_snapshot(current: &image::RgbaImage, name: &str) -> Result<(), /// /// # Panics /// Panics if the image does not match the snapshot. +#[track_caller] pub fn image_snapshot(current: &image::RgbaImage, name: &str) { match try_image_snapshot(current, name) { Ok(_) => {} From e1a81969ffdb5070bb4673423a5e5a7005f93c83 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 5 Oct 2024 16:04:33 +0200 Subject: [PATCH 26/47] Add Harness::builder and add README.md --- .../src/demo/demo_app_windows.rs | 5 +- .../egui_demo_lib/src/demo/widget_gallery.rs | 8 +- .../tests/snapshots/widget_gallery.png | 4 +- crates/egui_kittest/README.md | 35 +++ crates/egui_kittest/examples/kittest.rs | 50 ----- crates/egui_kittest/kittest.png | Bin 4430 -> 0 bytes crates/egui_kittest/src/builder.rs | 33 +++ crates/egui_kittest/src/lib.rs | 199 ++++++++++-------- crates/egui_kittest/src/snapshot.rs | 71 +++++-- .../tests/snapshots/readme_example.png | 3 + 10 files changed, 244 insertions(+), 164 deletions(-) create mode 100644 crates/egui_kittest/README.md delete mode 100644 crates/egui_kittest/examples/kittest.rs delete mode 100644 crates/egui_kittest/kittest.png create mode 100644 crates/egui_kittest/src/builder.rs create mode 100644 crates/egui_kittest/tests/snapshots/readme_example.png diff --git a/crates/egui_demo_lib/src/demo/demo_app_windows.rs b/crates/egui_demo_lib/src/demo/demo_app_windows.rs index 621471ab45e..0bc7f23c45d 100644 --- a/crates/egui_demo_lib/src/demo/demo_app_windows.rs +++ b/crates/egui_demo_lib/src/demo/demo_app_windows.rs @@ -383,7 +383,7 @@ mod tests { use crate::demo::demo_app_windows::Demos; use egui::Vec2; use egui_kittest::kittest::Queryable; - use egui_kittest::snapshot::try_image_snapshot; + use egui_kittest::try_image_snapshot; use egui_kittest::wgpu::TestRenderer; use egui_kittest::Harness; @@ -406,14 +406,13 @@ mod tests { // We need to run the app for multiple frames before all windows have the right size harness.run(); harness.run(); - harness.run(); let window = harness.node().children().next().unwrap(); // TODO(lucasmerlin): Windows should probably have a label? //let window = harness.get_by_name(name); let size = window.raw_bounds().expect("window bounds").size(); - harness = harness.with_size(Vec2::new(size.width as f32, size.height as f32)); + harness.set_size(Vec2::new(size.width as f32, size.height as f32)); // We need to run the app for some more frames... harness.run(); diff --git a/crates/egui_demo_lib/src/demo/widget_gallery.rs b/crates/egui_demo_lib/src/demo/widget_gallery.rs index 2dfcd35820e..75d74a9ba1a 100644 --- a/crates/egui_demo_lib/src/demo/widget_gallery.rs +++ b/crates/egui_demo_lib/src/demo/widget_gallery.rs @@ -291,7 +291,7 @@ mod tests { use super::*; use crate::View; use egui::{CentralPanel, Context, Vec2}; - use egui_kittest::snapshot::image_snapshot; + use egui_kittest::image_snapshot; use egui_kittest::wgpu::TestRenderer; use egui_kittest::Harness; @@ -303,10 +303,12 @@ mod tests { demo.ui(ui); }); }; - let mut harness = Harness::new(app) + let mut harness = Harness::builder() .with_size(Vec2::new(380.0, 550.0)) - .with_dpi(2.0); + .with_dpi(2.0) + .build(app); + // The first and second frames are slightly different, so we take the second frame harness.run(); let image = TestRenderer::new().render(&harness); diff --git a/crates/egui_demo_lib/tests/snapshots/widget_gallery.png b/crates/egui_demo_lib/tests/snapshots/widget_gallery.png index 29574beb03e..2a5b8108404 100644 --- a/crates/egui_demo_lib/tests/snapshots/widget_gallery.png +++ b/crates/egui_demo_lib/tests/snapshots/widget_gallery.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1e3c37b58611bf14983b87320a220a8befa81273c05cbcb073399c13f6d5b630 -size 177431 +oid sha256:8ac74ddfafd31883f07a5474e30bbeafda197ef9c080d5e941122bbb6cfa4ef4 +size 177515 diff --git a/crates/egui_kittest/README.md b/crates/egui_kittest/README.md new file mode 100644 index 00000000000..d9cfc35a2f2 --- /dev/null +++ b/crates/egui_kittest/README.md @@ -0,0 +1,35 @@ +# egui_kittest + +Ui testing library for egui, based on [kittest](https://github.com/rerun-io/kittest) (a AccessKit based testing library). + +```rust +use egui::accesskit::{Role, Toggled}; +use egui::{CentralPanel, Context, TextEdit, Vec2}; +use egui_kittest::Harness; +use kittest::Queryable; +use std::cell::RefCell; + +fn main() { + let mut checked = false; + let app = |ctx: &Context| { + CentralPanel::default().show(ctx, |ui| { + ui.checkbox(&mut checked, "Check me!"); + }); + }; + + let mut harness = Harness::builder().with_size(egui::Vec2::new(200.0, 100.0)).build(app); + + let checkbox = harness.get_by_name("Check me!"); + assert_eq!(checkbox.toggled(), Some(Toggled::False)); + checkbox.click(); + + harness.run(); + + let checkbox = harness.get_by_name("Check me!"); + assert_eq!(checkbox.toggled(), Some(Toggled::True)); + + // You can even render the ui and do image snapshot tests + #[cfg(all(feature = "wgpu", feature = "snapshot"))] + egui_kittest::image_snapshot(&egui_kittest::wgpu::TestRenderer::new().render(&harness), "readme_example"); +} +``` diff --git a/crates/egui_kittest/examples/kittest.rs b/crates/egui_kittest/examples/kittest.rs deleted file mode 100644 index 6fd3e412ea3..00000000000 --- a/crates/egui_kittest/examples/kittest.rs +++ /dev/null @@ -1,50 +0,0 @@ -use egui::accesskit::{Role, Toggled}; -use egui::{CentralPanel, Context, TextEdit, Vec2}; -use egui_kittest::Harness; -use kittest::Queryable; -use std::cell::RefCell; - -fn main() { - let checked = RefCell::new(false); - let text = RefCell::new(String::new()); - let app = |ctx: &Context| { - CentralPanel::default().show(ctx, |ui| { - ui.checkbox(&mut checked.borrow_mut(), "Check me!"); - TextEdit::singleline(&mut *text.borrow_mut()) - .hint_text("Type here") - .show(ui); - }); - }; - - let mut harness = Harness::new(app).with_size(Vec2::new(200.0, 100.0)); - - harness.run(); - - harness.get_by_name("Check me!").click(); - - harness.run(); - - assert!(*checked.borrow()); - let checkbox = harness.get_by_name("Check me!"); - assert_eq!(checkbox.toggled(), Some(Toggled::True)); - - harness - .get_by_role(Role::TextInput) - .type_text("Hello, World!"); - - harness.run(); - - assert_eq!(&*text.borrow_mut(), "Hello, World!"); - assert_eq!( - harness.get_by_role(Role::TextInput).value().as_deref(), - Some("Hello, World!") - ); - - #[cfg(feature = "wgpu")] - { - let mut renderer = egui_kittest::wgpu::TestRenderer::new(); - let image = renderer.render(&harness); - - image.save("../kittest.png").unwrap(); - } -} diff --git a/crates/egui_kittest/kittest.png b/crates/egui_kittest/kittest.png deleted file mode 100644 index 3fa3303889a0beb9b8da7b092740c62c0e7119fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4430 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 Self { + Self { + screen_rect: Rect::from_min_size(Pos2::ZERO, Vec2::new(800.0, 600.0)), + dpi: 1.0, + } + } +} + +impl HarnessBuilder { + pub fn with_size(mut self, size: Vec2) -> Self { + self.screen_rect.set_width(size.x); + self.screen_rect.set_height(size.y); + self + } + + pub fn with_dpi(mut self, dpi: f32) -> Self { + self.dpi = dpi; + self + } + + pub fn build<'a>(self, app: impl FnMut(&egui::Context) + 'a) -> Harness<'a> { + Harness::from_builder(&self, app) + } +} diff --git a/crates/egui_kittest/src/lib.rs b/crates/egui_kittest/src/lib.rs index f4afb7b6313..6593158efb1 100644 --- a/crates/egui_kittest/src/lib.rs +++ b/crates/egui_kittest/src/lib.rs @@ -1,24 +1,30 @@ +mod builder; +#[doc = include_str!("../README.md")] mod event; #[cfg(feature = "snapshot")] -pub mod snapshot; +mod snapshot; +#[cfg(feature = "snapshot")] +pub use snapshot::*; #[cfg(feature = "wgpu")] mod texture_to_bytes; #[cfg(feature = "wgpu")] pub mod wgpu; pub use kittest; +use std::mem; use crate::event::{kittest_key_to_egui, pointer_button_to_egui}; pub use accesskit_consumer; +pub use builder::*; use egui::accesskit::NodeId; -use egui::{Event, Modifiers, Pos2, Rect, TexturesDelta, Vec2}; +use egui::{Event, Modifiers, Pos2, Rect, TexturesDelta, Vec2, ViewportId}; use kittest::{ElementState, Node, Queryable, SimulatedEvent, State}; pub struct Harness<'a> { pub ctx: egui::Context, input: egui::RawInput, - tree: Option, - output: Option, + kittest: State, + output: egui::FullOutput, texture_deltas: Vec, update_fn: Box, @@ -27,122 +33,135 @@ pub struct Harness<'a> { } impl<'a> Harness<'a> { - pub fn new(app: impl FnMut(&egui::Context) + 'a) -> Self { + pub(crate) fn from_builder( + builder: &HarnessBuilder, + mut app: impl FnMut(&egui::Context) + 'a, + ) -> Self { let ctx = egui::Context::default(); ctx.enable_accesskit(); + let mut input = egui::RawInput { + screen_rect: Some(builder.screen_rect), + ..Default::default() + }; + let viewport = input.viewports.get_mut(&ViewportId::ROOT).unwrap(); + viewport.native_pixels_per_point = Some(builder.dpi); + + let mut output = ctx.run(input.clone(), &mut app); Self { update_fn: Box::new(app), ctx, - input: egui::RawInput { - screen_rect: Some(Rect::from_min_size(Pos2::ZERO, Vec2::new(800.0, 600.0))), - ..Default::default() - }, - tree: None, - output: None, - texture_deltas: Vec::new(), + input, + kittest: State::new( + output + .platform_output + .accesskit_update + .take() + .expect("AccessKit was disabled"), + ), + texture_deltas: vec![mem::take(&mut output.textures_delta)], + output, last_mouse_pos: Pos2::ZERO, modifiers: Modifiers::NONE, } } + pub fn builder() -> HarnessBuilder { + HarnessBuilder::default() + } + + pub fn new(app: impl FnMut(&egui::Context) + 'a) -> Self { + Self::builder().build(app) + } + + /// Set the size of the window. + /// Note: If you only want to set the size once at the beginning, + /// prefer using [`HarnessBuilder::with_size`]. #[inline] - pub fn with_size(mut self, size: Vec2) -> Self { + pub fn set_size(&mut self, size: Vec2) -> &mut Self { self.input.screen_rect = Some(Rect::from_min_size(Pos2::ZERO, size)); self } + /// Set the DPI of the window. + /// Note: If you only want to set the DPI once at the beginning, + /// prefer using [`HarnessBuilder::with_dpi`]. #[inline] - pub fn with_dpi(mut self, dpi: f32) -> Self { - self.input - .viewports - .get_mut(&self.input.viewport_id) - .unwrap() - .native_pixels_per_point = Some(dpi); + pub fn set_dpi(&mut self, dpi: f32) -> &mut Self { + self.ctx.set_pixels_per_point(dpi); self } pub fn run(&mut self) { - if let Some(tree) = &mut self.tree { - for event in tree.take_events() { - match event { - kittest::Event::ActionRequest(e) => { - self.input.events.push(Event::AccessKitActionRequest(e)); + for event in self.kittest.take_events() { + match event { + kittest::Event::ActionRequest(e) => { + self.input.events.push(Event::AccessKitActionRequest(e)); + } + kittest::Event::Simulated(e) => match e { + SimulatedEvent::CursorMoved { position } => { + self.input.events.push(Event::PointerMoved(Pos2::new( + position.x as f32, + position.y as f32, + ))); } - kittest::Event::Simulated(e) => match e { - SimulatedEvent::CursorMoved { position } => { - self.input.events.push(Event::PointerMoved(Pos2::new( - position.x as f32, - position.y as f32, - ))); + SimulatedEvent::MouseInput { state, button } => { + let button = pointer_button_to_egui(button); + if let Some(button) = button { + self.input.events.push(Event::PointerButton { + button, + modifiers: self.modifiers, + pos: self.last_mouse_pos, + pressed: matches!(state, ElementState::Pressed), + }); } - SimulatedEvent::MouseInput { state, button } => { - let button = pointer_button_to_egui(button); - if let Some(button) = button { - self.input.events.push(Event::PointerButton { - button, - modifiers: self.modifiers, - pos: self.last_mouse_pos, - pressed: matches!(state, ElementState::Pressed), - }); + } + SimulatedEvent::Ime(text) => { + self.input.events.push(Event::Text(text)); + } + SimulatedEvent::KeyInput { state, key } => { + match key { + kittest::Key::Alt => { + self.modifiers.alt = matches!(state, ElementState::Pressed); } - } - SimulatedEvent::Ime(text) => { - self.input.events.push(Event::Text(text)); - } - SimulatedEvent::KeyInput { state, key } => { - match key { - kittest::Key::Alt => { - self.modifiers.alt = matches!(state, ElementState::Pressed); - } - kittest::Key::Command => { - self.modifiers.command = matches!(state, ElementState::Pressed); - } - kittest::Key::Control => { - self.modifiers.ctrl = matches!(state, ElementState::Pressed); - } - kittest::Key::Shift => { - self.modifiers.shift = matches!(state, ElementState::Pressed); - } - _ => {} + kittest::Key::Command => { + self.modifiers.command = matches!(state, ElementState::Pressed); + } + kittest::Key::Control => { + self.modifiers.ctrl = matches!(state, ElementState::Pressed); } - let key = kittest_key_to_egui(key); - if let Some(key) = key { - self.input.events.push(Event::Key { - key, - modifiers: self.modifiers, - pressed: matches!(state, ElementState::Pressed), - repeat: false, - physical_key: None, - }); + kittest::Key::Shift => { + self.modifiers.shift = matches!(state, ElementState::Pressed); } + _ => {} } - }, - } + let key = kittest_key_to_egui(key); + if let Some(key) = key { + self.input.events.push(Event::Key { + key, + modifiers: self.modifiers, + pressed: matches!(state, ElementState::Pressed), + repeat: false, + physical_key: None, + }); + } + } + }, } } + let mut output = self.ctx.run(self.input.take(), self.update_fn.as_mut()); - if let Some(tree) = &mut self.tree { - tree.update( - output - .platform_output - .accesskit_update - .take() - .expect("AccessKit was disabled"), - ); - } else { - self.tree = Some(State::new( - output - .platform_output - .accesskit_update - .take() - .expect("AccessKit was disabled"), - )); - } - self.output = Some(output); + self.kittest.update( + output + .platform_output + .accesskit_update + .take() + .expect("AccessKit was disabled"), + ); self.texture_deltas - .push(self.output().textures_delta.clone()); + .push(mem::take(&mut output.textures_delta)); + self.output = output; } pub fn click(&mut self, id: NodeId) { @@ -193,11 +212,11 @@ impl<'a> Harness<'a> { } pub fn output(&self) -> &egui::FullOutput { - self.output.as_ref().expect("Not initialized") + &self.output } pub fn kittest_state(&self) -> &State { - self.tree.as_ref().expect("Not initialized") + &self.kittest } } diff --git a/crates/egui_kittest/src/snapshot.rs b/crates/egui_kittest/src/snapshot.rs index 7afd7b65e64..be061c05dda 100644 --- a/crates/egui_kittest/src/snapshot.rs +++ b/crates/egui_kittest/src/snapshot.rs @@ -1,10 +1,22 @@ +use image::ImageError; use std::fmt::Display; +use std::io::ErrorKind; use std::path::{Path, PathBuf}; #[derive(Debug)] pub enum SnapshotError { - Diff { diff: i32, diff_path: PathBuf }, - MissingSnapshot { path: PathBuf }, + Diff { + diff: i32, + diff_path: PathBuf, + }, + OpenSnapshot { + path: PathBuf, + err: image::ImageError, + }, + SizeMismatch { + expected: (u32, u32), + actual: (u32, u32), + }, } impl Display for SnapshotError { @@ -16,8 +28,24 @@ impl Display for SnapshotError { "Image did not match snapshot. Diff: {diff}, {diff_path:?}" ) } - Self::MissingSnapshot { path } => { - write!(f, "Missing snapshot: {path:?}") + Self::OpenSnapshot { path, err } => match err { + ImageError::IoError(io) => match io.kind() { + ErrorKind::NotFound => { + write!(f, "Missing snapshot: {path:?}") + } + err => { + write!(f, "Error reading snapshot: {err:?}") + } + }, + err => { + write!(f, "Error decoding snapshot: {err:?}") + } + }, + Self::SizeMismatch { expected, actual } => { + write!( + f, + "Image size did not match snapshot. Expected: {expected:?}, Actual: {actual:?}" + ) } } } @@ -41,25 +69,25 @@ pub fn try_image_snapshot(current: &image::RgbaImage, name: &str) -> Result<(), let previous = match image::open(&path) { Ok(image) => image.to_rgba8(), Err(err) => { - println!("Error opening image: {err}"); - println!("Saving current image as {path:?}"); - current.save(&path).unwrap(); - - return Err(SnapshotError::MissingSnapshot { path }); + maybe_update_snapshot(&path, current); + return Err(SnapshotError::OpenSnapshot { path, err }); } }; + if previous.dimensions() != current.dimensions() { + maybe_update_snapshot(&path, current); + return Err(SnapshotError::SizeMismatch { + expected: previous.dimensions(), + actual: current.dimensions(), + }); + } + let result = dify::diff::get_results(previous, current.clone(), 0.1, true, None, &None, &None); if let Some((diff, result_image)) = result { result_image.save(diff_path.clone()).unwrap(); - - if std::env::var("UPDATE_SNAPSHOTS").is_ok() { - current.save(&path).unwrap(); - println!("Updated snapshot: {path:?}"); - } else { - return Err(SnapshotError::Diff { diff, diff_path }); - } + maybe_update_snapshot(&path, current); + return Err(SnapshotError::Diff { diff, diff_path }); } else { // Delete old diff if it exists std::fs::remove_file(diff_path).ok(); @@ -68,6 +96,17 @@ pub fn try_image_snapshot(current: &image::RgbaImage, name: &str) -> Result<(), Ok(()) } +fn should_update_snapshots() -> bool { + std::env::var("UPDATE_SNAPSHOTS").is_ok() +} + +fn maybe_update_snapshot(snapshot_path: &Path, current: &image::RgbaImage) { + if should_update_snapshots() { + current.save(snapshot_path).unwrap(); + println!("Updated snapshot: {snapshot_path:?}"); + } +} + /// Image snapshot test. /// /// # Panics diff --git a/crates/egui_kittest/tests/snapshots/readme_example.png b/crates/egui_kittest/tests/snapshots/readme_example.png new file mode 100644 index 00000000000..3c0fe1f2e3c --- /dev/null +++ b/crates/egui_kittest/tests/snapshots/readme_example.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20600ce0f58d9593b644a69c749b1c2aebd6b6839a9a9a52b8f6d709cd660b25 +size 2624 From a5994d89c99bbba30437dcf38b024cae60e674f3 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 5 Oct 2024 16:23:53 +0200 Subject: [PATCH 27/47] Add documentation --- crates/egui_kittest/src/builder.rs | 21 +++++++++ crates/egui_kittest/src/lib.rs | 72 ++++++++++++------------------ 2 files changed, 49 insertions(+), 44 deletions(-) diff --git a/crates/egui_kittest/src/builder.rs b/crates/egui_kittest/src/builder.rs index 6269f706a91..b315ebe9967 100644 --- a/crates/egui_kittest/src/builder.rs +++ b/crates/egui_kittest/src/builder.rs @@ -1,6 +1,7 @@ use crate::Harness; use egui::{Pos2, Rect, Vec2}; +/// Builder for [`Harness`]. pub struct HarnessBuilder { pub(crate) screen_rect: Rect, pub(crate) dpi: f32, @@ -16,17 +17,37 @@ impl Default for HarnessBuilder { } impl HarnessBuilder { + /// Set the size of the window. + #[inline] pub fn with_size(mut self, size: Vec2) -> Self { self.screen_rect.set_width(size.x); self.screen_rect.set_height(size.y); self } + /// Set the DPI of the window. + #[inline] pub fn with_dpi(mut self, dpi: f32) -> Self { self.dpi = dpi; self } + /// Create a new Harness with the given app closure. + /// + /// The ui closure will immediately be called once to create the initial ui. + /// + /// # Example + /// ```rust + /// # use egui::CentralPanel; + /// # use egui_kittest::Harness; + /// let mut harness = Harness::builder() + /// .with_size(egui::Vec2::new(300.0, 200.0)) + /// .build(|ctx| { + /// CentralPanel::default().show(ctx, |ui| { + /// ui.label("Hello, world!"); + /// }); + /// }); + /// ``` pub fn build<'a>(self, app: impl FnMut(&egui::Context) + 'a) -> Harness<'a> { Harness::from_builder(&self, app) } diff --git a/crates/egui_kittest/src/lib.rs b/crates/egui_kittest/src/lib.rs index 6593158efb1..ffd25227591 100644 --- a/crates/egui_kittest/src/lib.rs +++ b/crates/egui_kittest/src/lib.rs @@ -16,14 +16,15 @@ use std::mem; use crate::event::{kittest_key_to_egui, pointer_button_to_egui}; pub use accesskit_consumer; pub use builder::*; -use egui::accesskit::NodeId; use egui::{Event, Modifiers, Pos2, Rect, TexturesDelta, Vec2, ViewportId}; -use kittest::{ElementState, Node, Queryable, SimulatedEvent, State}; +use kittest::{ElementState, Node, Queryable, SimulatedEvent}; +/// The test Harness. This contains everything needed to run the test. +/// Create a new Harness using [`Harness::new`] or [`Harness::builder`]. pub struct Harness<'a> { pub ctx: egui::Context, input: egui::RawInput, - kittest: State, + kittest: kittest::State, output: egui::FullOutput, texture_deltas: Vec, update_fn: Box, @@ -52,7 +53,7 @@ impl<'a> Harness<'a> { update_fn: Box::new(app), ctx, input, - kittest: State::new( + kittest: kittest::State::new( output .platform_output .accesskit_update @@ -71,6 +72,22 @@ impl<'a> Harness<'a> { HarnessBuilder::default() } + /// Create a new Harness with the given app closure. + /// + /// The ui closure will immediately be called once to create the initial ui. + /// + /// If you e.g. want to customize the size of the window, you can use [`Harness::builder`]. + /// + /// # Example + /// ```rust + /// # use egui::CentralPanel; + /// # use egui_kittest::Harness; + /// let mut harness = Harness::new(|ctx| { + /// CentralPanel::default().show(ctx, |ui| { + /// ui.label("Hello, world!"); + /// }); + /// }); + /// ``` pub fn new(app: impl FnMut(&egui::Context) + 'a) -> Self { Self::builder().build(app) } @@ -93,6 +110,8 @@ impl<'a> Harness<'a> { self } + /// Run a frame. + /// This will call the app closure with the current context and update the Harness. pub fn run(&mut self) { for event in self.kittest.take_events() { match event { @@ -164,58 +183,23 @@ impl<'a> Harness<'a> { self.output = output; } - pub fn click(&mut self, id: NodeId) { - let action = egui::accesskit::ActionRequest { - target: id, - action: egui::accesskit::Action::Default, - data: None, - }; - self.input - .events - .push(egui::Event::AccessKitActionRequest(action)); - } - - pub fn focus(&mut self, id: NodeId) { - let action = egui::accesskit::ActionRequest { - target: id, - action: egui::accesskit::Action::Focus, - data: None, - }; - self.input - .events - .push(Event::AccessKitActionRequest(action)); - } - - // TODO(lucasmerlin): SetValue is currently not supported by egui - // pub fn set_text(&mut self, id: NodeId, text: &str) { - // let action = egui::accesskit::ActionRequest { - // target: id, - // action: egui::accesskit::Action::SetValue, - // data: Some(ActionData::Value(Box::from(text))), - // }; - // self.input - // .events - // .push(egui::Event::AccessKitActionRequest(action)); - // } - - pub fn type_text(&mut self, id: NodeId, text: &str) { - self.focus(id); - self.input.events.push(egui::Event::Text(text.to_owned())); - } - + /// Access the [`egui::RawInput`] for the next frame. pub fn input(&self) -> &egui::RawInput { &self.input } + /// Access the [`egui::RawInput`] for the next frame mutably. pub fn input_mut(&mut self) -> &mut egui::RawInput { &mut self.input } + /// Access the [`egui::FullOutput`] for the last frame. pub fn output(&self) -> &egui::FullOutput { &self.output } - pub fn kittest_state(&self) -> &State { + /// Access the [`kittest::State`]. + pub fn kittest_state(&self) -> &kittest::State { &self.kittest } } From dcdc60190d6971d554de1dc3b620dcf3333c1624 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 5 Oct 2024 16:27:38 +0200 Subject: [PATCH 28/47] Fixes after rebase --- Cargo.lock | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c4e9c569aaf..08194a9f156 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1336,7 +1336,6 @@ dependencies = [ "egui_demo_lib", "egui_extras", "egui_kittest", - "log", "serde", "unicode_names2", "wgpu", @@ -1383,7 +1382,7 @@ dependencies = [ [[package]] name = "egui_kittest" -version = "0.28.1" +version = "0.29.1" dependencies = [ "accesskit_consumer", "dify", From 76aa7adaa88b36e6fbaa6fb07c389746ff912e44 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 5 Oct 2024 16:38:23 +0200 Subject: [PATCH 29/47] Fixes tests after rebase (where do those dots come from?) --- crates/egui_demo_lib/tests/snapshots/demos/Panels.png | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Panels.png b/crates/egui_demo_lib/tests/snapshots/demos/Panels.png index 6e6d658970c..c7cc349bc26 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Panels.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Panels.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:394837e1331cf3b0640d21201a121080fa78f3290d8f1a942104e63fee68fe4e -size 456632 +oid sha256:f076b2781f4c5b74c64037ede4524d5f5c3a0ebdf54933da4f962e21600137b7 +size 456944 From da32e8cc354416496913b1d69cac412e2ec42ee6 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 5 Oct 2024 16:43:45 +0200 Subject: [PATCH 30/47] Checkout lfs --- .github/workflows/rust.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8837442cdcf..2ae8675f076 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -13,6 +13,8 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 + with: + lfs: true - uses: dtolnay/rust-toolchain@master with: @@ -233,7 +235,7 @@ jobs: steps: - uses: actions/checkout@v4 with: - lfs: 'true' + lfs: true - uses: dtolnay/rust-toolchain@master with: toolchain: 1.76.0 From d0a307dae3a2b961276beaa30738c6c82b9b3982 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Wed, 9 Oct 2024 17:28:27 +0200 Subject: [PATCH 31/47] Only run tests on macos --- .github/workflows/rust.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 2ae8675f076..095c1f4baec 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -62,18 +62,12 @@ jobs: - name: cargo check -p test_egui_extras_compilation run: cargo check -p test_egui_extras_compilation - - name: Test doc-tests - run: cargo test --doc --all-features - - name: cargo doc --lib run: cargo doc --lib --no-deps --all-features - name: cargo doc --document-private-items run: cargo doc --document-private-items --no-deps --all-features - - name: Test - run: cargo test --all-features - - name: clippy run: cargo clippy --all-targets --all-features -- -D warnings @@ -247,6 +241,9 @@ jobs: # TODO: Enable --all-features (currently this breaks the rendering in the tests) run: cargo test + - name: Run doc-tests + run: cargo test --doc --all-features + - name: Upload artifacts uses: actions/upload-artifact@v4 if: always() From 0d4cebf1b977d5ed6685771345745f2f844860e8 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Wed, 9 Oct 2024 17:57:37 +0200 Subject: [PATCH 32/47] Set fixed date in widget_gallery test --- crates/egui_demo_lib/src/demo/demo_app_windows.rs | 6 ++++++ crates/egui_demo_lib/src/demo/widget_gallery.rs | 6 +++++- .../egui_demo_lib/tests/snapshots/demos/Widget Gallery.png | 3 --- crates/egui_demo_lib/tests/snapshots/widget_gallery.png | 4 ++-- 4 files changed, 13 insertions(+), 6 deletions(-) delete mode 100644 crates/egui_demo_lib/tests/snapshots/demos/Widget Gallery.png diff --git a/crates/egui_demo_lib/src/demo/demo_app_windows.rs b/crates/egui_demo_lib/src/demo/demo_app_windows.rs index 0bc7f23c45d..929aec7b1b7 100644 --- a/crates/egui_demo_lib/src/demo/demo_app_windows.rs +++ b/crates/egui_demo_lib/src/demo/demo_app_windows.rs @@ -394,11 +394,17 @@ mod tests { let mut errors = Vec::new(); for mut demo in demos.demos { + // Remove the emoji from the demo name let name = demo .name() .split_once(' ') .map_or(demo.name(), |(_, name)| name); + // Widget Gallery needs to be customized (to set a specific date) and has its own test + if name == "Widget Gallery" { + continue; + } + let mut harness = Harness::new(|ctx| { demo.show(ctx, &mut true); }); diff --git a/crates/egui_demo_lib/src/demo/widget_gallery.rs b/crates/egui_demo_lib/src/demo/widget_gallery.rs index 75d74a9ba1a..e8851a34c02 100644 --- a/crates/egui_demo_lib/src/demo/widget_gallery.rs +++ b/crates/egui_demo_lib/src/demo/widget_gallery.rs @@ -297,7 +297,11 @@ mod tests { #[test] pub fn should_match_screenshot() { - let mut demo = WidgetGallery::default(); + let mut demo = WidgetGallery { + // If we don't set a fixed date, the snapshot test will fail. + date: Some(chrono::NaiveDate::from_ymd_opt(2024, 1, 1).unwrap()), + ..Default::default() + }; let app = |ctx: &Context| { CentralPanel::default().show(ctx, |ui| { demo.ui(ui); diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Widget Gallery.png b/crates/egui_demo_lib/tests/snapshots/demos/Widget Gallery.png deleted file mode 100644 index da7f58d44f4..00000000000 --- a/crates/egui_demo_lib/tests/snapshots/demos/Widget Gallery.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c3b604629cdb4f9d48c2bb1b30e0650da38a50f130ac10b64defb5334e8a2b90 -size 106900 diff --git a/crates/egui_demo_lib/tests/snapshots/widget_gallery.png b/crates/egui_demo_lib/tests/snapshots/widget_gallery.png index 2a5b8108404..9c46e244fdf 100644 --- a/crates/egui_demo_lib/tests/snapshots/widget_gallery.png +++ b/crates/egui_demo_lib/tests/snapshots/widget_gallery.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ac74ddfafd31883f07a5474e30bbeafda197ef9c080d5e941122bbb6cfa4ef4 -size 177515 +oid sha256:7752724def1a0f7e72c6b058c196c0d2d6b3ee05fe78761d105e69cf5200dc2a +size 177261 From 84977aa89d504a3331036ef0743d0c74b0da9f8d Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Wed, 9 Oct 2024 18:01:28 +0200 Subject: [PATCH 33/47] Fix doc --- crates/egui_kittest/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/egui_kittest/src/lib.rs b/crates/egui_kittest/src/lib.rs index ffd25227591..009f9073d97 100644 --- a/crates/egui_kittest/src/lib.rs +++ b/crates/egui_kittest/src/lib.rs @@ -1,5 +1,5 @@ +#![doc = include_str!("../README.md")] mod builder; -#[doc = include_str!("../README.md")] mod event; #[cfg(feature = "snapshot")] mod snapshot; From 2d411a8cc75cc1dace4e0d6e3ecfa43cc67cebee Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Wed, 9 Oct 2024 18:05:53 +0200 Subject: [PATCH 34/47] Fix deny --- Cargo.toml | 1 + crates/egui_demo_lib/Cargo.toml | 2 +- crates/egui_kittest/Cargo.toml | 2 +- deny.toml | 5 ++++- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index aec446d822a..6ca4941abad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,7 @@ egui_extras = { version = "0.29.1", path = "crates/egui_extras", default-feature egui-wgpu = { version = "0.29.1", path = "crates/egui-wgpu", default-features = false } egui_demo_lib = { version = "0.29.1", path = "crates/egui_demo_lib", default-features = false } egui_glow = { version = "0.29.1", path = "crates/egui_glow", default-features = false } +egui_kittest = { version = "0.29.1", path = "crates/egui_kittest", default-features = false } eframe = { version = "0.29.1", path = "crates/eframe", default-features = false } ahash = { version = "0.8.11", default-features = false, features = [ diff --git a/crates/egui_demo_lib/Cargo.toml b/crates/egui_demo_lib/Cargo.toml index a00657ea1f0..e98bf5d3406 100644 --- a/crates/egui_demo_lib/Cargo.toml +++ b/crates/egui_demo_lib/Cargo.toml @@ -59,7 +59,7 @@ serde = { workspace = true, optional = true } egui_demo_lib = { features = ["chrono"], workspace = true } criterion.workspace = true -egui_kittest = { path = "../egui_kittest", features = ["wgpu", "snapshot"] } +egui_kittest = { workspace = true, features = ["default", "wgpu", "snapshot"] } wgpu = { workspace = true, features = ["metal"] } egui = { workspace = true, features = ["default_fonts"] } diff --git a/crates/egui_kittest/Cargo.toml b/crates/egui_kittest/Cargo.toml index 03a78a5556b..4f1c435d7f8 100644 --- a/crates/egui_kittest/Cargo.toml +++ b/crates/egui_kittest/Cargo.toml @@ -15,7 +15,7 @@ default = ["image?/png"] [dependencies] accesskit_consumer = "0.24.0" -kittest = { git = "https://github.com/rerun-io/kittest", branch = "kittest" } +kittest = { git = "https://github.com/rerun-io/kittest", version = "0.1", branch = "kittest" } egui = { workspace = true, features = ["accesskit"] } # wgpu dependencies diff --git a/deny.toml b/deny.toml index f5291700dfc..5c946782b35 100644 --- a/deny.toml +++ b/deny.toml @@ -60,7 +60,6 @@ skip = [ { name = "windows-core" }, # old version via accesskit_windows { name = "windows" }, # old version via accesskit_windows { name = "glow" }, # wgpu uses an old `glow`, but realistically no one uses _both_ `egui_wgpu` and `egui_glow`, so we won't get a duplicate dependency - ] skip-tree = [ { name = "criterion" }, # dev-dependency @@ -109,3 +108,7 @@ license-files = [{ path = "LICENSE", hash = 0xbd0eed23 }] [sources] unknown-registry = "deny" unknown-git = "deny" + +allow-git = [ + "https://github.com/rerun-io/kittest", # TODO(lucasmerlin): remove this once the kittest crate is published" +] From cac6db8cfa572a64ffa6fc0a4e0a17b6ac8dfc86 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Wed, 9 Oct 2024 18:26:46 +0200 Subject: [PATCH 35/47] Fix doc tests --- .github/workflows/rust.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 095c1f4baec..077580dcafb 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -238,11 +238,12 @@ jobs: uses: Swatinem/rust-cache@v2 - name: Run tests - # TODO: Enable --all-features (currently this breaks the rendering in the tests) + # TODO(lucasmerlin): Enable --all-features (currently this breaks the rendering in the tests because of the `unity` feature) run: cargo test - name: Run doc-tests - run: cargo test --doc --all-features + # TODO(lucasmerlin): Enable --all-features (currently this breaks the rendering in the tests because of the `unity` feature) + run: cargo test --doc - name: Upload artifacts uses: actions/upload-artifact@v4 From 311d44731dcc5b2439965601ce020e6bba5e4b44 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Thu, 10 Oct 2024 14:52:44 +0200 Subject: [PATCH 36/47] Refactor events and impl debug for Harness --- Cargo.lock | 2 +- crates/egui_kittest/Cargo.toml | 2 +- crates/egui_kittest/src/event.rs | 269 +++++++++++++++++++------------ crates/egui_kittest/src/lib.rs | 75 ++------- 4 files changed, 179 insertions(+), 169 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08194a9f156..2d21f7981ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2348,7 +2348,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "kittest" version = "0.1.0" -source = "git+https://github.com/rerun-io/kittest?branch=kittest#526e8469d266cc7e6d9a941f8ddd27248cf819b4" +source = "git+https://github.com/rerun-io/kittest?branch=impl-debug#240832d5d086ae0a9cf358af9450c0cef16fbeab" dependencies = [ "accesskit", "accesskit_consumer", diff --git a/crates/egui_kittest/Cargo.toml b/crates/egui_kittest/Cargo.toml index 4f1c435d7f8..ee161541d05 100644 --- a/crates/egui_kittest/Cargo.toml +++ b/crates/egui_kittest/Cargo.toml @@ -15,7 +15,7 @@ default = ["image?/png"] [dependencies] accesskit_consumer = "0.24.0" -kittest = { git = "https://github.com/rerun-io/kittest", version = "0.1", branch = "kittest" } +kittest = { git = "https://github.com/rerun-io/kittest", version = "0.1", branch = "impl-debug" } egui = { workspace = true, features = ["accesskit"] } # wgpu dependencies diff --git a/crates/egui_kittest/src/event.rs b/crates/egui_kittest/src/event.rs index 5c06342f034..b1b90cb2220 100644 --- a/crates/egui_kittest/src/event.rs +++ b/crates/egui_kittest/src/event.rs @@ -1,111 +1,168 @@ -use kittest::{Key, MouseButton}; +use egui::Event::PointerButton; +use egui::{Event, Modifiers, Pos2}; +use kittest::{ElementState, MouseButton, SimulatedEvent}; -pub fn kittest_key_to_egui(value: Key) -> Option { +#[derive(Default)] +pub(crate) struct EventState { + modifiers: Modifiers, + last_mouse_pos: Pos2, +} + +impl EventState { + pub fn kittest_event_to_egui(&mut self, event: kittest::Event) -> Option { + match event { + kittest::Event::ActionRequest(e) => Some(Event::AccessKitActionRequest(e)), + kittest::Event::Simulated(e) => { + match e { + SimulatedEvent::CursorMoved { position } => Some(Event::PointerMoved( + Pos2::new(position.x as f32, position.y as f32), + )), + SimulatedEvent::MouseInput { state, button } => pointer_button_to_egui(button) + .map(|button| PointerButton { + button, + modifiers: self.modifiers, + pos: self.last_mouse_pos, + pressed: matches!(state, ElementState::Pressed), + }), + SimulatedEvent::Ime(text) => Some(Event::Text(text)), + SimulatedEvent::KeyInput { state, key } => { + match key { + kittest::Key::Alt => { + self.modifiers.alt = matches!(state, ElementState::Pressed); + } + kittest::Key::Command => { + self.modifiers.command = matches!(state, ElementState::Pressed); + } + kittest::Key::Control => { + self.modifiers.ctrl = matches!(state, ElementState::Pressed); + } + kittest::Key::Shift => { + self.modifiers.shift = matches!(state, ElementState::Pressed); + } + _ => {} + } + kittest_key_to_egui(key).map(|key| Event::Key { + key, + modifiers: self.modifiers, + pressed: matches!(state, ElementState::Pressed), + repeat: false, + physical_key: None, + }) + } + } + } + } + } +} + +pub fn kittest_key_to_egui(value: kittest::Key) -> Option { + use egui::Key as EKey; + use kittest::Key; match value { - Key::ArrowDown => Some(egui::Key::ArrowDown), - Key::ArrowLeft => Some(egui::Key::ArrowLeft), - Key::ArrowRight => Some(egui::Key::ArrowRight), - Key::ArrowUp => Some(egui::Key::ArrowUp), - Key::Escape => Some(egui::Key::Escape), - Key::Tab => Some(egui::Key::Tab), - Key::Backspace => Some(egui::Key::Backspace), - Key::Enter => Some(egui::Key::Enter), - Key::Space => Some(egui::Key::Space), - Key::Insert => Some(egui::Key::Insert), - Key::Delete => Some(egui::Key::Delete), - Key::Home => Some(egui::Key::Home), - Key::End => Some(egui::Key::End), - Key::PageUp => Some(egui::Key::PageUp), - Key::PageDown => Some(egui::Key::PageDown), - Key::Copy => Some(egui::Key::Copy), - Key::Cut => Some(egui::Key::Cut), - Key::Paste => Some(egui::Key::Paste), - Key::Colon => Some(egui::Key::Colon), - Key::Comma => Some(egui::Key::Comma), - Key::Backslash => Some(egui::Key::Backslash), - Key::Slash => Some(egui::Key::Slash), - Key::Pipe => Some(egui::Key::Pipe), - Key::Questionmark => Some(egui::Key::Questionmark), - Key::OpenBracket => Some(egui::Key::OpenBracket), - Key::CloseBracket => Some(egui::Key::CloseBracket), - Key::Backtick => Some(egui::Key::Backtick), - Key::Minus => Some(egui::Key::Minus), - Key::Period => Some(egui::Key::Period), - Key::Plus => Some(egui::Key::Plus), - Key::Equals => Some(egui::Key::Equals), - Key::Semicolon => Some(egui::Key::Semicolon), - Key::Quote => Some(egui::Key::Quote), - Key::Num0 => Some(egui::Key::Num0), - Key::Num1 => Some(egui::Key::Num1), - Key::Num2 => Some(egui::Key::Num2), - Key::Num3 => Some(egui::Key::Num3), - Key::Num4 => Some(egui::Key::Num4), - Key::Num5 => Some(egui::Key::Num5), - Key::Num6 => Some(egui::Key::Num6), - Key::Num7 => Some(egui::Key::Num7), - Key::Num8 => Some(egui::Key::Num8), - Key::Num9 => Some(egui::Key::Num9), - Key::A => Some(egui::Key::A), - Key::B => Some(egui::Key::B), - Key::C => Some(egui::Key::C), - Key::D => Some(egui::Key::D), - Key::E => Some(egui::Key::E), - Key::F => Some(egui::Key::F), - Key::G => Some(egui::Key::G), - Key::H => Some(egui::Key::H), - Key::I => Some(egui::Key::I), - Key::J => Some(egui::Key::J), - Key::K => Some(egui::Key::K), - Key::L => Some(egui::Key::L), - Key::M => Some(egui::Key::M), - Key::N => Some(egui::Key::N), - Key::O => Some(egui::Key::O), - Key::P => Some(egui::Key::P), - Key::Q => Some(egui::Key::Q), - Key::R => Some(egui::Key::R), - Key::S => Some(egui::Key::S), - Key::T => Some(egui::Key::T), - Key::U => Some(egui::Key::U), - Key::V => Some(egui::Key::V), - Key::W => Some(egui::Key::W), - Key::X => Some(egui::Key::X), - Key::Y => Some(egui::Key::Y), - Key::Z => Some(egui::Key::Z), - Key::F1 => Some(egui::Key::F1), - Key::F2 => Some(egui::Key::F2), - Key::F3 => Some(egui::Key::F3), - Key::F4 => Some(egui::Key::F4), - Key::F5 => Some(egui::Key::F5), - Key::F6 => Some(egui::Key::F6), - Key::F7 => Some(egui::Key::F7), - Key::F8 => Some(egui::Key::F8), - Key::F9 => Some(egui::Key::F9), - Key::F10 => Some(egui::Key::F10), - Key::F11 => Some(egui::Key::F11), - Key::F12 => Some(egui::Key::F12), - Key::F13 => Some(egui::Key::F13), - Key::F14 => Some(egui::Key::F14), - Key::F15 => Some(egui::Key::F15), - Key::F16 => Some(egui::Key::F16), - Key::F17 => Some(egui::Key::F17), - Key::F18 => Some(egui::Key::F18), - Key::F19 => Some(egui::Key::F19), - Key::F20 => Some(egui::Key::F20), - Key::F21 => Some(egui::Key::F21), - Key::F22 => Some(egui::Key::F22), - Key::F23 => Some(egui::Key::F23), - Key::F24 => Some(egui::Key::F24), - Key::F25 => Some(egui::Key::F25), - Key::F26 => Some(egui::Key::F26), - Key::F27 => Some(egui::Key::F27), - Key::F28 => Some(egui::Key::F28), - Key::F29 => Some(egui::Key::F29), - Key::F30 => Some(egui::Key::F30), - Key::F31 => Some(egui::Key::F31), - Key::F32 => Some(egui::Key::F32), - Key::F33 => Some(egui::Key::F33), - Key::F34 => Some(egui::Key::F34), - Key::F35 => Some(egui::Key::F35), + Key::ArrowDown => Some(EKey::ArrowDown), + Key::ArrowLeft => Some(EKey::ArrowLeft), + Key::ArrowRight => Some(EKey::ArrowRight), + Key::ArrowUp => Some(EKey::ArrowUp), + Key::Escape => Some(EKey::Escape), + Key::Tab => Some(EKey::Tab), + Key::Backspace => Some(EKey::Backspace), + Key::Enter => Some(EKey::Enter), + Key::Space => Some(EKey::Space), + Key::Insert => Some(EKey::Insert), + Key::Delete => Some(EKey::Delete), + Key::Home => Some(EKey::Home), + Key::End => Some(EKey::End), + Key::PageUp => Some(EKey::PageUp), + Key::PageDown => Some(EKey::PageDown), + Key::Copy => Some(EKey::Copy), + Key::Cut => Some(EKey::Cut), + Key::Paste => Some(EKey::Paste), + Key::Colon => Some(EKey::Colon), + Key::Comma => Some(EKey::Comma), + Key::Backslash => Some(EKey::Backslash), + Key::Slash => Some(EKey::Slash), + Key::Pipe => Some(EKey::Pipe), + Key::Questionmark => Some(EKey::Questionmark), + Key::OpenBracket => Some(EKey::OpenBracket), + Key::CloseBracket => Some(EKey::CloseBracket), + Key::Backtick => Some(EKey::Backtick), + Key::Minus => Some(EKey::Minus), + Key::Period => Some(EKey::Period), + Key::Plus => Some(EKey::Plus), + Key::Equals => Some(EKey::Equals), + Key::Semicolon => Some(EKey::Semicolon), + Key::Quote => Some(EKey::Quote), + Key::Num0 => Some(EKey::Num0), + Key::Num1 => Some(EKey::Num1), + Key::Num2 => Some(EKey::Num2), + Key::Num3 => Some(EKey::Num3), + Key::Num4 => Some(EKey::Num4), + Key::Num5 => Some(EKey::Num5), + Key::Num6 => Some(EKey::Num6), + Key::Num7 => Some(EKey::Num7), + Key::Num8 => Some(EKey::Num8), + Key::Num9 => Some(EKey::Num9), + Key::A => Some(EKey::A), + Key::B => Some(EKey::B), + Key::C => Some(EKey::C), + Key::D => Some(EKey::D), + Key::E => Some(EKey::E), + Key::F => Some(EKey::F), + Key::G => Some(EKey::G), + Key::H => Some(EKey::H), + Key::I => Some(EKey::I), + Key::J => Some(EKey::J), + Key::K => Some(EKey::K), + Key::L => Some(EKey::L), + Key::M => Some(EKey::M), + Key::N => Some(EKey::N), + Key::O => Some(EKey::O), + Key::P => Some(EKey::P), + Key::Q => Some(EKey::Q), + Key::R => Some(EKey::R), + Key::S => Some(EKey::S), + Key::T => Some(EKey::T), + Key::U => Some(EKey::U), + Key::V => Some(EKey::V), + Key::W => Some(EKey::W), + Key::X => Some(EKey::X), + Key::Y => Some(EKey::Y), + Key::Z => Some(EKey::Z), + Key::F1 => Some(EKey::F1), + Key::F2 => Some(EKey::F2), + Key::F3 => Some(EKey::F3), + Key::F4 => Some(EKey::F4), + Key::F5 => Some(EKey::F5), + Key::F6 => Some(EKey::F6), + Key::F7 => Some(EKey::F7), + Key::F8 => Some(EKey::F8), + Key::F9 => Some(EKey::F9), + Key::F10 => Some(EKey::F10), + Key::F11 => Some(EKey::F11), + Key::F12 => Some(EKey::F12), + Key::F13 => Some(EKey::F13), + Key::F14 => Some(EKey::F14), + Key::F15 => Some(EKey::F15), + Key::F16 => Some(EKey::F16), + Key::F17 => Some(EKey::F17), + Key::F18 => Some(EKey::F18), + Key::F19 => Some(EKey::F19), + Key::F20 => Some(EKey::F20), + Key::F21 => Some(EKey::F21), + Key::F22 => Some(EKey::F22), + Key::F23 => Some(EKey::F23), + Key::F24 => Some(EKey::F24), + Key::F25 => Some(EKey::F25), + Key::F26 => Some(EKey::F26), + Key::F27 => Some(EKey::F27), + Key::F28 => Some(EKey::F28), + Key::F29 => Some(EKey::F29), + Key::F30 => Some(EKey::F30), + Key::F31 => Some(EKey::F31), + Key::F32 => Some(EKey::F32), + Key::F33 => Some(EKey::F33), + Key::F34 => Some(EKey::F34), + Key::F35 => Some(EKey::F35), _ => None, } } diff --git a/crates/egui_kittest/src/lib.rs b/crates/egui_kittest/src/lib.rs index 009f9073d97..4d17ebb89eb 100644 --- a/crates/egui_kittest/src/lib.rs +++ b/crates/egui_kittest/src/lib.rs @@ -3,8 +3,10 @@ mod builder; mod event; #[cfg(feature = "snapshot")] mod snapshot; + #[cfg(feature = "snapshot")] pub use snapshot::*; +use std::fmt::{Debug, Formatter}; #[cfg(feature = "wgpu")] mod texture_to_bytes; #[cfg(feature = "wgpu")] @@ -13,11 +15,11 @@ pub mod wgpu; pub use kittest; use std::mem; -use crate::event::{kittest_key_to_egui, pointer_button_to_egui}; +use crate::event::EventState; pub use accesskit_consumer; pub use builder::*; -use egui::{Event, Modifiers, Pos2, Rect, TexturesDelta, Vec2, ViewportId}; -use kittest::{ElementState, Node, Queryable, SimulatedEvent}; +use egui::{Pos2, Rect, TexturesDelta, Vec2, ViewportId}; +use kittest::{Node, Queryable}; /// The test Harness. This contains everything needed to run the test. /// Create a new Harness using [`Harness::new`] or [`Harness::builder`]. @@ -28,9 +30,13 @@ pub struct Harness<'a> { output: egui::FullOutput, texture_deltas: Vec, update_fn: Box, + event_state: EventState, +} - last_mouse_pos: Pos2, - modifiers: Modifiers, +impl<'a> Debug for Harness<'a> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + self.kittest.fmt(f) + } } impl<'a> Harness<'a> { @@ -62,9 +68,7 @@ impl<'a> Harness<'a> { ), texture_deltas: vec![mem::take(&mut output.textures_delta)], output, - - last_mouse_pos: Pos2::ZERO, - modifiers: Modifiers::NONE, + event_state: EventState::default(), } } @@ -114,59 +118,8 @@ impl<'a> Harness<'a> { /// This will call the app closure with the current context and update the Harness. pub fn run(&mut self) { for event in self.kittest.take_events() { - match event { - kittest::Event::ActionRequest(e) => { - self.input.events.push(Event::AccessKitActionRequest(e)); - } - kittest::Event::Simulated(e) => match e { - SimulatedEvent::CursorMoved { position } => { - self.input.events.push(Event::PointerMoved(Pos2::new( - position.x as f32, - position.y as f32, - ))); - } - SimulatedEvent::MouseInput { state, button } => { - let button = pointer_button_to_egui(button); - if let Some(button) = button { - self.input.events.push(Event::PointerButton { - button, - modifiers: self.modifiers, - pos: self.last_mouse_pos, - pressed: matches!(state, ElementState::Pressed), - }); - } - } - SimulatedEvent::Ime(text) => { - self.input.events.push(Event::Text(text)); - } - SimulatedEvent::KeyInput { state, key } => { - match key { - kittest::Key::Alt => { - self.modifiers.alt = matches!(state, ElementState::Pressed); - } - kittest::Key::Command => { - self.modifiers.command = matches!(state, ElementState::Pressed); - } - kittest::Key::Control => { - self.modifiers.ctrl = matches!(state, ElementState::Pressed); - } - kittest::Key::Shift => { - self.modifiers.shift = matches!(state, ElementState::Pressed); - } - _ => {} - } - let key = kittest_key_to_egui(key); - if let Some(key) = key { - self.input.events.push(Event::Key { - key, - modifiers: self.modifiers, - pressed: matches!(state, ElementState::Pressed), - repeat: false, - physical_key: None, - }); - } - } - }, + if let Some(event) = self.event_state.kittest_event_to_egui(event) { + self.input.events.push(event); } } From ddf79ce1a57f696c42b37336352a532e5fcc2d8b Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Fri, 11 Oct 2024 12:08:20 +0200 Subject: [PATCH 37/47] Use kittest from main --- Cargo.lock | 2 +- crates/egui_kittest/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d21f7981ef..30d09557179 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2348,7 +2348,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "kittest" version = "0.1.0" -source = "git+https://github.com/rerun-io/kittest?branch=impl-debug#240832d5d086ae0a9cf358af9450c0cef16fbeab" +source = "git+https://github.com/rerun-io/kittest?branch=main#1336a504aefd05f7e9aa7c9237ae44ba9e72acdd" dependencies = [ "accesskit", "accesskit_consumer", diff --git a/crates/egui_kittest/Cargo.toml b/crates/egui_kittest/Cargo.toml index ee161541d05..410403105b6 100644 --- a/crates/egui_kittest/Cargo.toml +++ b/crates/egui_kittest/Cargo.toml @@ -15,7 +15,7 @@ default = ["image?/png"] [dependencies] accesskit_consumer = "0.24.0" -kittest = { git = "https://github.com/rerun-io/kittest", version = "0.1", branch = "impl-debug" } +kittest = { git = "https://github.com/rerun-io/kittest", version = "0.1", branch = "main" } egui = { workspace = true, features = ["accesskit"] } # wgpu dependencies From 148e79a057caf3a1fb2533d41f656b2e7e64c712 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 12 Oct 2024 13:23:50 +0200 Subject: [PATCH 38/47] Review changes --- .gitignore | 4 ++-- Cargo.lock | 2 +- Cargo.toml | 3 +++ crates/egui_demo_lib/Cargo.toml | 4 ++-- crates/egui_kittest/Cargo.toml | 28 ++++++++++++++++++++-------- crates/egui_kittest/README.md | 2 +- crates/egui_kittest/src/builder.rs | 2 +- crates/egui_kittest/src/lib.rs | 5 ++++- 8 files changed, 34 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index fab7870a6e8..887de9da3de 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,9 @@ **/target **/target_ra **/target_wasm +**/tests/snapshots/**/*.diff.png +**/tests/snapshots/**/*.new.png /.*.json /.vscode /media/* .idea/ -**/tests/snapshots/**/*.new.png -**/tests/snapshots/**/*.diff.png diff --git a/Cargo.lock b/Cargo.lock index 30d09557179..43a25113bd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1384,8 +1384,8 @@ dependencies = [ name = "egui_kittest" version = "0.29.1" dependencies = [ - "accesskit_consumer", "dify", + "document-features", "egui", "egui-wgpu", "image", diff --git a/Cargo.toml b/Cargo.toml index 6ca4941abad..c50a51d76e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,15 +75,18 @@ ahash = { version = "0.8.11", default-features = false, features = [ backtrace = "0.3" bytemuck = "1.7.2" criterion = { version = "0.5.1", default-features = false } +dify = { version = "0.7", default-features = false } document-features = " 0.2.8" glow = "0.14" glutin = "0.32.0" glutin-winit = "0.5.0" home = "0.5.9" image = { version = "0.25", default-features = false } +kittest = { git = "https://github.com/rerun-io/kittest", version = "0.1", branch = "main"} log = { version = "0.4", features = ["std"] } nohash-hasher = "0.2" parking_lot = "0.12" +pollster = "0.3" puffin = "0.19" puffin_http = "0.16" ron = "0.8" diff --git a/crates/egui_demo_lib/Cargo.toml b/crates/egui_demo_lib/Cargo.toml index e98bf5d3406..f8f1f47f686 100644 --- a/crates/egui_demo_lib/Cargo.toml +++ b/crates/egui_demo_lib/Cargo.toml @@ -56,10 +56,10 @@ serde = { workspace = true, optional = true } [dev-dependencies] # when running tests we always want to use the `chrono` feature -egui_demo_lib = { features = ["chrono"], workspace = true } +egui_demo_lib = { workspace = true, features = ["chrono"] } criterion.workspace = true -egui_kittest = { workspace = true, features = ["default", "wgpu", "snapshot"] } +egui_kittest = { workspace = true, features = ["wgpu", "snapshot"] } wgpu = { workspace = true, features = ["metal"] } egui = { workspace = true, features = ["default_fonts"] } diff --git a/crates/egui_kittest/Cargo.toml b/crates/egui_kittest/Cargo.toml index 410403105b6..5063b59658b 100644 --- a/crates/egui_kittest/Cargo.toml +++ b/crates/egui_kittest/Cargo.toml @@ -1,30 +1,42 @@ [package] name = "egui_kittest" +version.workspace = true +authors = ["Lucas Meurer ", "Emil Ernerfeldt "] +description = "Testing library for egui based on kittest and AccessKit" edition.workspace = true -license.workspace = true rust-version.workspace = true -version.workspace = true +homepage = "https://github.com/emilk/egui" +license.workspace = true +readme = "./README.md" +repository = "https://github.com/emilk/egui" +categories = ["gui", "development-tools::testing", "accessibility"] +keywords = ["gui", "immediate", "egui", "testing", "accesskit"] +include = ["../LICENSE-APACHE", "../LICENSE-MIT", "**/*.rs", "Cargo.toml"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] +# Adds a wgpu-based test renderer. wgpu = ["dep:egui-wgpu", "dep:pollster", "dep:image"] -snapshot = ["dep:dify"] -default = ["image?/png"] +# Adds a dify-based image snapshot utility. +snapshot = ["dep:dify", "dep:image", "image/png"] + [dependencies] -accesskit_consumer = "0.24.0" -kittest = { git = "https://github.com/rerun-io/kittest", version = "0.1", branch = "main" } +kittest.workspace = true egui = { workspace = true, features = ["accesskit"] } # wgpu dependencies egui-wgpu = { workspace = true, optional = true } -pollster = { version = "0.3", optional = true } +pollster = { workspace = true, optional = true } image = { workspace = true, optional = true } # snapshot dependencies -dify = { version = "0.7.0", optional = true, default-features = false } +dify = { workspace = true, optional = true } + +## Enable this when generating docs. +document-features = { workspace = true, optional = true } [dev-dependencies] wgpu = { workspace = true, features = ["metal"] } diff --git a/crates/egui_kittest/README.md b/crates/egui_kittest/README.md index d9cfc35a2f2..78b46b662f6 100644 --- a/crates/egui_kittest/README.md +++ b/crates/egui_kittest/README.md @@ -1,6 +1,6 @@ # egui_kittest -Ui testing library for egui, based on [kittest](https://github.com/rerun-io/kittest) (a AccessKit based testing library). +Ui testing library for egui, based on [kittest](https://github.com/rerun-io/kittest) (an [AccessKit](https://github.com/AccessKit/accesskit) based testing library). ```rust use egui::accesskit::{Role, Toggled}; diff --git a/crates/egui_kittest/src/builder.rs b/crates/egui_kittest/src/builder.rs index b315ebe9967..bf54c624546 100644 --- a/crates/egui_kittest/src/builder.rs +++ b/crates/egui_kittest/src/builder.rs @@ -19,7 +19,7 @@ impl Default for HarnessBuilder { impl HarnessBuilder { /// Set the size of the window. #[inline] - pub fn with_size(mut self, size: Vec2) -> Self { + pub fn with_size(mut self, size: impl Into) -> Self { self.screen_rect.set_width(size.x); self.screen_rect.set_height(size.y); self diff --git a/crates/egui_kittest/src/lib.rs b/crates/egui_kittest/src/lib.rs index 4d17ebb89eb..fb5b4f7fb9a 100644 --- a/crates/egui_kittest/src/lib.rs +++ b/crates/egui_kittest/src/lib.rs @@ -1,4 +1,8 @@ #![doc = include_str!("../README.md")] +//! +//! ## Feature flags +#![cfg_attr(feature = "document-features", doc = document_features::document_features!())] + mod builder; mod event; #[cfg(feature = "snapshot")] @@ -16,7 +20,6 @@ pub use kittest; use std::mem; use crate::event::EventState; -pub use accesskit_consumer; pub use builder::*; use egui::{Pos2, Rect, TexturesDelta, Vec2, ViewportId}; use kittest::{Node, Queryable}; From 24f29d6635122212bf45912e5f82a1e023954fd2 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 12 Oct 2024 13:26:24 +0200 Subject: [PATCH 39/47] Remember mouse position --- crates/egui_kittest/src/builder.rs | 1 + crates/egui_kittest/src/event.rs | 75 ++++++++++++++++-------------- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/crates/egui_kittest/src/builder.rs b/crates/egui_kittest/src/builder.rs index bf54c624546..bf1daf3622b 100644 --- a/crates/egui_kittest/src/builder.rs +++ b/crates/egui_kittest/src/builder.rs @@ -20,6 +20,7 @@ impl HarnessBuilder { /// Set the size of the window. #[inline] pub fn with_size(mut self, size: impl Into) -> Self { + let size = size.into(); self.screen_rect.set_width(size.x); self.screen_rect.set_height(size.y); self diff --git a/crates/egui_kittest/src/event.rs b/crates/egui_kittest/src/event.rs index b1b90cb2220..5ac07488d0c 100644 --- a/crates/egui_kittest/src/event.rs +++ b/crates/egui_kittest/src/event.rs @@ -12,45 +12,48 @@ impl EventState { pub fn kittest_event_to_egui(&mut self, event: kittest::Event) -> Option { match event { kittest::Event::ActionRequest(e) => Some(Event::AccessKitActionRequest(e)), - kittest::Event::Simulated(e) => { - match e { - SimulatedEvent::CursorMoved { position } => Some(Event::PointerMoved( - Pos2::new(position.x as f32, position.y as f32), - )), - SimulatedEvent::MouseInput { state, button } => pointer_button_to_egui(button) - .map(|button| PointerButton { - button, - modifiers: self.modifiers, - pos: self.last_mouse_pos, - pressed: matches!(state, ElementState::Pressed), - }), - SimulatedEvent::Ime(text) => Some(Event::Text(text)), - SimulatedEvent::KeyInput { state, key } => { - match key { - kittest::Key::Alt => { - self.modifiers.alt = matches!(state, ElementState::Pressed); - } - kittest::Key::Command => { - self.modifiers.command = matches!(state, ElementState::Pressed); - } - kittest::Key::Control => { - self.modifiers.ctrl = matches!(state, ElementState::Pressed); - } - kittest::Key::Shift => { - self.modifiers.shift = matches!(state, ElementState::Pressed); - } - _ => {} + kittest::Event::Simulated(e) => match e { + SimulatedEvent::CursorMoved { position } => { + self.last_mouse_pos = Pos2::new(position.x as f32, position.y as f32); + Some(Event::PointerMoved(Pos2::new( + position.x as f32, + position.y as f32, + ))) + } + SimulatedEvent::MouseInput { state, button } => { + pointer_button_to_egui(button).map(|button| PointerButton { + button, + modifiers: self.modifiers, + pos: self.last_mouse_pos, + pressed: matches!(state, ElementState::Pressed), + }) + } + SimulatedEvent::Ime(text) => Some(Event::Text(text)), + SimulatedEvent::KeyInput { state, key } => { + match key { + kittest::Key::Alt => { + self.modifiers.alt = matches!(state, ElementState::Pressed); + } + kittest::Key::Command => { + self.modifiers.command = matches!(state, ElementState::Pressed); + } + kittest::Key::Control => { + self.modifiers.ctrl = matches!(state, ElementState::Pressed); + } + kittest::Key::Shift => { + self.modifiers.shift = matches!(state, ElementState::Pressed); } - kittest_key_to_egui(key).map(|key| Event::Key { - key, - modifiers: self.modifiers, - pressed: matches!(state, ElementState::Pressed), - repeat: false, - physical_key: None, - }) + _ => {} } + kittest_key_to_egui(key).map(|key| Event::Key { + key, + modifiers: self.modifiers, + pressed: matches!(state, ElementState::Pressed), + repeat: false, + physical_key: None, + }) } - } + }, } } } From 27414eae8a39183eda2b1d5f72cf5b1df6e4b053 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 12 Oct 2024 13:53:33 +0200 Subject: [PATCH 40/47] Add comment about threshold and for the SnapshotError variants --- crates/egui_kittest/src/lib.rs | 2 ++ crates/egui_kittest/src/snapshot.rs | 28 ++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/crates/egui_kittest/src/lib.rs b/crates/egui_kittest/src/lib.rs index fb5b4f7fb9a..f65dcecc031 100644 --- a/crates/egui_kittest/src/lib.rs +++ b/crates/egui_kittest/src/lib.rs @@ -56,6 +56,8 @@ impl<'a> Harness<'a> { let viewport = input.viewports.get_mut(&ViewportId::ROOT).unwrap(); viewport.native_pixels_per_point = Some(builder.dpi); + // We need to run egui for a single frame so that the AccessKit state can be initialized + // and users can immediately start querying for widgets. let mut output = ctx.run(input.clone(), &mut app); Self { diff --git a/crates/egui_kittest/src/snapshot.rs b/crates/egui_kittest/src/snapshot.rs index be061c05dda..9f7cf2a2637 100644 --- a/crates/egui_kittest/src/snapshot.rs +++ b/crates/egui_kittest/src/snapshot.rs @@ -5,16 +5,26 @@ use std::path::{Path, PathBuf}; #[derive(Debug)] pub enum SnapshotError { + /// Image did not match snapshot Diff { + /// Count of pixels that were different diff: i32, + /// Path where the diff image was saved diff_path: PathBuf, }, + /// Error opening the existing snapshot (it probably doesn't exist, check the + /// [`ImageError`] for more information) OpenSnapshot { + /// Path where the snapshot was expected to be path: PathBuf, - err: image::ImageError, + /// The error that occurred + err: ImageError, }, + /// The size of the image did not match the snapshot SizeMismatch { + /// Expected size expected: (u32, u32), + /// Actual size actual: (u32, u32), }, } @@ -82,7 +92,21 @@ pub fn try_image_snapshot(current: &image::RgbaImage, name: &str) -> Result<(), }); } - let result = dify::diff::get_results(previous, current.clone(), 0.1, true, None, &None, &None); + // Looking at dify's source code, the threshold is based on the distance between two colors in + // YIQ color space. + // The default is 0.1, but we'll try 0.0 because ideally the output should not change at all. + // We might have to increase the threshold if there are minor differences when running tests + // on different gpus or different backends. + let threshold = 0.0; + let result = dify::diff::get_results( + previous, + current.clone(), + threshold, + true, + None, + &None, + &None, + ); if let Some((diff, result_image)) = result { result_image.save(diff_path.clone()).unwrap(); From b2fe731a64ff5b9809e883b57c5ed42f5817d4dd Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 12 Oct 2024 14:05:10 +0200 Subject: [PATCH 41/47] Improved snapshot error handling --- crates/egui_kittest/src/snapshot.rs | 49 +++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/crates/egui_kittest/src/snapshot.rs b/crates/egui_kittest/src/snapshot.rs index 9f7cf2a2637..679927f9983 100644 --- a/crates/egui_kittest/src/snapshot.rs +++ b/crates/egui_kittest/src/snapshot.rs @@ -27,6 +27,13 @@ pub enum SnapshotError { /// Actual size actual: (u32, u32), }, + /// Error writing the snapshot output + WriteSnapshot { + /// Path where a file was expected to be written + path: PathBuf, + /// The error that occurred + err: ImageError, + }, } impl Display for SnapshotError { @@ -44,11 +51,11 @@ impl Display for SnapshotError { write!(f, "Missing snapshot: {path:?}") } err => { - write!(f, "Error reading snapshot: {err:?}") + write!(f, "Error reading snapshot: {err:?}\nAt: {path:?}") } }, err => { - write!(f, "Error decoding snapshot: {err:?}") + write!(f, "Error decoding snapshot: {err:?}\nAt: {path:?}") } }, Self::SizeMismatch { expected, actual } => { @@ -57,6 +64,9 @@ impl Display for SnapshotError { "Image size did not match snapshot. Expected: {expected:?}, Actual: {actual:?}" ) } + Self::WriteSnapshot { path, err } => { + write!(f, "Error writing snapshot: {err:?}\nAt: {path:?}") + } } } } @@ -69,23 +79,28 @@ pub fn try_image_snapshot(current: &image::RgbaImage, name: &str) -> Result<(), let snapshots_path = Path::new("tests/snapshots"); let path = snapshots_path.join(format!("{name}.png")); - std::fs::create_dir_all(path.parent().unwrap()).ok(); + std::fs::create_dir_all(path.parent().expect("Could not get snapshot folder")).ok(); let diff_path = snapshots_path.join(format!("{name}.diff.png")); let current_path = snapshots_path.join(format!("{name}.new.png")); - current.save(¤t_path).unwrap(); + current + .save(¤t_path) + .map_err(|err| SnapshotError::WriteSnapshot { + err, + path: current_path, + })?; let previous = match image::open(&path) { Ok(image) => image.to_rgba8(), Err(err) => { - maybe_update_snapshot(&path, current); + maybe_update_snapshot(&path, current)?; return Err(SnapshotError::OpenSnapshot { path, err }); } }; if previous.dimensions() != current.dimensions() { - maybe_update_snapshot(&path, current); + maybe_update_snapshot(&path, current)?; return Err(SnapshotError::SizeMismatch { expected: previous.dimensions(), actual: current.dimensions(), @@ -109,8 +124,13 @@ pub fn try_image_snapshot(current: &image::RgbaImage, name: &str) -> Result<(), ); if let Some((diff, result_image)) = result { - result_image.save(diff_path.clone()).unwrap(); - maybe_update_snapshot(&path, current); + result_image + .save(diff_path.clone()) + .map_err(|err| SnapshotError::WriteSnapshot { + path: diff_path.clone(), + err, + })?; + maybe_update_snapshot(&path, current)?; return Err(SnapshotError::Diff { diff, diff_path }); } else { // Delete old diff if it exists @@ -124,11 +144,20 @@ fn should_update_snapshots() -> bool { std::env::var("UPDATE_SNAPSHOTS").is_ok() } -fn maybe_update_snapshot(snapshot_path: &Path, current: &image::RgbaImage) { +fn maybe_update_snapshot( + snapshot_path: &Path, + current: &image::RgbaImage, +) -> Result<(), SnapshotError> { if should_update_snapshots() { - current.save(snapshot_path).unwrap(); + current + .save(snapshot_path) + .map_err(|err| SnapshotError::WriteSnapshot { + err, + path: snapshot_path.into(), + })?; println!("Updated snapshot: {snapshot_path:?}"); } + Ok(()) } /// Image snapshot test. From 554fc57da468622e60e43551e0807e1b759b6978 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 12 Oct 2024 14:07:28 +0200 Subject: [PATCH 42/47] Rename texture_to_bytes --- crates/egui_kittest/src/lib.rs | 2 +- .../src/{texture_to_bytes.rs => texture_to_image.rs} | 2 +- crates/egui_kittest/src/wgpu.rs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) rename crates/egui_kittest/src/{texture_to_bytes.rs => texture_to_image.rs} (97%) diff --git a/crates/egui_kittest/src/lib.rs b/crates/egui_kittest/src/lib.rs index f65dcecc031..106f920c9f4 100644 --- a/crates/egui_kittest/src/lib.rs +++ b/crates/egui_kittest/src/lib.rs @@ -12,7 +12,7 @@ mod snapshot; pub use snapshot::*; use std::fmt::{Debug, Formatter}; #[cfg(feature = "wgpu")] -mod texture_to_bytes; +mod texture_to_image; #[cfg(feature = "wgpu")] pub mod wgpu; diff --git a/crates/egui_kittest/src/texture_to_bytes.rs b/crates/egui_kittest/src/texture_to_image.rs similarity index 97% rename from crates/egui_kittest/src/texture_to_bytes.rs rename to crates/egui_kittest/src/texture_to_image.rs index 63335b09a7e..98803ac8a37 100644 --- a/crates/egui_kittest/src/texture_to_bytes.rs +++ b/crates/egui_kittest/src/texture_to_image.rs @@ -5,7 +5,7 @@ use std::iter; use std::mem::size_of; use std::sync::mpsc::channel; -pub(crate) fn texture_to_bytes(device: &Device, queue: &Queue, texture: &Texture) -> RgbaImage { +pub(crate) fn texture_to_image(device: &Device, queue: &Queue, texture: &Texture) -> RgbaImage { let buffer_dimensions = BufferDimensions::new(texture.width() as usize, texture.height() as usize); diff --git a/crates/egui_kittest/src/wgpu.rs b/crates/egui_kittest/src/wgpu.rs index ef3d8f6cdd2..c113fca22c3 100644 --- a/crates/egui_kittest/src/wgpu.rs +++ b/crates/egui_kittest/src/wgpu.rs @@ -1,4 +1,4 @@ -use crate::texture_to_bytes::texture_to_bytes; +use crate::texture_to_image::texture_to_image; use crate::Harness; use egui_wgpu::wgpu::{Backends, InstanceDescriptor, StoreOp, TextureFormat}; use egui_wgpu::{wgpu, ScreenDescriptor}; @@ -62,7 +62,7 @@ impl TestRenderer { let size = harness.ctx.screen_rect().size() * harness.ctx.pixels_per_point(); let screen = ScreenDescriptor { pixels_per_point: harness.ctx.pixels_per_point(), - size_in_pixels: [size.x as u32, size.y as u32], + size_in_pixels: [size.x.round() as u32, size.y.round() as u32], }; let tessellated = harness.ctx.tessellate( @@ -121,6 +121,6 @@ impl TestRenderer { self.device.poll(Maintain::Wait); - texture_to_bytes(&self.device, &self.queue, &texture) + texture_to_image(&self.device, &self.queue, &texture) } } From 97ecb25f2abb10ca48079788c270404e22d0a757 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 12 Oct 2024 14:12:31 +0200 Subject: [PATCH 43/47] Round screen size --- .../tests/snapshots/demos/B\303\251zier Curve.png" | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Code Example.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Context Menus.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Drag and Drop.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Extra Viewport.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Font Book.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Frame.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Highlighting.png | 4 ++-- .../tests/snapshots/demos/Interactive Container.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Multi Touch.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Painting.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Pan Zoom.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Panels.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Sliders.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Strip.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Table.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png | 4 ++-- crates/egui_demo_lib/tests/snapshots/demos/Window Options.png | 4 ++-- crates/egui_kittest/src/wgpu.rs | 4 ++-- 22 files changed, 44 insertions(+), 44 deletions(-) diff --git "a/crates/egui_demo_lib/tests/snapshots/demos/B\303\251zier Curve.png" "b/crates/egui_demo_lib/tests/snapshots/demos/B\303\251zier Curve.png" index 73a3fd5afe6..34125f1bdad 100644 --- "a/crates/egui_demo_lib/tests/snapshots/demos/B\303\251zier Curve.png" +++ "b/crates/egui_demo_lib/tests/snapshots/demos/B\303\251zier Curve.png" @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:baa595e6d1f67e09bb9303b925ae7e8bfcb1095869dedd15980f2da553286a51 -size 153229 +oid sha256:56ae71faf0786aedc9d78c8bfe822c1a138085f31c477a8117e4906189c66cdd +size 153413 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Code Example.png b/crates/egui_demo_lib/tests/snapshots/demos/Code Example.png index 23eaa8fcf42..0c43a9e95ef 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Code Example.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Code Example.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9a2a0b05229f926cf60dea21a37a9980af4a8aac8fba32a948143d5d78e55ed3 -size 97752 +oid sha256:7ce3216aa8082c797b59ebd245a519ec3c3ec405c3952650dc8a5a8c7458915d +size 97977 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Context Menus.png b/crates/egui_demo_lib/tests/snapshots/demos/Context Menus.png index 54dd2634a4a..43dafee1cbf 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Context Menus.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Context Menus.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d2077c0047e00e61983090268768a298bda1a6d3ae12312f58bdbe401725d03c -size 25151 +oid sha256:00d208432d86f03f9c3be94f4abf3810e8de367bedd13926f04f8e3762ed4f98 +size 25357 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Drag and Drop.png b/crates/egui_demo_lib/tests/snapshots/demos/Drag and Drop.png index c78be16618c..dd0007e498c 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Drag and Drop.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Drag and Drop.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d9466eaad8b642daf4b1ec07e9311294aacd8384c2ea657c24157b4a5efa59e4 -size 57546 +oid sha256:3ea0cad20d1e27e1a8119b72ae1e518b1f20c3a751502ff1fe98dd2d3187e6cd +size 57699 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Extra Viewport.png b/crates/egui_demo_lib/tests/snapshots/demos/Extra Viewport.png index 53f5dfe1896..69f7165ce92 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Extra Viewport.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Extra Viewport.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dbd2677a131cc8b1d4b2ebac547bcd907375dcdf90d26245be8a2f121bf5d74f -size 20333 +oid sha256:9e55adec917b41d56ea98122c8274e7430dfe3cc4b0faecd75c36cea88c97250 +size 20522 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Font Book.png b/crates/egui_demo_lib/tests/snapshots/demos/Font Book.png index 97b9f11c229..d253b2c3d8c 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Font Book.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Font Book.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e8731835a1ece9f3e5a97ba40b297c68a0d9a4061319e67878e7b6fe200ad24 -size 153264 +oid sha256:f33c094b90b4eef4bc9622d1e871c3943c557be9393ace007624ec895fb5d04b +size 153464 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Frame.png b/crates/egui_demo_lib/tests/snapshots/demos/Frame.png index 12277d7e5ba..f958a9ad942 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Frame.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Frame.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cdae677c8366af17eeb38445b5babee544bfc5070abaa7cfb48e42f41824fa56 -size 51884 +oid sha256:1990cddcfddec74973689b45aa4bb6d10e2ab4e45c70da03f7f5daef24f34b73 +size 52093 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Highlighting.png b/crates/egui_demo_lib/tests/snapshots/demos/Highlighting.png index 2e3df16ed60..ea24aca8e58 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Highlighting.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Highlighting.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5534494c0b8372639e9d24acc5f5c1e15ef5987a0820ca1e244c22e74e0f18bf -size 31102 +oid sha256:ca14bb1c6a95fd12d15442af9e9526d1afff224f4d16afee1d9ee0001a389154 +size 31294 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Interactive Container.png b/crates/egui_demo_lib/tests/snapshots/demos/Interactive Container.png index fa4fda5c871..9983bc4a5f8 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Interactive Container.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Interactive Container.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bfc85be4e113fb986157435d7acfb3381a56b21921317224abe649b4da36e798 -size 36819 +oid sha256:227a4b4acfe2f1eced25853268919e4e186277a44d4770be4940fcdbb28089e4 +size 36986 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png b/crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png index 39074b780bd..7d90397e41d 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e5ecc6c377e16bec5228859c839b661f456db224b4b329f4bae932ffff1624f7 -size 75710 +oid sha256:6a16afc76a9330b815d90c9b1d90b0f1672c6788d4bad35d5ced024d2e33b439 +size 75910 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Multi Touch.png b/crates/egui_demo_lib/tests/snapshots/demos/Multi Touch.png index 1c47a0c41c1..bdb5081196e 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Multi Touch.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Multi Touch.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9b74dcf0b119e03b231a4a288639c035021324bb9d8014c1f5228956d14f58b1 -size 324143 +oid sha256:3f9f1ef4f040bf66123ac1a4ab0c324cf77acfa9d75ac6f30409d50ade48db8e +size 324417 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Painting.png b/crates/egui_demo_lib/tests/snapshots/demos/Painting.png index 0f1c6d36246..3fba3df87fd 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Painting.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Painting.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:912b1d3c06864261d3a084de6e7cee9464841b6d54fd74699fb1541a39298bba -size 323025 +oid sha256:0765fe7c99045c712ca61ff9041ad52d35a72e2a10906cb53c8ee2e1616345ce +size 323299 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Pan Zoom.png b/crates/egui_demo_lib/tests/snapshots/demos/Pan Zoom.png index 84a8362c4de..ab70a0ca0a1 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Pan Zoom.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Pan Zoom.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ebe157e8a32125aaa6691d7fb231b1c557f2b30c261205579a605c25720bb73 -size 39762 +oid sha256:9d0f2cb342d0d362cebd55efa2597379b54ebf30409139bfd1dfe50e9e01e086 +size 39949 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Panels.png b/crates/egui_demo_lib/tests/snapshots/demos/Panels.png index c7cc349bc26..4b8649140d3 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Panels.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Panels.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f076b2781f4c5b74c64037ede4524d5f5c3a0ebdf54933da4f962e21600137b7 -size 456944 +oid sha256:d620ae7b39e45eb2a8dbd983de981a3bb01c17c779794d1d7f7a664e5d01859b +size 457277 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png b/crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png index 28154c31919..cd0098fb6aa 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:05e081870e934880dd1efcd479cfb5a07d5ccc40b4c773e1458b88c50b654a01 -size 210058 +oid sha256:65f868023382bae61ad9ce34ec0ef5d666e1d1058e72a406f917ebd12bd6e64a +size 210361 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Sliders.png b/crates/egui_demo_lib/tests/snapshots/demos/Sliders.png index 240fac5b5aa..4bd15045151 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Sliders.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Sliders.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:78a8fbe91614e4ea481cf2b773a7e881a3b64becdcad162ed3383af2d8a30960 -size 138692 +oid sha256:1b48c83f6a0ed1eff52711b294f4a40f1b4b5f9b2738a29b4de37a3f748070c4 +size 138886 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Strip.png b/crates/egui_demo_lib/tests/snapshots/demos/Strip.png index 8edd42a1fff..1bc42553c70 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Strip.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Strip.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3eb0943dd207a3ae8c20f503a5046351d1268d612e8a2230a199c70971ec0b58 -size 123211 +oid sha256:6e952386e6fcf854976ddc4fe66abd51d2f2cb2d7365c3dbdf4f8ad9a987d075 +size 123440 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Table.png b/crates/egui_demo_lib/tests/snapshots/demos/Table.png index 194d0a33a88..71f81cc331c 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Table.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Table.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7268ac64bfd6128f8f4ee5aee1d80a2612536550f3158f895d39af39b5f07cb0 -size 95381 +oid sha256:fea321e004352fd52c34ed9231fa41a37467665239ac57b20175d33252b91abb +size 95610 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png b/crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png index d0875f7db84..25d5e6eaac7 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4cd97103a9b536779fe7b86e940e82f0574bf774f6883f7d38c38dc880b4cddf -size 83206 +oid sha256:a7f649fea4527922b2e2ebe60e5935c9b5c1e53f5a6006e96cad74baccbc5fb5 +size 83406 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png b/crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png index 1749b834d1f..bda5aad0673 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b12673d58ff153449777baf01d183ab73a311c74f82c79c6c292f05752b72b92 -size 195954 +oid sha256:abbe31223ca2f34d608cfd27af6ebfe4eedcd05724481c514cfbcab767838834 +size 196557 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Window Options.png b/crates/egui_demo_lib/tests/snapshots/demos/Window Options.png index c37be4216ed..83ac40c476c 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Window Options.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Window Options.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71d56fa2d6ee4a7cfba57d1a186e1496046c4cb7509d7bb0d20d6446360bc93c -size 59316 +oid sha256:eeac86f381618379f57a702a7db47a4a6915885b4acea13b87457b2c6d2d2981 +size 59516 diff --git a/crates/egui_kittest/src/wgpu.rs b/crates/egui_kittest/src/wgpu.rs index c113fca22c3..b6085aae815 100644 --- a/crates/egui_kittest/src/wgpu.rs +++ b/crates/egui_kittest/src/wgpu.rs @@ -81,8 +81,8 @@ impl TestRenderer { let texture = self.device.create_texture(&wgpu::TextureDescriptor { label: Some("Egui Texture"), size: wgpu::Extent3d { - width: size.x as u32, - height: size.y as u32, + width: screen.size_in_pixels[0], + height: screen.size_in_pixels[1], depth_or_array_layers: 1, }, mip_level_count: 1, From c9d1bea00d64246456baf9fd12d920f9d4aeff6c Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 12 Oct 2024 14:42:57 +0200 Subject: [PATCH 44/47] Add step function --- crates/egui_kittest/src/lib.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/crates/egui_kittest/src/lib.rs b/crates/egui_kittest/src/lib.rs index 106f920c9f4..f4f00ad652f 100644 --- a/crates/egui_kittest/src/lib.rs +++ b/crates/egui_kittest/src/lib.rs @@ -60,7 +60,7 @@ impl<'a> Harness<'a> { // and users can immediately start querying for widgets. let mut output = ctx.run(input.clone(), &mut app); - Self { + let mut harness = Self { update_fn: Box::new(app), ctx, input, @@ -74,7 +74,10 @@ impl<'a> Harness<'a> { texture_deltas: vec![mem::take(&mut output.textures_delta)], output, event_state: EventState::default(), - } + }; + // Run the harness until it is stable, ensuring that all Areas are shown and animations are done + harness.run(); + harness } pub fn builder() -> HarnessBuilder { @@ -121,7 +124,7 @@ impl<'a> Harness<'a> { /// Run a frame. /// This will call the app closure with the current context and update the Harness. - pub fn run(&mut self) { + pub fn step(&mut self) { for event in self.kittest.take_events() { if let Some(event) = self.event_state.kittest_event_to_egui(event) { self.input.events.push(event); @@ -141,6 +144,17 @@ impl<'a> Harness<'a> { self.output = output; } + /// Run a few frames. + /// This will soon be changed to run the app until it is "stable", meaning + /// - all animations are done + /// - no more repaints are requested + pub fn run(&mut self) { + const STEPS: usize = 2; + for _ in 0..STEPS { + self.step(); + } + } + /// Access the [`egui::RawInput`] for the next frame. pub fn input(&self) -> &egui::RawInput { &self.input From 2b1fafa5a1744d1d369bbb601c006afa403db0c1 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 12 Oct 2024 15:14:18 +0200 Subject: [PATCH 45/47] Add more convenient snapshot api, allow reusing the TestRenderer and disable dithering --- .../src/demo/demo_app_windows.rs | 12 ++----- .../egui_demo_lib/src/demo/widget_gallery.rs | 11 ++---- .../snapshots/demos/B\303\251zier Curve.png" | 4 +-- .../tests/snapshots/demos/Code Editor.png | 4 +-- .../tests/snapshots/demos/Code Example.png | 4 +-- .../tests/snapshots/demos/Context Menus.png | 4 +-- .../tests/snapshots/demos/Dancing Strings.png | 4 +-- .../tests/snapshots/demos/Drag and Drop.png | 4 +-- .../tests/snapshots/demos/Extra Viewport.png | 4 +-- .../tests/snapshots/demos/Font Book.png | 4 +-- .../tests/snapshots/demos/Frame.png | 4 +-- .../tests/snapshots/demos/Highlighting.png | 4 +-- .../snapshots/demos/Interactive Container.png | 4 +-- .../tests/snapshots/demos/Misc Demos.png | 4 +-- .../tests/snapshots/demos/Multi Touch.png | 4 +-- .../tests/snapshots/demos/Painting.png | 4 +-- .../tests/snapshots/demos/Pan Zoom.png | 4 +-- .../tests/snapshots/demos/Panels.png | 4 +-- .../tests/snapshots/demos/Scrolling.png | 4 +-- .../tests/snapshots/demos/Sliders.png | 4 +-- .../tests/snapshots/demos/Strip.png | 4 +-- .../tests/snapshots/demos/Table.png | 4 +-- .../tests/snapshots/demos/Text Layout.png | 4 +-- .../tests/snapshots/demos/TextEdit.png | 4 +-- .../tests/snapshots/demos/Tooltips.png | 4 +-- .../tests/snapshots/demos/Undo Redo.png | 4 +-- .../tests/snapshots/demos/Window Options.png | 4 +-- .../tests/snapshots/widget_gallery.png | 4 +-- crates/egui_kittest/README.md | 2 +- crates/egui_kittest/src/snapshot.rs | 36 +++++++++++++++++-- crates/egui_kittest/src/wgpu.rs | 28 +++++++++++---- 31 files changed, 112 insertions(+), 81 deletions(-) diff --git a/crates/egui_demo_lib/src/demo/demo_app_windows.rs b/crates/egui_demo_lib/src/demo/demo_app_windows.rs index 929aec7b1b7..6a6becd599d 100644 --- a/crates/egui_demo_lib/src/demo/demo_app_windows.rs +++ b/crates/egui_demo_lib/src/demo/demo_app_windows.rs @@ -383,8 +383,6 @@ mod tests { use crate::demo::demo_app_windows::Demos; use egui::Vec2; use egui_kittest::kittest::Queryable; - use egui_kittest::try_image_snapshot; - use egui_kittest::wgpu::TestRenderer; use egui_kittest::Harness; #[test] @@ -409,10 +407,6 @@ mod tests { demo.show(ctx, &mut true); }); - // We need to run the app for multiple frames before all windows have the right size - harness.run(); - harness.run(); - let window = harness.node().children().next().unwrap(); // TODO(lucasmerlin): Windows should probably have a label? //let window = harness.get_by_name(name); @@ -420,12 +414,10 @@ mod tests { let size = window.raw_bounds().expect("window bounds").size(); harness.set_size(Vec2::new(size.width as f32, size.height as f32)); - // We need to run the app for some more frames... - harness.run(); + // Run the app for some more frames... harness.run(); - let image = TestRenderer::new().render(&harness); - let result = try_image_snapshot(&image, &format!("demos/{name}")); + let result = harness.try_wgpu_snapshot(&format!("demos/{name}")); if let Err(err) = result { errors.push(err); } diff --git a/crates/egui_demo_lib/src/demo/widget_gallery.rs b/crates/egui_demo_lib/src/demo/widget_gallery.rs index e8851a34c02..60c9bccf0a9 100644 --- a/crates/egui_demo_lib/src/demo/widget_gallery.rs +++ b/crates/egui_demo_lib/src/demo/widget_gallery.rs @@ -291,8 +291,6 @@ mod tests { use super::*; use crate::View; use egui::{CentralPanel, Context, Vec2}; - use egui_kittest::image_snapshot; - use egui_kittest::wgpu::TestRenderer; use egui_kittest::Harness; #[test] @@ -307,16 +305,11 @@ mod tests { demo.ui(ui); }); }; - let mut harness = Harness::builder() + let harness = Harness::builder() .with_size(Vec2::new(380.0, 550.0)) .with_dpi(2.0) .build(app); - // The first and second frames are slightly different, so we take the second frame - harness.run(); - - let image = TestRenderer::new().render(&harness); - - image_snapshot(&image, "widget_gallery"); + harness.wgpu_snapshot("widget_gallery"); } } diff --git "a/crates/egui_demo_lib/tests/snapshots/demos/B\303\251zier Curve.png" "b/crates/egui_demo_lib/tests/snapshots/demos/B\303\251zier Curve.png" index 34125f1bdad..ad7d9becfaa 100644 --- "a/crates/egui_demo_lib/tests/snapshots/demos/B\303\251zier Curve.png" +++ "b/crates/egui_demo_lib/tests/snapshots/demos/B\303\251zier Curve.png" @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56ae71faf0786aedc9d78c8bfe822c1a138085f31c477a8117e4906189c66cdd -size 153413 +oid sha256:4a725aa81433f301fda4ff8a28be869366332964995d1ae4ed996591596eb7e2 +size 31461 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Code Editor.png b/crates/egui_demo_lib/tests/snapshots/demos/Code Editor.png index a472ee0ded8..252c7c8f205 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Code Editor.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Code Editor.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4116ee3996fab18e591e8f82023f9a3aa6c7c8f4081cf33b34596f952f637e4c -size 88807 +oid sha256:36028d85f49ee77562250214237def2b676ecc9ed413d2fd8afc473d61289ca1 +size 32761 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Code Example.png b/crates/egui_demo_lib/tests/snapshots/demos/Code Example.png index 0c43a9e95ef..093b2c6a33b 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Code Example.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Code Example.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7ce3216aa8082c797b59ebd245a519ec3c3ec405c3952650dc8a5a8c7458915d -size 97977 +oid sha256:b8d4f004ee11ea68ae0f30657601b6e51403fcc3ca91fa5b8cdcb58585d8d40d +size 78318 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Context Menus.png b/crates/egui_demo_lib/tests/snapshots/demos/Context Menus.png index 43dafee1cbf..c29267377b7 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Context Menus.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Context Menus.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:00d208432d86f03f9c3be94f4abf3810e8de367bedd13926f04f8e3762ed4f98 -size 25357 +oid sha256:684648bea4ef5ce138fc25dbe7576e3937a797e87f2244cb3656ff8b4c2777f5 +size 11574 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Dancing Strings.png b/crates/egui_demo_lib/tests/snapshots/demos/Dancing Strings.png index 048bbdcfe4c..bdc4739c77f 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Dancing Strings.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Dancing Strings.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d6dad3634f4792d04351e2146e17f6aec3736d2ca11a6d3f524acba501114fe0 -size 144784 +oid sha256:ad38bff7cc5661be43e730e1b34c444b571b24b9f50791209496a1687610dd3d +size 20543 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Drag and Drop.png b/crates/egui_demo_lib/tests/snapshots/demos/Drag and Drop.png index dd0007e498c..035d4c13f7b 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Drag and Drop.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Drag and Drop.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ea0cad20d1e27e1a8119b72ae1e518b1f20c3a751502ff1fe98dd2d3187e6cd -size 57699 +oid sha256:ff78748f2571c49638d8fe8fdc859aaa5181758aad65498b7217551350fb9138 +size 20672 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Extra Viewport.png b/crates/egui_demo_lib/tests/snapshots/demos/Extra Viewport.png index 69f7165ce92..2d48a7e085f 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Extra Viewport.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Extra Viewport.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e55adec917b41d56ea98122c8274e7430dfe3cc4b0faecd75c36cea88c97250 -size 20522 +oid sha256:9dee66004cc47f5e27aaac34d137ff005eedf70cbfa3fbe43153dfd5c09d5e18 +size 10610 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Font Book.png b/crates/egui_demo_lib/tests/snapshots/demos/Font Book.png index d253b2c3d8c..69201f86154 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Font Book.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Font Book.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f33c094b90b4eef4bc9622d1e871c3943c557be9393ace007624ec895fb5d04b -size 153464 +oid sha256:0d1086b789f1fe0a8085c86f5b6a5ae7ecb53020f385b84775d6812ebc9d74a3 +size 132349 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Frame.png b/crates/egui_demo_lib/tests/snapshots/demos/Frame.png index f958a9ad942..ff4d08bafe8 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Frame.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Frame.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1990cddcfddec74973689b45aa4bb6d10e2ab4e45c70da03f7f5daef24f34b73 -size 52093 +oid sha256:08be378c01e376aab6e99ba3158519bbd7b301e815dc3447b57c9abab558977f +size 24237 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Highlighting.png b/crates/egui_demo_lib/tests/snapshots/demos/Highlighting.png index ea24aca8e58..a3cab2a3097 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Highlighting.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Highlighting.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ca14bb1c6a95fd12d15442af9e9526d1afff224f4d16afee1d9ee0001a389154 -size 31294 +oid sha256:53097b2c26ebcba8b8ad657ed8e52ca40261155e96dbbfca1e8eb01fce25d290 +size 17586 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Interactive Container.png b/crates/egui_demo_lib/tests/snapshots/demos/Interactive Container.png index 9983bc4a5f8..2bfbf20f91e 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Interactive Container.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Interactive Container.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:227a4b4acfe2f1eced25853268919e4e186277a44d4770be4940fcdbb28089e4 -size 36986 +oid sha256:d9c8395e6b4287b92d85a52ca2d47750f67abeb0ad88c6b42264bfe2e62fd09d +size 22283 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png b/crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png index 7d90397e41d..80cb5b5a177 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Misc Demos.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6a16afc76a9330b815d90c9b1d90b0f1672c6788d4bad35d5ced024d2e33b439 -size 75910 +oid sha256:38d21b6f8c364f86ad759e88ea1068649c23c58ded5d2953ba8ff1c83b46112f +size 63884 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Multi Touch.png b/crates/egui_demo_lib/tests/snapshots/demos/Multi Touch.png index bdb5081196e..23bad456c8c 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Multi Touch.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Multi Touch.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f9f1ef4f040bf66123ac1a4ab0c324cf77acfa9d75ac6f30409d50ade48db8e -size 324417 +oid sha256:83162f8c496a55230375dbc4cc636cfacf63049c913904bea9d06bdb56e63da6 +size 36282 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Painting.png b/crates/egui_demo_lib/tests/snapshots/demos/Painting.png index 3fba3df87fd..89a17e67406 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Painting.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Painting.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0765fe7c99045c712ca61ff9041ad52d35a72e2a10906cb53c8ee2e1616345ce -size 323299 +oid sha256:2537c681d1ffceb5cf4bf19d11295891525c96aea0b1422ab28f133021185be0 +size 17451 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Pan Zoom.png b/crates/egui_demo_lib/tests/snapshots/demos/Pan Zoom.png index ab70a0ca0a1..7ba225feae8 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Pan Zoom.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Pan Zoom.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d0f2cb342d0d362cebd55efa2597379b54ebf30409139bfd1dfe50e9e01e086 -size 39949 +oid sha256:79ce1dbf7627579d4e10de6494e34d8fd9685506d7b35cb3c9148f90f8c01366 +size 25144 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Panels.png b/crates/egui_demo_lib/tests/snapshots/demos/Panels.png index 4b8649140d3..585c126360c 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Panels.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Panels.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d620ae7b39e45eb2a8dbd983de981a3bb01c17c779794d1d7f7a664e5d01859b -size 457277 +oid sha256:5068df8549ffc91028addfec6f851f12a4de80e208b50b39e4d44b6aa2c7240e +size 261946 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png b/crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png index cd0098fb6aa..440a51f3871 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Scrolling.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:65f868023382bae61ad9ce34ec0ef5d666e1d1058e72a406f917ebd12bd6e64a -size 210361 +oid sha256:be2ac005fd5aafa293e21b162c22a09078e46d2d45b6208ce0f7841eeb05314a +size 183934 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Sliders.png b/crates/egui_demo_lib/tests/snapshots/demos/Sliders.png index 4bd15045151..e3a213176e9 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Sliders.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Sliders.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1b48c83f6a0ed1eff52711b294f4a40f1b4b5f9b2738a29b4de37a3f748070c4 -size 138886 +oid sha256:2e3436906f7ac459b7f4330a286937722e78ad885ae1e90f75be566e970a8ca7 +size 116899 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Strip.png b/crates/egui_demo_lib/tests/snapshots/demos/Strip.png index 1bc42553c70..69ec9e88230 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Strip.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Strip.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e952386e6fcf854976ddc4fe66abd51d2f2cb2d7365c3dbdf4f8ad9a987d075 -size 123440 +oid sha256:df7dabf726620ab5205ce153f692d1ba02365848ead7b79c95b873d5121d52a6 +size 25850 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Table.png b/crates/egui_demo_lib/tests/snapshots/demos/Table.png index 71f81cc331c..9f3618ba039 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Table.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Table.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fea321e004352fd52c34ed9231fa41a37467665239ac57b20175d33252b91abb -size 95610 +oid sha256:ae6c2e3aad43cfad3322340ff7045ec50ba01d58feb7b8acc5ba062a8a5c9ab8 +size 70230 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png b/crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png index 25d5e6eaac7..ff972ae484c 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Text Layout.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7f649fea4527922b2e2ebe60e5935c9b5c1e53f5a6006e96cad74baccbc5fb5 -size 83406 +oid sha256:ec0c2efff75cb8d621f5a4ea59f9fa8d3076521ca34f4499e07fb9dc8681d7ba +size 65916 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/TextEdit.png b/crates/egui_demo_lib/tests/snapshots/demos/TextEdit.png index ceeb5082b3d..7af3611b924 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/TextEdit.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/TextEdit.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7bd317d11a0f7e7b548736b93e24f421d18061394f1dcacfa0ab2774551109b7 -size 53625 +oid sha256:c04aee0a3a77a3691bb601a93871117500be917e0896138fda43251454ec04c2 +size 20988 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png b/crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png index bda5aad0673..4e7d8a9230b 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Tooltips.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:abbe31223ca2f34d608cfd27af6ebfe4eedcd05724481c514cfbcab767838834 -size 196557 +oid sha256:814d863deaa4fa029044da1783db87744f0d82e874edd6cbab16e712ed8715aa +size 59881 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Undo Redo.png b/crates/egui_demo_lib/tests/snapshots/demos/Undo Redo.png index c441c93d104..a635cdfabd0 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Undo Redo.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Undo Redo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:96f65efbb8a5a4a33454a7bf5f2a679cce078df9405c18207dddbcaace5a7553 -size 31041 +oid sha256:e682f5cb9ecb1bdf89281c2ba1612078e70e97f28c76facc64d717e4015ced6a +size 12977 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Window Options.png b/crates/egui_demo_lib/tests/snapshots/demos/Window Options.png index 83ac40c476c..f28774030aa 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Window Options.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Window Options.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eeac86f381618379f57a702a7db47a4a6915885b4acea13b87457b2c6d2d2981 -size 59516 +oid sha256:15acfb041cc53ef9bd966d6edd53a6b692cdb645ae5cf34bc20e70d403371c30 +size 34809 diff --git a/crates/egui_demo_lib/tests/snapshots/widget_gallery.png b/crates/egui_demo_lib/tests/snapshots/widget_gallery.png index 9c46e244fdf..273b85a6303 100644 --- a/crates/egui_demo_lib/tests/snapshots/widget_gallery.png +++ b/crates/egui_demo_lib/tests/snapshots/widget_gallery.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7752724def1a0f7e72c6b058c196c0d2d6b3ee05fe78761d105e69cf5200dc2a -size 177261 +oid sha256:5dc632962f8894c4f20a48c9b9e57d60470f3f83ef7f19d05854dba718610a2f +size 161820 diff --git a/crates/egui_kittest/README.md b/crates/egui_kittest/README.md index 78b46b662f6..86ccf551506 100644 --- a/crates/egui_kittest/README.md +++ b/crates/egui_kittest/README.md @@ -30,6 +30,6 @@ fn main() { // You can even render the ui and do image snapshot tests #[cfg(all(feature = "wgpu", feature = "snapshot"))] - egui_kittest::image_snapshot(&egui_kittest::wgpu::TestRenderer::new().render(&harness), "readme_example"); + harness.wgpu_snapshot("readme_example"); } ``` diff --git a/crates/egui_kittest/src/snapshot.rs b/crates/egui_kittest/src/snapshot.rs index 679927f9983..62b5b6ba8e8 100644 --- a/crates/egui_kittest/src/snapshot.rs +++ b/crates/egui_kittest/src/snapshot.rs @@ -1,3 +1,4 @@ +use crate::Harness; use image::ImageError; use std::fmt::Display; use std::io::ErrorKind; @@ -74,7 +75,8 @@ impl Display for SnapshotError { /// Image snapshot test. /// /// # Errors -/// Returns a [`SnapshotError`] if the image does not match the snapshot. +/// Returns a [`SnapshotError`] if the image does not match the snapshot or if there was an error +/// reading or writing the snapshot. pub fn try_image_snapshot(current: &image::RgbaImage, name: &str) -> Result<(), SnapshotError> { let snapshots_path = Path::new("tests/snapshots"); @@ -163,7 +165,8 @@ fn maybe_update_snapshot( /// Image snapshot test. /// /// # Panics -/// Panics if the image does not match the snapshot. +/// Panics if the image does not match the snapshot or if there was an error reading or writing the +/// snapshot. #[track_caller] pub fn image_snapshot(current: &image::RgbaImage, name: &str) { match try_image_snapshot(current, name) { @@ -173,3 +176,32 @@ pub fn image_snapshot(current: &image::RgbaImage, name: &str) { } } } + +#[cfg(feature = "wgpu")] +impl Harness<'_> { + /// Render a image using a default [`crate::wgpu::TestRenderer`] and compare it to the snapshot. + /// + /// # Errors + /// Returns a [`SnapshotError`] if the image does not match the snapshot or if there was an error + /// reading or writing the snapshot. + #[track_caller] + pub fn try_wgpu_snapshot(&self, name: &str) -> Result<(), SnapshotError> { + let image = crate::wgpu::TestRenderer::new().render(self); + try_image_snapshot(&image, name) + } + + /// Render a image using a default [`crate::wgpu::TestRenderer`] and compare it to the snapshot. + /// + /// # Panics + /// Panics if the image does not match the snapshot or if there was an error reading or writing the + /// snapshot. + #[track_caller] + pub fn wgpu_snapshot(&self, name: &str) { + match self.try_wgpu_snapshot(name) { + Ok(_) => {} + Err(err) => { + panic!("{}", err); + } + } + } +} diff --git a/crates/egui_kittest/src/wgpu.rs b/crates/egui_kittest/src/wgpu.rs index b6085aae815..e6a4c419379 100644 --- a/crates/egui_kittest/src/wgpu.rs +++ b/crates/egui_kittest/src/wgpu.rs @@ -7,9 +7,9 @@ use std::iter::once; use wgpu::Maintain; pub struct TestRenderer { - renderer: egui_wgpu::Renderer, device: wgpu::Device, queue: wgpu::Queue, + dithering: bool, } impl Default for TestRenderer { @@ -36,20 +36,34 @@ impl TestRenderer { )) .expect("Failed to create device"); - let renderer = egui_wgpu::Renderer::new(&device, TextureFormat::Rgba8Unorm, None, 1, true); + Self::create(device, queue) + } + pub fn create(device: wgpu::Device, queue: wgpu::Queue) -> Self { Self { - renderer, device, queue, + dithering: false, } } + pub fn with_dithering(mut self, dithering: bool) -> Self { + self.dithering = dithering; + self + } + pub fn render(&mut self, harness: &Harness<'_>) -> RgbaImage { + let mut renderer = egui_wgpu::Renderer::new( + &self.device, + TextureFormat::Rgba8Unorm, + None, + 1, + self.dithering, + ); + for delta in &harness.texture_deltas { for (id, image_delta) in &delta.set { - self.renderer - .update_texture(&self.device, &self.queue, *id, image_delta); + renderer.update_texture(&self.device, &self.queue, *id, image_delta); } } @@ -70,7 +84,7 @@ impl TestRenderer { harness.ctx.pixels_per_point(), ); - let user_buffers = self.renderer.update_buffers( + let user_buffers = renderer.update_buffers( &self.device, &self.queue, &mut encoder, @@ -113,7 +127,7 @@ impl TestRenderer { }) .forget_lifetime(); - self.renderer.render(&mut pass, &tessellated, &screen); + renderer.render(&mut pass, &tessellated, &screen); } self.queue From df24f74c3a7f8b3ea98ed61b121305b6665e5c99 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 12 Oct 2024 15:16:27 +0200 Subject: [PATCH 46/47] lints --- crates/egui_kittest/src/snapshot.rs | 7 +++++++ crates/egui_kittest/src/wgpu.rs | 1 + 2 files changed, 8 insertions(+) diff --git a/crates/egui_kittest/src/snapshot.rs b/crates/egui_kittest/src/snapshot.rs index 62b5b6ba8e8..a2c31a44130 100644 --- a/crates/egui_kittest/src/snapshot.rs +++ b/crates/egui_kittest/src/snapshot.rs @@ -10,28 +10,35 @@ pub enum SnapshotError { Diff { /// Count of pixels that were different diff: i32, + /// Path where the diff image was saved diff_path: PathBuf, }, + /// Error opening the existing snapshot (it probably doesn't exist, check the /// [`ImageError`] for more information) OpenSnapshot { /// Path where the snapshot was expected to be path: PathBuf, + /// The error that occurred err: ImageError, }, + /// The size of the image did not match the snapshot SizeMismatch { /// Expected size expected: (u32, u32), + /// Actual size actual: (u32, u32), }, + /// Error writing the snapshot output WriteSnapshot { /// Path where a file was expected to be written path: PathBuf, + /// The error that occurred err: ImageError, }, diff --git a/crates/egui_kittest/src/wgpu.rs b/crates/egui_kittest/src/wgpu.rs index e6a4c419379..c79f411433a 100644 --- a/crates/egui_kittest/src/wgpu.rs +++ b/crates/egui_kittest/src/wgpu.rs @@ -47,6 +47,7 @@ impl TestRenderer { } } + #[inline] pub fn with_dithering(mut self, dithering: bool) -> Self { self.dithering = dithering; self From e824e0171f7bbfcb5a4e613f2a86c8432806ca72 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Sat, 12 Oct 2024 15:29:08 +0200 Subject: [PATCH 47/47] Update example snapshot --- crates/egui_kittest/tests/snapshots/readme_example.png | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/egui_kittest/tests/snapshots/readme_example.png b/crates/egui_kittest/tests/snapshots/readme_example.png index 3c0fe1f2e3c..66b21e7f4bf 100644 --- a/crates/egui_kittest/tests/snapshots/readme_example.png +++ b/crates/egui_kittest/tests/snapshots/readme_example.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:20600ce0f58d9593b644a69c749b1c2aebd6b6839a9a9a52b8f6d709cd660b25 -size 2624 +oid sha256:36c1b432140456ea5cbb687076b1c910aea8b31affd33a0ece22218f60af2d6e +size 2296