commit 8e24f19a0759d2acf316417761259dccb1b787e4 Author: workD12 Date: Fri Jul 31 20:16:28 2026 +0300 0.0.1 diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..5ed6338 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[target.x86_64-pc-windows-gnu] +linker = "x86_64-w64-mingw32-gcc" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..9cc98d6 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,6226 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ab_glyph" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" + +[[package]] +name = "accesskit" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b7f7f85a7e5f68090000ed7622545829afd484d210358702ae4cb97dd0c320" +dependencies = [ + "uuid", +] + +[[package]] +name = "accesskit_atspi_common" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "023da0e5097f46df7092d5280b02efb9bbf8d93298daeced42652463e357d636" +dependencies = [ + "accesskit", + "accesskit_consumer", + "atspi-common", + "phf", + "serde", + "zvariant", +] + +[[package]] +name = "accesskit_consumer" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d10a236f96f87d70732e44520046785431ef01d5bcd6b041317bfadd2f88245" +dependencies = [ + "accesskit", + "hashbrown 0.16.1", +] + +[[package]] +name = "accesskit_ios" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "750c4e9f6ce888dfe8a10c0f1b5ceb646a7854fd46579d74919219d1bb314083" +dependencies = [ + "accesskit", + "accesskit_consumer", + "hashbrown 0.16.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-ui-kit 0.2.2", +] + +[[package]] +name = "accesskit_macos" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce02dc63b43f0c9296af9ac946312a2dc8814427d7a64d2d600971dac55b6076" +dependencies = [ + "accesskit", + "accesskit_consumer", + "hashbrown 0.16.1", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "accesskit_unix" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03e156ed3802e35eefe894ef2671bc6c889303d8a7e110b5e1b48f504b91362f" +dependencies = [ + "accesskit", + "accesskit_atspi_common", + "async-channel", + "async-executor", + "async-task", + "atspi", + "futures-lite", + "futures-util", + "serde", + "zbus", +] + +[[package]] +name = "accesskit_windows" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "106c2b961215864d1c2e703ee63269c25c4e80a577ffb2c1017b9c17dcdf83a1" +dependencies = [ + "accesskit", + "accesskit_consumer", + "hashbrown 0.16.1", + "static_assertions", + "windows", + "windows-core 0.62.2", +] + +[[package]] +name = "accesskit_winit" +version = "0.33.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5b41e63a69f36d9f1f41e70464c7e5f72eee485ef26aab19f0b4f86e6c0a84c" +dependencies = [ + "accesskit", + "accesskit_ios", + "accesskit_macos", + "accesskit_unix", + "accesskit_windows", + "raw-window-handle", + "winit", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.4", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "aligned" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee4508988c62edf04abd8d92897fca0c2995d907ce1dfeaf369dac3716a40685" +dependencies = [ + "as-slice", +] + +[[package]] +name = "aligned-vec" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b" +dependencies = [ + "equator", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android-activity" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f2a1bb052857d5dd49572219344a7332b31b76405648eabac5bc68978251bcd" +dependencies = [ + "android-properties", + "bitflags 2.13.1", + "cc", + "jni", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum", + "thiserror 2.0.19", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "annotate-snippets" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f211a51805bc641f3ad5b7664c77d2547af685cc33b4cd8d31964027a46f13f1" +dependencies = [ + "anstyle", + "memchr", + "unicode-width", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" + +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + +[[package]] +name = "as-slice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "async-broadcast" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-channel" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", +] + +[[package]] +name = "async-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" +dependencies = [ + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix 1.1.4", + "slab", + "windows-sys 0.61.2", +] + +[[package]] +name = "async-lock" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" +dependencies = [ + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix 1.1.4", +] + +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "async-signal" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 1.1.4", + "signal-hook-registry", + "slab", + "windows-sys 0.61.2", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae36dc4177970ef04fde5178d3e2429882def40e57a451f919c098f72baa6cec" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "atspi" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77886257be21c9cd89a4ae7e64860c6f0eefca799bb79127913052bd0eefb3d" +dependencies = [ + "atspi-common", + "atspi-proxies", +] + +[[package]] +name = "atspi-common" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20c5617155740c98003016429ad13fe43ce7a77b007479350a9f8bf95a29f63d" +dependencies = [ + "enumflags2", + "serde", + "static_assertions", + "zbus", + "zbus-lockstep", + "zbus-lockstep-macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "atspi-proxies" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2230e48787ed3eb4088996eab66a32ca20c0b67bbd4fd6cdfe79f04f1f04c9fc" +dependencies = [ + "atspi-common", + "serde", + "zbus", +] + +[[package]] +name = "auto_enums" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3091d68264354f211516b91dce6f71046e444fab1867716035f736667243affb" +dependencies = [ + "derive_utils", + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "av-scenechange" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f321d77c20e19b92c39e7471cf986812cbb46659d2af674adc4331ef3f18394" +dependencies = [ + "aligned", + "anyhow", + "arg_enum_proc_macro", + "arrayvec", + "log", + "num-rational", + "num-traits", + "pastey 0.1.1", + "rayon", + "thiserror 2.0.19", + "v_frame", + "y4m", +] + +[[package]] +name = "av1-grain" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cfddb07216410377231960af4fcab838eaa12e013417781b78bd95ee22077f8" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom 8.0.0", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7178fe5f7d460b13895ebb9dcb28a3a6216d2df2574a0806cb51b555d297f38" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bincode" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" +dependencies = [ + "serde", + "unty", +] + +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags 2.13.1", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 2.1.3", + "shlex 1.3.0", + "syn 2.0.119", +] + +[[package]] +name = "bit_field" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" +dependencies = [ + "serde_core", +] + +[[package]] +name = "bitstream-io" +version = "4.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eff00be299a18769011411c9def0d827e8f2d7bf0c3dbf53633147a8867fd1f" +dependencies = [ + "no_std_io2", +] + +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2 0.5.2", +] + +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2 0.6.4", +] + +[[package]] +name = "blocking" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" +dependencies = [ + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[package]] +name = "borsh" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a88b7ea17d208c4193f2c1e6de3c35fe71f98c96982d5ced308bdcc749ff6e1f" +dependencies = [ + "bytes", + "cfg_aliases", +] + +[[package]] +name = "built" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c0e531d93d39c34eef561e929e8a7f86d77a5af08aac4f6d6e39976c51858e9" + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "by_address" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" + +[[package]] +name = "bytemuck" +version = "1.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f65693059b6b9c588b9f62fed1cedbf0a8b805631457ea162d68f0de186f3de5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + +[[package]] +name = "calloop" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" +dependencies = [ + "bitflags 2.13.1", + "log", + "polling", + "rustix 0.38.44", + "slab", + "thiserror 1.0.69", +] + +[[package]] +name = "calloop" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dbf9978365bac10f54d1d4b04f7ce4427e51f71d61f2fe15e3fed5166474df7" +dependencies = [ + "bitflags 2.13.1", + "polling", + "rustix 1.1.4", + "slab", + "tracing", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +dependencies = [ + "calloop 0.13.0", + "rustix 0.38.44", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138efcf0940a02ebf0cc8d1eff41a1682a46b431630f4c52450d6265876021fa" +dependencies = [ + "calloop 0.14.4", + "rustix 1.1.4", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "cc" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5add81bb678e6cb321aff7fa0dc7689ad82b112dbc032cea19f91d6b8e3582b9" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex 2.0.1", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom 7.1.3", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" + +[[package]] +name = "cgl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +dependencies = [ + "libc", +] + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "clang-sys" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "157a8ba7b480713b56f4c09fd13fc3e0a22a5dfab8097ba61cbc5feef950788a" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clipboard-win" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" +dependencies = [ + "error-code", +] + +[[package]] +name = "clru" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "197fd99cb113a8d5d9b6376f3aa817f32c1078f2343b714fff7d2ca44fdf67d5" +dependencies = [ + "hashbrown 0.16.1", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-field-offset" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9713489fbc45a2d113f58d17448c73115d533ed27fd2f2d0e5e5c69663eaf19b" +dependencies = [ + "const-field-offset-macro", + "field-offset", +] + +[[package]] +name = "const-field-offset-macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b5dc851b7ea80cc4f69aa28632385ffd3e0f88014d53db3f2e5a781896ca783" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "convert_case" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "copypasta" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e6811e17f81fe246ef2bc553f76b6ee6ab41a694845df1d37e52a92b7bbd38a" +dependencies = [ + "clipboard-win", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", + "smithay-clipboard", + "x11-clipboard", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "core_maths" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30" +dependencies = [ + "libm", +] + +[[package]] +name = "countme" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crossbeam-channel" +version = "0.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "ctor" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83cf0d42651b16c6dfe68685716d18480d18a9c39c62d76e8cf3eb6ed5d8bcbf" +dependencies = [ + "dtor", +] + +[[package]] +name = "cursor-icon" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" + +[[package]] +name = "data-url" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" + +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.119", + "unicode-xid", +] + +[[package]] +name = "derive_utils" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc05a5d33db20c784f873e84934ad94bb209a090987ac5f62fede2c178234f23" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dispatch2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags 2.13.1", + "objc2 0.6.4", +] + +[[package]] +name = "displaydoc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "dlib" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab8ecd87370524b461f8557c119c405552c396ed91fc0a8eec68679eab26f94a" +dependencies = [ + "libloading", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dpi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" + +[[package]] +name = "drm" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80bc8c5c6c2941f70a55c15f8d9f00f9710ebda3ffda98075f996a0e6c92756f" +dependencies = [ + "bitflags 2.13.1", + "bytemuck", + "drm-ffi", + "drm-fourcc", + "libc", + "rustix 0.38.44", +] + +[[package]] +name = "drm-ffi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51a91c9b32ac4e8105dec255e849e0d66e27d7c34d184364fb93e469db08f690" +dependencies = [ + "drm-sys", + "rustix 1.1.4", +] + +[[package]] +name = "drm-fourcc" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4" + +[[package]] +name = "drm-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8e1361066d91f5ffccff060a3c3be9c3ecde15be2959c1937595f7a82a9f8" +dependencies = [ + "libc", + "linux-raw-sys 0.9.4", +] + +[[package]] +name = "dtor" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edf234dd1594d6dd434a8fb8cada51ddbbc593e40e4a01556a0b31c62da2775b" + +[[package]] +name = "either" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" + +[[package]] +name = "endi" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" + +[[package]] +name = "enumflags2" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "equator" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc" +dependencies = [ + "equator-macro", +] + +[[package]] +name = "equator-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "error-code" +version = "3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" + +[[package]] +name = "euclid" +version = "0.22.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a05365e3b1c6d1650318537c7460c6923f1abdd272ad6842baa2b509957a06" +dependencies = [ + "num-traits", +] + +[[package]] +name = "event-listener" +version = "5.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" +dependencies = [ + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "exr" +version = "1.74.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711fe42c9964295e01ee3fba3f9fe0e1d24b98886950d68efe81b1c76e21adf3" +dependencies = [ + "bit_field", + "half", + "lebe", + "miniz_oxide", + "num-complex", + "pulp", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] +name = "fastrand" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" + +[[package]] +name = "fax" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a" + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "femtovg" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43d05da42e81724c16d34a150fb7fda53d3f786e5a94673ee526ff8602f0f6a" +dependencies = [ + "bitflags 2.13.1", + "bytemuck", + "fnv", + "glow", + "imgref", + "itertools 0.14.0", + "log", + "rgb", + "slotmap", + "swash", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "filetime" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" +dependencies = [ + "cfg-if", + "libc", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fixed_decimal" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79c3c892f121fff406e5dd6b28c1b30096b95111c30701a899d4f2b18da6d1bd" +dependencies = [ + "displaydoc", + "smallvec", + "writeable", +] + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "font-types" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b38ad915f6dadd993ced50848a8291a543bd41ca62bc10740d5e64e2ab4cfd7" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "font-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a7299a780854a6d391be2ae1c8521c9368471b559dbfd6a8dbd9f407eaff100" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "fontdb" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "457e789b3d1202543297a350643cf459f836cade38934e7a4cf6a39e7cde2905" +dependencies = [ + "log", + "slotmap", + "tinyvec", + "ttf-parser", +] + +[[package]] +name = "fontique" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "274fa4f0f0a926ae182c7c076c078cce8a38471d15e61a102a02cac984be9813" +dependencies = [ + "hashbrown 0.17.1", + "linebender_resource_handle", + "memmap2", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-core-text", + "objc2-foundation 0.3.2", + "parlance", + "read-fonts 0.39.2", + "roxmltree", + "smallvec", + "windows", + "windows-core 0.62.2", + "yeslogic-fontconfig-sys", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea5190182e6915eb873ddbc16e23b711b6eb1f9c00a0d0a3a91b5f6228475225" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a88cf1f829d945f548cf8fec32c61b1f202b6d93b45848602fc02af4b12ad218" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" + +[[package]] +name = "futures-executor" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6754879cc9f2c66f88c6e5c35344bb0bdb0708b0352b1201815667c7eabc7458" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a" + +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "futures-sink" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307" + +[[package]] +name = "futures-task" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" + +[[package]] +name = "futures-util" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gbm" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce852e998d3ca5e4a97014fb31c940dc5ef344ec7d364984525fd11e8a547e6a" +dependencies = [ + "bitflags 2.13.1", + "drm", + "drm-fourcc", + "gbm-sys", + "libc", +] + +[[package]] +name = "gbm-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13a5f2acc785d8fb6bf6b7ab6bfb0ef5dad4f4d97e8e70bb8e470722312f76f" +dependencies = [ + "libc", +] + +[[package]] +name = "gethostname" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" +dependencies = [ + "rustix 1.1.4", + "windows-link", +] + +[[package]] +name = "getopts" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi 5.3.0", + "wasip2", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", +] + +[[package]] +name = "gif" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee8cfcc411d9adbbaba82fb72661cc1bcca13e8bba98b364e62b2dba8f960159" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "glob" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" + +[[package]] +name = "glow" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29038e1c483364cc6bb3cf78feee1816002e127c331a1eec55a4d202b9e1adb5" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12124de845cacfebedff80e877bb37b5b75c34c5a4c89e47e1cdd67fb6041325" +dependencies = [ + "bitflags 2.13.1", + "cfg_aliases", + "cgl", + "dispatch2", + "glutin_egl_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "libloading", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "once_cell", + "raw-window-handle", + "wayland-sys", + "windows-sys 0.52.0", + "x11-dl", +] + +[[package]] +name = "glutin-winit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" +dependencies = [ + "cfg_aliases", + "glutin", + "raw-window-handle", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c4680ba6195f424febdc3ba46e7a42a0e58743f2edb115297b86d7f8ecc02d2" +dependencies = [ + "gl_generator", + "windows-sys 0.52.0", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7bb2938045a88b612499fbcba375a77198e01306f52272e692f8c1f3751185" +dependencies = [ + "gl_generator", + "x11-dl", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "grid" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b40ca9252762c466af32d0b1002e91e4e1bc5398f77455e55474deb466355ff5" + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "harfrust" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d12c7c642d4ce8c2e784b4751a6634bd89583912265add4a679a8882d123fbcd" +dependencies = [ + "bitflags 2.13.1", + "bytemuck", + "read-fonts 0.39.2", + "smallvec", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "foldhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "htmlparser" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48ce8546b993eaf241d69ded33b1be6d205dd9857ec879d9d18bd05d3676e144" + +[[package]] +name = "i-slint-backend-linuxkms" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68e76f2b13846ca54bba6b8eb3b5454b26879ad987396d0a2d8abedc31a6c469" +dependencies = [ + "bytemuck", + "calloop 0.14.4", + "cfg_aliases", + "drm", + "gbm", + "glutin", + "i-slint-common", + "i-slint-core", + "i-slint-renderer-femtovg", + "i-slint-renderer-software", + "input", + "memmap2", + "nix", + "raw-window-handle", + "xkbcommon", +] + +[[package]] +name = "i-slint-backend-selector" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2247a4590a02a466b2f4916cc789dfe66247f6af826f00eb84a2685259a45c1c" +dependencies = [ + "cfg-if", + "cfg_aliases", + "i-slint-backend-linuxkms", + "i-slint-backend-testing", + "i-slint-backend-winit", + "i-slint-common", + "i-slint-core", + "i-slint-core-macros", + "i-slint-renderer-femtovg", +] + +[[package]] +name = "i-slint-backend-testing" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521e901e3d47ab829c0ef500c63155776208707cd93259e6a7803ed627fa2786" +dependencies = [ + "cfg_aliases", + "i-slint-common", + "i-slint-core", + "i-slint-renderer-software", + "vtable", +] + +[[package]] +name = "i-slint-backend-winit" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a27c7e8f53418d3017362465367b6612b6e439a68097d627d1b91c94b885f0a6" +dependencies = [ + "accesskit", + "accesskit_winit", + "block2 0.6.2", + "bytemuck", + "cfg-if", + "cfg_aliases", + "copypasta", + "derive_more", + "futures", + "glutin", + "glutin-winit", + "i-slint-common", + "i-slint-core", + "i-slint-core-macros", + "i-slint-renderer-femtovg", + "i-slint-renderer-skia", + "i-slint-renderer-software", + "imgref", + "lyon_path", + "muda", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", + "objc2-ui-kit 0.3.2", + "pin-weak", + "raw-window-handle", + "rgb", + "scoped-tls-hkt", + "scopeguard", + "softbuffer", + "strum", + "vtable", + "wasm-bindgen", + "web-sys", + "webbrowser", + "windows", + "winit", + "zbus", +] + +[[package]] +name = "i-slint-common" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e63f8ea55ba21e44567ae67d2b01a4f5d09bb1fab693b1e6c79d96bef9e456" +dependencies = [ + "derive_more", + "fontique", + "htmlparser", + "icu_decimal", + "icu_locale_core", + "icu_provider", + "pulldown-cmark", + "resvg", + "skrifa 0.42.1", +] + +[[package]] +name = "i-slint-compiler" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ea275b15a425c7f2f77481151e1f5f8f1ea83feae580273090ef6b9e192218" +dependencies = [ + "annotate-snippets", + "by_address", + "data-url", + "derive_more", + "i-slint-common", + "icu_normalizer", + "image", + "itertools 0.14.0", + "linked_hash_set", + "lyon_extra", + "lyon_path", + "num_enum", + "proc-macro2", + "quote", + "rayon", + "resvg", + "rowan", + "rspolib", + "skrifa 0.42.1", + "smol_str 0.3.6", + "strum", + "swash", + "typed-index-collections", + "unicode-segmentation", + "url", +] + +[[package]] +name = "i-slint-core" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e407dc2bd5385dcbdd9c1cf927213d2e4bacda667545abf8839c60f8290f754" +dependencies = [ + "async-channel", + "auto_enums", + "bitflags 2.13.1", + "cfg-if", + "chrono", + "clru", + "const-field-offset", + "derive_more", + "euclid", + "i-slint-common", + "i-slint-core-macros", + "icu_normalizer", + "image", + "ksni", + "lyon_algorithms", + "lyon_extra", + "lyon_geom", + "lyon_path", + "num-traits", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-foundation 0.3.2", + "once_cell", + "parley", + "pin-project", + "pin-weak", + "portable-atomic", + "raw-window-handle", + "resvg", + "rgb", + "scopeguard", + "skrifa 0.42.1", + "slab", + "strum", + "swash", + "sys-locale", + "taffy", + "unicode-linebreak", + "unicode-script", + "unicode-segmentation", + "vtable", + "wasm-bindgen", + "web-sys", + "web-time", + "windows", +] + +[[package]] +name = "i-slint-core-macros" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a842640da4c4d0909d25cc5a51e1f9cde02bd48f7fdfa94df10d595d4e3c80a" +dependencies = [ + "quote", + "serde_json", + "syn 2.0.119", +] + +[[package]] +name = "i-slint-renderer-femtovg" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78d0d99a18d66738b684758fe8460743a0aa0f64a96e05940942231a340085b1" +dependencies = [ + "cfg-if", + "const-field-offset", + "derive_more", + "femtovg", + "glow", + "i-slint-common", + "i-slint-core", + "i-slint-core-macros", + "imgref", + "lyon_path", + "pin-weak", + "rgb", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "i-slint-renderer-skia" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b6eed7f3f0a9a3d3ca6e8b9d4ca233371d989351fdb2a7ab88ec368b99e7b57" +dependencies = [ + "bytemuck", + "cfg-if", + "cfg_aliases", + "clru", + "const-field-offset", + "derive_more", + "glow", + "glutin", + "i-slint-common", + "i-slint-core", + "i-slint-core-macros", + "lyon_path", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", + "objc2-quartz-core 0.3.2", + "pin-weak", + "raw-window-handle", + "raw-window-metal", + "read-fonts 0.39.2", + "scoped-tls-hkt", + "skia-safe", + "softbuffer", + "unicode-segmentation", + "vtable", + "windows", + "write-fonts", +] + +[[package]] +name = "i-slint-renderer-software" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73496f164f8e471877c35e0fadb996dcc674922712abd9c2be2cbe80c58859bd" +dependencies = [ + "bytemuck", + "clru", + "derive_more", + "euclid", + "i-slint-common", + "i-slint-core", + "integer-sqrt", + "lyon_path", + "num-traits", + "skrifa 0.42.1", + "swash", + "zeno", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.58.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_decimal" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "288247df2e32aa776ac54fdd64de552149ac43cb840f2761811f0e8d09719dd4" +dependencies = [ + "displaydoc", + "fixed_decimal", + "icu_decimal_data", + "icu_locale", + "icu_locale_core", + "icu_plurals", + "icu_provider", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_decimal_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f14a5ca9e8af29eef62064f269078424283d90dbaffeac5225addf62aaabc22" + +[[package]] +name = "icu_locale" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5a396343c7208121dc86e35623d3dfe19814a7613cfd14964994cdc9c9a2e26" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_locale_data", + "icu_provider", + "potential_utf", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +dependencies = [ + "displaydoc", + "litemap", + "serde", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locale_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fdcc9ac77c6d74ff5cf6e65ef3181d6af32003b16fce3a77fb451d2f695993" + +[[package]] +name = "icu_normalizer" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" + +[[package]] +name = "icu_plurals" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a50023f1d49ad5c4333380328a0d4a19e4b9d6d842ec06639affd5ba47c8103" +dependencies = [ + "fixed_decimal", + "icu_locale", + "icu_plurals_data", + "icu_provider", + "zerovec", +] + +[[package]] +name = "icu_plurals_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8485497155dc865f901decb93ecc20d3e467df67bfeceb91e3ba34e2b11e8e1d" + +[[package]] +name = "icu_properties" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" + +[[package]] +name = "icu_provider" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +dependencies = [ + "displaydoc", + "icu_locale_core", + "serde", + "stable_deref_trait", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_segmenter" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c0794db0b1a86193ac9c48768d0e6c52c54448e0870ad87907d456ee0dac964" +dependencies = [ + "icu_collections", + "icu_locale", + "icu_provider", + "icu_segmenter_data", + "potential_utf", + "utf8_iter", + "zerovec", +] + +[[package]] +name = "icu_segmenter_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a2c462a4d927d512f5f882a033ddd62f33a05bb9f230d98f736ac3dc85938f" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "image" +version = "0.25.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104" +dependencies = [ + "bytemuck", + "byteorder-lite", + "color_quant", + "exr", + "gif", + "image-webp", + "moxcms", + "num-traits", + "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3" +dependencies = [ + "byteorder-lite", + "quick-error", +] + +[[package]] +name = "imagesize" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e54e57b4c48b40f7aec75635392b12b3421fa26fe8b4332e63138ed278459c" + +[[package]] +name = "imgref" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89194689a993ab15268672e99e7b0e19da2da3268ac682e8f02d29d4d1434cd7" + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + +[[package]] +name = "input" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9793345a65d71317763a33066b5d8351f8760dde8d4930fe9e39b5f14a7959d" +dependencies = [ + "bitflags 2.13.1", + "input-sys", + "libc", + "log", + "udev", +] + +[[package]] +name = "input-sys" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36eee07d8e02bd95bf52b2e642cf13d33701b94c6e4b04fbf1d1fb07e9cb19e7" + +[[package]] +name = "integer-sqrt" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" +dependencies = [ + "num-traits", +] + +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys 0.4.1", + "log", + "simd_cesu8", + "thiserror 2.0.19", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.119", +] + +[[package]] +name = "jni-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "keyboard-types" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" +dependencies = [ + "bitflags 2.13.1", + "serde", + "unicode-segmentation", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "ksni" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "814b44c24cd2cb236c3b8a41c7f08237b452a8e76ecaa81f1cec40b5b678215b" +dependencies = [ + "async-executor", + "async-io", + "async-lock", + "futures-channel", + "futures-lite", + "futures-util", + "pastey 0.2.3", + "serde", + "task-local", + "zbus", +] + +[[package]] +name = "kurbo" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b60dfc32f652b926df6192e55525b16d186c69d47876c3ead4da5cc9f8450e2" +dependencies = [ + "arrayvec", + "euclid", + "polycool", + "smallvec", +] + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" + +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "libfuzzer-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9fd2f41a1cba099f79a0b6b6c35656cf7c03351a7bae8ff0f28f25270f929d2" +dependencies = [ + "arbitrary", + "cc", +] + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "libredox" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652" +dependencies = [ + "bitflags 2.13.1", + "libc", + "plain", + "redox_syscall 0.9.1", +] + +[[package]] +name = "libudev-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "linebender_resource_handle" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a5ff6bcca6c4867b1c4fd4ef63e4db7436ef363e0ad7531d1558856bae64f4" + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linked_hash_set" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "984fb35d06508d1e69fc91050cceba9c0b748f983e6739fa2c7a9237154c52c8" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + +[[package]] +name = "log" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" + +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + +[[package]] +name = "lyon_algorithms" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8575c0d003ae459399623c4def180c63b77f343b1a7fee64f249b349e7699a31" +dependencies = [ + "lyon_path", + "num-traits", +] + +[[package]] +name = "lyon_extra" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7755f08423275157ad1680aaecc9ccb7e0cc633da3240fea2d1522935cc15c72" +dependencies = [ + "lyon_path", + "thiserror 2.0.19", +] + +[[package]] +name = "lyon_geom" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4336502e29e32af93cf2dad2214ed6003c17ceb5bd499df77b1de663b9042b92" +dependencies = [ + "arrayvec", + "euclid", + "num-traits", +] + +[[package]] +name = "lyon_path" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c463f9c428b7fc5ec885dcd39ce4aa61e29111d0e33483f6f98c74e89d8621e" +dependencies = [ + "lyon_geom", + "num-traits", +] + +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "memmap2" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "moxcms" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b" +dependencies = [ + "num-traits", + "pxfm", +] + +[[package]] +name = "muda" +version = "0.19.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd04e60bc0b07438a6771710ee1698f98f6ebbc7f89b61264af1563b8aeb878" +dependencies = [ + "crossbeam-channel", + "dpi", + "keyboard-types", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "once_cell", + "png", + "thiserror 2.0.19", + "windows-sys 0.61.2", +] + +[[package]] +name = "natord" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308d96db8debc727c3fd9744aac51751243420e46edf401010908da7f8d5e57c" + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.13.1", + "jni-sys 0.3.1", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys 0.3.1", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags 2.13.1", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "no_std_io2" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418abd1b6d34fbf6cae440dc874771b0525a604428704c76e48b29a5e67b8003" +dependencies = [ + "memchr", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + +[[package]] +name = "num-bigint" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "bytemuck", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.13.1", + "block2 0.5.1", + "libc", + "objc2 0.5.2", + "objc2-core-data 0.2.2", + "objc2-core-image 0.2.2", + "objc2-foundation 0.2.2", + "objc2-quartz-core 0.2.2", +] + +[[package]] +name = "objc2-app-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" +dependencies = [ + "bitflags 2.13.1", + "block2 0.6.2", + "libc", + "objc2 0.6.4", + "objc2-cloud-kit 0.3.2", + "objc2-core-data 0.3.2", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image 0.3.2", + "objc2-core-text", + "objc2-core-video", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.13.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" +dependencies = [ + "bitflags 2.13.1", + "objc2 0.6.4", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.13.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-data" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" +dependencies = [ + "bitflags 2.13.1", + "objc2 0.6.4", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.13.1", + "dispatch2", + "objc2 0.6.4", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" +dependencies = [ + "bitflags 2.13.1", + "dispatch2", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-io-surface", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal 0.2.2", +] + +[[package]] +name = "objc2-core-image" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" +dependencies = [ + "objc2 0.6.4", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-contacts", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-text" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" +dependencies = [ + "bitflags 2.13.1", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-core-graphics", +] + +[[package]] +name = "objc2-core-video" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" +dependencies = [ + "bitflags 2.13.1", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-io-surface", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.13.1", + "block2 0.5.1", + "dispatch", + "libc", + "objc2 0.5.2", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags 2.13.1", + "block2 0.6.2", + "objc2 0.6.4", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" +dependencies = [ + "bitflags 2.13.1", + "objc2 0.6.4", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.13.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-metal" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0125f776a10d00af4152d74616409f0d4a2053a6f57fa5b7d6aa2854ac04794" +dependencies = [ + "bitflags 2.13.1", + "objc2 0.6.4", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.13.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal 0.2.2", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" +dependencies = [ + "bitflags 2.13.1", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.13.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-cloud-kit 0.2.2", + "objc2-core-data 0.2.2", + "objc2-core-image 0.2.2", + "objc2-core-location", + "objc2-foundation 0.2.2", + "objc2-link-presentation", + "objc2-quartz-core 0.2.2", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" +dependencies = [ + "bitflags 2.13.1", + "block2 0.6.2", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.13.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +dependencies = [ + "critical-section", + "portable-atomic", +] + +[[package]] +name = "orbclient" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5df339f526ea9a60e371768d50efc2f2508c7203290731565d1f7a6f71d21747" +dependencies = [ + "libc", + "libredox", +] + +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b" +dependencies = [ + "ttf-parser", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parlance" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b6937eda350acc1a5d05872c3cbf99fe78619c269096e2be3d4a350058639d5" + +[[package]] +name = "parley" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1cfcf399c774719fb1fa51bc6b91e86bdf003b03202a0902f1827ba6750746" +dependencies = [ + "fontique", + "harfrust", + "hashbrown 0.17.1", + "icu_normalizer", + "icu_properties", + "icu_segmenter", + "linebender_resource_handle", + "parlance", + "parley_data", + "skrifa 0.42.1", +] + +[[package]] +name = "parley_data" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1d3755e2cc12c0625b0cd2f2773c6a37dd11d1531940c945ade4aeb78f2b145" +dependencies = [ + "icu_properties", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pastey" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" + +[[package]] +name = "pastey" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_macros", + "phf_shared", + "serde", +] + +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared", +] + +[[package]] +name = "phf_macros" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + +[[package]] +name = "pin-project" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pin-weak" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b330c9d1b92dfe68442ca20b009c717d5f0b1e3cf4965e62f704c3c6e95a1305" + +[[package]] +name = "piper" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +name = "png" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" +dependencies = [ + "bitflags 2.13.1", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.5.2", + "pin-project-lite", + "rustix 1.1.4", + "windows-sys 0.61.2", +] + +[[package]] +name = "polycool" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50596ddc09eb5ad5f75cacd40209568e66df71baf86e1499a0e99c4cff12a5a6" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "portable-atomic" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3" +dependencies = [ + "critical-section", +] + +[[package]] +name = "potential_utf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +dependencies = [ + "serde_core", + "writeable", + "zerovec", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.119", +] + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4488a4a36b9a4ba6b9334a32a39971f77c1436ec82c38707bce707699cc3bbcb" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "pulldown-cmark" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f068eba8e7071c5f9511831b44f32c740d5adf574e990f946ddb53db2f314e" +dependencies = [ + "bitflags 2.13.1", + "getopts", + "memchr", + "pulldown-cmark-escape", + "unicase", +] + +[[package]] +name = "pulldown-cmark-escape" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" + +[[package]] +name = "pulp" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046aa45b989642ec2e4717c8e72d677b13edd831a4d3b6cf37d9a3e54912496a" +dependencies = [ + "bytemuck", + "cfg-if", + "libm", + "num-complex", + "paste", + "pulp-wasm-simd-flag", + "raw-cpuid", + "reborrow", + "version_check", +] + +[[package]] +name = "pulp-wasm-simd-flag" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d8f70e07b9c3962945a74e59ca1c511bba65b6419468acc217c457d93f3c740" + +[[package]] +name = "pxfm" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea" + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quick-xml" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rand" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rav1e" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b6dd56e85d9483277cde964fd1bdb0428de4fec5ebba7540995639a21cb32b" +dependencies = [ + "aligned-vec", + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av-scenechange", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools 0.14.0", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "paste", + "profiling", + "rand", + "rand_chacha", + "simd_helpers", + "thiserror 2.0.19", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e52310197d971b0f5be7fe6b57530dcd27beb35c1b013f29d66c1ad73fbbcc45" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + +[[package]] +name = "raw-cpuid" +version = "11.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" +dependencies = [ + "bitflags 2.13.1", +] + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "raw-window-metal" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40d213455a5f1dc59214213c7330e074ddf8114c9a42411eb890c767357ce135" +dependencies = [ + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", +] + +[[package]] +name = "rayon" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rcalc" +version = "0.1.0" +dependencies = [ + "slint", + "slint-build", +] + +[[package]] +name = "read-fonts" +version = "0.39.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4ed38b89c2c77ff968c524145ad65fb010f38af5c7a224b53b81d47ac2daa81" +dependencies = [ + "bytemuck", + "font-types 0.11.3", +] + +[[package]] +name = "read-fonts" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046a7d674daf459825b32f5062056d6882db0d2f5a479fbd76ccfc870ac18709" +dependencies = [ + "bytemuck", + "font-types 0.12.2", + "once_cell", +] + +[[package]] +name = "reborrow" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03251193000f4bd3b042892be858ee50e8b3719f2b08e5833ac4353724632430" + +[[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_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.13.1", +] + +[[package]] +name = "redox_syscall" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07507be7b4a5f9f26eeb41eeaebb1f5a7ff29dfb29739facc21d35bf8b11c21e" +dependencies = [ + "bitflags 2.13.1", +] + +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "resvg" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be183ad6a216aa96f33e4c8033b0988b8b3ea6fd2359d19af5bac4643fd8e81" +dependencies = [ + "gif", + "image-webp", + "log", + "pico-args", + "rgb", + "svgtypes", + "tiny-skia 0.12.0", + "usvg", + "zune-jpeg", +] + +[[package]] +name = "rgb" +version = "0.8.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "rowan" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "417a3a9f582e349834051b8a10c8d71ca88da4211e4093528e36b9845f6b5f21" +dependencies = [ + "countme", + "hashbrown 0.14.5", + "rustc-hash 1.1.0", + "text-size", +] + +[[package]] +name = "roxmltree" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1964b10c76125c36f8afe190065a4bf9a87bf324842c05701330bba9f1cacbb" +dependencies = [ + "memchr", +] + +[[package]] +name = "rspolib" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fda9a7796aff63a7b1b39ccc93fffaaf65e20042984b4843041a49ca4677535" +dependencies = [ + "lazy_static", + "natord", + "snafu", + "unicode-linebreak", + "unicode-width", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hash" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.13.1", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags 2.13.1", + "errno", + "libc", + "linux-raw-sys 0.12.1", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "rustybuzz" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3c7c96f8a08ee34eff8857b11b49b07d71d1c3f4e88f8a88d4c9e9f90b1702" +dependencies = [ + "bitflags 2.13.1", + "bytemuck", + "core_maths", + "log", + "smallvec", + "ttf-parser", + "unicode-bidi-mirroring", + "unicode-ccc", + "unicode-properties", + "unicode-script", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scoped-tls-hkt" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9603871ffe5df3ac39cb624790c296dbd47a400d202f56bf3e414045099524d" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sctk-adwaita" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" +dependencies = [ + "ab_glyph", + "log", + "memmap2", + "smithay-client-toolkit 0.19.2", + "tiny-skia 0.11.4", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_repr" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + +[[package]] +name = "simd_cesu8" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "simplecss" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9c6883ca9c3c7c90e888de77b7a5c849c779d25d74a1269b0218b14e8b136c" +dependencies = [ + "log", +] + +[[package]] +name = "siphasher" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" + +[[package]] +name = "skia-bindings" +version = "0.99.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2d1c3ebd697c0cbded0145e9204a38fa6b268446051b7196d0a096414ea7f3" +dependencies = [ + "bindgen", + "cc", + "flate2", + "heck", + "pkg-config", + "regex", + "serde_json", + "tar", + "toml", +] + +[[package]] +name = "skia-safe" +version = "0.99.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f512ac418a64194842dd05566320805dad1c957c521039db2486fd6368865bc" +dependencies = [ + "bitflags 2.13.1", + "skia-bindings", + "windows", +] + +[[package]] +name = "skrifa" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c34617370ae968efb7161bb2beb517d9084659aae19e24b89e3db25b46e4564" +dependencies = [ + "bytemuck", + "read-fonts 0.39.2", +] + +[[package]] +name = "skrifa" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819ab7d62b1d3e72d9d9dea5650bac30424f9111364bb94928dbf5ecad1baa68" +dependencies = [ + "bytemuck", + "read-fonts 0.41.0", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "slint" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce12038f57f8f3a423564b0c9301a2ab3fda4246e4cbadd6b97acf9124bdc315" +dependencies = [ + "const-field-offset", + "i-slint-backend-selector", + "i-slint-common", + "i-slint-core", + "i-slint-core-macros", + "i-slint-renderer-femtovg", + "i-slint-renderer-software", + "num-traits", + "once_cell", + "pin-weak", + "slint-macros", + "unicode-segmentation", + "vtable", +] + +[[package]] +name = "slint-build" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76684c11441f775b10bbc7b0e6b3016a39f17efdd659ffca112f17cfd6bdaed1" +dependencies = [ + "derive_more", + "fontique", + "i-slint-compiler", + "spin_on", + "toml_edit", +] + +[[package]] +name = "slint-macros" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f2a763e72e1e53c496f571d36327e777da1eb0d9e58fceb83890c2a83ee7223" +dependencies = [ + "i-slint-compiler", + "proc-macro2", + "quote", + "spin_on", +] + +[[package]] +name = "slotmap" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "smithay-client-toolkit" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +dependencies = [ + "bitflags 2.13.1", + "calloop 0.13.0", + "calloop-wayland-source 0.3.0", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix 0.38.44", + "thiserror 1.0.69", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + +[[package]] +name = "smithay-client-toolkit" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0" +dependencies = [ + "bitflags 2.13.1", + "calloop 0.14.4", + "calloop-wayland-source 0.4.1", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix 1.1.4", + "thiserror 2.0.19", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-experimental", + "wayland-protocols-misc", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + +[[package]] +name = "smithay-clipboard" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71704c03f739f7745053bde45fa203a46c58d25bc5c4efba1d9a60e9dba81226" +dependencies = [ + "libc", + "smithay-client-toolkit 0.20.0", + "wayland-backend", +] + +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + +[[package]] +name = "smol_str" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aaa7368fcf4852a4c2dd92df0cace6a71f2091ca0a23391ce7f3a31833f1523" +dependencies = [ + "borsh", + "serde_core", +] + +[[package]] +name = "snafu" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e84b3f4eacbf3a1ce05eac6763b4d629d60cbc94d632e4092c54ade71f1e1a2" +dependencies = [ + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1c97747dbf44bb1ca44a561ece23508e99cb592e862f22222dcf42f51d1e451" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "softbuffer" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aac18da81ebbf05109ab275b157c22a653bb3c12cf884450179942f81bcbf6c3" +dependencies = [ + "as-raw-xcb-connection", + "bytemuck", + "fastrand", + "js-sys", + "memmap2", + "ndk", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", + "raw-window-handle", + "redox_syscall 0.5.18", + "rustix 1.1.4", + "tiny-xlib", + "tracing", + "wasm-bindgen", + "wayland-backend", + "wayland-client", + "wayland-sys", + "web-sys", + "windows-sys 0.61.2", + "x11rb", +] + +[[package]] +name = "spin_on" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076e103ed41b9864aa838287efe5f4e3a7a0362dd00671ae62a212e5e4612da2" +dependencies = [ + "pin-utils", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strict-num" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" +dependencies = [ + "float-cmp", +] + +[[package]] +name = "strum" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "svgtypes" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "695b5790b3131dafa99b3bbfd25a216edb3d216dad9ca208d4657bfb8f2abc3d" +dependencies = [ + "kurbo", + "siphasher", +] + +[[package]] +name = "swash" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c2499c2d826531388872b2268718aed907a39bd785ab0dcfe57fab26283f92e" +dependencies = [ + "skrifa 0.44.0", + "yazi", + "zeno", +] + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "sys-locale" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4" +dependencies = [ + "js-sys", + "libc", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "taffy" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aea22054047c16c3f34d3ac473a2170be1424b1115b2a3adcf28cfb067c88859" +dependencies = [ + "arrayvec", + "grid", + "serde", + "slotmap", +] + +[[package]] +name = "tar" +version = "0.4.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "task-local" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2972044a9e5e448a506a7ff6f0d03b566d8ef4cd6918a58fc59835a0f8666626" +dependencies = [ + "pin-project-lite", +] + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.3", + "once_cell", + "rustix 1.1.4", + "windows-sys 0.61.2", +] + +[[package]] +name = "text-size" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233" + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9" +dependencies = [ + "thiserror-impl 2.0.19", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "tiff" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52" +dependencies = [ + "fax", + "flate2", + "half", + "quick-error", + "weezl", + "zune-jpeg", +] + +[[package]] +name = "tiny-skia" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "log", + "tiny-skia-path 0.11.4", +] + +[[package]] +name = "tiny-skia" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47ffee5eaaf5527f630fb0e356b90ebdec84d5d18d937c5e440350f88c5a91ea" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "log", + "png", + "tiny-skia-path 0.12.0", +] + +[[package]] +name = "tiny-skia-path" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + +[[package]] +name = "tiny-skia-path" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edca365c3faccca67d06593c5980fa6c57687de727a03131735bb85f01fdeeb9" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + +[[package]] +name = "tiny-xlib" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a90a0ca3ee6a69f2ad28fd11621a4c3f03b371f366be500b64df260c4ffbafb4" +dependencies = [ + "as-raw-xcb-connection", + "ctor", + "libloading", + "pkg-config", + "tracing", +] + +[[package]] +name = "tinystr" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +dependencies = [ + "displaydoc", + "serde_core", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml" +version = "1.1.4+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3aace63f4bbcdfc2c965b059de67119c89c4017a70d633be6c104910f67056f5" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.13+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "ttf-parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" +dependencies = [ + "core_maths", +] + +[[package]] +name = "typed-index-collections" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "898160f1dfd383b4e92e17f0512a7d62f3c51c44937b23b6ffc3a1614a8eaccd" +dependencies = [ + "bincode", + "serde", +] + +[[package]] +name = "udev" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af4e37e9ea4401fc841ff54b9ddfc9be1079b1e89434c1a6a865dd68980f7e9f" +dependencies = [ + "io-lifetimes", + "libc", + "libudev-sys", + "pkg-config", +] + +[[package]] +name = "uds_windows" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" +dependencies = [ + "memoffset", + "tempfile", + "windows-sys 0.61.2", +] + +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + +[[package]] +name = "unicode-bidi-mirroring" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfa6e8c60bb66d49db113e0125ee8711b7647b5579dc7f5f19c42357ed039fe" + +[[package]] +name = "unicode-ccc" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce61d488bcdc9bc8b5d1772c404828b17fc481c0a582b5581e95fb233aef503e" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + +[[package]] +name = "unicode-properties" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" + +[[package]] +name = "unicode-script" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "383ad40bb927465ec0ce7720e033cb4ca06912855fc35db31b5755d0de75b1ee" + +[[package]] +name = "unicode-segmentation" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" + +[[package]] +name = "unicode-vo" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" + +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "unty" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "usvg" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d46cf96c5f498d36b7a9693bc6a7075c0bb9303189d61b2249b0dc3d309c07de" +dependencies = [ + "base64", + "data-url", + "flate2", + "fontdb", + "imagesize", + "kurbo", + "log", + "pico-args", + "roxmltree", + "rustybuzz", + "simplecss", + "siphasher", + "strict-num", + "svgtypes", + "tiny-skia-path 0.12.0", + "ttf-parser", + "unicode-bidi", + "unicode-script", + "unicode-vo", + "xmlwriter", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "uuid" +version = "1.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239" +dependencies = [ + "js-sys", + "serde_core", + "wasm-bindgen", +] + +[[package]] +name = "v_frame" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "666b7727c8875d6ab5db9533418d7c764233ac9c0cff1d469aec8fa127597be2" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "vtable" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea953f65593feb5287b022b83c35046d1ff49c7417b6f5851a079d8a231fe31" +dependencies = [ + "const-field-offset", + "portable-atomic", + "stable_deref_trait", + "vtable-macro", +] + +[[package]] +name = "vtable-macro" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "482a37f9777480673d3a99c80ac2edc69f92382230440946855fa27ebc47cba6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.119", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wayland-backend" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016ccf01d1c58b6f8999612813e17c9b2390f7d70671428869913310f83f54b8" +dependencies = [ + "cc", + "downcast-rs", + "rustix 1.1.4", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c36a0f861ad76d0901f2800b46321410d9f73f2ea88aac0650d86c32688073" +dependencies = [ + "bitflags 2.13.1", + "rustix 1.1.4", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-csd-frame" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.13.1", + "cursor-icon", + "wayland-backend", +] + +[[package]] +name = "wayland-cursor" +version = "0.31.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a52d18780be9b1314328a3de5f930b73d2200112e3849ca6cb11822793fb34d" +dependencies = [ + "rustix 1.1.4", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.32.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6" +dependencies = [ + "bitflags 2.13.1", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-experimental" +version = "20250721.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1" +dependencies = [ + "bitflags 2.13.1", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-misc" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e9567599ef23e09b8dad6e429e5738d4509dfc46b3b21f32841a304d16b29c8" +dependencies = [ + "bitflags 2.13.1", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b6d8cf1eb2c1c31ed1f5643c88a6e53538129d4af80030c8cabd1f9fa884d91" +dependencies = [ + "bitflags 2.13.1", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234" +dependencies = [ + "bitflags 2.13.1", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "338e30461b3a2b67d70eb30a6d89f8e0c93a833e07d2ae89085cd070c4a00ac0" +dependencies = [ + "proc-macro2", + "quick-xml", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be" +dependencies = [ + "dlib", + "log", + "once_cell", + "pkg-config", +] + +[[package]] +name = "web-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webbrowser" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef62a3d5f7b2411119a11b6f62570dbff91d7105e011a20fb83fbf8f5761c40f" +dependencies = [ + "jni", + "log", + "ndk-context", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-foundation 0.3.2", + "url", + "web-sys", +] + +[[package]] +name = "weezl" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections", + "windows-core 0.62.2", + "windows-future", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core 0.62.2", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core 0.62.2", + "windows-link", + "windows-threading", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core 0.62.2", + "windows-link", +] + +[[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-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winit" +version = "0.30.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6755fa58a9f8350bd1e472d4c3fcc25f824ec358933bba33306d0b63df5978d" +dependencies = [ + "ahash", + "android-activity", + "atomic-waker", + "bitflags 2.13.1", + "block2 0.5.1", + "bytemuck", + "calloop 0.13.0", + "cfg_aliases", + "concurrent-queue", + "core-foundation", + "core-graphics", + "cursor-icon", + "dpi", + "js-sys", + "libc", + "memmap2", + "ndk", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", + "objc2-ui-kit 0.2.2", + "orbclient", + "percent-encoding", + "pin-project", + "raw-window-handle", + "redox_syscall 0.4.1", + "rustix 0.38.44", + "sctk-adwaita", + "smithay-client-toolkit 0.19.2", + "smol_str 0.2.2", + "tracing", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-plasma", + "web-sys", + "web-time", + "windows-sys 0.52.0", + "x11-dl", + "x11rb", + "xkbcommon-dl", +] + +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "write-fonts" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb731d4c4d93eacc69a1ad2f270f905788a98e4a3438267bcafbe08d3431c8d8" +dependencies = [ + "font-types 0.11.3", + "indexmap", + "kurbo", + "log", + "read-fonts 0.39.2", +] + +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "x11-clipboard" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "662d74b3d77e396b8e5beb00b9cad6a9eccf40b2ef68cc858784b14c41d535a3" +dependencies = [ + "libc", + "x11rb", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix 1.1.4", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" + +[[package]] +name = "xattr" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" +dependencies = [ + "libc", + "rustix 1.1.4", +] + +[[package]] +name = "xcursor" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b" + +[[package]] +name = "xkbcommon" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a974f48060a14e95705c01f24ad9c3345022f4d97441b8a36beb7ed5c4a02d" +dependencies = [ + "libc", + "memmap2", + "xkeysym", +] + +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.13.1", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" + +[[package]] +name = "xml-rs" +version = "0.8.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" + +[[package]] +name = "xmlwriter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" + +[[package]] +name = "y4m" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5a4b21e1a62b67a2970e6831bc091d7b87e119e7f9791aef9702e3bef04448" + +[[package]] +name = "yazi" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5" + +[[package]] +name = "yeslogic-fontconfig-sys" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d8b8abf912b9a29ff112e1671c97c33636903d13a69712037190e6805af4f76" +dependencies = [ + "dlib", + "once_cell", + "pkg-config", +] + +[[package]] +name = "yoke" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", +] + +[[package]] +name = "zbus" +version = "5.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe18fb60dc696039e738717b76eaea21e7a4489bbb1885020b43c94236d7e98a" +dependencies = [ + "async-broadcast", + "async-executor", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener", + "futures-core", + "futures-lite", + "hex", + "libc", + "ordered-stream", + "rustix 1.1.4", + "serde", + "serde_repr", + "tracing", + "uds_windows", + "uuid", + "windows-sys 0.61.2", + "winnow", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus-lockstep" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6998de05217a084b7578728a9443d04ea4cd80f2a0839b8d78770b76ccd45863" +dependencies = [ + "zbus_xml", + "zvariant", +] + +[[package]] +name = "zbus-lockstep-macros" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10da05367f3a7b7553c8cdf8fa91aee6b64afebe32b51c95177957efc47ca3a0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "zbus-lockstep", + "zbus_xml", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "5.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe96480bed92df2b442a1a30df364e12d08eed03aeb061f2b8dc6afb2be91119" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.119", + "zbus_names", + "zvariant", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "4.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8bf88b4a3ff53e883001e0e0115b297a9d53c31b9c1edd2bfdd853e3428624e" +dependencies = [ + "serde", + "winnow", + "zvariant", +] + +[[package]] +name = "zbus_xml" +version = "5.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1586c021a01ca0a9216dcd874e546382e156a5cbab5fab6cb5f10087e22682a" +dependencies = [ + "serde", + "winnow", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zeno" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" + +[[package]] +name = "zerocopy" +version = "0.8.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "zerovec" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +dependencies = [ + "serde", + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" + +[[package]] +name = "zune-core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9" + +[[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.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" +dependencies = [ + "zune-core", +] + +[[package]] +name = "zvariant" +version = "5.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee2a0bcd2a907786a456fff45aaaaf54c9ba5f50b71ae9ec1a4edd200c94911" +dependencies = [ + "endi", + "enumflags2", + "serde", + "winnow", + "zvariant_derive", + "zvariant_utils", +] + +[[package]] +name = "zvariant_derive" +version = "5.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38a708216a18780796770bfe3f4739c7c83a3e8f789b755534bbbc06e4e23e12" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.119", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90cb9383f9b45290407a1258b202d3f8f01db719eb60b4e4055c6375af4fc7c7" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "syn 2.0.119", + "winnow", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..1c1c525 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "rcalc" +version = "0.1.0" +edition = "2021" +build = "build.rs" + +[dependencies] +slint = "1.11" + +[build-dependencies] +slint-build = "1.11" diff --git a/README.md b/README.md new file mode 100644 index 0000000..e5cbefc --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# rcalc + +Desktop calculator for Linux/Windows/macOS, inspired by the Windows Calculator (standard mode). + +Built with Rust + [Slint](https://slint.dev). + +## Run + +```bash +cargo run --release +# or +./dist/rcalc +``` + +### Icon (Linux / Wayland) + +On **Wayland** the window `icon` property is ignored — the desktop uses +`.desktop` + `app_id`. Install once: + +```bash +./scripts/install-desktop.sh +``` + +Then start **rcalc** from the app menu (or `~/.local/bin/rcalc`), not by +clicking a random binary path, so KDE/GNOME can match `app_id=rcalc` to +`rcalc.desktop` and show the icon. + +## Features + +- Modes: **Standard**, **Programmer**, **Convert** +- Standard: `+ − × ÷`, `%`, `±`, `1/x`, `x²`, `√x`, memory +- Programmer: simultaneous **HEX / DEC / OCT / BIN**, sizes **QWORD / DWORD / DINT / WORD / INT / BYTE**, + bitwise ops, clickable bits + (WORD/DWORD — unsigned DEC; INT/DINT — signed) +- Convert: **float32 ↔ two 16-bit words** with endian **AB CD / CD AB / BA DC / DC BA** +- Convert → **Ratio**: float → minimal **num/den** for electronic gear (Byte≤255 / Word≤65535) +- Convert → **ASCII**: Char ↔ Hex ↔ Dec (control names for NUL…DEL) +- **CRC**: Modbus RTU CRC-16 + Modbus ASCII LRC from hex bytes (`01 03 00 00 00 0A`) +- Keyboard input + +## Project layout + +- `src/engine.rs` — standard calculator logic +- `src/programmer.rs` — programmer mode logic +- `src/convert.rs` — float32 / word endian convert +- `src/main.rs` — UI wiring +- `ui/app.slint` — Slint interface +- `dist/rcalc` — release binary diff --git a/assets/icon-256.png b/assets/icon-256.png new file mode 100644 index 0000000..e62de89 Binary files /dev/null and b/assets/icon-256.png differ diff --git a/assets/icon-64.png b/assets/icon-64.png new file mode 100644 index 0000000..c1af56d Binary files /dev/null and b/assets/icon-64.png differ diff --git a/assets/icon.png b/assets/icon.png new file mode 100644 index 0000000..e669fb2 Binary files /dev/null and b/assets/icon.png differ diff --git a/assets/rcalc.desktop b/assets/rcalc.desktop new file mode 100644 index 0000000..fd8db6d --- /dev/null +++ b/assets/rcalc.desktop @@ -0,0 +1,13 @@ +[Desktop Entry] +Type=Application +Name=rcalc +GenericName=Calculator +Comment=Calculator with Programmer, Convert, CRC tools +Exec=/home/alex/cloud/rust/rcalc/dist/rcalc +Icon=rcalc +Path=/home/alex/cloud/rust/rcalc +Terminal=false +Categories=Utility;Calculator;Science;Engineering; +StartupNotify=true +# Wayland app_id / X11 WM_CLASS — must match set_xdg_app_id("rcalc") +StartupWMClass=rcalc diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..688393d --- /dev/null +++ b/build.rs @@ -0,0 +1,3 @@ +fn main() { + slint_build::compile("ui/app.slint").expect("Slint build failed"); +} diff --git a/dist/rcalc b/dist/rcalc new file mode 100755 index 0000000..8602f5b Binary files /dev/null and b/dist/rcalc differ diff --git a/dist/rcalc.exe b/dist/rcalc.exe new file mode 100755 index 0000000..7669943 Binary files /dev/null and b/dist/rcalc.exe differ diff --git a/dist/win_rcalc.zip b/dist/win_rcalc.zip new file mode 100644 index 0000000..0f38a3e Binary files /dev/null and b/dist/win_rcalc.zip differ diff --git a/scripts/install-desktop.sh b/scripts/install-desktop.sh new file mode 100755 index 0000000..9412e8a --- /dev/null +++ b/scripts/install-desktop.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# Install rcalc launcher + icon for Wayland/XDG desktops (KDE, GNOME, …). +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +BIN="${ROOT}/dist/rcalc" +ICON_SRC="${ROOT}/assets/icon-256.png" +DESKTOP_SRC="${ROOT}/assets/rcalc.desktop" + +if [[ ! -x "$BIN" ]]; then + echo "Building release binary…" + (cd "$ROOT" && cargo build --release) + # Prefer project dist/, else cargo target + if [[ -x "$ROOT/dist/rcalc" ]]; then + BIN="$ROOT/dist/rcalc" + else + BIN="$(find "$ROOT" /tmp/cursor-sandbox-cache -path '*/release/rcalc' -type f 2>/dev/null | head -1 || true)" + fi +fi + +if [[ ! -x "$BIN" ]]; then + echo "error: binary not found; run: cargo build --release && cp target/release/rcalc dist/" >&2 + exit 1 +fi + +APP_DIR="${HOME}/.local/share/applications" +ICON_DIR="${HOME}/.local/share/icons/hicolor/256x256/apps" +mkdir -p "$APP_DIR" "$ICON_DIR" "${HOME}/.local/bin" + +cp -f "$ICON_SRC" "${ICON_DIR}/rcalc.png" +ln -sfn "$BIN" "${HOME}/.local/bin/rcalc" + +# Rewrite Exec to absolute binary path +sed "s|^Exec=.*|Exec=${BIN}|" "$DESKTOP_SRC" \ + | sed "s|^Path=.*|Path=${ROOT}|" \ + > "${APP_DIR}/rcalc.desktop" +chmod 644 "${APP_DIR}/rcalc.desktop" + +# Refresh caches (ignore failures on minimal setups) +update-desktop-database "$APP_DIR" 2>/dev/null || true +gtk-update-icon-cache -f -t "${HOME}/.local/share/icons/hicolor" 2>/dev/null || true + +echo "Installed:" +echo " launcher: ${APP_DIR}/rcalc.desktop" +echo " icon: ${ICON_DIR}/rcalc.png" +echo " symlink: ${HOME}/.local/bin/rcalc" +echo +echo "On Wayland: quit rcalc if running, then start it from the app menu" +echo "(or: rcalc). The dock should show the custom icon." diff --git a/src/convert.rs b/src/convert.rs new file mode 100644 index 0000000..8ef71c0 --- /dev/null +++ b/src/convert.rs @@ -0,0 +1,892 @@ +//! Float32 ↔ two 16-bit words with Modbus-style endian (AB CD). + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Endian { + /// Big-endian: bytes A B C D as-is (Motorola / network order). + AbCd, + /// Word-swapped: C D A B. + CdAb, + /// Bytes swapped inside each word: B A D C. + BaDc, + /// Little-endian: D C B A (Intel). + DcBa, +} + +impl Endian { + pub fn label(self) -> &'static str { + match self { + Endian::AbCd => "AB CD", + Endian::CdAb => "CD AB", + Endian::BaDc => "BA DC", + Endian::DcBa => "DC BA", + } + } + + pub fn all() -> [Endian; 4] { + [Endian::AbCd, Endian::CdAb, Endian::BaDc, Endian::DcBa] + } + + fn index(self) -> i32 { + match self { + Endian::AbCd => 0, + Endian::CdAb => 1, + Endian::BaDc => 2, + Endian::DcBa => 3, + } + } + + pub fn from_index(i: i32) -> Self { + match i { + 1 => Endian::CdAb, + 2 => Endian::BaDc, + 3 => Endian::DcBa, + _ => Endian::AbCd, + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ConvField { + Float, + Word0, + Word1, + AsciiChar, + AsciiHex, + AsciiDec, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ConvPanel { + Words, + Ratio, + Ascii, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum RatioWidth { + Byte, + Word, +} + +impl RatioWidth { + pub fn label(self) -> &'static str { + match self { + RatioWidth::Byte => "Byte", + RatioWidth::Word => "Word", + } + } + + pub fn max(self) -> u32 { + match self { + RatioWidth::Byte => 255, + RatioWidth::Word => 65535, + } + } +} + +/// Relative-error precision presets for gear-ratio approximation. +pub const PRECISION_PRESETS: &[f64] = &[ + 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8, 1e-9, +]; + +#[derive(Debug, Clone, Copy)] +pub struct RatioResult { + pub num: u32, + pub den: u32, + pub approx: f64, + pub rel_error: f64, + pub exact: bool, +} + +#[derive(Debug, Clone)] +pub struct Converter { + endian: Endian, + float_bits: u32, + /// Text currently being edited in the active field. + draft: String, + active: ConvField, + error: Option<&'static str>, + panel: ConvPanel, + ratio_width: RatioWidth, + precision_idx: usize, + /// Current ASCII / Latin-1 code (0..=255). + ascii_code: u8, +} + +impl Default for Converter { + fn default() -> Self { + Self::new() + } +} + +impl Converter { + pub fn new() -> Self { + Self { + endian: Endian::AbCd, + float_bits: 1.0f32.to_bits(), + draft: "1".into(), + active: ConvField::Float, + error: None, + panel: ConvPanel::Words, + ratio_width: RatioWidth::Word, + precision_idx: 3, // 1e-6 + ascii_code: b'A', + } + } + + pub fn panel(&self) -> ConvPanel { + self.panel + } + + pub fn set_panel(&mut self, panel: ConvPanel) { + self.commit_draft(); + self.panel = panel; + self.active = match panel { + ConvPanel::Words => ConvField::Float, + ConvPanel::Ratio => ConvField::Float, + ConvPanel::Ascii => ConvField::AsciiChar, + }; + self.sync_draft(); + } + + pub fn ratio_width(&self) -> RatioWidth { + self.ratio_width + } + + pub fn set_ratio_width(&mut self, width: RatioWidth) { + self.ratio_width = width; + } + + pub fn cycle_ratio_width(&mut self) { + self.ratio_width = match self.ratio_width { + RatioWidth::Byte => RatioWidth::Word, + RatioWidth::Word => RatioWidth::Byte, + }; + } + + pub fn precision_idx(&self) -> usize { + self.precision_idx + } + + pub fn precision(&self) -> f64 { + PRECISION_PRESETS[self.precision_idx.min(PRECISION_PRESETS.len() - 1)] + } + + pub fn precision_text(&self) -> String { + let p = self.precision(); + format!("{p:.0e}") + } + + pub fn cycle_precision(&mut self) { + self.precision_idx = (self.precision_idx + 1) % PRECISION_PRESETS.len(); + } + + pub fn ratio(&self) -> Option { + let x = self.float_value() as f64; + approximate_ratio(x, self.ratio_width.max(), self.precision()) + } + + pub fn ratio_num_text(&self) -> String { + match self.ratio() { + Some(r) => format!("{}", r.num), + None => "—".into(), + } + } + + pub fn ratio_den_text(&self) -> String { + match self.ratio() { + Some(r) => format!("{}", r.den), + None => "—".into(), + } + } + + pub fn ratio_frac_text(&self) -> String { + match self.ratio() { + Some(r) => format!("{} / {}", r.num, r.den), + None => "—".into(), + } + } + + pub fn ratio_approx_text(&self) -> String { + match self.ratio() { + Some(r) => format!("{:.10}", r.approx).trim_end_matches('0').trim_end_matches('.').to_string(), + None => "—".into(), + } + } + + pub fn ratio_error_text(&self) -> String { + match self.ratio() { + Some(r) if r.exact => "exact".into(), + Some(r) => format!("{:.3e}", r.rel_error), + None => "—".into(), + } + } + + pub fn endian(&self) -> Endian { + self.endian + } + + pub fn endian_index(&self) -> i32 { + self.endian.index() + } + + pub fn active(&self) -> ConvField { + self.active + } + + pub fn error(&self) -> Option<&'static str> { + self.error + } + + pub fn set_endian(&mut self, endian: Endian) { + self.commit_draft(); + self.endian = endian; + self.sync_draft(); + } + + pub fn set_active(&mut self, field: ConvField) { + let ok = match self.panel { + ConvPanel::Words => matches!( + field, + ConvField::Float | ConvField::Word0 | ConvField::Word1 + ), + ConvPanel::Ratio => field == ConvField::Float, + ConvPanel::Ascii => matches!( + field, + ConvField::AsciiChar | ConvField::AsciiHex | ConvField::AsciiDec + ), + }; + if !ok || field == self.active { + return; + } + self.commit_draft(); + self.active = field; + self.sync_draft(); + } + + pub fn ascii_code(&self) -> u8 { + self.ascii_code + } + + pub fn ascii_char_text(&self) -> String { + if self.active == ConvField::AsciiChar { + return self.draft.clone(); + } + format_ascii_glyph(self.ascii_code) + } + + pub fn ascii_hex_text(&self) -> String { + if self.active == ConvField::AsciiHex { + return self.draft.clone(); + } + format!("{:02X}", self.ascii_code) + } + + pub fn ascii_dec_text(&self) -> String { + if self.active == ConvField::AsciiDec { + return self.draft.clone(); + } + format!("{}", self.ascii_code) + } + + pub fn ascii_name_text(&self) -> String { + ascii_control_name(self.ascii_code) + .map(|n| n.to_string()) + .unwrap_or_else(|| { + if self.ascii_code.is_ascii_graphic() || self.ascii_code == b' ' { + format!("'{}'", self.ascii_code as char) + } else { + format!("0x{:02X}", self.ascii_code) + } + }) + } + + pub fn float_value(&self) -> f32 { + f32::from_bits(self.float_bits) + } + + pub fn words(&self) -> (u16, u16) { + float_to_words(self.float_value(), self.endian) + } + + pub fn float_text(&self) -> String { + if self.active == ConvField::Float { + return self.draft.clone(); + } + format_float(self.float_value()) + } + + pub fn word0_text(&self) -> String { + if self.active == ConvField::Word0 { + return self.draft.clone(); + } + format!("{:04X}", self.words().0) + } + + pub fn word1_text(&self) -> String { + if self.active == ConvField::Word1 { + return self.draft.clone(); + } + format!("{:04X}", self.words().1) + } + + pub fn wire_bytes_text(&self) -> String { + let (w0, w1) = self.words(); + let a = w0.to_be_bytes(); + let b = w1.to_be_bytes(); + format!("{:02X} {:02X} {:02X} {:02X}", a[0], a[1], b[0], b[1]) + } + + pub fn ieee_hex_text(&self) -> String { + format!("0x{:08X}", self.float_bits) + } + + pub fn clear_active(&mut self) { + self.error = None; + self.draft = match self.active { + ConvField::Float => "0".into(), + ConvField::Word0 | ConvField::Word1 => "0".into(), + ConvField::AsciiChar => " ".into(), + ConvField::AsciiHex => "00".into(), + ConvField::AsciiDec => "0".into(), + }; + let _ = self.apply_draft(); + } + + pub fn backspace(&mut self) { + self.error = None; + if self.active == ConvField::AsciiChar { + self.draft = " ".into(); + self.ascii_code = b' '; + return; + } + self.draft.pop(); + if self.draft.is_empty() { + self.draft = match self.active { + ConvField::AsciiHex => "0".into(), + _ => "0".into(), + }; + } + let _ = self.apply_draft(); + } + + pub fn input_char(&mut self, ch: char) { + self.error = None; + match self.active { + ConvField::Float => { + let ch = ch.to_ascii_uppercase(); + if !matches!(ch, '0'..='9' | '.' | '-' | '+' | 'E') { + return; + } + if self.draft == "0" && ch != '.' && ch != 'E' { + self.draft = ch.to_string(); + } else if self.draft == "-0" && ch != '.' && ch != 'E' { + self.draft = format!("-{ch}"); + } else { + self.draft.push(ch); + } + } + ConvField::Word0 | ConvField::Word1 => { + let ch = ch.to_ascii_uppercase(); + if !ch.is_ascii_hexdigit() { + return; + } + if self.draft == "0" { + self.draft = ch.to_string(); + } else if self.draft.len() < 4 { + self.draft.push(ch); + } else { + return; + } + } + ConvField::AsciiChar => { + if (ch as u32) > 255 { + return; + } + self.ascii_code = ch as u8; + self.draft = format_ascii_glyph(self.ascii_code); + return; + } + ConvField::AsciiHex => { + let ch = ch.to_ascii_uppercase(); + if !ch.is_ascii_hexdigit() { + return; + } + if self.draft == "0" { + self.draft = ch.to_string(); + } else if self.draft.len() < 2 { + self.draft.push(ch); + } else { + self.draft = ch.to_string(); + } + } + ConvField::AsciiDec => { + if !ch.is_ascii_digit() { + return; + } + if self.draft == "0" { + self.draft = ch.to_string(); + } else if self.draft.len() < 3 { + self.draft.push(ch); + } else { + self.draft = ch.to_string(); + } + } + } + let _ = self.apply_draft(); + } + + pub fn negate_float(&mut self) { + if self.panel != ConvPanel::Words && self.panel != ConvPanel::Ratio { + return; + } + if self.active != ConvField::Float { + self.set_active(ConvField::Float); + } + if let Some(rest) = self.draft.strip_prefix('-') { + self.draft = rest.to_string(); + if self.draft.is_empty() { + self.draft = "0".into(); + } + } else if self.draft != "0" { + self.draft = format!("-{}", self.draft); + } + let _ = self.apply_draft(); + } + + fn commit_draft(&mut self) { + let _ = self.apply_draft(); + self.sync_draft(); + } + + fn sync_draft(&mut self) { + self.draft = match self.active { + ConvField::Float => format_float(self.float_value()), + ConvField::Word0 => format!("{:04X}", self.words().0), + ConvField::Word1 => format!("{:04X}", self.words().1), + ConvField::AsciiChar => format_ascii_glyph(self.ascii_code), + ConvField::AsciiHex => format!("{:02X}", self.ascii_code), + ConvField::AsciiDec => format!("{}", self.ascii_code), + }; + self.error = None; + } + + fn apply_draft(&mut self) -> Result<(), ()> { + match self.active { + ConvField::Float => { + let t = self.draft.trim(); + if t.is_empty() || t == "-" || t == "." || t == "-." { + return Ok(()); + } + match t.parse::() { + Ok(v) => { + self.float_bits = v.to_bits(); + self.error = None; + Ok(()) + } + Err(_) => { + self.error = Some("Invalid float"); + Err(()) + } + } + } + ConvField::Word0 => { + let w0 = parse_word(&self.draft)?; + let w1 = self.words().1; + self.float_bits = words_to_float(w0, w1, self.endian).to_bits(); + self.error = None; + Ok(()) + } + ConvField::Word1 => { + let w0 = self.words().0; + let w1 = parse_word(&self.draft)?; + self.float_bits = words_to_float(w0, w1, self.endian).to_bits(); + self.error = None; + Ok(()) + } + ConvField::AsciiChar => { + let t = self.draft.trim(); + if t.is_empty() { + self.ascii_code = b' '; + } else if let Some(c) = t.chars().next() { + if (c as u32) <= 255 { + self.ascii_code = c as u8; + } else { + self.error = Some("Not Latin-1"); + return Err(()); + } + } + self.error = None; + Ok(()) + } + ConvField::AsciiHex => { + let cleaned: String = self + .draft + .chars() + .filter(|c| c.is_ascii_hexdigit()) + .collect(); + if cleaned.is_empty() { + return Ok(()); + } + match u8::from_str_radix(&cleaned, 16) { + Ok(v) => { + self.ascii_code = v; + self.error = None; + Ok(()) + } + Err(_) => { + self.error = Some("Invalid hex"); + Err(()) + } + } + } + ConvField::AsciiDec => { + let t = self.draft.trim(); + if t.is_empty() { + return Ok(()); + } + match t.parse::() { + Ok(v) if v <= 255 => { + self.ascii_code = v as u8; + self.error = None; + Ok(()) + } + Ok(_) => { + self.error = Some("Max 255"); + Err(()) + } + Err(_) => { + self.error = Some("Invalid dec"); + Err(()) + } + } + } + } + } +} + +fn format_ascii_glyph(code: u8) -> String { + if let Some(name) = ascii_control_name(code) { + format!("<{name}>") + } else if code == b' ' { + " ".into() + } else if code.is_ascii_graphic() { + (code as char).to_string() + } else { + // Latin-1 printable or other + match char::from_u32(code as u32) { + Some(c) if !c.is_control() => c.to_string(), + _ => format!("<{code:02X}>"), + } + } +} + +fn ascii_control_name(code: u8) -> Option<&'static str> { + Some(match code { + 0x00 => "NUL", + 0x01 => "SOH", + 0x02 => "STX", + 0x03 => "ETX", + 0x04 => "EOT", + 0x05 => "ENQ", + 0x06 => "ACK", + 0x07 => "BEL", + 0x08 => "BS", + 0x09 => "TAB", + 0x0A => "LF", + 0x0B => "VT", + 0x0C => "FF", + 0x0D => "CR", + 0x0E => "SO", + 0x0F => "SI", + 0x10 => "DLE", + 0x11 => "DC1", + 0x12 => "DC2", + 0x13 => "DC3", + 0x14 => "DC4", + 0x15 => "NAK", + 0x16 => "SYN", + 0x17 => "ETB", + 0x18 => "CAN", + 0x19 => "EM", + 0x1A => "SUB", + 0x1B => "ESC", + 0x1C => "FS", + 0x1D => "GS", + 0x1E => "RS", + 0x1F => "US", + 0x7F => "DEL", + _ => return None, + }) +} + +/// Best rational approximation of `x` with num, den ∈ [0..=max_val], den ≥ 1. +/// Stops early when relative error ≤ `max_rel_err` (smallest such convergent preferred). +pub fn approximate_ratio(x: f64, max_val: u32, max_rel_err: f64) -> Option { + if !x.is_finite() { + return None; + } + if x == 0.0 { + return Some(RatioResult { + num: 0, + den: 1, + approx: 0.0, + rel_error: 0.0, + exact: true, + }); + } + + let x = x.abs(); + let max_val = max_val as u64; + + let mut best = RatioResult { + num: 0, + den: 1, + approx: 0.0, + rel_error: 1.0, + exact: false, + }; + + let consider = |n: u64, d: u64, best: &mut RatioResult| { + if d == 0 || d > max_val || n > max_val { + return; + } + let approx = n as f64 / d as f64; + let rel = if x == 0.0 { + 0.0 + } else { + (approx - x).abs() / x + }; + let exact = (approx - x).abs() <= f64::EPSILON * x.max(1.0) * 4.0; + if rel < best.rel_error + || ((rel - best.rel_error).abs() < 1e-18 && d < best.den as u64) + || ((rel - best.rel_error).abs() < 1e-18 && d == best.den as u64 && n < best.num as u64) + { + *best = RatioResult { + num: n as u32, + den: d as u32, + approx, + rel_error: rel, + exact, + }; + } + }; + + // Continued fraction: h₋₂=0,k₋₂=1 ; h₋₁=1,k₋₁=0 + let mut h2 = 0u64; + let mut k2 = 1u64; + let mut h1 = 1u64; + let mut k1 = 0u64; + + let mut remaining = x; + for _ in 0..64 { + if best.rel_error <= max_rel_err { + break; + } + let a = remaining.floor() as u64; + let t_start = if a == 0 { 0 } else { 1 }; + let mut last_h = h1; + let mut last_k = k1; + let mut fitted = false; + + for t in t_start..=a { + let Some(hn) = h1.checked_mul(t).and_then(|v| v.checked_add(h2)) else { + fitted = false; + break; + }; + let Some(kn) = k1.checked_mul(t).and_then(|v| v.checked_add(k2)) else { + fitted = false; + break; + }; + if hn > max_val || kn > max_val { + let mut lo = t_start; + let mut hi = t.saturating_sub(1); + while lo < hi { + let mid = (lo + hi + 1) / 2; + let ok = h1 + .checked_mul(mid) + .and_then(|v| v.checked_add(h2)) + .zip(k1.checked_mul(mid).and_then(|v| v.checked_add(k2))) + .is_some_and(|(h, k)| h <= max_val && k <= max_val); + if ok { + lo = mid; + } else { + hi = mid - 1; + } + } + if a == 0 || lo >= t_start { + if let (Some(hn), Some(kn)) = ( + h1.checked_mul(lo).and_then(|v| v.checked_add(h2)), + k1.checked_mul(lo).and_then(|v| v.checked_add(k2)), + ) { + if kn > 0 && hn <= max_val && kn <= max_val { + consider(hn, kn, &mut best); + } + } + } + fitted = false; + break; + } + consider(hn, kn, &mut best); + last_h = hn; + last_k = kn; + fitted = true; + if best.rel_error <= max_rel_err { + break; + } + } + + if best.rel_error <= max_rel_err { + break; + } + + if fitted { + h2 = h1; + k2 = k1; + h1 = last_h; + k1 = last_k; + } else { + break; + } + + let frac = remaining - a as f64; + if frac <= 1e-18 { + break; + } + remaining = 1.0 / frac; + } + + Some(best) +} + +fn parse_word(s: &str) -> Result { + let cleaned: String = s.chars().filter(|c| c.is_ascii_hexdigit()).collect(); + if cleaned.is_empty() { + return Ok(0); + } + u16::from_str_radix(&cleaned, 16).map_err(|_| ()) +} + +fn format_float(v: f32) -> String { + if !v.is_finite() { + return if v.is_nan() { + "NaN".into() + } else if v.is_sign_negative() { + "-Inf".into() + } else { + "Inf".into() + }; + } + let s = format!("{v}"); + s +} + +/// IEEE float bytes in natural order A B C D (big-endian bit pattern), +/// then rearrange into two register words for the selected endian. +pub fn float_to_words(f: f32, endian: Endian) -> (u16, u16) { + let abcd = f.to_be_bytes(); // [A, B, C, D] + let wire = match endian { + Endian::AbCd => abcd, + Endian::CdAb => [abcd[2], abcd[3], abcd[0], abcd[1]], + Endian::BaDc => [abcd[1], abcd[0], abcd[3], abcd[2]], + Endian::DcBa => [abcd[3], abcd[2], abcd[1], abcd[0]], + }; + let w0 = u16::from_be_bytes([wire[0], wire[1]]); + let w1 = u16::from_be_bytes([wire[2], wire[3]]); + (w0, w1) +} + +pub fn words_to_float(w0: u16, w1: u16, endian: Endian) -> f32 { + let a = w0.to_be_bytes(); + let b = w1.to_be_bytes(); + let wire = [a[0], a[1], b[0], b[1]]; + let abcd = match endian { + Endian::AbCd => wire, + Endian::CdAb => [wire[2], wire[3], wire[0], wire[1]], + Endian::BaDc => [wire[1], wire[0], wire[3], wire[2]], + Endian::DcBa => [wire[3], wire[2], wire[1], wire[0]], + }; + f32::from_be_bytes(abcd) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn one_point_zero_abcd() { + let (w0, w1) = float_to_words(1.0, Endian::AbCd); + assert_eq!(w0, 0x3F80); + assert_eq!(w1, 0x0000); + assert_eq!(words_to_float(w0, w1, Endian::AbCd), 1.0); + } + + #[test] + fn one_point_zero_dcba() { + let (w0, w1) = float_to_words(1.0, Endian::DcBa); + assert_eq!(w0, 0x0000); + assert_eq!(w1, 0x803F); + assert_eq!(words_to_float(w0, w1, Endian::DcBa), 1.0); + } + + #[test] + fn one_point_zero_cdab() { + let (w0, w1) = float_to_words(1.0, Endian::CdAb); + assert_eq!(w0, 0x0000); + assert_eq!(w1, 0x3F80); + assert_eq!(words_to_float(w0, w1, Endian::CdAb), 1.0); + } + + #[test] + fn roundtrip_all_endians() { + let samples = [0.0f32, -1.0, 3.1415927, 12345.678, f32::MIN_POSITIVE]; + for e in Endian::all() { + for &f in &samples { + let (w0, w1) = float_to_words(f, e); + let back = words_to_float(w0, w1, e); + assert_eq!(back.to_bits(), f.to_bits(), "endian {:?}", e); + } + } + } + + #[test] + fn pi_word_ratio() { + let r = approximate_ratio(std::f64::consts::PI, 65535, 1e-6).unwrap(); + assert_eq!((r.num, r.den), (355, 113)); + } + + #[test] + fn half_byte_ratio() { + let r = approximate_ratio(0.5, 255, 1e-9).unwrap(); + assert_eq!((r.num, r.den), (1, 2)); + } + + #[test] + fn gear_ratio_example() { + // 17/23 electronic gear style + let r = approximate_ratio(17.0 / 23.0, 255, 1e-9).unwrap(); + assert_eq!((r.num, r.den), (17, 23)); + } + + #[test] + fn ascii_char_to_codes() { + let mut c = Converter::new(); + c.set_panel(ConvPanel::Ascii); + c.set_active(ConvField::AsciiChar); + c.input_char('A'); + assert_eq!(c.ascii_code(), 0x41); + assert_eq!(c.ascii_hex_text(), "41"); + assert_eq!(c.ascii_dec_text(), "65"); + } + + #[test] + fn ascii_hex_to_char() { + let mut c = Converter::new(); + c.set_panel(ConvPanel::Ascii); + c.set_active(ConvField::AsciiHex); + c.input_char('4'); + c.input_char('1'); + assert_eq!(c.ascii_code(), b'A'); + assert_eq!(c.ascii_char_text(), "A"); + } +} diff --git a/src/crc.rs b/src/crc.rs new file mode 100644 index 0000000..f419377 --- /dev/null +++ b/src/crc.rs @@ -0,0 +1,168 @@ +//! Modbus RTU CRC-16 and Modbus ASCII LRC. + +#[derive(Debug, Clone, Default)] +pub struct CrcTool { + /// Raw text from the input field (hex bytes, spaces optional). + input: String, +} + +#[derive(Debug, Clone)] +pub struct CrcView { + pub input: String, + pub parsed_hex: String, + pub byte_count: usize, + pub rtu_crc_lo_hi: String, + pub rtu_crc_word: String, + pub rtu_frame: String, + pub ascii_lrc: String, + pub ascii_frame: String, + pub error: String, +} + +impl CrcTool { + pub fn new() -> Self { + Self { + input: "01 03 00 00 00 0A".into(), + } + } + + pub fn input(&self) -> &str { + &self.input + } + + pub fn set_input(&mut self, text: impl Into) { + self.input = text.into(); + } + + pub fn view(&self) -> CrcView { + match parse_hex_bytes(&self.input) { + Ok(bytes) => { + let crc = modbus_crc16(&bytes); + let lo = (crc & 0xFF) as u8; + let hi = (crc >> 8) as u8; + let lrc = modbus_lrc(&bytes); + + let parsed_hex = format_bytes(&bytes); + let mut frame = bytes.clone(); + frame.push(lo); + frame.push(hi); + + let ascii_payload: String = bytes.iter().map(|b| format!("{b:02X}")).collect(); + let ascii_frame = format!(":{ascii_payload}{lrc:02X}\\r\\n"); + + CrcView { + input: self.input.clone(), + parsed_hex, + byte_count: bytes.len(), + rtu_crc_lo_hi: format!("{lo:02X} {hi:02X}"), + rtu_crc_word: format!("0x{crc:04X}"), + rtu_frame: format_bytes(&frame), + ascii_lrc: format!("{lrc:02X}"), + ascii_frame, + error: String::new(), + } + } + Err(e) => CrcView { + input: self.input.clone(), + parsed_hex: String::new(), + byte_count: 0, + rtu_crc_lo_hi: "—".into(), + rtu_crc_word: "—".into(), + rtu_frame: "—".into(), + ascii_lrc: "—".into(), + ascii_frame: "—".into(), + error: e.into(), + }, + } + } +} + +/// Modbus RTU CRC-16 (poly 0xA001, init 0xFFFF). Returned value is host u16; +/// on the wire it is sent low-byte first. +pub fn modbus_crc16(data: &[u8]) -> u16 { + let mut crc = 0xFFFFu16; + for &b in data { + crc ^= u16::from(b); + for _ in 0..8 { + if crc & 1 != 0 { + crc = (crc >> 1) ^ 0xA001; + } else { + crc >>= 1; + } + } + } + crc +} + +/// Modbus ASCII LRC: two's complement of the sum of bytes. +pub fn modbus_lrc(data: &[u8]) -> u8 { + let sum = data.iter().fold(0u8, |acc, &b| acc.wrapping_add(b)); + (!sum).wrapping_add(1) +} + +fn format_bytes(data: &[u8]) -> String { + data.iter() + .map(|b| format!("{b:02X}")) + .collect::>() + .join(" ") +} + +/// Accepts `01 03 00 00`, `01-03-00`, `0x01,0x03`, or continuous `01030000`. +fn parse_hex_bytes(text: &str) -> Result, &'static str> { + let cleaned: String = text + .chars() + .filter(|c| c.is_ascii_hexdigit()) + .collect::() + .to_ascii_uppercase(); + + if cleaned.is_empty() { + return Ok(Vec::new()); + } + if cleaned.len() % 2 != 0 { + return Err("Odd number of hex digits"); + } + + let mut out = Vec::with_capacity(cleaned.len() / 2); + let bytes = cleaned.as_bytes(); + for i in (0..bytes.len()).step_by(2) { + let hi = from_hex(bytes[i])?; + let lo = from_hex(bytes[i + 1])?; + out.push((hi << 4) | lo); + } + Ok(out) +} + +fn from_hex(b: u8) -> Result { + match b { + b'0'..=b'9' => Ok(b - b'0'), + b'A'..=b'F' => Ok(b - b'A' + 10), + b'a'..=b'f' => Ok(b - b'a' + 10), + _ => Err("Invalid hex"), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn known_modbus_crc() { + // 01 03 00 00 00 0A → CRC lo hi = C5 CD + let data = [0x01u8, 0x03, 0x00, 0x00, 0x00, 0x0A]; + let crc = modbus_crc16(&data); + assert_eq!(crc & 0xFF, 0xC5); + assert_eq!(crc >> 8, 0xCD); + } + + #[test] + fn known_modbus_lrc() { + let data = [0x01u8, 0x03, 0x00, 0x00, 0x00, 0x0A]; + assert_eq!(modbus_lrc(&data), 0xF2); + } + + #[test] + fn parse_spaced() { + let b = parse_hex_bytes("01 03 00 00 00 0A").unwrap(); + assert_eq!(b, vec![0x01, 0x03, 0x00, 0x00, 0x00, 0x0A]); + } +} diff --git a/src/engine.rs b/src/engine.rs new file mode 100644 index 0000000..de43017 --- /dev/null +++ b/src/engine.rs @@ -0,0 +1,425 @@ +//! Calculator logic (standard / Windows-like). + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Op { + Add, + Sub, + Mul, + Div, +} + +impl Op { + pub fn symbol(self) -> &'static str { + match self { + Op::Add => "+", + Op::Sub => "−", + Op::Mul => "×", + Op::Div => "÷", + } + } + + fn apply(self, a: f64, b: f64) -> Result { + let r = match self { + Op::Add => a + b, + Op::Sub => a - b, + Op::Mul => a * b, + Op::Div => { + if b == 0.0 { + return Err(CalcError::DivByZero); + } + a / b + } + }; + if !r.is_finite() { + Err(CalcError::Overflow) + } else { + Ok(r) + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum CalcError { + DivByZero, + Overflow, + Invalid, +} + +impl CalcError { + pub fn message(self) -> &'static str { + match self { + CalcError::DivByZero => "Cannot divide by zero", + CalcError::Overflow => "Overflow", + CalcError::Invalid => "Invalid input", + } + } +} + +#[derive(Debug, Clone)] +pub struct Calculator { + /// Digits currently being entered (or last result as string). + entry: String, + /// True while the user is typing a new number. + typing: bool, + /// Left operand waiting for the next number / equals. + pending: Option, + /// Pending binary operator. + op: Option, + /// Expression line above the main display (e.g. "12 +"). + expression: String, + /// Last error, if any. + error: Option, + /// Memory register. + memory: f64, + /// Whether memory has been set (for UI hint). + memory_set: bool, +} + +impl Default for Calculator { + fn default() -> Self { + Self::new() + } +} + +impl Calculator { + pub fn new() -> Self { + Self { + entry: "0".into(), + typing: false, + pending: None, + op: None, + expression: String::new(), + error: None, + memory: 0.0, + memory_set: false, + } + } + + pub fn display(&self) -> &str { + if let Some(err) = self.error { + return err.message(); + } + &self.entry + } + + pub fn expression(&self) -> &str { + &self.expression + } + + pub fn has_memory(&self) -> bool { + self.memory_set + } + + pub fn clear_all(&mut self) { + *self = Self { + memory: self.memory, + memory_set: self.memory_set, + ..Self::new() + }; + } + + pub fn clear_entry(&mut self) { + self.error = None; + self.entry = "0".into(); + self.typing = false; + } + + pub fn backspace(&mut self) { + if self.error.is_some() { + self.clear_entry(); + return; + } + if !self.typing { + return; + } + self.entry.pop(); + if self.entry.is_empty() || self.entry == "-" { + self.entry = "0".into(); + self.typing = false; + } + } + + pub fn input_digit(&mut self, d: char) { + debug_assert!(d.is_ascii_digit()); + if self.error.is_some() { + self.clear_all(); + } + if !self.typing { + self.entry = d.to_string(); + self.typing = true; + return; + } + if self.entry == "0" { + self.entry = d.to_string(); + } else if self.entry == "-0" { + self.entry = format!("-{d}"); + } else if digit_count(&self.entry) < 16 { + self.entry.push(d); + } + } + + pub fn input_dot(&mut self) { + if self.error.is_some() { + self.clear_all(); + } + if !self.typing { + self.entry = "0.".into(); + self.typing = true; + return; + } + if !self.entry.contains('.') { + self.entry.push('.'); + } + } + + pub fn negate(&mut self) { + if self.error.is_some() { + return; + } + if let Ok(v) = self.current_value() { + self.set_entry(-v); + self.typing = true; + } + } + + pub fn percent(&mut self) { + if self.error.is_some() { + return; + } + let Ok(cur) = self.current_value() else { + return; + }; + let result = match (self.pending, self.op) { + (Some(a), Some(Op::Add | Op::Sub)) => a * cur / 100.0, + _ => cur / 100.0, + }; + self.set_entry(result); + self.typing = false; + } + + pub fn reciprocal(&mut self) { + self.unary(|x| { + if x == 0.0 { + Err(CalcError::DivByZero) + } else { + Ok(1.0 / x) + } + }); + } + + pub fn square(&mut self) { + self.unary(|x| { + let r = x * x; + if r.is_finite() { + Ok(r) + } else { + Err(CalcError::Overflow) + } + }); + } + + pub fn sqrt(&mut self) { + self.unary(|x| { + if x < 0.0 { + Err(CalcError::Invalid) + } else { + Ok(x.sqrt()) + } + }); + } + + pub fn set_op(&mut self, op: Op) { + if self.error.is_some() { + return; + } + if let Err(e) = self.commit_pending() { + self.fail(e); + return; + } + let Ok(v) = self.current_value() else { + return; + }; + self.pending = Some(v); + self.op = Some(op); + self.expression = format!("{} {}", format_number(v), op.symbol()); + self.typing = false; + } + + pub fn equals(&mut self) { + if self.error.is_some() { + return; + } + let Some(op) = self.op else { + self.expression.clear(); + self.typing = false; + return; + }; + let Ok(b) = self.current_value() else { + return; + }; + let a = self.pending.unwrap_or(b); + match op.apply(a, b) { + Ok(r) => { + self.expression = format!( + "{} {} {} =", + format_number(a), + op.symbol(), + format_number(b) + ); + self.set_entry(r); + self.pending = None; + self.op = None; + self.typing = false; + } + Err(e) => self.fail(e), + } + } + + // --- Memory --- + + pub fn memory_clear(&mut self) { + self.memory = 0.0; + self.memory_set = false; + } + + pub fn memory_recall(&mut self) { + if self.error.is_some() { + self.clear_all(); + } + self.set_entry(self.memory); + self.typing = false; + } + + pub fn memory_add(&mut self) { + if self.error.is_some() { + return; + } + if let Ok(v) = self.current_value() { + self.memory += v; + self.memory_set = true; + self.typing = false; + } + } + + pub fn memory_sub(&mut self) { + if self.error.is_some() { + return; + } + if let Ok(v) = self.current_value() { + self.memory -= v; + self.memory_set = true; + self.typing = false; + } + } + + pub fn memory_store(&mut self) { + if self.error.is_some() { + return; + } + if let Ok(v) = self.current_value() { + self.memory = v; + self.memory_set = true; + self.typing = false; + } + } + + // --- internals --- + + fn unary(&mut self, f: impl FnOnce(f64) -> Result) { + if self.error.is_some() { + return; + } + let Ok(v) = self.current_value() else { + return; + }; + match f(v) { + Ok(r) => { + self.expression.clear(); + self.set_entry(r); + self.typing = false; + } + Err(e) => self.fail(e), + } + } + + fn commit_pending(&mut self) -> Result<(), CalcError> { + let (Some(a), Some(op)) = (self.pending, self.op) else { + return Ok(()); + }; + if !self.typing { + return Ok(()); + } + let b = self.current_value()?; + let r = op.apply(a, b)?; + self.set_entry(r); + self.pending = Some(r); + self.op = None; + Ok(()) + } + + fn current_value(&self) -> Result { + self.entry + .parse::() + .map_err(|_| CalcError::Invalid) + } + + fn set_entry(&mut self, v: f64) { + self.entry = format_number(v); + self.error = None; + } + + fn fail(&mut self, e: CalcError) { + self.error = Some(e); + self.pending = None; + self.op = None; + self.expression.clear(); + self.typing = false; + } +} + +fn digit_count(s: &str) -> usize { + s.chars().filter(|c| c.is_ascii_digit()).count() +} + +fn format_number(v: f64) -> String { + if !v.is_finite() { + return "0".into(); + } + // Prefer integer display when close enough. + if v.fract().abs() < 1e-12 && v.abs() < 1e15 { + return format!("{}", v as i64); + } + let s = format!("{:.12}", v); + let s = s.trim_end_matches('0').trim_end_matches('.').to_string(); + if s.is_empty() || s == "-" { + "0".into() + } else { + s + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn basic_add() { + let mut c = Calculator::new(); + c.input_digit('1'); + c.input_digit('2'); + c.set_op(Op::Add); + c.input_digit('3'); + c.equals(); + assert_eq!(c.display(), "15"); + } + + #[test] + fn div_by_zero() { + let mut c = Calculator::new(); + c.input_digit('1'); + c.set_op(Op::Div); + c.input_digit('0'); + c.equals(); + assert!(c.display().contains("zero")); + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..1a3d58c --- /dev/null +++ b/src/main.rs @@ -0,0 +1,370 @@ +// Hide the extra console window on Windows GUI builds. +#![cfg_attr(all(windows, not(debug_assertions)), windows_subsystem = "windows")] + +mod convert; +mod crc; +mod engine; +mod programmer; + +use std::cell::RefCell; +use std::rc::Rc; + +use convert::{ConvField, ConvPanel, Converter, Endian, RatioWidth}; +use crc::CrcTool; +use engine::{Calculator, Op}; +use programmer::{Base, ProgOp, Programmer}; +use slint::{ComponentHandle, ModelRc, VecModel}; + +slint::include_modules!(); + +#[derive(Clone, Copy, PartialEq, Eq)] +enum Mode { + Standard, + Programmer, + Convert, + Crc, +} + +struct State { + mode: Mode, + std: Calculator, + prog: Programmer, + conv: Converter, + crc: CrcTool, + show_bits: bool, + win_profile: u32, +} + +impl Default for State { + fn default() -> Self { + Self { + mode: Mode::Standard, + std: Calculator::new(), + prog: Programmer::new(), + conv: Converter::new(), + crc: CrcTool::new(), + show_bits: true, + win_profile: u32::MAX, + } + } +} + +fn main() -> Result<(), slint::PlatformError> { + // Platform must exist first — calling set_xdg_app_id before AppWindow::new + // returns NoPlatform and the Wayland app_id stays unset (KDE shows the "W" icon). + let ui = AppWindow::new()?; + // Must match the .desktop basename (rcalc.desktop → "rcalc"), before show/run. + slint::set_xdg_app_id("rcalc")?; + + let state = Rc::new(RefCell::new(State::default())); + + refresh(&ui, &mut state.borrow_mut()); + + let ui_weak = ui.as_weak(); + let state_keys = state.clone(); + ui.on_key_pressed(move |id| { + let mut s = state_keys.borrow_mut(); + handle_key(&mut s, id.as_str()); + if let Some(ui) = ui_weak.upgrade() { + refresh(&ui, &mut s); + } + }); + + let ui_weak = ui.as_weak(); + let state_crc = state.clone(); + ui.on_crc_edited(move |text| { + let mut s = state_crc.borrow_mut(); + s.crc.set_input(text.as_str()); + if let Some(ui) = ui_weak.upgrade() { + apply_crc_results(&ui, &s); + } + }); + + ui.run() +} + +fn bit_row_model(row: &[(bool, u32)]) -> ModelRc { + let items: Vec = row + .iter() + .map(|(on, idx)| BitInfo { + value: *on, + index: *idx as i32, + }) + .collect(); + ModelRc::new(VecModel::from(items)) +} + +fn window_profile(state: &State) -> u32 { + let mode = match state.mode { + Mode::Standard => 0, + Mode::Programmer => 1, + Mode::Convert => 2, + Mode::Crc => 3, + }; + let bits = if state.show_bits { + state.prog.word_size().bits() + } else { + 0 + }; + let panel = match state.conv.panel() { + ConvPanel::Words => 0, + ConvPanel::Ratio => 1, + ConvPanel::Ascii => 2, + }; + mode * 1000 + bits * 10 + panel +} + +fn fit_window(ui: &AppWindow, state: &mut State) { + let profile = window_profile(state); + if state.win_profile == profile { + return; + } + state.win_profile = profile; + + let (w, h) = match state.mode { + Mode::Standard => (340.0, 560.0), + Mode::Programmer => { + let bit_h = if state.show_bits { + match state.prog.word_size().bits() { + 64 => 120.0, + 32 => 64.0, + 16 => 36.0, + _ => 36.0, + } + } else { + 0.0 + }; + (420.0, 720.0 + bit_h) + } + Mode::Convert => (420.0, 820.0), + Mode::Crc => (460.0, 560.0), + }; + ui.window() + .set_size(slint::LogicalSize::new(w as f32, h as f32)); +} + +fn apply_crc_results(ui: &AppWindow, state: &State) { + let v = state.crc.view(); + ui.set_crc_parsed(v.parsed_hex.into()); + ui.set_crc_count(v.byte_count.to_string().into()); + ui.set_crc_rtu_bytes(v.rtu_crc_lo_hi.into()); + ui.set_crc_rtu_word(v.rtu_crc_word.into()); + ui.set_crc_rtu_frame(v.rtu_frame.into()); + ui.set_crc_ascii_lrc(v.ascii_lrc.into()); + ui.set_crc_ascii_frame(v.ascii_frame.into()); + ui.set_crc_error(v.error.into()); +} + +fn refresh(ui: &AppWindow, state: &mut State) { + ui.set_mode(match state.mode { + Mode::Standard => 0, + Mode::Programmer => 1, + Mode::Convert => 2, + Mode::Crc => 3, + }); + + fit_window(ui, state); + + match state.mode { + Mode::Standard => { + ui.set_display_text(state.std.display().into()); + ui.set_expression_text(state.std.expression().into()); + ui.set_has_memory(state.std.has_memory()); + } + Mode::Programmer => { + ui.set_display_text(state.prog.display().into()); + ui.set_expression_text(state.prog.expression().into()); + ui.set_has_memory(false); + ui.set_hex_text(state.prog.hex_text().into()); + ui.set_dec_text(state.prog.dec_text().into()); + ui.set_oct_text(state.prog.oct_text().into()); + ui.set_bin_text(state.prog.bin_text().into()); + ui.set_active_base(match state.prog.base() { + Base::Hex => 0, + Base::Dec => 1, + Base::Oct => 2, + Base::Bin => 3, + }); + ui.set_word_size_label(state.prog.word_size().label().into()); + ui.set_show_bits(state.show_bits); + + let rows = state.prog.bit_rows(); + ui.set_bit_row_count(rows.len() as i32); + ui.set_bit_row0(bit_row_model(rows.first().map(|r| r.as_slice()).unwrap_or(&[]))); + ui.set_bit_row1(bit_row_model(rows.get(1).map(|r| r.as_slice()).unwrap_or(&[]))); + ui.set_bit_row2(bit_row_model(rows.get(2).map(|r| r.as_slice()).unwrap_or(&[]))); + ui.set_bit_row3(bit_row_model(rows.get(3).map(|r| r.as_slice()).unwrap_or(&[]))); + } + Mode::Convert => { + ui.set_conv_panel(match state.conv.panel() { + ConvPanel::Words => 0, + ConvPanel::Ratio => 1, + ConvPanel::Ascii => 2, + }); + ui.set_conv_endian(state.conv.endian_index()); + ui.set_conv_active(match state.conv.active() { + ConvField::Float | ConvField::AsciiChar => 0, + ConvField::Word0 | ConvField::AsciiHex => 1, + ConvField::Word1 | ConvField::AsciiDec => 2, + }); + ui.set_conv_float(state.conv.float_text().into()); + ui.set_conv_word0(state.conv.word0_text().into()); + ui.set_conv_word1(state.conv.word1_text().into()); + ui.set_conv_bytes(state.conv.wire_bytes_text().into()); + ui.set_conv_ieee(state.conv.ieee_hex_text().into()); + ui.set_conv_error(state.conv.error().unwrap_or("").into()); + ui.set_ratio_width(match state.conv.ratio_width() { + RatioWidth::Byte => 0, + RatioWidth::Word => 1, + }); + ui.set_ratio_precision(state.conv.precision_text().into()); + ui.set_ratio_num(state.conv.ratio_num_text().into()); + ui.set_ratio_den(state.conv.ratio_den_text().into()); + ui.set_ratio_frac(state.conv.ratio_frac_text().into()); + ui.set_ratio_approx(state.conv.ratio_approx_text().into()); + ui.set_ratio_error(state.conv.ratio_error_text().into()); + ui.set_ascii_char(state.conv.ascii_char_text().into()); + ui.set_ascii_hex(state.conv.ascii_hex_text().into()); + ui.set_ascii_dec(state.conv.ascii_dec_text().into()); + ui.set_ascii_name(state.conv.ascii_name_text().into()); + } + Mode::Crc => { + ui.set_crc_input(state.crc.input().into()); + apply_crc_results(ui, state); + } + } +} + +fn handle_key(state: &mut State, id: &str) { + match id { + "mode:std" => { + state.mode = Mode::Standard; + return; + } + "mode:prog" => { + state.mode = Mode::Programmer; + return; + } + "mode:conv" => { + state.mode = Mode::Convert; + return; + } + "mode:crc" => { + state.mode = Mode::Crc; + return; + } + _ => {} + } + + match state.mode { + Mode::Standard => handle_standard(&mut state.std, id), + Mode::Programmer => handle_programmer(state, id), + Mode::Convert => handle_convert(&mut state.conv, id), + Mode::Crc => {} + } +} + +fn handle_standard(calc: &mut Calculator, id: &str) { + match id { + "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" => { + calc.input_digit(id.chars().next().unwrap()); + } + "." | "," => calc.input_dot(), + "+" => calc.set_op(Op::Add), + "-" | "−" => calc.set_op(Op::Sub), + "*" | "×" => calc.set_op(Op::Mul), + "/" | "÷" => calc.set_op(Op::Div), + "=" => calc.equals(), + "%" => calc.percent(), + "CE" => calc.clear_entry(), + "C" => calc.clear_all(), + "BS" => calc.backspace(), + "1/x" => calc.reciprocal(), + "x2" => calc.square(), + "sqrt" => calc.sqrt(), + "neg" => calc.negate(), + "MC" => calc.memory_clear(), + "MR" => calc.memory_recall(), + "M+" => calc.memory_add(), + "M-" => calc.memory_sub(), + "MS" => calc.memory_store(), + _ => {} + } +} + +fn handle_programmer(state: &mut State, id: &str) { + if id == "bits" { + state.show_bits = !state.show_bits; + return; + } + + if let Some(rest) = id.strip_prefix("bit:") { + if let Ok(bit) = rest.parse::() { + state.prog.toggle_bit(bit); + } + return; + } + + let calc = &mut state.prog; + match id { + "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "A" | "B" | "C" | "D" + | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f" => { + calc.input_digit(id.chars().next().unwrap()); + } + "base:hex" => calc.set_base(Base::Hex), + "base:dec" => calc.set_base(Base::Dec), + "base:oct" => calc.set_base(Base::Oct), + "base:bin" => calc.set_base(Base::Bin), + "word" => calc.cycle_word_size(), + "+" => calc.set_op(ProgOp::Add), + "-" | "−" => calc.set_op(ProgOp::Sub), + "*" | "×" => calc.set_op(ProgOp::Mul), + "/" | "÷" => calc.set_op(ProgOp::Div), + "%" => calc.set_op(ProgOp::Mod), + "AND" => calc.set_op(ProgOp::And), + "OR" => calc.set_op(ProgOp::Or), + "XOR" => calc.set_op(ProgOp::Xor), + "NAND" => calc.set_op(ProgOp::Nand), + "NOR" => calc.set_op(ProgOp::Nor), + "Lsh" => calc.set_op(ProgOp::Lsh), + "Rsh" => calc.set_op(ProgOp::Rsh), + "NOT" => calc.not(), + "=" => calc.equals(), + "CE" => calc.clear_entry(), + "clear" => calc.clear_all(), + "BS" => calc.backspace(), + "neg" => calc.negate(), + _ => {} + } +} + +fn handle_convert(conv: &mut Converter, id: &str) { + match id { + "panel:words" => conv.set_panel(ConvPanel::Words), + "panel:ratio" => conv.set_panel(ConvPanel::Ratio), + "panel:ascii" => conv.set_panel(ConvPanel::Ascii), + "endian:0" => conv.set_endian(Endian::AbCd), + "endian:1" => conv.set_endian(Endian::CdAb), + "endian:2" => conv.set_endian(Endian::BaDc), + "endian:3" => conv.set_endian(Endian::DcBa), + "rwidth:byte" => conv.set_ratio_width(RatioWidth::Byte), + "rwidth:word" => conv.set_ratio_width(RatioWidth::Word), + "rprec" => conv.cycle_precision(), + "conv:float" => conv.set_active(ConvField::Float), + "conv:w0" => conv.set_active(ConvField::Word0), + "conv:w1" => conv.set_active(ConvField::Word1), + "ascii:char" => conv.set_active(ConvField::AsciiChar), + "ascii:hex" => conv.set_active(ConvField::AsciiHex), + "ascii:dec" => conv.set_active(ConvField::AsciiDec), + "CE" | "clear" => conv.clear_active(), + "BS" => conv.backspace(), + "neg" => conv.negate_float(), + other => { + // Single-character input (digits, letters, space, punctuation). + let mut chars = other.chars(); + if let (Some(ch), None) = (chars.next(), chars.next()) { + conv.input_char(ch); + } + } + } +} diff --git a/src/programmer.rs b/src/programmer.rs new file mode 100644 index 0000000..dbe1c24 --- /dev/null +++ b/src/programmer.rs @@ -0,0 +1,680 @@ +//! Programmer calculator (Windows-like): integer bases + bitwise ops. + +use std::fmt::Write as _; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Base { + Hex, + Dec, + Oct, + Bin, +} + +impl Base { + pub fn radix(self) -> u32 { + match self { + Base::Hex => 16, + Base::Dec => 10, + Base::Oct => 8, + Base::Bin => 2, + } + } + + pub fn label(self) -> &'static str { + match self { + Base::Hex => "HEX", + Base::Dec => "DEC", + Base::Oct => "OCT", + Base::Bin => "BIN", + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum WordSize { + /// 64-bit (signed DEC). + Qword, + /// 32-bit unsigned (PLC DWORD). + Dword, + /// 32-bit signed (PLC DINT). + Dint, + /// 16-bit unsigned (PLC WORD). + Word, + /// 16-bit signed (PLC INT). + Int, + /// 8-bit (signed DEC). + Byte, +} + +impl WordSize { + pub fn bits(self) -> u32 { + match self { + WordSize::Qword => 64, + WordSize::Dword | WordSize::Dint => 32, + WordSize::Word | WordSize::Int => 16, + WordSize::Byte => 8, + } + } + + /// Signed two's-complement DEC display (INT / DINT / QWORD / BYTE). + pub fn is_signed(self) -> bool { + matches!( + self, + WordSize::Qword | WordSize::Dint | WordSize::Int | WordSize::Byte + ) + } + + pub fn label(self) -> &'static str { + match self { + WordSize::Qword => "QWORD", + WordSize::Dword => "DWORD", + WordSize::Dint => "DINT", + WordSize::Word => "WORD", + WordSize::Int => "INT", + WordSize::Byte => "BYTE", + } + } + + pub fn cycle(self) -> Self { + match self { + WordSize::Qword => WordSize::Dword, + WordSize::Dword => WordSize::Dint, + WordSize::Dint => WordSize::Word, + WordSize::Word => WordSize::Int, + WordSize::Int => WordSize::Byte, + WordSize::Byte => WordSize::Qword, + } + } + + fn mask(self) -> u64 { + match self.bits() { + 64 => u64::MAX, + bits => (1u64 << bits) - 1, + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ProgOp { + Add, + Sub, + Mul, + Div, + Mod, + And, + Or, + Xor, + Nand, + Nor, + Lsh, + Rsh, +} + +impl ProgOp { + pub fn symbol(self) -> &'static str { + match self { + ProgOp::Add => "+", + ProgOp::Sub => "−", + ProgOp::Mul => "×", + ProgOp::Div => "÷", + ProgOp::Mod => "%", + ProgOp::And => "AND", + ProgOp::Or => "OR", + ProgOp::Xor => "XOR", + ProgOp::Nand => "NAND", + ProgOp::Nor => "NOR", + ProgOp::Lsh => "Lsh", + ProgOp::Rsh => "Rsh", + } + } + + fn apply(self, a: u64, b: u64, size: WordSize) -> Result { + let mask = size.mask(); + let a = a & mask; + let b = b & mask; + let r = match self { + ProgOp::Add => a.wrapping_add(b), + ProgOp::Sub => a.wrapping_sub(b), + ProgOp::Mul => a.wrapping_mul(b), + ProgOp::Div => { + if b == 0 { + return Err(ProgError::DivByZero); + } + a / b + } + ProgOp::Mod => { + if b == 0 { + return Err(ProgError::DivByZero); + } + a % b + } + ProgOp::And => a & b, + ProgOp::Or => a | b, + ProgOp::Xor => a ^ b, + ProgOp::Nand => !(a & b), + ProgOp::Nor => !(a | b), + ProgOp::Lsh => { + let sh = (b as u32) % size.bits().max(1); + a << sh + } + ProgOp::Rsh => { + let sh = (b as u32) % size.bits().max(1); + a >> sh + } + }; + Ok(r & mask) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ProgError { + DivByZero, + Invalid, +} + +impl ProgError { + pub fn message(self) -> &'static str { + match self { + ProgError::DivByZero => "Cannot divide by zero", + ProgError::Invalid => "Invalid input", + } + } +} + +#[derive(Debug, Clone)] +pub struct Programmer { + entry: String, + typing: bool, + value: u64, + pending: Option, + op: Option, + expression: String, + error: Option, + base: Base, + word_size: WordSize, +} + +impl Default for Programmer { + fn default() -> Self { + Self::new() + } +} + +impl Programmer { + pub fn new() -> Self { + Self { + entry: "0".into(), + typing: false, + value: 0, + pending: None, + op: None, + expression: String::new(), + error: None, + base: Base::Dec, + word_size: WordSize::Qword, + } + } + + pub fn base(&self) -> Base { + self.base + } + + pub fn word_size(&self) -> WordSize { + self.word_size + } + + pub fn expression(&self) -> &str { + &self.expression + } + + pub fn display(&self) -> String { + if let Some(err) = self.error { + return err.message().into(); + } + if self.typing { + format_grouped_entry(&self.entry, self.base) + } else { + format_value(self.value, self.base, self.word_size) + } + } + + pub fn hex_text(&self) -> String { + format_value(self.current_bits(), Base::Hex, self.word_size) + } + + pub fn dec_text(&self) -> String { + format_value(self.current_bits(), Base::Dec, self.word_size) + } + + pub fn oct_text(&self) -> String { + format_value(self.current_bits(), Base::Oct, self.word_size) + } + + pub fn bin_text(&self) -> String { + format_value(self.current_bits(), Base::Bin, self.word_size) + } + + /// Bit rows for the clickable bit board (MSB-first within each row). + /// Each entry is `(is_set, bit_index)` with `bit_index` counted from LSB = 0. + pub fn bit_rows(&self) -> Vec> { + let n = self.word_size.bits(); + let v = self.current_bits(); + let cols: u32 = if n <= 8 { 8 } else { 16 }; + let mut rows = Vec::new(); + let mut row = Vec::new(); + for i in (0..n).rev() { + row.push(((v >> i) & 1 == 1, i)); + if row.len() == cols as usize { + rows.push(std::mem::take(&mut row)); + } + } + if !row.is_empty() { + rows.push(row); + } + rows + } + + pub fn toggle_bit(&mut self, bit: u32) { + if bit >= self.word_size.bits() { + return; + } + if self.error.is_some() { + self.clear_entry(); + } + let v = self.current_bits(); + self.value = (v ^ (1u64 << bit)) & self.word_size.mask(); + self.typing = false; + self.error = None; + self.entry = format_raw(self.value, self.base, self.word_size); + } + + pub fn set_base(&mut self, base: Base) { + if self.error.is_some() { + self.clear_entry(); + } + // Commit typed digits into value when switching bases. + if self.typing { + if let Ok(v) = parse_entry(&self.entry, self.base) { + self.value = v & self.word_size.mask(); + } + self.typing = false; + } + self.base = base; + self.entry = format_raw(self.value, base, self.word_size); + } + + pub fn cycle_word_size(&mut self) { + if self.typing { + if let Ok(v) = parse_entry(&self.entry, self.base) { + self.value = v; + } + self.typing = false; + } + self.word_size = self.word_size.cycle(); + self.value &= self.word_size.mask(); + if let Some(p) = self.pending.as_mut() { + *p &= self.word_size.mask(); + } + self.entry = format_raw(self.value, self.base, self.word_size); + } + + pub fn clear_all(&mut self) { + let base = self.base; + let word_size = self.word_size; + *self = Self::new(); + self.base = base; + self.word_size = word_size; + } + + pub fn clear_entry(&mut self) { + self.error = None; + self.entry = "0".into(); + self.value = 0; + self.typing = false; + } + + pub fn backspace(&mut self) { + if self.error.is_some() { + self.clear_entry(); + return; + } + if !self.typing { + return; + } + self.entry.pop(); + if self.entry.is_empty() { + self.entry = "0".into(); + self.typing = false; + self.value = 0; + } else if let Ok(v) = parse_entry(&self.entry, self.base) { + self.value = v & self.word_size.mask(); + } + } + + pub fn input_digit(&mut self, ch: char) { + let ch = ch.to_ascii_uppercase(); + if !is_valid_digit(ch, self.base) { + return; + } + if self.error.is_some() { + self.clear_all(); + } + + if !self.typing { + self.entry = ch.to_string(); + self.typing = true; + } else if self.entry == "0" { + self.entry = ch.to_string(); + } else { + let max_digits = max_digits(self.base, self.word_size); + if digit_len(&self.entry) >= max_digits { + return; + } + self.entry.push(ch); + } + + match parse_entry(&self.entry, self.base) { + Ok(v) => { + let masked = v & self.word_size.mask(); + // Reject overflow beyond word size (except wrapping interpretation of typed hex). + if v != masked && self.base != Base::Bin { + self.entry.pop(); + if self.entry.is_empty() { + self.entry = "0".into(); + self.typing = false; + } + return; + } + self.value = masked; + } + Err(_) => { + self.entry.pop(); + } + } + } + + pub fn negate(&mut self) { + if self.error.is_some() { + return; + } + let v = self.current_bits(); + self.value = (!v).wrapping_add(1) & self.word_size.mask(); + self.typing = false; + self.entry = format_raw(self.value, self.base, self.word_size); + } + + pub fn not(&mut self) { + if self.error.is_some() { + return; + } + let v = self.current_bits(); + self.value = (!v) & self.word_size.mask(); + self.expression.clear(); + self.typing = false; + self.entry = format_raw(self.value, self.base, self.word_size); + } + + pub fn set_op(&mut self, op: ProgOp) { + if self.error.is_some() { + return; + } + if let Err(e) = self.commit_pending() { + self.fail(e); + return; + } + let v = self.current_bits(); + self.pending = Some(v); + self.op = Some(op); + self.expression = format!( + "{} {}", + format_value(v, self.base, self.word_size), + op.symbol() + ); + self.typing = false; + self.entry = format_raw(v, self.base, self.word_size); + } + + pub fn equals(&mut self) { + if self.error.is_some() { + return; + } + let Some(op) = self.op else { + self.expression.clear(); + self.typing = false; + return; + }; + let b = self.current_bits(); + let a = self.pending.unwrap_or(b); + match op.apply(a, b, self.word_size) { + Ok(r) => { + self.expression = format!( + "{} {} {} =", + format_value(a, self.base, self.word_size), + op.symbol(), + format_value(b, self.base, self.word_size) + ); + self.value = r; + self.pending = None; + self.op = None; + self.typing = false; + self.entry = format_raw(r, self.base, self.word_size); + } + Err(e) => self.fail(e), + } + } + + fn current_bits(&self) -> u64 { + if self.typing { + parse_entry(&self.entry, self.base) + .unwrap_or(self.value) + & self.word_size.mask() + } else { + self.value & self.word_size.mask() + } + } + + fn commit_pending(&mut self) -> Result<(), ProgError> { + let (Some(a), Some(op)) = (self.pending, self.op) else { + return Ok(()); + }; + if !self.typing { + return Ok(()); + } + let b = self.current_bits(); + let r = op.apply(a, b, self.word_size)?; + self.value = r; + self.pending = Some(r); + self.op = None; + self.entry = format_raw(r, self.base, self.word_size); + Ok(()) + } + + fn fail(&mut self, e: ProgError) { + self.error = Some(e); + self.pending = None; + self.op = None; + self.expression.clear(); + self.typing = false; + } +} + +fn is_valid_digit(ch: char, base: Base) -> bool { + match base { + Base::Bin => matches!(ch, '0' | '1'), + Base::Oct => matches!(ch, '0'..='7'), + Base::Dec => ch.is_ascii_digit(), + Base::Hex => ch.is_ascii_hexdigit(), + } +} + +fn digit_len(s: &str) -> usize { + s.chars().filter(|c| c.is_ascii_hexdigit()).count() +} + +fn max_digits(base: Base, size: WordSize) -> usize { + let bits = size.bits() as f64; + match base { + Base::Bin => size.bits() as usize, + Base::Oct => (bits / 3.0).ceil() as usize, + Base::Dec => (bits * std::f64::consts::LN_2 / std::f64::consts::LN_10).ceil() as usize, + Base::Hex => (bits / 4.0).ceil() as usize, + } +} + +fn parse_entry(entry: &str, base: Base) -> Result { + let cleaned: String = entry + .chars() + .filter(|c| c.is_ascii_hexdigit()) + .collect(); + if cleaned.is_empty() { + return Ok(0); + } + u64::from_str_radix(&cleaned, base.radix()).map_err(|_| ProgError::Invalid) +} + +fn format_raw(v: u64, base: Base, size: WordSize) -> String { + let v = v & size.mask(); + match base { + Base::Dec => { + if size.is_signed() { + format!("{}", to_signed(v, size)) + } else { + format!("{v}") + } + } + Base::Hex => format!("{:X}", v), + Base::Oct => format!("{:o}", v), + Base::Bin => format!("{:b}", v), + } +} + +fn format_value(v: u64, base: Base, size: WordSize) -> String { + format_grouped_entry(&format_raw(v, base, size), base) +} + +fn format_grouped_entry(raw: &str, base: Base) -> String { + // Keep leading minus for signed decimal. + let (sign, digits) = if let Some(rest) = raw.strip_prefix('-') { + ("-", rest) + } else { + ("", raw) + }; + let digits: String = digits + .chars() + .filter(|c| c.is_ascii_hexdigit()) + .collect::() + .to_ascii_uppercase(); + if digits.is_empty() { + return format!("{sign}0"); + } + let group = match base { + Base::Bin => 4, + Base::Hex | Base::Oct => 4, + Base::Dec => 3, + }; + let mut out = String::new(); + for (i, ch) in digits.chars().rev().enumerate() { + if i > 0 && i % group == 0 { + out.push(' '); + } + out.push(ch); + } + let grouped: String = out.chars().rev().collect(); + let mut result = String::new(); + let _ = write!(result, "{sign}{grouped}"); + result +} + +fn to_signed(v: u64, size: WordSize) -> i64 { + let bits = size.bits(); + if bits == 64 { + return v as i64; + } + let mask = size.mask(); + let v = v & mask; + let sign_bit = 1u64 << (bits - 1); + if v & sign_bit != 0 { + (v | !mask) as i64 + } else { + v as i64 + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn hex_and() { + let mut p = Programmer::new(); + p.set_base(Base::Hex); + p.input_digit('F'); + p.input_digit('F'); + p.set_op(ProgOp::And); + p.input_digit('0'); + p.input_digit('F'); + p.equals(); + assert_eq!(p.current_bits(), 0x0F); + } + + #[test] + fn simultaneous_bases() { + let mut p = Programmer::new(); + p.input_digit('2'); + p.input_digit('5'); + p.input_digit('5'); + assert_eq!(p.hex_text().replace(' ', ""), "FF"); + assert_eq!(p.bin_text().replace(' ', ""), "11111111"); + } + + #[test] + fn toggle_bit_flips() { + let mut p = Programmer::new(); + // QWORD → DWORD → DINT → WORD → INT → BYTE + for _ in 0..5 { + p.cycle_word_size(); + } + assert_eq!(p.word_size(), WordSize::Byte); + p.toggle_bit(0); + p.toggle_bit(7); + assert_eq!(p.current_bits(), 0b1000_0001); + p.toggle_bit(0); + assert_eq!(p.current_bits(), 0b1000_0000); + } + + #[test] + fn int_vs_word_dec() { + let mut p = Programmer::new(); + p.set_base(Base::Hex); + // → DWORD → DINT → WORD + p.cycle_word_size(); + p.cycle_word_size(); + p.cycle_word_size(); + assert_eq!(p.word_size(), WordSize::Word); + p.input_digit('F'); + p.input_digit('F'); + p.input_digit('F'); + p.input_digit('F'); + assert_eq!(p.dec_text().replace(' ', ""), "65535"); + + p.cycle_word_size(); // INT + assert_eq!(p.word_size(), WordSize::Int); + assert_eq!(p.dec_text().replace(' ', ""), "-1"); + } + + #[test] + fn dint_vs_dword_dec() { + let mut p = Programmer::new(); + p.set_base(Base::Hex); + p.cycle_word_size(); // DWORD + assert_eq!(p.word_size(), WordSize::Dword); + for _ in 0..8 { + p.input_digit('F'); + } + assert_eq!(p.dec_text().replace(' ', ""), "4294967295"); + + p.cycle_word_size(); // DINT + assert_eq!(p.word_size(), WordSize::Dint); + assert_eq!(p.dec_text().replace(' ', ""), "-1"); + } +} diff --git a/ui/app.slint b/ui/app.slint new file mode 100644 index 0000000..25c9484 --- /dev/null +++ b/ui/app.slint @@ -0,0 +1,1149 @@ +export struct BitInfo { + value: bool, + index: int, +} + +component BitCell inherits Rectangle { + callback toggled(); + in property on; + width: 14px; + height: 16px; + border-radius: 2px; + background: touch.has-hover ? #3a4550 : transparent; + + Text { + text: root.on ? "1" : "0"; + color: root.on ? #60cdff : #6a6a6a; + font-size: 10px; + font-weight: 700; + font-family: "Cascadia Mono, Consolas, DejaVu Sans Mono, monospace"; + horizontal-alignment: center; + vertical-alignment: center; + } + + touch := TouchArea { + clicked => { root.toggled(); } + } +} + +component BitLine inherits Rectangle { + callback toggle-bit(int); + in property <[BitInfo]> cells; + height: 28px; + background: transparent; + + VerticalLayout { + spacing: 0px; + + HorizontalLayout { + padding-left: 2px; + padding-right: 2px; + height: 10px; + Text { + text: root.cells.length > 0 ? "\{root.cells[0].index}" : ""; + color: #808080; + font-size: 9px; + horizontal-alignment: left; + vertical-alignment: center; + } + Text { + text: root.cells.length > 0 ? "\{root.cells[root.cells.length - 1].index}" : ""; + color: #808080; + font-size: 9px; + horizontal-alignment: right; + vertical-alignment: center; + } + } + + HorizontalLayout { + spacing: 0px; + padding-left: 2px; + alignment: start; + + for c[i] in root.cells: HorizontalLayout { + spacing: 0px; + if i > 0 && mod(i, 4) == 0: Rectangle { + width: 6px; + height: 1px; + } + BitCell { + on: c.value; + toggled => { root.toggle-bit(c.index); } + } + } + } + } +} + +component MemBtn inherits Rectangle { + callback clicked(); + in property label; + height: 32px; + background: touch.has-hover ? #323232 : transparent; + border-radius: 4px; + + Text { + text: root.label; + color: #c8c8c8; + font-size: 13px; + horizontal-alignment: center; + vertical-alignment: center; + } + + touch := TouchArea { + clicked => { root.clicked(); } + } +} + +component FuncBtn inherits Rectangle { + callback clicked(); + in property label; + in property enabled: true; + in property min-h: 42px; + background: !root.enabled ? #2a2a2a : (touch.has-hover ? #464646 : #323232); + border-radius: 4px; + min-height: root.min-h; + opacity: root.enabled ? 1.0 : 0.45; + + Text { + text: root.label; + color: white; + font-size: 14px; + horizontal-alignment: center; + vertical-alignment: center; + } + + touch := TouchArea { + enabled: root.enabled; + clicked => { root.clicked(); } + } +} + +component DigitBtn inherits Rectangle { + callback clicked(); + in property label; + in property enabled: true; + in property min-h: 42px; + background: !root.enabled ? #2a2a2a : (touch.has-hover ? #505050 : #3b3b3b); + border-radius: 4px; + min-height: root.min-h; + opacity: root.enabled ? 1.0 : 0.4; + + Text { + text: root.label; + color: white; + font-size: 16px; + font-weight: 600; + horizontal-alignment: center; + vertical-alignment: center; + } + + touch := TouchArea { + enabled: root.enabled; + clicked => { root.clicked(); } + } +} + +component EqBtn inherits Rectangle { + callback clicked(); + in property min-h: 42px; + background: touch.has-hover ? #78d7ff : #60cdff; + border-radius: 4px; + min-height: root.min-h; + + Text { + text: "="; + color: #141414; + font-size: 18px; + font-weight: 700; + horizontal-alignment: center; + vertical-alignment: center; + } + + touch := TouchArea { + clicked => { root.clicked(); } + } +} + +component ModeTab inherits Rectangle { + callback clicked(); + in property label; + in property active; + height: 30px; + border-radius: 4px; + background: root.active ? #3b3b3b : (touch.has-hover ? #2c2c2c : transparent); + + Text { + text: root.label; + color: root.active ? #60cdff : #c8c8c8; + font-size: 13px; + font-weight: root.active ? 700 : 500; + horizontal-alignment: center; + vertical-alignment: center; + } + + touch := TouchArea { + clicked => { root.clicked(); } + } +} + +component BaseRow inherits Rectangle { + callback clicked(); + in property label; + in property value; + in property active; + height: 24px; + border-radius: 4px; + background: root.active ? #2f3a42 : (touch.has-hover ? #2a2a2a : transparent); + + HorizontalLayout { + padding-left: 8px; + padding-right: 8px; + spacing: 12px; + + Text { + text: root.label; + color: root.active ? #60cdff : #9a9a9a; + font-size: 12px; + font-weight: 700; + width: 36px; + vertical-alignment: center; + } + + Text { + text: root.value; + color: white; + font-size: 13px; + font-family: "Cascadia Mono, Consolas, monospace"; + horizontal-alignment: left; + vertical-alignment: center; + overflow: elide; + } + } + + touch := TouchArea { + clicked => { root.clicked(); } + } +} + +component FieldRow inherits Rectangle { + callback clicked(); + in property label; + in property value; + in property active; + height: 40px; + border-radius: 4px; + background: root.active ? #2f3a42 : (touch.has-hover ? #2a2a2a : #262626); + border-width: root.active ? 1px : 0; + border-color: #60cdff; + + HorizontalLayout { + padding-left: 10px; + padding-right: 10px; + spacing: 12px; + + Text { + text: root.label; + color: root.active ? #60cdff : #9a9a9a; + font-size: 12px; + font-weight: 700; + width: 64px; + vertical-alignment: center; + } + + Text { + text: root.value; + color: white; + font-size: 20px; + font-weight: 600; + font-family: "Cascadia Mono, Consolas, DejaVu Sans Mono, monospace"; + horizontal-alignment: right; + vertical-alignment: center; + overflow: elide; + } + } + + touch := TouchArea { + clicked => { root.clicked(); } + } +} + +component EndianChip inherits Rectangle { + callback clicked(); + in property label; + in property active; + height: 30px; + border-radius: 4px; + background: root.active ? #3b3b3b : (touch.has-hover ? #2c2c2c : #262626); + border-width: root.active ? 1px : 0; + border-color: #60cdff; + + Text { + text: root.label; + color: root.active ? #60cdff : #c8c8c8; + font-size: 12px; + font-weight: root.active ? 700 : 500; + font-family: "Cascadia Mono, Consolas, DejaVu Sans Mono, monospace"; + horizontal-alignment: center; + vertical-alignment: center; + } + + touch := TouchArea { + clicked => { root.clicked(); } + } +} + +export component AppWindow inherits Window { + title: "rcalc"; + icon: @image-url("../assets/icon-256.png"); + preferred-width: 420px; + preferred-height: 640px; + min-width: 380px; + min-height: 520px; + background: #202020; + + // 0 = standard, 1 = programmer, 2 = convert, 3 = crc + in-out property mode: 0; + + in property display-text: "0"; + in property expression-text: ""; + in property has-memory: false; + + in property hex-text: "0"; + in property dec-text: "0"; + in property oct-text: "0"; + in property bin-text: "0"; + // 0=hex 1=dec 2=oct 3=bin + in property active-base: 1; + in property word-size-label: "QWORD"; + in property show-bits: true; + in property bit-row-count: 0; + in property <[BitInfo]> bit-row0; + in property <[BitInfo]> bit-row1; + in property <[BitInfo]> bit-row2; + in property <[BitInfo]> bit-row3; + + // Convert tab + // 0=words 1=ratio + in property conv-panel: 0; + in property conv-endian: 0; // 0=AB CD 1=CD AB 2=BA DC 3=DC BA + in property conv-active: 0; // 0=float 1=word0 2=word1 + in property conv-float: "0"; + in property conv-word0: "0000"; + in property conv-word1: "0000"; + in property conv-bytes: "00 00 00 00"; + in property conv-ieee: "0x00000000"; + in property conv-error: ""; + in property ratio-width: 1; // 0=byte 1=word + in property ratio-precision: "1e-6"; + in property ratio-num: "1"; + in property ratio-den: "1"; + in property ratio-frac: "1 / 1"; + in property ratio-approx: "1"; + in property ratio-error: "exact"; + in property ascii-char: "A"; + in property ascii-hex: "41"; + in property ascii-dec: "65"; + in property ascii-name: "'A'"; + + // CRC tab + in-out property crc-input: "01 03 00 00 00 0A"; + in property crc-parsed: ""; + in property crc-count: "0"; + in property crc-rtu-bytes: "—"; + in property crc-rtu-word: "—"; + in property crc-rtu-frame: "—"; + in property crc-ascii-lrc: "—"; + in property crc-ascii-frame: "—"; + in property crc-error: ""; + + callback key-pressed(string); + callback crc-edited(string); + + function press(id: string) { + root.key-pressed(id); + } + + property hex-digits: root.mode == 1 && root.active-base == 0; + property allow-2: root.mode == 0 || root.active-base <= 2; + property allow-8: root.mode == 0 || root.active-base <= 1; + property allow-a: root.mode == 1 && root.active-base == 0; + + VerticalLayout { + padding: 12px; + spacing: 6px; + + HorizontalLayout { + spacing: 6px; + height: 30px; + ModeTab { + label: "Standard"; + active: root.mode == 0; + clicked => { root.press("mode:std"); } + } + ModeTab { + label: "Programmer"; + active: root.mode == 1; + clicked => { root.press("mode:prog"); } + } + ModeTab { + label: "Convert"; + active: root.mode == 2; + clicked => { root.press("mode:conv"); } + } + ModeTab { + label: "CRC"; + active: root.mode == 3; + clicked => { root.press("mode:crc"); } + } + } + + if root.mode == 0 || root.mode == 1: HorizontalLayout { + height: 18px; + Text { + text: root.has-memory && root.mode == 0 ? "M" : ""; + color: #b4b4b4; + font-size: 12px; + horizontal-alignment: left; + vertical-alignment: center; + width: 16px; + } + Text { + text: root.mode == 1 ? root.word-size-label : ""; + color: #60cdff; + font-size: 11px; + vertical-alignment: center; + } + Text { + text: root.expression-text; + color: #aaaaaa; + font-size: 13px; + horizontal-alignment: right; + vertical-alignment: center; + } + } + + if root.mode == 0 || root.mode == 1: Text { + text: root.display-text; + color: white; + font-size: root.mode == 1 ? 28px : 34px; + font-weight: 700; + horizontal-alignment: right; + vertical-alignment: center; + height: root.mode == 1 ? 40px : 48px; + overflow: elide; + } + + if root.mode == 3: VerticalLayout { + spacing: 10px; + + Text { + text: "Hex bytes (space-separated)"; + color: #9a9a9a; + font-size: 12px; + } + + Rectangle { + height: 44px; + border-radius: 4px; + background: #2a2a2a; + border-width: 1px; + border-color: crc-input.has-focus ? #60cdff : #3a3a3a; + + crc-input := TextInput { + x: 10px; + width: parent.width - 20px; + height: 100%; + color: white; + font-size: 15px; + font-family: "Cascadia Mono, Consolas, DejaVu Sans Mono, monospace"; + single-line: true; + text <=> root.crc-input; + edited => { + root.crc-edited(self.text); + } + } + } + + Text { + text: "example: 01 03 00 00 00 0A"; + color: #666666; + font-size: 11px; + } + + if root.crc-error != "": Text { + text: root.crc-error; + color: #ff8a80; + font-size: 12px; + } + + HorizontalLayout { + height: 18px; + Text { text: "Parsed"; color: #9a9a9a; font-size: 11px; width: 70px; } + Text { + text: root.crc-parsed; + color: #c8c8c8; + font-size: 12px; + font-family: "Cascadia Mono, Consolas, DejaVu Sans Mono, monospace"; + overflow: elide; + } + } + HorizontalLayout { + height: 18px; + Text { text: "Length"; color: #9a9a9a; font-size: 11px; width: 70px; } + Text { + text: root.crc-count + " bytes"; + color: #c8c8c8; + font-size: 12px; + } + } + + Rectangle { height: 1px; background: #333333; } + + Text { + text: "Modbus RTU (CRC-16)"; + color: #60cdff; + font-size: 13px; + font-weight: 700; + } + HorizontalLayout { + height: 22px; + Text { text: "CRC"; color: #9a9a9a; font-size: 12px; width: 70px; vertical-alignment: center; } + Text { + text: root.crc-rtu-bytes + " (" + root.crc-rtu-word + ")"; + color: white; + font-size: 16px; + font-weight: 700; + font-family: "Cascadia Mono, Consolas, DejaVu Sans Mono, monospace"; + vertical-alignment: center; + } + } + Text { + text: "lo hi — append after PDU"; + color: #666666; + font-size: 11px; + } + HorizontalLayout { + height: 18px; + Text { text: "Frame"; color: #9a9a9a; font-size: 11px; width: 70px; } + Text { + text: root.crc-rtu-frame; + color: #c8c8c8; + font-size: 12px; + font-family: "Cascadia Mono, Consolas, DejaVu Sans Mono, monospace"; + overflow: elide; + } + } + + Rectangle { height: 1px; background: #333333; } + + Text { + text: "Modbus ASCII (LRC)"; + color: #60cdff; + font-size: 13px; + font-weight: 700; + } + HorizontalLayout { + height: 22px; + Text { text: "LRC"; color: #9a9a9a; font-size: 12px; width: 70px; vertical-alignment: center; } + Text { + text: root.crc-ascii-lrc; + color: white; + font-size: 16px; + font-weight: 700; + font-family: "Cascadia Mono, Consolas, DejaVu Sans Mono, monospace"; + vertical-alignment: center; + } + } + HorizontalLayout { + height: 18px; + Text { text: "Frame"; color: #9a9a9a; font-size: 11px; width: 70px; } + Text { + text: root.crc-ascii-frame; + color: #c8c8c8; + font-size: 12px; + font-family: "Cascadia Mono, Consolas, DejaVu Sans Mono, monospace"; + overflow: elide; + } + } + + Rectangle { height: 8px; background: transparent; } + + HorizontalLayout { + spacing: 6px; + height: 36px; + FuncBtn { + min-h: 36px; + label: "Clear"; + clicked => { + root.crc-input = ""; + root.crc-edited(""); + } + } + FuncBtn { + min-h: 36px; + label: "Example"; + clicked => { + root.crc-input = "01 03 00 00 00 0A"; + root.crc-edited(root.crc-input); + } + } + } + } + + if root.mode == 2: VerticalLayout { + spacing: 8px; + + HorizontalLayout { + spacing: 6px; + height: 30px; + ModeTab { + label: "Words"; + active: root.conv-panel == 0; + clicked => { root.press("panel:words"); } + } + ModeTab { + label: "Ratio"; + active: root.conv-panel == 1; + clicked => { root.press("panel:ratio"); } + } + ModeTab { + label: "ASCII"; + active: root.conv-panel == 2; + clicked => { root.press("panel:ascii"); } + } + } + + if root.conv-panel == 0: VerticalLayout { + spacing: 8px; + + Text { + text: "Endian (byte / word order)"; + color: #9a9a9a; + font-size: 12px; + } + + HorizontalLayout { + spacing: 6px; + height: 30px; + EndianChip { + label: "AB CD"; + active: root.conv-endian == 0; + clicked => { root.press("endian:0"); } + } + EndianChip { + label: "CD AB"; + active: root.conv-endian == 1; + clicked => { root.press("endian:1"); } + } + EndianChip { + label: "BA DC"; + active: root.conv-endian == 2; + clicked => { root.press("endian:2"); } + } + EndianChip { + label: "DC BA"; + active: root.conv-endian == 3; + clicked => { root.press("endian:3"); } + } + } + + FieldRow { + label: "Float32"; + value: root.conv-float; + active: root.conv-active == 0; + clicked => { root.press("conv:float"); } + } + FieldRow { + label: "Word 0"; + value: root.conv-word0; + active: root.conv-active == 1; + clicked => { root.press("conv:w0"); } + } + FieldRow { + label: "Word 1"; + value: root.conv-word1; + active: root.conv-active == 2; + clicked => { root.press("conv:w1"); } + } + + HorizontalLayout { + height: 18px; + Text { + text: "Wire"; + color: #9a9a9a; + font-size: 11px; + width: 40px; + } + Text { + text: root.conv-bytes; + color: #c8c8c8; + font-size: 12px; + font-family: "Cascadia Mono, Consolas, DejaVu Sans Mono, monospace"; + } + } + HorizontalLayout { + height: 18px; + Text { + text: "IEEE"; + color: #9a9a9a; + font-size: 11px; + width: 40px; + } + Text { + text: root.conv-ieee; + color: #c8c8c8; + font-size: 12px; + font-family: "Cascadia Mono, Consolas, DejaVu Sans Mono, monospace"; + } + } + } + + if root.conv-panel == 1: VerticalLayout { + spacing: 8px; + + Text { + text: "Electronic gear: float → num / den"; + color: #9a9a9a; + font-size: 12px; + } + + HorizontalLayout { + spacing: 6px; + height: 30px; + EndianChip { + label: "Byte (≤255)"; + active: root.ratio-width == 0; + clicked => { root.press("rwidth:byte"); } + } + EndianChip { + label: "Word (≤65535)"; + active: root.ratio-width == 1; + clicked => { root.press("rwidth:word"); } + } + } + + HorizontalLayout { + spacing: 6px; + height: 30px; + Text { + text: "Precision"; + color: #9a9a9a; + font-size: 12px; + vertical-alignment: center; + width: 70px; + } + EndianChip { + label: root.ratio-precision; + active: true; + clicked => { root.press("rprec"); } + } + Text { + text: "rel. error (tap to cycle)"; + color: #666666; + font-size: 11px; + vertical-alignment: center; + } + } + + FieldRow { + label: "Float32"; + value: root.conv-float; + active: true; + clicked => { root.press("conv:float"); } + } + + FieldRow { + label: "Num"; + value: root.ratio-num; + active: false; + clicked => { } + } + FieldRow { + label: "Den"; + value: root.ratio-den; + active: false; + clicked => { } + } + + HorizontalLayout { + height: 18px; + Text { + text: "Frac"; + color: #9a9a9a; + font-size: 11px; + width: 40px; + } + Text { + text: root.ratio-frac; + color: #60cdff; + font-size: 13px; + font-weight: 700; + font-family: "Cascadia Mono, Consolas, DejaVu Sans Mono, monospace"; + } + } + HorizontalLayout { + height: 18px; + Text { + text: "≈"; + color: #9a9a9a; + font-size: 11px; + width: 40px; + } + Text { + text: root.ratio-approx; + color: #c8c8c8; + font-size: 12px; + font-family: "Cascadia Mono, Consolas, DejaVu Sans Mono, monospace"; + } + } + HorizontalLayout { + height: 18px; + Text { + text: "Err"; + color: #9a9a9a; + font-size: 11px; + width: 40px; + } + Text { + text: root.ratio-error; + color: #c8c8c8; + font-size: 12px; + font-family: "Cascadia Mono, Consolas, DejaVu Sans Mono, monospace"; + } + } + } + + if root.conv-panel == 2: VerticalLayout { + spacing: 8px; + + Text { + text: "ASCII / Latin-1 · Char ↔ Hex ↔ Dec"; + color: #9a9a9a; + font-size: 12px; + } + + FieldRow { + label: "Char"; + value: root.ascii-char; + active: root.conv-active == 0; + clicked => { root.press("ascii:char"); } + } + FieldRow { + label: "Hex"; + value: root.ascii-hex; + active: root.conv-active == 1; + clicked => { root.press("ascii:hex"); } + } + FieldRow { + label: "Dec"; + value: root.ascii-dec; + active: root.conv-active == 2; + clicked => { root.press("ascii:dec"); } + } + + HorizontalLayout { + height: 20px; + Text { + text: "Name"; + color: #9a9a9a; + font-size: 11px; + width: 40px; + } + Text { + text: root.ascii-name; + color: #60cdff; + font-size: 13px; + font-weight: 700; + font-family: "Cascadia Mono, Consolas, DejaVu Sans Mono, monospace"; + } + } + + Text { + text: "Char: type on keyboard · Hex/Dec: keypad"; + color: #666666; + font-size: 11px; + } + } + + if root.conv-error != "": Text { + text: root.conv-error; + color: #ff8a80; + font-size: 12px; + } + + GridLayout { + spacing: 5px; + Row { + FuncBtn { label: "CE"; clicked => { root.press("CE"); } } + FuncBtn { label: "C"; clicked => { root.press("clear"); } } + FuncBtn { label: "⌫"; clicked => { root.press("BS"); } } + FuncBtn { + label: "±"; + enabled: root.conv-panel == 1 || (root.conv-panel == 0 && root.conv-active == 0); + clicked => { root.press("neg"); } + } + } + Row { + DigitBtn { + label: "A"; + enabled: (root.conv-panel == 0 && root.conv-active != 0) || (root.conv-panel == 2 && root.conv-active != 2); + clicked => { root.press("A"); } + } + DigitBtn { + label: "B"; + enabled: (root.conv-panel == 0 && root.conv-active != 0) || (root.conv-panel == 2 && root.conv-active != 2); + clicked => { root.press("B"); } + } + DigitBtn { + label: "C"; + enabled: (root.conv-panel == 0 && root.conv-active != 0) || (root.conv-panel == 2 && root.conv-active != 2); + clicked => { root.press("C"); } + } + DigitBtn { + label: "D"; + enabled: (root.conv-panel == 0 && root.conv-active != 0) || (root.conv-panel == 2 && root.conv-active != 2); + clicked => { root.press("D"); } + } + } + Row { + DigitBtn { + label: "E"; + enabled: (root.conv-panel == 0 && root.conv-active != 0) || (root.conv-panel == 2 && root.conv-active != 2); + clicked => { root.press("E"); } + } + DigitBtn { + label: "F"; + enabled: (root.conv-panel == 0 && root.conv-active != 0) || (root.conv-panel == 2 && root.conv-active != 2); + clicked => { root.press("F"); } + } + DigitBtn { + label: "."; + enabled: root.conv-panel == 1 || (root.conv-panel == 0 && root.conv-active == 0); + clicked => { root.press("."); } + } + FuncBtn { + label: "e"; + enabled: root.conv-panel == 1 || (root.conv-panel == 0 && root.conv-active == 0); + clicked => { root.press("e"); } + } + } + Row { + DigitBtn { label: "7"; clicked => { root.press("7"); } } + DigitBtn { label: "8"; clicked => { root.press("8"); } } + DigitBtn { label: "9"; clicked => { root.press("9"); } } + DigitBtn { label: "4"; clicked => { root.press("4"); } } + } + Row { + DigitBtn { label: "5"; clicked => { root.press("5"); } } + DigitBtn { label: "6"; clicked => { root.press("6"); } } + DigitBtn { label: "1"; clicked => { root.press("1"); } } + DigitBtn { label: "2"; clicked => { root.press("2"); } } + } + Row { + DigitBtn { label: "3"; clicked => { root.press("3"); } } + DigitBtn { label: "0"; clicked => { root.press("0"); } } + FuncBtn { + label: "Spc"; + enabled: root.conv-panel == 2 && root.conv-active == 0; + clicked => { root.press(" "); } + } + Rectangle { background: transparent; } + } + } + } + + if root.mode == 1: VerticalLayout { + spacing: 2px; + BaseRow { + label: "HEX"; + value: root.hex-text; + active: root.active-base == 0; + clicked => { root.press("base:hex"); } + } + BaseRow { + label: "DEC"; + value: root.dec-text; + active: root.active-base == 1; + clicked => { root.press("base:dec"); } + } + BaseRow { + label: "OCT"; + value: root.oct-text; + active: root.active-base == 2; + clicked => { root.press("base:oct"); } + } + BaseRow { + label: "BIN"; + value: root.bin-text; + active: root.active-base == 3; + clicked => { root.press("base:bin"); } + } + } + + if root.mode == 1 && root.show-bits: VerticalLayout { + spacing: 2px; + padding-top: 4px; + padding-bottom: 4px; + + if root.bit-row-count > 0: BitLine { + cells: root.bit-row0; + toggle-bit(idx) => { root.press("bit:\{idx}"); } + } + if root.bit-row-count > 1: BitLine { + cells: root.bit-row1; + toggle-bit(idx) => { root.press("bit:\{idx}"); } + } + if root.bit-row-count > 2: BitLine { + cells: root.bit-row2; + toggle-bit(idx) => { root.press("bit:\{idx}"); } + } + if root.bit-row-count > 3: BitLine { + cells: root.bit-row3; + toggle-bit(idx) => { root.press("bit:\{idx}"); } + } + } + + if root.mode == 0: HorizontalLayout { + spacing: 6px; + height: 32px; + MemBtn { label: "MC"; clicked => { root.press("MC"); } } + MemBtn { label: "MR"; clicked => { root.press("MR"); } } + MemBtn { label: "M+"; clicked => { root.press("M+"); } } + MemBtn { label: "M-"; clicked => { root.press("M-"); } } + MemBtn { label: "MS"; clicked => { root.press("MS"); } } + } + + if root.mode == 0: GridLayout { + spacing: 6px; + Row { + FuncBtn { label: "%"; clicked => { root.press("%"); } } + FuncBtn { label: "CE"; clicked => { root.press("CE"); } } + FuncBtn { label: "C"; clicked => { root.press("C"); } } + FuncBtn { label: "⌫"; clicked => { root.press("BS"); } } + } + Row { + FuncBtn { label: "1/x"; clicked => { root.press("1/x"); } } + FuncBtn { label: "x²"; clicked => { root.press("x2"); } } + FuncBtn { label: "√x"; clicked => { root.press("sqrt"); } } + FuncBtn { label: "÷"; clicked => { root.press("/"); } } + } + Row { + DigitBtn { label: "7"; clicked => { root.press("7"); } } + DigitBtn { label: "8"; clicked => { root.press("8"); } } + DigitBtn { label: "9"; clicked => { root.press("9"); } } + FuncBtn { label: "×"; clicked => { root.press("*"); } } + } + Row { + DigitBtn { label: "4"; clicked => { root.press("4"); } } + DigitBtn { label: "5"; clicked => { root.press("5"); } } + DigitBtn { label: "6"; clicked => { root.press("6"); } } + FuncBtn { label: "−"; clicked => { root.press("-"); } } + } + Row { + DigitBtn { label: "1"; clicked => { root.press("1"); } } + DigitBtn { label: "2"; clicked => { root.press("2"); } } + DigitBtn { label: "3"; clicked => { root.press("3"); } } + FuncBtn { label: "+"; clicked => { root.press("+"); } } + } + Row { + DigitBtn { label: "±"; clicked => { root.press("neg"); } } + DigitBtn { label: "0"; clicked => { root.press("0"); } } + DigitBtn { label: "."; clicked => { root.press("."); } } + EqBtn { clicked => { root.press("="); } } + } + } + + if root.mode == 1: GridLayout { + spacing: 4px; + Row { + FuncBtn { min-h: 34px; label: root.word-size-label; clicked => { root.press("word"); } } + FuncBtn { min-h: 34px; label: "CE"; clicked => { root.press("CE"); } } + FuncBtn { min-h: 34px; label: "C"; clicked => { root.press("clear"); } } + FuncBtn { min-h: 34px; label: "⌫"; clicked => { root.press("BS"); } } + } + Row { + FuncBtn { min-h: 34px; label: "AND"; clicked => { root.press("AND"); } } + FuncBtn { min-h: 34px; label: "OR"; clicked => { root.press("OR"); } } + FuncBtn { min-h: 34px; label: "NOT"; clicked => { root.press("NOT"); } } + FuncBtn { min-h: 34px; label: "NAND"; clicked => { root.press("NAND"); } } + } + Row { + FuncBtn { min-h: 34px; label: "NOR"; clicked => { root.press("NOR"); } } + FuncBtn { min-h: 34px; label: "XOR"; clicked => { root.press("XOR"); } } + FuncBtn { min-h: 34px; label: "Lsh"; clicked => { root.press("Lsh"); } } + FuncBtn { min-h: 34px; label: "Rsh"; clicked => { root.press("Rsh"); } } + } + Row { + DigitBtn { min-h: 34px; label: "A"; enabled: root.allow-a; clicked => { root.press("A"); } } + DigitBtn { min-h: 34px; label: "B"; enabled: root.allow-a; clicked => { root.press("B"); } } + DigitBtn { min-h: 34px; label: "C"; enabled: root.allow-a; clicked => { root.press("C"); } } + FuncBtn { min-h: 34px; label: "÷"; clicked => { root.press("/"); } } + } + Row { + DigitBtn { min-h: 34px; label: "D"; enabled: root.allow-a; clicked => { root.press("D"); } } + DigitBtn { min-h: 34px; label: "E"; enabled: root.allow-a; clicked => { root.press("E"); } } + DigitBtn { min-h: 34px; label: "F"; enabled: root.allow-a; clicked => { root.press("F"); } } + FuncBtn { min-h: 34px; label: "×"; clicked => { root.press("*"); } } + } + Row { + DigitBtn { min-h: 34px; label: "7"; enabled: root.allow-2; clicked => { root.press("7"); } } + DigitBtn { min-h: 34px; label: "8"; enabled: root.allow-8; clicked => { root.press("8"); } } + DigitBtn { min-h: 34px; label: "9"; enabled: root.allow-8; clicked => { root.press("9"); } } + FuncBtn { min-h: 34px; label: "−"; clicked => { root.press("-"); } } + } + Row { + DigitBtn { min-h: 34px; label: "4"; enabled: root.allow-2; clicked => { root.press("4"); } } + DigitBtn { min-h: 34px; label: "5"; enabled: root.allow-2; clicked => { root.press("5"); } } + DigitBtn { min-h: 34px; label: "6"; enabled: root.allow-2; clicked => { root.press("6"); } } + FuncBtn { min-h: 34px; label: "+"; clicked => { root.press("+"); } } + } + Row { + DigitBtn { min-h: 34px; label: "1"; clicked => { root.press("1"); } } + DigitBtn { min-h: 34px; label: "2"; enabled: root.active-base != 3; clicked => { root.press("2"); } } + DigitBtn { min-h: 34px; label: "3"; enabled: root.allow-2; clicked => { root.press("3"); } } + FuncBtn { min-h: 34px; label: "%"; clicked => { root.press("%"); } } + } + Row { + DigitBtn { min-h: 34px; label: "±"; clicked => { root.press("neg"); } } + DigitBtn { min-h: 34px; label: "0"; clicked => { root.press("0"); } } + FuncBtn { + min-h: 34px; + label: root.show-bits ? "Bits●" : "Bits"; + clicked => { root.press("bits"); } + } + EqBtn { min-h: 34px; clicked => { root.press("="); } } + } + } + } + + forward-focus: key-handler; + key-handler := FocusScope { + key-pressed(event) => { + if (root.mode == 3) { + return reject; + } + if (event.text == Key.Return) { + root.press("="); + return accept; + } + if (event.text == Key.Backspace) { + root.press("BS"); + return accept; + } + if (event.text == Key.Escape) { + root.press(root.mode == 0 ? "C" : "clear"); + return accept; + } + if (event.text == Key.Delete) { + root.press("CE"); + return accept; + } + if (event.text != "") { + root.press(event.text); + return accept; + } + reject + } + } +}