diff --git a/Cargo.lock b/Cargo.lock index a0b6abf..5ca63a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,118 @@ # 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.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b76d84ee70e30a4a7e39ab9018e2b17a6a09e31084176cc7c0b2dec036ba45" + +[[package]] +name = "accesskit_atspi_common" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5393c75d4666f580f4cac0a968bc97c36076bb536a129f28210dac54ee127ed" +dependencies = [ + "accesskit", + "accesskit_consumer", + "atspi-common", + "serde", + "thiserror 1.0.69", + "zvariant 4.2.0", +] + +[[package]] +name = "accesskit_consumer" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a12dc159d52233c43d9fe5415969433cbdd52c3d6e0df51bda7d447427b9986" +dependencies = [ + "accesskit", + "immutable-chunkmap", +] + +[[package]] +name = "accesskit_macos" +version = "0.17.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfc6c1ecd82053d127961ad80a8beaa6004fb851a3a5b96506d7a6bd462403f6" +dependencies = [ + "accesskit", + "accesskit_consumer", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", + "once_cell", +] + +[[package]] +name = "accesskit_unix" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be7f5cf6165be10a54b2655fa2e0e12b2509f38ed6fc43e11c31fdb7ee6230bb" +dependencies = [ + "accesskit", + "accesskit_atspi_common", + "async-channel", + "async-executor", + "async-task", + "atspi", + "futures-lite", + "futures-util", + "serde", + "zbus 4.4.0", +] + +[[package]] +name = "accesskit_windows" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "974e96c347384d9133427167fb8a58c340cb0496988dacceebdc1ed27071023b" +dependencies = [ + "accesskit", + "accesskit_consumer", + "paste", + "static_assertions", + "windows 0.58.0", + "windows-core 0.58.0", +] + +[[package]] +name = "accesskit_winit" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aea3522719f1c44564d03e9469a8e2f3a98b3a8a880bd66d0789c6b9c4a669dd" +dependencies = [ + "accesskit", + "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.7.8" @@ -20,6 +132,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", + "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -31,6 +144,42 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +[[package]] +name = "android-activity" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" +dependencies = [ + "android-properties", + "bitflags 2.10.0", + "cc", + "cesu8", + "jni 0.21.1", + "jni-sys 0.3.0", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys 0.6.0+11769913", + "num_enum", + "thiserror 1.0.69", +] + +[[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 = "ar_archive_writer" version = "0.2.0" @@ -40,6 +189,23 @@ dependencies = [ "object", ] +[[package]] +name = "arboard" +version = "3.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0348a1c054491f4bfe6ab86a7b6ab1e44e45d899005de92f58b3df180b36ddaf" +dependencies = [ + "clipboard-win", + "log", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-foundation 0.3.2", + "parking_lot", + "percent-encoding", + "windows-sys 0.59.0", + "x11rb", +] + [[package]] name = "arc-swap" version = "1.7.1" @@ -56,27 +222,307 @@ dependencies = [ "yansi", ] +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + +[[package]] +name = "ash" +version = "0.38.0+1.3.281" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" +dependencies = [ + "libloading", +] + +[[package]] +name = "ashpd" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f3f79755c74fd155000314eb349864caa787c6592eace6c6882dad873d9c39" +dependencies = [ + "async-fs", + "async-net", + "enumflags2", + "futures-channel", + "futures-util", + "rand 0.9.2", + "raw-window-handle", + "serde", + "serde_repr", + "url", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "zbus 5.14.0", +] + +[[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-fs" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5" +dependencies = [ + "async-lock", + "blocking", + "futures-lite", +] + +[[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.2", + "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-net" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" +dependencies = [ + "async-io", + "blocking", + "futures-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.2", +] + +[[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.111", +] + +[[package]] +name = "async-signal" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 1.1.2", + "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.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[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.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be534b16650e35237bb1ed189ba2aab86ce65e88cc84c66f4935ba38575cecbf" +dependencies = [ + "atspi-common", + "atspi-connection", + "atspi-proxies", +] + +[[package]] +name = "atspi-common" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1909ed2dc01d0a17505d89311d192518507e8a056a48148e3598fef5e7bb6ba7" +dependencies = [ + "enumflags2", + "serde", + "static_assertions", + "zbus 4.4.0", + "zbus-lockstep", + "zbus-lockstep-macros", + "zbus_names 3.0.0", + "zvariant 4.2.0", +] + +[[package]] +name = "atspi-connection" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "430c5960624a4baaa511c9c0fcc2218e3b58f5dbcc47e6190cafee344b873333" +dependencies = [ + "atspi-common", + "atspi-proxies", + "futures-lite", + "zbus 4.4.0", +] + +[[package]] +name = "atspi-proxies" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e6c5de3e524cf967569722446bcd458d5032348554d9a17d7d72b041ab7496" +dependencies = [ + "atspi-common", + "serde", + "zbus 4.4.0", + "zvariant 4.2.0", +] + [[package]] name = "autocfg" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "bit-set" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0481a0e032742109b1133a095184ee93d88f3dc9e0d28a5d033dc77a073f44f" +dependencies = [ + "bit-vec 0.7.0", +] + [[package]] name = "bit-set" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ - "bit-vec", + "bit-vec 0.8.0", ] +[[package]] +name = "bit-vec" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22" + [[package]] name = "bit-vec" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.10.0" @@ -95,6 +541,52 @@ dependencies = [ "wyz", ] +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[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 = "bumpalo" version = "3.19.0" @@ -129,6 +621,20 @@ name = "bytemuck" version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] [[package]] name = "byteorder" @@ -136,12 +642,69 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +[[package]] +name = "calloop" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" +dependencies = [ + "bitflags 2.10.0", + "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.10.0", + "polling", + "rustix 1.1.2", + "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.2", + "wayland-backend", + "wayland-client", +] + [[package]] name = "cc" version = "1.2.49" @@ -149,21 +712,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[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.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "cfg_aliases" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "cgl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +dependencies = [ + "libc", +] + [[package]] name = "chumsky" version = "0.9.3" @@ -183,6 +769,66 @@ dependencies = [ "error-code", ] +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width 0.1.14", +] + +[[package]] +name = "com" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6" +dependencies = [ + "com_macros", +] + +[[package]] +name = "com_macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5" +dependencies = [ + "com_macros_support", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "com_macros_support" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[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 = "console" version = "0.15.11" @@ -195,6 +841,74 @@ dependencies = [ "windows-sys 0.59.0", ] +[[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" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +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 0.9.4", + "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 0.9.4", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam" version = "0.8.4" @@ -251,6 +965,136 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cursor-icon" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[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.10.0", + "block2 0.6.2", + "libc", + "objc2 0.6.4", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "dlib" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab8ecd87370524b461f8557c119c405552c396ed91fc0a8eec68679eab26f94a" +dependencies = [ + "libloading", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[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 = "ecolor" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775cfde491852059e386c4e1deb4aef381c617dc364184c6f6afee99b87c402b" +dependencies = [ + "bytemuck", + "emath", +] + +[[package]] +name = "eframe" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ac2645a9bf4826eb4e91488b1f17b8eaddeef09396706b2f14066461338e24f" +dependencies = [ + "ahash 0.8.12", + "bytemuck", + "document-features", + "egui", + "egui-wgpu", + "egui-winit", + "egui_glow", + "glow 0.14.2", + "glutin", + "glutin-winit", + "image", + "js-sys", + "log", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", + "parking_lot", + "percent-encoding", + "raw-window-handle", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "web-time", + "winapi", + "windows-sys 0.52.0", + "winit", +] + [[package]] name = "egglog-concurrency" version = "1.0.0" @@ -281,24 +1125,185 @@ dependencies = [ "egglog-numeric-id", ] +[[package]] +name = "egui" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53eafabcce0cb2325a59a98736efe0bf060585b437763f8c476957fb274bb974" +dependencies = [ + "accesskit", + "ahash 0.8.12", + "emath", + "epaint", + "log", + "nohash-hasher", +] + +[[package]] +name = "egui-wgpu" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d00fd5d06d8405397e64a928fa0ef3934b3c30273ea7603e3dc4627b1f7a1a82" +dependencies = [ + "ahash 0.8.12", + "bytemuck", + "document-features", + "egui", + "epaint", + "log", + "thiserror 1.0.69", + "type-map", + "web-time", + "wgpu", + "winit", +] + +[[package]] +name = "egui-winit" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a9c430f4f816340e8e8c1b20eec274186b1be6bc4c7dfc467ed50d57abc36c6" +dependencies = [ + "accesskit_winit", + "ahash 0.8.12", + "arboard", + "egui", + "log", + "raw-window-handle", + "smithay-clipboard", + "web-time", + "webbrowser", + "winit", +] + +[[package]] +name = "egui_extras" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf3c1f5cd8dfe2ade470a218696c66cf556fcfd701e7830fa2e9f4428292a2a1" +dependencies = [ + "ahash 0.8.12", + "egui", + "enum-map", + "log", + "mime_guess2", +] + +[[package]] +name = "egui_glow" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e39bccc683cd43adab530d8f21a13eb91e80de10bcc38c3f1c16601b6f62b26" +dependencies = [ + "ahash 0.8.12", + "bytemuck", + "egui", + "glow 0.14.2", + "log", + "memoffset", + "wasm-bindgen", + "web-sys", + "winit", +] + [[package]] name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[package]] +name = "emath" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1fe0049ce51d0fb414d029e668dd72eb30bc2b739bf34296ed97bd33df544f3" +dependencies = [ + "bytemuck", +] + [[package]] name = "encode_unicode" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" +[[package]] +name = "endi" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" + [[package]] name = "endian-type" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" +[[package]] +name = "enum-map" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" +dependencies = [ + "enum-map-derive", + "serde", +] + +[[package]] +name = "enum-map-derive" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[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.111", +] + +[[package]] +name = "epaint" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a32af8da821bd4f43f2c137e295459ee2e1661d87ca8779dfa0eaf45d870e20f" +dependencies = [ + "ab_glyph", + "ahash 0.8.12", + "bytemuck", + "ecolor", + "emath", + "epaint_default_fonts", + "log", + "nohash-hasher", + "parking_lot", +] + +[[package]] +name = "epaint_default_fonts" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "483440db0b7993cf77a20314f08311dbe95675092405518c0677aa08c151a3ea" + [[package]] name = "equivalent" version = "1.0.2" @@ -321,6 +1326,27 @@ version = "3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "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 = "fastrand" version = "2.3.0" @@ -334,43 +1360,190 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" dependencies = [ "cfg-if", - "rustix", + "rustix 1.1.2", "windows-sys 0.59.0", ] +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + [[package]] name = "find-msvc-tools" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +[[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 = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foreign-types" +version = "0.5.0" +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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[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 = "funty" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[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.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "geolog" version = "0.1.0" dependencies = [ "ariadne", "chumsky", + "eframe", "egglog-numeric-id", "egglog-union-find", + "egui_extras", "indexmap 2.12.1", "insta", "itertools", "memmap2", "nonminmax", "proptest", - "rand", + "rand 0.9.2", + "rfd", "rkyv", "roaring", "rustyline", @@ -381,6 +1554,16 @@ dependencies = [ "uuid", ] +[[package]] +name = "gethostname" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" +dependencies = [ + "rustix 1.1.2", + "windows-link", +] + [[package]] name = "getrandom" version = "0.2.16" @@ -404,6 +1587,159 @@ dependencies = [ "wasip2", ] +[[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 = "glow" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glow" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51fa363f025f5c111e03f13eda21162faeacb6911fe8caa0c0349f9cf0c4483" +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.10.0", + "cfg_aliases 0.2.1", + "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 0.2.1", + "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 = "gpu-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" +dependencies = [ + "bitflags 2.10.0", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "gpu-allocator" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd4240fc91d3433d5e5b0fc5b67672d771850dc19bbee03c1381e19322803d7" +dependencies = [ + "log", + "presser", + "thiserror 1.0.69", + "winapi", + "windows 0.52.0", +] + +[[package]] +name = "gpu-descriptor" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" +dependencies = [ + "bitflags 2.10.0", + "gpu-descriptor-types", + "hashbrown 0.15.5", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" +dependencies = [ + "bitflags 2.10.0", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -423,12 +1759,54 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + [[package]] name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +[[package]] +name = "hassle-rs" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" +dependencies = [ + "bitflags 2.10.0", + "com", + "libc", + "libloading", + "thiserror 1.0.69", + "widestring", + "winapi", +] + +[[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 = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + [[package]] name = "home" version = "0.5.12" @@ -438,6 +1816,130 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +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", + "moxcms", + "num-traits", + "png", +] + +[[package]] +name = "immutable-chunkmap" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3e98b1520e49e252237edc238a39869da9f3241f2ec19dc788c1d24694d1e4" +dependencies = [ + "arrayvec", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -478,6 +1980,87 @@ dependencies = [ "either", ] +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys 0.3.0", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[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.18", + "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.111", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[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.111", +] + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + [[package]] name = "js-sys" version = "0.3.83" @@ -488,24 +2071,99 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "khronos-egl" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" +dependencies = [ + "libc", + "libloading", + "pkg-config", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + [[package]] name = "libc" version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +[[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 = "libredox" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" +dependencies = [ + "bitflags 2.10.0", + "libc", + "plain", + "redox_syscall 0.7.3", +] + +[[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.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + [[package]] name = "memchr" version = "2.7.6" @@ -521,6 +2179,128 @@ 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 = "metal" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" +dependencies = [ + "bitflags 2.10.0", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", + "paste", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess2" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1706dc14a2e140dec0a7a07109d9a3d5890b81e85bd6c60b906b249a77adf0ca" +dependencies = [ + "mime", + "phf", + "phf_shared", + "unicase", +] + +[[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 = "naga" +version = "22.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bd5a652b6faf21496f2cfd88fc49989c8db0825d1f6746b1a71a6ede24a63ad" +dependencies = [ + "arrayvec", + "bit-set 0.6.0", + "bitflags 2.10.0", + "cfg_aliases 0.1.1", + "codespan-reporting", + "hexf-parse", + "indexmap 2.12.1", + "log", + "rustc-hash 1.1.0", + "spirv", + "termcolor", + "thiserror 1.0.69", + "unicode-xid", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.10.0", + "jni-sys 0.3.0", + "log", + "ndk-sys 0.6.0+11769913", + "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.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys 0.3.0", +] + +[[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.0", +] + [[package]] name = "nibble_vec" version = "0.1.0" @@ -536,12 +2316,19 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags", + "bitflags 2.10.0", "cfg-if", - "cfg_aliases", + "cfg_aliases 0.2.1", "libc", + "memoffset", ] +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + [[package]] name = "nonminmax" version = "0.1.1" @@ -557,6 +2344,309 @@ dependencies = [ "autocfg", ] +[[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.111", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[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.10.0", + "block2 0.5.1", + "libc", + "objc2 0.5.2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation 0.2.2", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-app-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" +dependencies = [ + "bitflags 2.10.0", + "block2 0.6.2", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 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.10.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation 0.2.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.10.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.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.10.0", + "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.10.0", + "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", +] + +[[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-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.10.0", + "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.10.0", + "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.10.0", + "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.10.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.10.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal", +] + +[[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.10.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation 0.2.2", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[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.10.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation 0.2.2", +] + [[package]] name = "object" version = "0.32.2" @@ -572,6 +2662,211 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "orbclient" +version = "0.3.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59aed3b33578edcfa1bc96a321d590d31832b6ad55a26f0313362ce687e9abd6" +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 = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.18", + "smallvec", + "windows-link", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[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.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.111", + "unicase", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", + "unicase", +] + +[[package]] +name = "pin-project" +version = "1.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[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.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[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.10.0", + "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", + "pin-project-lite", + "rustix 1.1.2", + "windows-sys 0.61.2", +] + +[[package]] +name = "pollster" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -581,6 +2876,21 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "presser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit 0.25.5+spec-1.1.0", +] + [[package]] name = "proc-macro2" version = "1.0.103" @@ -590,18 +2900,24 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "profiling" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" + [[package]] name = "proptest" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" dependencies = [ - "bit-set", - "bit-vec", - "bitflags", + "bit-set 0.8.0", + "bit-vec 0.8.0", + "bitflags 2.10.0", "num-traits", - "rand", - "rand_chacha", + "rand 0.9.2", + "rand_chacha 0.9.0", "rand_xorshift", "regex-syntax", "rusty-fork", @@ -639,12 +2955,37 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "pxfm" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a041e753da8b807c9255f28de81879c78c876392ff2469cde94799b2896b9d" + [[package]] name = "quick-error" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quick-xml" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "quick-xml" +version = "0.39.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958f21e8e7ceb5a1aa7fa87fab28e7c75976e0bfe7e23ff069e0a260f894067d" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.42" @@ -676,14 +3017,35 @@ dependencies = [ "nibble_vec", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + [[package]] name = "rand" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "rand_chacha", - "rand_core", + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", ] [[package]] @@ -693,7 +3055,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", ] [[package]] @@ -711,9 +3082,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" dependencies = [ - "rand_core", + "rand_core 0.9.3", ] +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + [[package]] name = "rayon" version = "1.11.0" @@ -734,6 +3111,33 @@ dependencies = [ "crossbeam-utils", ] +[[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.10.0", +] + +[[package]] +name = "redox_syscall" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" +dependencies = [ + "bitflags 2.10.0", +] + [[package]] name = "regex-syntax" version = "0.8.8" @@ -749,6 +3153,36 @@ dependencies = [ "bytecheck", ] +[[package]] +name = "renderdoc-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + +[[package]] +name = "rfd" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2bee61e6cffa4635c72d7d81a84294e28f0930db0ddcb0f66d10244674ebed" +dependencies = [ + "ashpd", + "block2 0.6.2", + "dispatch2", + "js-sys", + "log", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "pollster", + "raw-window-handle", + "urlencoding", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-sys 0.59.0", +] + [[package]] name = "rkyv" version = "0.7.45" @@ -789,16 +3223,50 @@ dependencies = [ "byteorder", ] +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "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.10.0", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + [[package]] name = "rustix" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags", + "bitflags 2.10.0", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.11.0", "windows-sys 0.61.2", ] @@ -826,7 +3294,7 @@ version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ee1e066dc922e513bda599c6ccb5f3bb2b0ea5870a579448f2622993f0a9a2f" dependencies = [ - "bitflags", + "bitflags 2.10.0", "cfg-if", "clipboard-win", "fd-lock", @@ -842,12 +3310,52 @@ dependencies = [ "windows-sys 0.59.0", ] +[[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 = "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", +] + [[package]] name = "seahash" version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + [[package]] name = "serde" version = "1.0.228" @@ -878,6 +3386,17 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "serde_spanned" version = "0.6.9" @@ -887,12 +3406,49 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] + [[package]] name = "simdutf8" version = "0.1.5" @@ -905,12 +3461,120 @@ version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" +[[package]] +name = "siphasher" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[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.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "smithay-client-toolkit" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +dependencies = [ + "bitflags 2.10.0", + "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.10.0", + "calloop 0.14.4", + "calloop-wayland-source 0.4.1", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix 1.1.2", + "thiserror 2.0.18", + "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 = "spirv" +version = "0.3.0+sdk-1.3.268.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + [[package]] name = "stacker" version = "0.1.22" @@ -924,6 +3588,18 @@ dependencies = [ "windows-sys 0.59.0", ] +[[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" + [[package]] name = "syn" version = "1.0.109" @@ -946,6 +3622,17 @@ dependencies = [ "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.111", +] + [[package]] name = "tap" version = "1.0.1" @@ -961,10 +3648,94 @@ dependencies = [ "fastrand", "getrandom 0.3.4", "once_cell", - "rustix", + "rustix 1.1.2", "windows-sys 0.61.2", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[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.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[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.111", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[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", +] + +[[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 = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.10.0" @@ -988,8 +3759,8 @@ checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", - "toml_datetime", - "toml_edit", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", ] [[package]] @@ -1001,6 +3772,15 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "1.0.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b320e741db58cac564e26c607d3cc1fdc4a88fd36c879568c07856ed83ff3e9" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" version = "0.22.27" @@ -1010,9 +3790,30 @@ dependencies = [ "indexmap 2.12.1", "serde", "serde_spanned", - "toml_datetime", + "toml_datetime 0.6.11", "toml_write", - "winnow", + "winnow 0.7.14", +] + +[[package]] +name = "toml_edit" +version = "0.25.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca1a40644a28bce036923f6a431df0b34236949d111cc07cb6dca830c9ef2e1" +dependencies = [ + "indexmap 2.12.1", + "toml_datetime 1.0.1+spec-1.1.0", + "toml_parser", + "winnow 1.0.0", +] + +[[package]] +name = "toml_parser" +version = "1.0.10+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7df25b4befd31c4816df190124375d5a20c6b6921e2cad937316de3fccd63420" +dependencies = [ + "winnow 1.0.0", ] [[package]] @@ -1021,12 +3822,82 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +[[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.111", +] + +[[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" + +[[package]] +name = "type-map" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90" +dependencies = [ + "rustc-hash 2.1.1", +] + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[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 = "unarray" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + [[package]] name = "unicode-ident" version = "1.0.22" @@ -1051,6 +3922,37 @@ 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 = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", + "serde_derive", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -1065,6 +3967,7 @@ checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ "getrandom 0.3.4", "js-sys", + "serde_core", "wasm-bindgen", ] @@ -1083,6 +3986,16 @@ dependencies = [ "libc", ] +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -1111,6 +4024,19 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.106" @@ -1143,19 +4069,429 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wayland-backend" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa75f400b7f719bcd68b3f47cd939ba654cedeef690f486db71331eec4c6a406" +dependencies = [ + "cc", + "downcast-rs", + "rustix 1.1.2", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab51d9f7c071abeee76007e2b742499e535148035bb835f97aaed1338cf516c3" +dependencies = [ + "bitflags 2.10.0", + "rustix 1.1.2", + "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.10.0", + "cursor-icon", + "wayland-backend", +] + +[[package]] +name = "wayland-cursor" +version = "0.31.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b3298683470fbdc6ca40151dfc48c8f2fd4c41a26e13042f801f85002384091" +dependencies = [ + "rustix 1.1.2", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.32.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b23b5df31ceff1328f06ac607591d5ba360cf58f90c8fad4ac8d3a55a3c4aec7" +dependencies = [ + "bitflags 2.10.0", + "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.10.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-misc" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "429b99200febaf95d4f4e46deff6fe4382bcff3280ee16a41cf887b3c3364984" +dependencies = [ + "bitflags 2.10.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d392fc283a87774afc9beefcd6f931582bb97fe0e6ced0b306a62cb1d026527c" +dependencies = [ + "bitflags 2.10.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78248e4cc0eff8163370ba5c158630dcae1f3497a586b826eca2ef5f348d6235" +dependencies = [ + "bitflags 2.10.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c86287151a309799b821ca709b7345a048a2956af05957c89cb824ab919fa4e3" +dependencies = [ + "proc-macro2", + "quick-xml 0.39.2", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374f6b70e8e0d6bf9461a32988fd553b59ff630964924dad6e4a4eb6bd538d17" +dependencies = [ + "dlib", + "log", + "once_cell", + "pkg-config", +] + +[[package]] +name = "web-sys" +version = "0.3.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe985f41e291eecef5e5c0770a18d28390addb03331c043964d9e916453d6f16" +dependencies = [ + "core-foundation 0.10.1", + "jni 0.22.4", + "log", + "ndk-context", + "objc2 0.6.4", + "objc2-foundation 0.3.2", + "url", + "web-sys", +] + +[[package]] +name = "wgpu" +version = "22.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d1c4ba43f80542cf63a0a6ed3134629ae73e8ab51e4b765a67f3aa062eb433" +dependencies = [ + "arrayvec", + "cfg_aliases 0.1.1", + "document-features", + "js-sys", + "log", + "parking_lot", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "22.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0348c840d1051b8e86c3bcd31206080c5e71e5933dabd79be1ce732b0b2f089a" +dependencies = [ + "arrayvec", + "bit-vec 0.7.0", + "bitflags 2.10.0", + "cfg_aliases 0.1.1", + "document-features", + "indexmap 2.12.1", + "log", + "naga", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 1.0.69", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "22.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6bbf4b4de8b2a83c0401d9e5ae0080a2792055f25859a02bf9be97952bbed4f" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bitflags 2.10.0", + "cfg_aliases 0.1.1", + "core-graphics-types", + "glow 0.13.1", + "glutin_wgl_sys", + "gpu-alloc", + "gpu-allocator", + "gpu-descriptor", + "hassle-rs", + "js-sys", + "khronos-egl", + "libc", + "libloading", + "log", + "metal", + "naga", + "ndk-sys 0.5.0+25.2.9519653", + "objc", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle", + "renderdoc-sys", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 1.0.69", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "winapi", +] + +[[package]] +name = "wgpu-types" +version = "22.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc9d91f0e2c4b51434dfa6db77846f2793149d8e73f800fa2e41f52b8eac3c5d" +dependencies = [ + "bitflags 2.10.0", + "js-sys", + "web-sys", +] + +[[package]] +name = "widestring" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[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.111", +] + +[[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.111", +] + [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[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", + "windows-targets 0.52.6", ] [[package]] @@ -1167,34 +4503,67 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "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_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[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.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[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.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -1207,30 +4576,106 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.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 0.8.12", + "android-activity", + "atomic-waker", + "bitflags 2.10.0", + "block2 0.5.1", + "bytemuck", + "calloop 0.13.0", + "cfg_aliases 0.2.1", + "concurrent-queue", + "core-foundation 0.9.4", + "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", + "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", + "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 = "0.7.14" @@ -1240,12 +4685,27 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen" version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + [[package]] name = "wyz" version = "0.5.1" @@ -1255,12 +4715,268 @@ dependencies = [ "tap", ] +[[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.2", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" + +[[package]] +name = "xcursor" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b" + +[[package]] +name = "xdg-home" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.10.0", + "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 = "yansi" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "synstructure", +] + +[[package]] +name = "zbus" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" +dependencies = [ + "async-broadcast", + "async-executor", + "async-fs", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "nix", + "ordered-stream", + "rand 0.8.5", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tracing", + "uds_windows", + "windows-sys 0.52.0", + "xdg-home", + "zbus_macros 4.4.0", + "zbus_names 3.0.0", + "zvariant 4.2.0", +] + +[[package]] +name = "zbus" +version = "5.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca82f95dbd3943a40a53cfded6c2d0a2ca26192011846a1810c4256ef92c60bc" +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.2", + "serde", + "serde_repr", + "tracing", + "uds_windows", + "uuid", + "windows-sys 0.61.2", + "winnow 0.7.14", + "zbus_macros 5.14.0", + "zbus_names 4.3.1", + "zvariant 5.10.0", +] + +[[package]] +name = "zbus-lockstep" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca2c5dceb099bddaade154055c926bb8ae507a18756ba1d8963fd7b51d8ed1d" +dependencies = [ + "zbus_xml", + "zvariant 4.2.0", +] + +[[package]] +name = "zbus-lockstep-macros" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709ab20fc57cb22af85be7b360239563209258430bccf38d8b979c5a2ae3ecce" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "zbus-lockstep", + "zbus_xml", + "zvariant 4.2.0", +] + +[[package]] +name = "zbus_macros" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.111", + "zvariant_utils 2.1.0", +] + +[[package]] +name = "zbus_macros" +version = "5.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897e79616e84aac4b2c46e9132a4f63b93105d54fe8c0e8f6bffc21fa8d49222" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.111", + "zbus_names 4.3.1", + "zvariant 5.10.0", + "zvariant_utils 3.3.0", +] + +[[package]] +name = "zbus_names" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" +dependencies = [ + "serde", + "static_assertions", + "zvariant 4.2.0", +] + +[[package]] +name = "zbus_names" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f" +dependencies = [ + "serde", + "winnow 0.7.14", + "zvariant 5.10.0", +] + +[[package]] +name = "zbus_xml" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3f374552b954f6abb4bd6ce979e6c9b38fb9d0cd7cc68a7d796e70c9f3a233" +dependencies = [ + "quick-xml 0.30.0", + "serde", + "static_assertions", + "zbus_names 3.0.0", + "zvariant 4.2.0", +] + [[package]] name = "zerocopy" version = "0.8.31" @@ -1280,3 +4996,135 @@ dependencies = [ "quote", "syn 2.0.111", ] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "zvariant" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe" +dependencies = [ + "endi", + "enumflags2", + "serde", + "static_assertions", + "zvariant_derive 4.2.0", +] + +[[package]] +name = "zvariant" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5708299b21903bbe348e94729f22c49c55d04720a004aa350f1f9c122fd2540b" +dependencies = [ + "endi", + "enumflags2", + "serde", + "url", + "winnow 0.7.14", + "zvariant_derive 5.10.0", + "zvariant_utils 3.3.0", +] + +[[package]] +name = "zvariant_derive" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.111", + "zvariant_utils 2.1.0", +] + +[[package]] +name = "zvariant_derive" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b59b012ebe9c46656f9cc08d8da8b4c726510aef12559da3e5f1bf72780752c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.111", + "zvariant_utils 3.3.0", +] + +[[package]] +name = "zvariant_utils" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "zvariant_utils" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f75c23a64ef8f40f13a6989991e643554d9bef1d682a281160cf0c1bc389c5e9" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "syn 2.0.111", + "winnow 0.7.14", +] diff --git a/Cargo.toml b/Cargo.toml index 337e032..158456b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,27 @@ proptest = "1.4" # property-based testing rand = "0.9.2" tempfile = "3.10" # temp dirs for persistence tests +[features] +default = [] +gui = ["eframe", "egui_extras", "rfd"] + +[dependencies.eframe] +version = "0.29" +optional = true + +[dependencies.egui_extras] +version = "0.29" +optional = true + +[dependencies.rfd] +version = "0.15" +optional = true + [[bin]] name = "geolog" path = "src/bin/geolog.rs" + +[[bin]] +name = "geolog-gui" +path = "src/bin/geolog-gui.rs" +required-features = ["gui"] diff --git a/README2.md b/README2.md new file mode 100644 index 0000000..2712125 --- /dev/null +++ b/README2.md @@ -0,0 +1,249 @@ +# Geolog Development Notes + +This document describes the features and components added to the geolog project (by me, Hassan). + +## Overview + +Geolog is a language for geometric logic - a type theory with semantics in topoi and geometric morphisms, designed as a unified language for database schemas, queries, and migrations. + +## Components + +### Core Components (Pre-existing) + +- **Parser & Lexer** (`src/lexer.rs`, `src/parser.rs`) - Chumsky-based parser for geolog syntax +- **AST** (`src/ast.rs`) - Abstract syntax tree representation +- **Core Types** (`src/core.rs`) - Signatures, structures, theories, axioms +- **Elaboration** (`src/elaborate.rs`) - Type checking and elaboration +- **Store** (`src/store.rs`) - Append-only persistent storage with version control +- **REPL** (`src/repl.rs`) - Interactive command-line environment +- **Solver** (`src/solver.rs`) - Model enumeration for geometric theories +- **Query Engine** (`src/query/`) - Relational algebra backend for queries +- **Chase Algorithm** (`src/query/chase.rs`) - Fixpoint computation for axiom closure + +### Debugger (`src/debugger.rs`) + +Interactive debugger for the chase algorithm providing: +- Step-through execution +- Breakpoints on axiom name patterns +- Variable inspection +- Iteration stepping + +Usage in REPL: +``` +:debug-chase [max_iterations] +``` + +### GUI Application (`src/gui/`) + +A full-featured graphical interface built with egui. + +#### Building the GUI + +```bash +# Build with GUI feature +cargo build --features gui + +# Run the GUI +cargo run --features gui --bin geolog-gui + +# With workspace persistence +cargo run --features gui --bin geolog-gui -- -d ./myproject + +# Load a file on startup +cargo run --features gui --bin geolog-gui -- examples/preorder.geolog +``` + +#### GUI Architecture + +``` +src/gui/ +├── mod.rs # Module exports +├── app.rs # Main GeologApp (egui::App implementation) +├── state.rs # GuiState wrapping ReplState +├── panels/ +│ ├── mod.rs +│ ├── browser.rs # Theory/instance tree browser +│ ├── editor.rs # Code editor with line numbers +│ ├── inspector.rs # Detail view for selected items +│ └── console.rs # Output/error messages +└── visualizations/ + ├── mod.rs + ├── chase.rs # Chase step-through visualization + └── graph.rs # Relation graph visualization +``` + +#### GUI Features + +**Browser Panel (Left)** +- Tree view of all theories and instances +- Filter/search functionality +- Click to select, right-click for context menu +- Shows counts (sorts, functions, relations, axioms, elements) + +**Editor Panel (Center Top)** +- Multi-line code editor +- Line numbers +- Run button (or Ctrl+Enter) to execute code +- Clear button + +**Inspector Panel (Center Bottom)** +- Theory details: parameters, sorts, functions, relations, instance fields, axioms +- Instance details: elements by sort, function values, relation tuples, nested instances +- Collapsible sections +- "View Graph" button for instances + +**Console Panel (Bottom)** +- Scrollable message log +- Color-coded messages: info (gray), success (green), error (red), warning (orange) +- Auto-scroll option +- Clear button + +**Chase Visualization** +- Step/Run All/Stop controls +- Events log showing axiom firings with bindings +- Breakpoint management +- Current structure info (elements, relation tuples) +- Mode indicator (Idle/Stepping/Running/Completed) + +**Graph Visualization** +- Nodes represent elements (colored by sort) +- Edges represent relation tuples +- Interactive: drag nodes, zoom (scroll), pan +- Relation filter dropdown +- Reset Layout / Fit buttons +- Hover to see sort name + +#### UI Layout + +``` +┌─────────────────────────────────────────────────────────────┐ +│ File Edit View Chase Help │ +├────────────┬────────────────────────────────────────────────┤ +│ ▼ Theories │ ┌─────────────────────────────────────────┐ │ +│ Preorder │ │ Editor │ │ +│ Graph │ │ theory Foo { │ │ +│ ▼ Instances│ │ X : Sort; │ │ +│ Chain3 │ │ } [Run] [Clear] │ │ +│ │ └─────────────────────────────────────────┘ │ +│ │ ┌─────────────────────────────────────────┐ │ +│ │ │ Inspector: Chain3 : Preorder │ │ +│ │ │ ▼ Elements (3) │ │ +│ │ │ X: bot, mid, top │ │ +│ │ │ ▼ Relations │ │ +│ │ │ leq: 6 tuples [View Graph] │ │ +│ │ └─────────────────────────────────────────┘ │ +├────────────┴────────────────────────────────────────────────┤ +│ Console [Clear]│ +│ > Defined theory Preorder (1 sorts, 1 relations, 2 axioms) │ +│ + Defined instance Chain3 : Preorder (3 elements) │ +└─────────────────────────────────────────────────────────────┘ +``` + +## CLI Commands + +### REPL Commands + +``` +:help [topic] Show help (topics: syntax, examples) +:quit Exit the REPL +:list [target] List theories/instances +:inspect Show details of a theory or instance +:source Load and execute a geolog file +:clear Clear the screen +:reset Reset all state + +# Version Control +:commit [msg] Commit current changes +:history Show commit history + +# Instance Mutation +:add Add element to instance +:assert args Assert relation tuple +:retract Retract element + +# Query +:query List all elements of a sort +:explain Show query execution plan +:compile Show RelAlgIR compilation +:chase [max_iter] Run chase on instance axioms +:debug-chase [max] Run chase with interactive debugger + +# Solver +:solve [budget] Find model of theory from scratch +:extend Find extension of instance to theory +``` + +### CLI Usage + +```bash +# Start REPL (in-memory) +cargo run + +# Start REPL with workspace persistence +cargo run -- -d ./myproject + +# Load file on startup +cargo run -- examples/preorder.geolog + +# Show help +cargo run -- --help +``` + +## Dependencies + +### Core Dependencies +- `chumsky` - Parser combinators +- `ariadne` - Error reporting +- `uuid` - Unique identifiers +- `rkyv` - Zero-copy serialization +- `rustyline` - Readline for REPL +- `indexmap` - Ordered hash maps + +### GUI Dependencies (feature = "gui") +- `eframe` - egui framework with native window +- `egui_extras` - Additional egui widgets +- `rfd` - Native file dialogs + +## Example + +```geolog +// Define a preorder theory +theory Preorder { + X : Sort; + leq : [a: X, b: X] -> Prop; + + // Reflexivity + forall x : X. |- [a: x, b: x] leq; + + // Transitivity + forall x : X, y : X, z : X. + [a: x, b: y] leq, [a: y, b: z] leq |- [a: x, b: z] leq; +} + +// Define an instance +instance Chain3 : Preorder = { + bot : X; + mid : X; + top : X; + [a: bot, b: mid] leq; + [a: mid, b: top] leq; +} +``` + +Then run `:chase Chain3` to compute the transitive closure. + +## Development + +```bash +# Check without GUI +cargo check + +# Check with GUI +cargo check --features gui + +# Run tests +cargo test + +# Build release +cargo build --release --features gui +``` diff --git a/src/bin/geolog-gui.rs b/src/bin/geolog-gui.rs new file mode 100644 index 0000000..bfedff2 --- /dev/null +++ b/src/bin/geolog-gui.rs @@ -0,0 +1,134 @@ +//! Geolog GUI - Graphical interface for geometric logic +//! +//! Usage: geolog-gui [workspace] +//! +//! Provides a graphical interface for: +//! - Browsing and editing theories and instances +//! - Visualizing chase execution +//! - Displaying relation graphs + +use std::path::PathBuf; + +use eframe::egui; + +use geolog::gui::GeologApp; + +const VERSION: &str = env!("CARGO_PKG_VERSION"); + +fn main() -> eframe::Result<()> { + // Parse command line arguments + let args: Vec = std::env::args().skip(1).collect(); + let (workspace_path, source_files) = parse_args(&args); + + // Set up native window options + let options = eframe::NativeOptions { + viewport: egui::ViewportBuilder::default() + .with_inner_size([1200.0, 800.0]) + .with_min_inner_size([800.0, 600.0]) + .with_title(format!("Geolog v{}", VERSION)), + ..Default::default() + }; + + // Run the application + eframe::run_native( + "Geolog", + options, + Box::new(move |cc| { + // Set up custom fonts and styles + setup_fonts(&cc.egui_ctx); + + // Create the app + let mut app = if let Some(path) = workspace_path { + GeologApp::with_path(cc, path) + } else { + GeologApp::new(cc) + }; + + // Load source files if provided + for path in source_files { + app.state.load_file(&path); + app.state.execute_editor(); + } + + Ok(Box::new(app)) + }), + ) +} + +/// Parse command line arguments +fn parse_args(args: &[String]) -> (Option, Vec) { + let mut workspace_path = None; + let mut source_files = Vec::new(); + let mut i = 0; + + while i < args.len() { + let arg = &args[i]; + match arg.as_str() { + "-d" | "--dir" => { + if i + 1 < args.len() { + workspace_path = Some(PathBuf::from(&args[i + 1])); + i += 2; + } else { + eprintln!("Error: -d requires a path argument"); + std::process::exit(1); + } + } + "-h" | "--help" => { + println!("geolog-gui v{} - Geometric Logic GUI", VERSION); + println!(); + println!("Usage: geolog-gui [OPTIONS] [source_files...]"); + println!(); + println!("Options:"); + println!(" -d, --dir Use as workspace directory for persistence"); + println!(" -h, --help Show this help message"); + println!(" -v, --version Show version"); + println!(); + println!("Examples:"); + println!(" geolog-gui Start GUI (in-memory, no persistence)"); + println!(" geolog-gui -d ./myproject Start GUI with workspace persistence"); + println!(" geolog-gui file.geolog Load file.geolog on startup"); + std::process::exit(0); + } + "-v" | "--version" => { + println!("geolog-gui v{}", VERSION); + std::process::exit(0); + } + _ if arg.starts_with('-') => { + eprintln!("Error: Unknown option '{}'", arg); + eprintln!("Try 'geolog-gui --help' for usage information"); + std::process::exit(1); + } + _ => { + // Positional argument - treat as source file + source_files.push(PathBuf::from(arg)); + i += 1; + } + } + } + + (workspace_path, source_files) +} + +/// Set up custom fonts and styles +fn setup_fonts(ctx: &egui::Context) { + // Use a slightly larger default font + let mut style = (*ctx.style()).clone(); + style.text_styles.insert( + egui::TextStyle::Body, + egui::FontId::proportional(14.0), + ); + style.text_styles.insert( + egui::TextStyle::Heading, + egui::FontId::proportional(18.0), + ); + style.text_styles.insert( + egui::TextStyle::Monospace, + egui::FontId::monospace(13.0), + ); + + // Set up dark theme with custom colors + style.visuals = egui::Visuals::dark(); + style.visuals.override_text_color = Some(egui::Color32::from_gray(220)); + + ctx.set_style(style); +} diff --git a/src/gui/app.rs b/src/gui/app.rs new file mode 100644 index 0000000..ee62911 --- /dev/null +++ b/src/gui/app.rs @@ -0,0 +1,347 @@ +//! Main Geolog GUI application +//! +//! Implements the egui::App trait for the main application window. + +use eframe::egui; +use std::path::PathBuf; + +use super::panels::{BrowserPanel, ConsolePanel, EditorPanel, InspectorPanel}; +use super::state::{CentralView, GuiState}; +use super::visualizations::{ChaseVisualization, GraphView}; + +/// Main Geolog GUI application +pub struct GeologApp { + /// Application state + pub state: GuiState, + + /// Panel instances + browser: BrowserPanel, + editor: EditorPanel, + inspector: InspectorPanel, + console: ConsolePanel, + chase_viz: ChaseVisualization, + graph_view: GraphView, +} + +impl GeologApp { + /// Create a new Geolog application + pub fn new(_cc: &eframe::CreationContext<'_>) -> Self { + Self { + state: GuiState::new(), + browser: BrowserPanel::new(), + editor: EditorPanel::new(), + inspector: InspectorPanel::new(), + console: ConsolePanel::new(), + chase_viz: ChaseVisualization::new(), + graph_view: GraphView::new(), + } + } + + /// Create a new application with a workspace path + pub fn with_path(_cc: &eframe::CreationContext<'_>, path: PathBuf) -> Self { + let mut app = Self::new(_cc); + app.state = GuiState::with_path(path); + app + } + + /// Render the menu bar + fn menu_bar(&mut self, ui: &mut egui::Ui) { + egui::menu::bar(ui, |ui| { + ui.menu_button("File", |ui| { + if ui.button("Open...").clicked() { + self.handle_open_file(); + ui.close_menu(); + } + if ui.button("Save").clicked() { + self.handle_save_file(); + ui.close_menu(); + } + ui.separator(); + if ui.button("Reset State").clicked() { + self.state.repl.reset(); + self.state.log_info("State reset"); + ui.close_menu(); + } + ui.separator(); + if ui.button("Quit").clicked() { + std::process::exit(0); + } + }); + + ui.menu_button("Edit", |ui| { + if ui.button("Clear Editor").clicked() { + self.state.editor_content.clear(); + ui.close_menu(); + } + if ui.button("Clear Console").clicked() { + self.state.clear_console(); + ui.close_menu(); + } + }); + + ui.menu_button("View", |ui| { + if ui + .selectable_label( + self.state.central_view == CentralView::EditorAndInspector, + "Editor & Inspector", + ) + .clicked() + { + self.state.central_view = CentralView::EditorAndInspector; + ui.close_menu(); + } + if ui + .selectable_label( + self.state.central_view == CentralView::ChaseVisualization, + "Chase Visualization", + ) + .clicked() + { + self.state.central_view = CentralView::ChaseVisualization; + ui.close_menu(); + } + if ui + .selectable_label( + self.state.central_view == CentralView::GraphVisualization, + "Graph Visualization", + ) + .clicked() + { + self.state.central_view = CentralView::GraphVisualization; + ui.close_menu(); + } + }); + + ui.menu_button("Chase", |ui| { + if let Some(crate::gui::state::SelectedItem::Instance(name)) = + &self.state.selected_item + { + let name = name.clone(); + if ui.button(format!("Run Chase on {}", name)).clicked() { + self.handle_run_chase(&name); + ui.close_menu(); + } + if ui.button(format!("Debug Chase on {}", name)).clicked() { + self.state.start_chase(&name); + ui.close_menu(); + } + } else { + ui.label("(Select an instance first)"); + } + }); + + ui.menu_button("Help", |ui| { + if ui.button("About").clicked() { + self.state.log_info(format!( + "Geolog GUI v{}", + env!("CARGO_PKG_VERSION") + )); + ui.close_menu(); + } + if ui.button("Syntax Help").clicked() { + self.show_syntax_help(); + ui.close_menu(); + } + }); + }); + } + + /// Handle opening a file + fn handle_open_file(&mut self) { + if let Some(path) = rfd::FileDialog::new() + .add_filter("Geolog", &["geolog"]) + .add_filter("All Files", &["*"]) + .pick_file() + { + self.state.load_file(&path); + } + } + + /// Handle saving a file + fn handle_save_file(&mut self) { + if let Some(path) = &self.state.current_file { + match std::fs::write(path, &self.state.editor_content) { + Ok(()) => { + self.state.log_success(format!("Saved: {}", path.display())); + } + Err(e) => { + self.state.log_error(format!("Failed to save: {}", e)); + } + } + } else { + // Save As + if let Some(path) = rfd::FileDialog::new() + .add_filter("Geolog", &["geolog"]) + .save_file() + { + match std::fs::write(&path, &self.state.editor_content) { + Ok(()) => { + self.state.current_file = Some(path.clone()); + self.state.log_success(format!("Saved: {}", path.display())); + } + Err(e) => { + self.state.log_error(format!("Failed to save: {}", e)); + } + } + } + } + } + + /// Run chase on an instance + fn handle_run_chase(&mut self, instance_name: &str) { + use crate::core::RelationStorage; + use crate::query::chase::chase_fixpoint; + + // Get theory name first (immutable borrow) + let theory_name = match self.state.repl.instances.get(instance_name) { + Some(e) => e.theory_name.clone(), + None => { + self.state + .log_error(format!("Instance '{}' not found", instance_name)); + return; + } + }; + + let theory = match self.state.repl.theories.get(&theory_name) { + Some(t) => t.clone(), + None => { + self.state + .log_error(format!("Theory '{}' not found", theory_name)); + return; + } + }; + + let sig = &theory.theory.signature; + let axioms = &theory.theory.axioms; + + if axioms.is_empty() { + self.state + .log_warning(format!("Theory '{}' has no axioms to chase", theory_name)); + return; + } + + self.state.log_info(format!( + "Running chase on instance '{}' ({} axioms)...", + instance_name, + axioms.len() + )); + + // Now get mutable access to entry + let entry = self.state.repl.instances.get_mut(instance_name).unwrap(); + + let start = std::time::Instant::now(); + let result = chase_fixpoint( + axioms, + &mut entry.structure, + &mut self.state.repl.store.universe, + sig, + 100, + ); + + match result { + Ok(iterations) => { + let elapsed = start.elapsed(); + // Get structure info before releasing borrow + let total_tuples: usize = + entry.structure.relations.iter().map(|r| r.len()).sum(); + let num_elements = entry.structure.len(); + + self.state.log_success(format!( + "Chase completed in {} iterations ({:.2}ms)", + iterations, + elapsed.as_secs_f64() * 1000.0 + )); + + // Show structure summary + self.state.log_info(format!( + "Structure: {} elements, {} relation tuples", + num_elements, + total_tuples + )); + } + Err(e) => { + self.state.log_error(format!("Chase error: {}", e)); + } + } + } + + /// Show syntax help in the console + fn show_syntax_help(&mut self) { + self.state.log_info("=== Geolog Syntax ==="); + self.state.log_info(""); + self.state.log_info("theory Name {"); + self.state.log_info(" Sort1 : Sort;"); + self.state.log_info(" func : Sort1 -> Sort2;"); + self.state.log_info(" rel : Sort1 -> Prop;"); + self.state.log_info("}"); + self.state.log_info(""); + self.state.log_info("instance Name : Theory = {"); + self.state.log_info(" elem : Sort1;"); + self.state.log_info(" elem func = other_elem;"); + self.state.log_info(" elem rel;"); + self.state.log_info("}"); + } + + /// Render the central panel based on current view mode + fn central_panel(&mut self, ui: &mut egui::Ui) { + match self.state.central_view { + CentralView::EditorAndInspector => { + // Split vertically: editor on top, inspector on bottom + let available_height = ui.available_height(); + let editor_height = available_height * 0.5; + + // Editor section + ui.allocate_ui_with_layout( + egui::vec2(ui.available_width(), editor_height), + egui::Layout::top_down(egui::Align::LEFT), + |ui| { + self.editor.show(ui, &mut self.state); + }, + ); + + ui.separator(); + + // Inspector section + self.inspector.show(ui, &mut self.state); + } + CentralView::ChaseVisualization => { + self.chase_viz.show(ui, &mut self.state); + } + CentralView::GraphVisualization => { + self.graph_view.show(ui, &mut self.state); + } + } + } +} + +impl eframe::App for GeologApp { + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + // Top menu bar + egui::TopBottomPanel::top("menu_bar").show(ctx, |ui| { + self.menu_bar(ui); + }); + + // Left panel: Browser + egui::SidePanel::left("browser_panel") + .default_width(200.0) + .min_width(150.0) + .resizable(true) + .show(ctx, |ui| { + self.browser.show(ui, &mut self.state); + }); + + // Bottom panel: Console + egui::TopBottomPanel::bottom("console_panel") + .default_height(150.0) + .min_height(100.0) + .resizable(true) + .show(ctx, |ui| { + self.console.show(ui, &mut self.state); + }); + + // Central panel: Editor + Inspector or Visualizations + egui::CentralPanel::default().show(ctx, |ui| { + self.central_panel(ui); + }); + } +} diff --git a/src/gui/mod.rs b/src/gui/mod.rs new file mode 100644 index 0000000..00939f9 --- /dev/null +++ b/src/gui/mod.rs @@ -0,0 +1,15 @@ +//! GUI module for Geolog using egui +//! +//! Provides a graphical interface for: +//! - Browsing theories and instances +//! - Editing geolog code +//! - Visualizing chase execution +//! - Displaying relation graphs + +pub mod app; +pub mod panels; +pub mod state; +pub mod visualizations; + +pub use app::GeologApp; +pub use state::GuiState; diff --git a/src/gui/panels/browser.rs b/src/gui/panels/browser.rs new file mode 100644 index 0000000..40f4d04 --- /dev/null +++ b/src/gui/panels/browser.rs @@ -0,0 +1,178 @@ +//! Browser panel for theory/instance navigation +//! +//! Displays a tree view of all theories and instances. + +use eframe::egui; + +use crate::gui::state::{GuiState, SelectedItem}; + +/// Browser panel for navigating theories and instances +pub struct BrowserPanel { + /// Search/filter text + filter: String, +} + +impl BrowserPanel { + pub fn new() -> Self { + Self { + filter: String::new(), + } + } + + pub fn show(&mut self, ui: &mut egui::Ui, state: &mut GuiState) { + ui.heading("Browser"); + ui.separator(); + + // Filter input + ui.horizontal(|ui| { + ui.label("Filter:"); + ui.text_edit_singleline(&mut self.filter); + }); + ui.add_space(4.0); + + // Scrollable tree view + egui::ScrollArea::vertical() + .auto_shrink([false, false]) + .show(ui, |ui| { + self.show_theories_section(ui, state); + ui.add_space(8.0); + self.show_instances_section(ui, state); + }); + } + + fn show_theories_section(&mut self, ui: &mut egui::Ui, state: &mut GuiState) { + let theories = state.repl.list_theories(); + let filtered: Vec<_> = theories + .iter() + .filter(|t| { + self.filter.is_empty() + || t.name.to_lowercase().contains(&self.filter.to_lowercase()) + }) + .collect(); + + let header = if self.filter.is_empty() { + format!("Theories ({})", theories.len()) + } else { + format!("Theories ({}/{})", filtered.len(), theories.len()) + }; + + egui::CollapsingHeader::new(header) + .default_open(state.theories_expanded) + .show(ui, |ui| { + state.theories_expanded = true; + if filtered.is_empty() { + ui.label("(none)"); + } else { + for theory in filtered { + let is_selected = matches!( + &state.selected_item, + Some(SelectedItem::Theory(name)) if name == &theory.name + ); + + let label = format!( + "{} ({} sorts{}{}{})", + theory.name, + theory.num_sorts, + if theory.num_functions > 0 { + format!(", {} funcs", theory.num_functions) + } else { + String::new() + }, + if theory.num_relations > 0 { + format!(", {} rels", theory.num_relations) + } else { + String::new() + }, + if theory.num_axioms > 0 { + format!(", {} axioms", theory.num_axioms) + } else { + String::new() + }, + ); + + if ui.selectable_label(is_selected, label).clicked() { + state.selected_item = Some(SelectedItem::Theory(theory.name.clone())); + } + } + } + }); + } + + fn show_instances_section(&mut self, ui: &mut egui::Ui, state: &mut GuiState) { + let instances = state.repl.list_instances(); + let filtered: Vec<_> = instances + .iter() + .filter(|i| { + self.filter.is_empty() + || i.name.to_lowercase().contains(&self.filter.to_lowercase()) + || i.theory_name + .to_lowercase() + .contains(&self.filter.to_lowercase()) + }) + .collect(); + + let header = if self.filter.is_empty() { + format!("Instances ({})", instances.len()) + } else { + format!("Instances ({}/{})", filtered.len(), instances.len()) + }; + + egui::CollapsingHeader::new(header) + .default_open(state.instances_expanded) + .show(ui, |ui| { + state.instances_expanded = true; + if filtered.is_empty() { + ui.label("(none)"); + } else { + for instance in filtered { + let is_selected = matches!( + &state.selected_item, + Some(SelectedItem::Instance(name)) if name == &instance.name + ); + + let label = format!( + "{} : {} ({} elems)", + instance.name, instance.theory_name, instance.num_elements + ); + + let response = ui.selectable_label(is_selected, label); + + // Left click to select + if response.clicked() { + state.selected_item = + Some(SelectedItem::Instance(instance.name.clone())); + } + + // Right-click context menu + response.context_menu(|ui| { + if ui.button("Inspect").clicked() { + state.selected_item = + Some(SelectedItem::Instance(instance.name.clone())); + ui.close_menu(); + } + if ui.button("Run Chase").clicked() { + // This will be handled by the app + state.selected_item = + Some(SelectedItem::Instance(instance.name.clone())); + state.log_info(format!( + "Use Chase menu to run chase on '{}'", + instance.name + )); + ui.close_menu(); + } + if ui.button("View Graph").clicked() { + state.show_graph(&instance.name, None); + ui.close_menu(); + } + }); + } + } + }); + } +} + +impl Default for BrowserPanel { + fn default() -> Self { + Self::new() + } +} diff --git a/src/gui/panels/console.rs b/src/gui/panels/console.rs new file mode 100644 index 0000000..5a410bf --- /dev/null +++ b/src/gui/panels/console.rs @@ -0,0 +1,84 @@ +//! Console panel for displaying output and error messages +//! +//! Shows a scrollable log of messages with color coding. + +use eframe::egui; + +use crate::gui::state::{GuiState, MessageKind}; + +/// Console panel for output messages +pub struct ConsolePanel { + /// Whether to auto-scroll to bottom + auto_scroll: bool, +} + +impl ConsolePanel { + pub fn new() -> Self { + Self { auto_scroll: true } + } + + pub fn show(&mut self, ui: &mut egui::Ui, state: &mut GuiState) { + // Header with title and buttons + ui.horizontal(|ui| { + ui.heading("Console"); + + ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { + if ui.button("Clear").clicked() { + state.clear_console(); + } + + ui.checkbox(&mut self.auto_scroll, "Auto-scroll"); + + ui.label(format!("{} messages", state.console_messages.len())); + }); + }); + + ui.separator(); + + // Scrollable message area + let scroll_area = egui::ScrollArea::vertical() + .auto_shrink([false, false]) + .stick_to_bottom(self.auto_scroll); + + scroll_area.show(ui, |ui| { + if state.console_messages.is_empty() { + ui.label("(no messages)"); + } else { + for message in &state.console_messages { + let color = match message.kind { + MessageKind::Info => egui::Color32::LIGHT_GRAY, + MessageKind::Success => egui::Color32::from_rgb(100, 200, 100), + MessageKind::Error => egui::Color32::from_rgb(255, 100, 100), + MessageKind::Warning => egui::Color32::from_rgb(255, 200, 100), + }; + + let prefix = match message.kind { + MessageKind::Info => ">", + MessageKind::Success => "+", + MessageKind::Error => "!", + MessageKind::Warning => "?", + }; + + ui.horizontal(|ui| { + ui.label( + egui::RichText::new(prefix) + .color(color) + .monospace(), + ); + ui.label( + egui::RichText::new(&message.text) + .color(color) + .monospace(), + ); + }); + } + } + }); + } +} + +impl Default for ConsolePanel { + fn default() -> Self { + Self::new() + } +} diff --git a/src/gui/panels/editor.rs b/src/gui/panels/editor.rs new file mode 100644 index 0000000..97ebaa5 --- /dev/null +++ b/src/gui/panels/editor.rs @@ -0,0 +1,216 @@ +//! Code editor panel +//! +//! Provides a multi-line text editor for writing Geolog code. + +use eframe::egui; + +use crate::gui::state::GuiState; + +/// Code editor panel +pub struct EditorPanel { + /// Whether to show line numbers + show_line_numbers: bool, +} + +impl EditorPanel { + pub fn new() -> Self { + Self { + show_line_numbers: true, + } + } + + pub fn show(&mut self, ui: &mut egui::Ui, state: &mut GuiState) { + // Header with title and buttons + ui.horizontal(|ui| { + ui.heading("Editor"); + + ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { + if ui.button("Clear").clicked() { + state.editor_content.clear(); + } + + if ui.button("Run").clicked() { + state.execute_editor(); + } + + // Show current file if any + if let Some(path) = &state.current_file { + ui.label(format!( + "{}", + path.file_name() + .map(|s| s.to_string_lossy()) + .unwrap_or_default() + )); + } + }); + }); + + ui.separator(); + + // Editor area with syntax highlighting + egui::ScrollArea::vertical() + .auto_shrink([false, false]) + .show(ui, |ui| { + self.show_editor_content(ui, state); + }); + } + + fn show_editor_content(&mut self, ui: &mut egui::Ui, state: &mut GuiState) { + // Use a monospace font for code + let font_id = egui::FontId::monospace(14.0); + + // Calculate line numbers if needed + let line_count = state.editor_content.lines().count().max(1); + let line_number_width = if self.show_line_numbers { + let digits = (line_count as f32).log10().floor() as usize + 1; + digits.max(2) as f32 * 10.0 + 8.0 + } else { + 0.0 + }; + + ui.horizontal(|ui| { + // Line numbers column + if self.show_line_numbers { + ui.allocate_ui_with_layout( + egui::vec2(line_number_width, ui.available_height()), + egui::Layout::top_down(egui::Align::RIGHT), + |ui| { + ui.style_mut().visuals.override_text_color = + Some(egui::Color32::GRAY); + + for i in 1..=line_count { + ui.label( + egui::RichText::new(format!("{}", i)) + .font(font_id.clone()) + .color(egui::Color32::GRAY), + ); + } + }, + ); + + ui.separator(); + } + + // Main editor area + let text_edit = egui::TextEdit::multiline(&mut state.editor_content) + .font(font_id) + .code_editor() + .desired_width(f32::INFINITY) + .desired_rows(20) + .lock_focus(true); + + let response = ui.add(text_edit); + + // Handle keyboard shortcuts + if response.has_focus() { + let modifiers = ui.input(|i| i.modifiers); + if modifiers.ctrl || modifiers.command { + if ui.input(|i| i.key_pressed(egui::Key::Enter)) { + state.execute_editor(); + } + } + } + }); + } +} + +impl Default for EditorPanel { + fn default() -> Self { + Self::new() + } +} + +/// Simple syntax highlighting for Geolog code +/// Returns a layouter function for egui's code_editor +#[allow(dead_code)] +fn geolog_highlighter( + _ui: &egui::Ui, + text: &str, + _wrap_width: f32, +) -> egui::text::LayoutJob { + let mut job = egui::text::LayoutJob::default(); + + let keywords = [ + "theory", "instance", "query", "forall", "exists", "Sort", "Prop", "true", "false", + ]; + + let font_id = egui::FontId::monospace(14.0); + let default_color = egui::Color32::WHITE; + let keyword_color = egui::Color32::from_rgb(86, 156, 214); // Blue + let comment_color = egui::Color32::from_rgb(106, 153, 85); // Green + let string_color = egui::Color32::from_rgb(206, 145, 120); // Orange + + let mut chars = text.char_indices().peekable(); + + while let Some((i, c)) = chars.next() { + // Check for comments + if c == '/' && chars.peek().map(|(_, c)| *c) == Some('/') { + // Line comment - consume until end of line + let start = i; + while let Some((_, c)) = chars.next() { + if c == '\n' { + break; + } + } + let end = chars.peek().map(|(i, _)| *i).unwrap_or(text.len()); + job.append( + &text[start..end], + 0.0, + egui::TextFormat::simple(font_id.clone(), comment_color), + ); + continue; + } + + // Check for strings + if c == '"' { + let start = i; + while let Some((_, c)) = chars.next() { + if c == '"' { + break; + } + if c == '\\' { + chars.next(); // Skip escaped character + } + } + let end = chars.peek().map(|(i, _)| *i).unwrap_or(text.len()); + job.append( + &text[start..end], + 0.0, + egui::TextFormat::simple(font_id.clone(), string_color), + ); + continue; + } + + // Check for identifiers/keywords + if c.is_alphabetic() || c == '_' { + let start = i; + while chars.peek().map(|(_, c)| c.is_alphanumeric() || *c == '_') == Some(true) { + chars.next(); + } + let end = chars.peek().map(|(i, _)| *i).unwrap_or(text.len()); + let word = &text[start..end]; + + let color = if keywords.contains(&word) { + keyword_color + } else { + default_color + }; + + job.append( + word, + 0.0, + egui::TextFormat::simple(font_id.clone(), color), + ); + continue; + } + + // Default: single character + job.append( + &text[i..i + c.len_utf8()], + 0.0, + egui::TextFormat::simple(font_id.clone(), default_color), + ); + } + + job +} diff --git a/src/gui/panels/inspector.rs b/src/gui/panels/inspector.rs new file mode 100644 index 0000000..300cb3a --- /dev/null +++ b/src/gui/panels/inspector.rs @@ -0,0 +1,318 @@ +//! Inspector panel for viewing theory/instance details +//! +//! Shows detailed information about the currently selected item. + +use eframe::egui; + +use crate::gui::state::{GuiState, SelectedItem}; +use crate::repl::{InstanceDetail, TheoryDetail}; + +/// Inspector panel for viewing details +pub struct InspectorPanel {} + +impl InspectorPanel { + pub fn new() -> Self { + Self {} + } + + pub fn show(&mut self, ui: &mut egui::Ui, state: &mut GuiState) { + ui.heading("Inspector"); + ui.separator(); + + match &state.selected_item { + Some(SelectedItem::Theory(name)) => { + if let Some(detail) = state.selected_theory_detail() { + self.show_theory_detail(ui, state, &detail); + } else { + ui.label(format!("Theory '{}' not found", name)); + } + } + Some(SelectedItem::Instance(name)) => { + if let Some(detail) = state.selected_instance_detail() { + self.show_instance_detail(ui, state, &detail); + } else { + ui.label(format!("Instance '{}' not found", name)); + } + } + None => { + ui.label("Select a theory or instance to inspect"); + } + } + } + + fn show_theory_detail(&self, ui: &mut egui::Ui, state: &mut GuiState, detail: &TheoryDetail) { + // Theory header + ui.horizontal(|ui| { + ui.strong("Theory:"); + ui.label(&detail.name); + }); + + // Parameters + if !detail.params.is_empty() { + ui.horizontal(|ui| { + ui.label("Parameters:"); + for (name, theory) in &detail.params { + ui.label(format!("{}: {}", name, theory)); + } + }); + } + + ui.add_space(8.0); + + egui::ScrollArea::vertical() + .auto_shrink([false, false]) + .show(ui, |ui| { + // Sorts section + egui::CollapsingHeader::new(format!("Sorts ({})", detail.sorts.len())) + .default_open(state.inspector_sorts_expanded) + .show(ui, |ui| { + state.inspector_sorts_expanded = true; + if detail.sorts.is_empty() { + ui.label("(none)"); + } else { + for sort in &detail.sorts { + ui.label(format!(" {} : Sort", sort)); + } + } + }); + + // Functions section + egui::CollapsingHeader::new(format!("Functions ({})", detail.functions.len())) + .default_open(state.inspector_functions_expanded) + .show(ui, |ui| { + state.inspector_functions_expanded = true; + if detail.functions.is_empty() { + ui.label("(none)"); + } else { + for (name, domain, codomain) in &detail.functions { + ui.label(format!(" {} : {} -> {}", name, domain, codomain)); + } + } + }); + + // Relations section + egui::CollapsingHeader::new(format!("Relations ({})", detail.relations.len())) + .default_open(state.inspector_relations_expanded) + .show(ui, |ui| { + state.inspector_relations_expanded = true; + if detail.relations.is_empty() { + ui.label("(none)"); + } else { + for (name, domain) in &detail.relations { + ui.label(format!(" {} : {} -> Prop", name, domain)); + } + } + }); + + // Instance fields section + if !detail.instance_fields.is_empty() { + egui::CollapsingHeader::new(format!( + "Instance Fields ({})", + detail.instance_fields.len() + )) + .default_open(true) + .show(ui, |ui| { + for (name, theory_type) in &detail.instance_fields { + ui.label(format!(" {} : {} instance", name, theory_type)); + } + }); + } + + // Axioms section + egui::CollapsingHeader::new(format!("Axioms ({})", detail.axioms.len())) + .default_open(state.inspector_axioms_expanded) + .show(ui, |ui| { + state.inspector_axioms_expanded = true; + if detail.axioms.is_empty() { + ui.label("(none)"); + } else { + for (i, axiom) in detail.axioms.iter().enumerate() { + let context_str: Vec = axiom + .context + .iter() + .map(|(name, sort)| format!("{}: {}", name, sort)) + .collect(); + + let axiom_str = if axiom.premise == "true" { + format!( + "[{}] forall {}. |- {}", + i, + context_str.join(", "), + axiom.conclusion + ) + } else { + format!( + "[{}] forall {}. {} |- {}", + i, + context_str.join(", "), + axiom.premise, + axiom.conclusion + ) + }; + ui.label(axiom_str); + } + } + }); + }); + } + + fn show_instance_detail( + &self, + ui: &mut egui::Ui, + state: &mut GuiState, + detail: &InstanceDetail, + ) { + // Instance header + ui.horizontal(|ui| { + ui.strong("Instance:"); + ui.label(&detail.name); + ui.label(":"); + ui.label(&detail.theory_name); + }); + + ui.add_space(8.0); + + // Action buttons + ui.horizontal(|ui| { + let detail_name = detail.name.clone(); + if ui.button("View Graph").clicked() { + state.show_graph(&detail_name, None); + } + if ui.button("Run Chase").clicked() { + state.log_info(format!("Use Chase menu to run chase on '{}'", detail_name)); + } + }); + + ui.add_space(8.0); + + egui::ScrollArea::vertical() + .auto_shrink([false, false]) + .show(ui, |ui| { + // Elements section + let total_elements: usize = detail.elements.iter().map(|(_, v)| v.len()).sum(); + egui::CollapsingHeader::new(format!("Elements ({})", total_elements)) + .default_open(state.inspector_elements_expanded) + .show(ui, |ui| { + state.inspector_elements_expanded = true; + if detail.elements.is_empty() { + ui.label("(none)"); + } else { + for (sort_name, elements) in &detail.elements { + ui.horizontal(|ui| { + ui.strong(format!("{} ({}):", sort_name, elements.len())); + }); + ui.indent("elements", |ui| { + // Show elements in a grid if there are many + if elements.len() <= 10 { + for elem in elements { + ui.label(format!(" {}", elem)); + } + } else { + // Show first few and a count + for elem in elements.iter().take(5) { + ui.label(format!(" {}", elem)); + } + ui.label(format!(" ... and {} more", elements.len() - 5)); + } + }); + } + } + }); + + // Functions section + let total_func_values: usize = detail.functions.iter().map(|(_, v)| v.len()).sum(); + if total_func_values > 0 { + egui::CollapsingHeader::new(format!("Function Values ({})", total_func_values)) + .default_open(state.inspector_functions_expanded) + .show(ui, |ui| { + for (func_name, values) in &detail.functions { + ui.horizontal(|ui| { + ui.strong(format!("{} ({}):", func_name, values.len())); + }); + ui.indent("func_values", |ui| { + if values.len() <= 10 { + for value in values { + ui.label(format!(" {}", value)); + } + } else { + for value in values.iter().take(5) { + ui.label(format!(" {}", value)); + } + ui.label(format!(" ... and {} more", values.len() - 5)); + } + }); + } + }); + } + + // Relations section + let total_tuples: usize = detail.relations.iter().map(|(_, _, t)| t.len()).sum(); + if total_tuples > 0 { + egui::CollapsingHeader::new(format!("Relations ({} tuples)", total_tuples)) + .default_open(state.inspector_relations_expanded) + .show(ui, |ui| { + for (rel_name, field_names, tuples) in &detail.relations { + ui.horizontal(|ui| { + ui.strong(format!("{} ({} tuples):", rel_name, tuples.len())); + + // Add button to view as graph + let detail_name = detail.name.clone(); + let rel_name_clone = rel_name.clone(); + if ui.small_button("View Graph").clicked() { + state.show_graph(&detail_name, Some(&rel_name_clone)); + } + }); + + ui.indent("rel_tuples", |ui| { + let display_tuples = if tuples.len() <= 10 { + tuples.as_slice() + } else { + &tuples[..5] + }; + + for tuple in display_tuples { + let tuple_str = if field_names.is_empty() { + // Unary relation + format!(" {} {}", tuple.join(", "), rel_name) + } else { + // Multi-ary relation with field names + let fields: Vec = field_names + .iter() + .zip(tuple.iter()) + .map(|(f, v)| format!("{}: {}", f, v)) + .collect(); + format!(" [{}] {}", fields.join(", "), rel_name) + }; + ui.label(tuple_str); + } + + if tuples.len() > 10 { + ui.label(format!(" ... and {} more", tuples.len() - 5)); + } + }); + } + }); + } + + // Nested instances section + if !detail.nested.is_empty() { + egui::CollapsingHeader::new(format!( + "Nested Instances ({})", + detail.nested.len() + )) + .default_open(true) + .show(ui, |ui| { + for (field_name, elem_count) in &detail.nested { + ui.label(format!(" {} ({} elements)", field_name, elem_count)); + } + }); + } + }); + } +} + +impl Default for InspectorPanel { + fn default() -> Self { + Self::new() + } +} diff --git a/src/gui/panels/mod.rs b/src/gui/panels/mod.rs new file mode 100644 index 0000000..bf7668b --- /dev/null +++ b/src/gui/panels/mod.rs @@ -0,0 +1,11 @@ +//! GUI panels for the Geolog application + +pub mod browser; +pub mod console; +pub mod editor; +pub mod inspector; + +pub use browser::BrowserPanel; +pub use console::ConsolePanel; +pub use editor::EditorPanel; +pub use inspector::InspectorPanel; diff --git a/src/gui/state.rs b/src/gui/state.rs new file mode 100644 index 0000000..c6048f7 --- /dev/null +++ b/src/gui/state.rs @@ -0,0 +1,321 @@ +//! GUI state management +//! +//! Wraps ReplState with GUI-specific state for the egui application. + +use std::collections::HashSet; +use std::path::PathBuf; + +use crate::repl::{InstanceDetail, ReplState, TheoryDetail}; + +/// What item is currently selected in the browser +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum SelectedItem { + Theory(String), + Instance(String), +} + +/// A message displayed in the console +#[derive(Clone, Debug)] +pub struct ConsoleMessage { + pub text: String, + pub kind: MessageKind, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum MessageKind { + Info, + Success, + Error, + Warning, +} + +/// A recorded chase event for visualization +#[derive(Clone, Debug)] +pub struct ChaseEventRecord { + pub iteration: usize, + pub axiom_index: usize, + pub axiom_name: Option, + pub binding: Vec<(String, String)>, // (var_name, element_name) + pub changed: bool, +} + +/// Chase execution mode +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum ChaseMode { + /// Not running + Idle, + /// Stepping through events + Stepping, + /// Running continuously + Running, + /// Chase completed + Completed, +} + +/// State for chase visualization +#[derive(Clone, Debug)] +pub struct ChaseVisualizationState { + pub mode: ChaseMode, + pub instance_name: String, + pub events: Vec, + pub current_event: usize, + pub current_iteration: usize, + pub breakpoints: HashSet, + pub total_iterations: Option, +} + +impl ChaseVisualizationState { + pub fn new(instance_name: String) -> Self { + Self { + mode: ChaseMode::Idle, + instance_name, + events: Vec::new(), + current_event: 0, + current_iteration: 0, + breakpoints: HashSet::new(), + total_iterations: None, + } + } + + pub fn record_event(&mut self, event: ChaseEventRecord) { + self.events.push(event); + } + + pub fn step(&mut self) { + if self.current_event < self.events.len().saturating_sub(1) { + self.current_event += 1; + } + } + + pub fn has_next(&self) -> bool { + self.current_event < self.events.len().saturating_sub(1) + } +} + +/// Central view mode +#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] +pub enum CentralView { + #[default] + EditorAndInspector, + ChaseVisualization, + GraphVisualization, +} + +/// GUI state wrapping ReplState +pub struct GuiState { + /// The underlying REPL state (theories, instances, store) + pub repl: ReplState, + + /// Currently selected item in the browser + pub selected_item: Option, + + /// Content of the code editor + pub editor_content: String, + + /// Console output messages + pub console_messages: Vec, + + /// Chase visualization state (if running) + pub chase_state: Option, + + /// Graph view state + pub graph_instance: Option, + pub graph_relation: Option, + + /// Currently loaded file path (if any) + pub current_file: Option, + + /// Current view mode for the central panel + pub central_view: CentralView, + + /// Whether the browser tree sections are expanded + pub theories_expanded: bool, + pub instances_expanded: bool, + + /// Inspector collapsible sections + pub inspector_sorts_expanded: bool, + pub inspector_functions_expanded: bool, + pub inspector_relations_expanded: bool, + pub inspector_axioms_expanded: bool, + pub inspector_elements_expanded: bool, +} + +impl Default for GuiState { + fn default() -> Self { + Self::new() + } +} + +impl GuiState { + pub fn new() -> Self { + Self { + repl: ReplState::new(), + selected_item: None, + editor_content: String::new(), + console_messages: Vec::new(), + chase_state: None, + graph_instance: None, + graph_relation: None, + current_file: None, + central_view: CentralView::EditorAndInspector, + theories_expanded: true, + instances_expanded: true, + inspector_sorts_expanded: true, + inspector_functions_expanded: true, + inspector_relations_expanded: true, + inspector_axioms_expanded: true, + inspector_elements_expanded: true, + } + } + + /// Create a new GUI state with a workspace path for persistence + pub fn with_path(path: impl Into) -> Self { + Self { + repl: ReplState::with_path(path), + ..Self::new() + } + } + + /// Add an info message to the console + pub fn log_info(&mut self, text: impl Into) { + self.console_messages.push(ConsoleMessage { + text: text.into(), + kind: MessageKind::Info, + }); + } + + /// Add a success message to the console + pub fn log_success(&mut self, text: impl Into) { + self.console_messages.push(ConsoleMessage { + text: text.into(), + kind: MessageKind::Success, + }); + } + + /// Add an error message to the console + pub fn log_error(&mut self, text: impl Into) { + self.console_messages.push(ConsoleMessage { + text: text.into(), + kind: MessageKind::Error, + }); + } + + /// Add a warning message to the console + pub fn log_warning(&mut self, text: impl Into) { + self.console_messages.push(ConsoleMessage { + text: text.into(), + kind: MessageKind::Warning, + }); + } + + /// Clear all console messages + pub fn clear_console(&mut self) { + self.console_messages.clear(); + } + + /// Execute the editor content as geolog code + pub fn execute_editor(&mut self) { + let source = self.editor_content.clone(); + if source.trim().is_empty() { + return; + } + + match self.repl.execute_geolog(&source) { + Ok(results) => { + for result in results { + match result { + crate::repl::ExecuteResult::Namespace(name) => { + self.log_info(format!("Namespace: {}", name)); + } + crate::repl::ExecuteResult::Theory { + name, + num_sorts, + num_functions, + num_relations, + num_axioms, + } => { + let mut parts = vec![format!("{} sorts", num_sorts)]; + if num_functions > 0 { + parts.push(format!("{} functions", num_functions)); + } + if num_relations > 0 { + parts.push(format!("{} relations", num_relations)); + } + if num_axioms > 0 { + parts.push(format!("{} axioms", num_axioms)); + } + self.log_success(format!( + "Defined theory {} ({})", + name, + parts.join(", ") + )); + } + crate::repl::ExecuteResult::Instance { + name, + theory_name, + num_elements, + } => { + self.log_success(format!( + "Defined instance {} : {} ({} elements)", + name, theory_name, num_elements + )); + } + crate::repl::ExecuteResult::Query(_result) => { + self.log_info("Query executed"); + } + } + } + } + Err(e) => { + self.log_error(format!("Error: {}", e)); + } + } + } + + /// Load a file into the editor + pub fn load_file(&mut self, path: &PathBuf) { + match std::fs::read_to_string(path) { + Ok(content) => { + self.editor_content = content; + self.current_file = Some(path.clone()); + self.log_info(format!("Loaded: {}", path.display())); + } + Err(e) => { + self.log_error(format!("Failed to load {}: {}", path.display(), e)); + } + } + } + + /// Get the currently selected theory detail + pub fn selected_theory_detail(&self) -> Option { + if let Some(SelectedItem::Theory(name)) = &self.selected_item { + if let Some(crate::repl::InspectResult::Theory(detail)) = self.repl.inspect(name) { + return Some(detail); + } + } + None + } + + /// Get the currently selected instance detail + pub fn selected_instance_detail(&self) -> Option { + if let Some(SelectedItem::Instance(name)) = &self.selected_item { + if let Some(crate::repl::InspectResult::Instance(detail)) = self.repl.inspect(name) { + return Some(detail); + } + } + None + } + + /// Start a chase visualization for an instance + pub fn start_chase(&mut self, instance_name: &str) { + self.chase_state = Some(ChaseVisualizationState::new(instance_name.to_string())); + self.central_view = CentralView::ChaseVisualization; + } + + /// Start graph visualization for an instance and relation + pub fn show_graph(&mut self, instance_name: &str, relation_name: Option<&str>) { + self.graph_instance = Some(instance_name.to_string()); + self.graph_relation = relation_name.map(|s| s.to_string()); + self.central_view = CentralView::GraphVisualization; + } +} diff --git a/src/gui/visualizations/chase.rs b/src/gui/visualizations/chase.rs new file mode 100644 index 0000000..190faeb --- /dev/null +++ b/src/gui/visualizations/chase.rs @@ -0,0 +1,497 @@ +//! Chase algorithm visualization +//! +//! Provides step-through debugging and visualization of the chase algorithm. + +use eframe::egui; + +use crate::core::RelationStorage; +use crate::gui::state::{ChaseEventRecord, ChaseMode, ChaseVisualizationState, CentralView, GuiState, SelectedItem}; +use crate::query::chase::{ChaseControl, ChaseEvent, ChaseObserver}; + +/// Chase visualization panel +pub struct ChaseVisualization { + /// Breakpoint being added + new_breakpoint: String, +} + +impl ChaseVisualization { + pub fn new() -> Self { + Self { + new_breakpoint: String::new(), + } + } + + pub fn show(&mut self, ui: &mut egui::Ui, state: &mut GuiState) { + // Header + ui.horizontal(|ui| { + ui.heading("Chase Visualization"); + + if let Some(chase_state) = &state.chase_state { + ui.label(format!("Instance: {}", chase_state.instance_name)); + } + }); + + ui.separator(); + + if state.chase_state.is_none() { + self.show_start_panel(ui, state); + } else { + self.show_chase_panel(ui, state); + } + } + + fn show_start_panel(&mut self, ui: &mut egui::Ui, state: &mut GuiState) { + ui.label("Select an instance to start chase visualization:"); + ui.add_space(8.0); + + let instances = state.repl.list_instances(); + if instances.is_empty() { + ui.label("No instances defined. Create an instance first."); + } else { + for instance in instances { + if ui.button(format!("{} : {}", instance.name, instance.theory_name)).clicked() { + state.start_chase(&instance.name); + } + } + } + + // Or use currently selected instance + if let Some(SelectedItem::Instance(name)) = &state.selected_item { + ui.add_space(16.0); + let name = name.clone(); + if ui.button(format!("Start Chase on selected: {}", name)).clicked() { + state.start_chase(&name); + } + } + } + + fn show_chase_panel(&mut self, ui: &mut egui::Ui, state: &mut GuiState) { + // Read mode and instance_name before mutable operations + let (mode, instance_name) = { + let chase_state = state.chase_state.as_ref().unwrap(); + (chase_state.mode, chase_state.instance_name.clone()) + }; + + // Control buttons + let mut step_clicked = false; + let mut run_clicked = false; + let mut stop_clicked = false; + let mut reset_clicked = false; + let mut close_clicked = false; + + ui.horizontal(|ui| { + // Mode indicator + let mode_text = match mode { + ChaseMode::Idle => "Idle", + ChaseMode::Stepping => "Stepping", + ChaseMode::Running => "Running", + ChaseMode::Completed => "Completed", + }; + ui.label(format!("Mode: {}", mode_text)); + + ui.separator(); + + // Only show Run/Step if not completed + if mode != ChaseMode::Completed { + if ui.button("Step").clicked() { + step_clicked = true; + } + + if ui.button("Run All").clicked() { + run_clicked = true; + } + + if ui.button("Stop").clicked() { + stop_clicked = true; + } + } + + // Reset button + if ui.button("Reset").clicked() { + reset_clicked = true; + } + + // Close button + if ui.button("Close").clicked() { + close_clicked = true; + } + }); + + // Handle button actions + if step_clicked { + self.step_chase(state); + } + if run_clicked { + self.run_chase_to_completion(state); + } + if stop_clicked { + if let Some(chase_state) = &mut state.chase_state { + chase_state.mode = ChaseMode::Completed; + } + } + if reset_clicked { + state.chase_state = Some(ChaseVisualizationState::new(instance_name)); + } + if close_clicked { + state.chase_state = None; + state.central_view = CentralView::EditorAndInspector; + return; + } + + ui.separator(); + + // Main content area split into events and info + ui.columns(2, |columns| { + // Left column: Events + columns[0].heading("Events"); + self.show_events_panel(&mut columns[0], state); + + // Right column: Info and breakpoints + columns[1].heading("Information"); + self.show_info_panel(&mut columns[1], state); + }); + } + + fn show_events_panel(&mut self, ui: &mut egui::Ui, state: &mut GuiState) { + egui::ScrollArea::vertical() + .auto_shrink([false, false]) + .stick_to_bottom(true) + .show(ui, |ui| { + if let Some(chase_state) = &state.chase_state { + if chase_state.events.is_empty() { + ui.label("No events yet. Click 'Step' or 'Run All' to start."); + } else { + for (i, event) in chase_state.events.iter().enumerate() { + let is_current = i == chase_state.current_event; + let prefix = if is_current { ">" } else { " " }; + + let axiom_name = event.axiom_name.as_deref().unwrap_or("(unnamed)"); + let binding_str: Vec = event + .binding + .iter() + .map(|(var, val)| format!("{}={}", var, val)) + .collect(); + + let changed_marker = if event.changed { " [changed]" } else { "" }; + + let text = format!( + "{} [{}] #{} {} {{ {} }}{}", + prefix, + event.iteration, + event.axiom_index, + axiom_name, + binding_str.join(", "), + changed_marker + ); + + let color = if is_current { + egui::Color32::YELLOW + } else if event.changed { + egui::Color32::from_rgb(100, 200, 100) + } else { + egui::Color32::LIGHT_GRAY + }; + + ui.label(egui::RichText::new(text).color(color).monospace()); + } + } + } + }); + } + + fn show_info_panel(&mut self, ui: &mut egui::Ui, state: &mut GuiState) { + // Read info from chase_state + let (current_iteration, total_iterations, events_count, breakpoints, instance_name) = { + if let Some(chase_state) = &state.chase_state { + ( + chase_state.current_iteration, + chase_state.total_iterations, + chase_state.events.len(), + chase_state.breakpoints.iter().cloned().collect::>(), + chase_state.instance_name.clone(), + ) + } else { + return; + } + }; + + // Iteration info + ui.label(format!("Current iteration: {}", current_iteration)); + if let Some(total) = total_iterations { + ui.label(format!("Total iterations: {}", total)); + } + ui.label(format!("Events recorded: {}", events_count)); + + ui.add_space(16.0); + + // Breakpoints section + ui.heading("Breakpoints"); + + // Add new breakpoint + ui.horizontal(|ui| { + ui.text_edit_singleline(&mut self.new_breakpoint); + if ui.button("+").clicked() && !self.new_breakpoint.is_empty() { + if let Some(chase_state) = &mut state.chase_state { + chase_state.breakpoints.insert(self.new_breakpoint.clone()); + } + self.new_breakpoint.clear(); + } + }); + + // List breakpoints + if breakpoints.is_empty() { + ui.label("(no breakpoints)"); + } else { + let mut to_remove = None; + for bp in &breakpoints { + ui.horizontal(|ui| { + ui.label(format!(" {}", bp)); + if ui.small_button("x").clicked() { + to_remove = Some(bp.clone()); + } + }); + } + if let Some(bp) = to_remove { + if let Some(chase_state) = &mut state.chase_state { + chase_state.breakpoints.remove(&bp); + } + } + } + + ui.add_space(16.0); + + // Structure info + ui.heading("Structure"); + if let Some(entry) = state.repl.instances.get(&instance_name) { + ui.label(format!("Elements: {}", entry.structure.len())); + + let total_tuples: usize = entry.structure.relations.iter().map(|r| r.len()).sum(); + ui.label(format!("Relation tuples: {}", total_tuples)); + + // Show relation breakdown + let theory_name = entry.theory_name.clone(); + if let Some(theory) = state.repl.theories.get(&theory_name) { + for (rel_id, rel) in theory.theory.signature.relations.iter().enumerate() { + if rel_id < entry.structure.relations.len() { + let count = entry.structure.relations[rel_id].len(); + if count > 0 { + ui.label(format!(" {}: {} tuples", rel.name, count)); + } + } + } + } + } + } + + /// Execute a single step of the chase + fn step_chase(&mut self, state: &mut GuiState) { + let instance_name = match &state.chase_state { + Some(s) => s.instance_name.clone(), + None => return, + }; + + let current_iteration = state.chase_state.as_ref().map(|s| s.current_iteration).unwrap_or(0); + + // Get theory name first (immutable borrow) + let theory_name = match state.repl.instances.get(&instance_name) { + Some(e) => e.theory_name.clone(), + None => { + state.log_error(format!("Instance '{}' not found", instance_name)); + return; + } + }; + + let theory = match state.repl.theories.get(&theory_name) { + Some(t) => t.clone(), + None => { + state.log_error(format!("Theory '{}' not found", theory_name)); + return; + } + }; + + // Now get mutable access to entry + let entry = state.repl.instances.get_mut(&instance_name).unwrap(); + + // Create a GUI observer that records events + let mut observer = GuiChaseObserver { + events: Vec::new(), + slid_to_name: &entry.slid_to_name, + iteration: current_iteration, + step_mode: true, + steps_remaining: 1, + }; + + // Run chase with observer (just one step) + let sig = &theory.theory.signature; + let axioms = &theory.theory.axioms; + let axiom_names = &theory.theory.axiom_names; + + let result = crate::query::chase::chase_fixpoint_with_observer( + axioms, + axiom_names, + &mut entry.structure, + &mut state.repl.store.universe, + sig, + 1, // Just one iteration + &mut observer, + ); + + // Record events + let events = observer.events; + if let Some(chase_state) = &mut state.chase_state { + chase_state.mode = ChaseMode::Stepping; + for event in events { + chase_state.events.push(event); + } + chase_state.current_event = chase_state.events.len().saturating_sub(1); + chase_state.current_iteration += 1; + + if let Ok(iterations) = result { + if iterations == 0 { + chase_state.mode = ChaseMode::Completed; + chase_state.total_iterations = Some(chase_state.current_iteration); + } + } + } + + // Log completion separately + if let Ok(iterations) = result { + if iterations == 0 { + let total = state.chase_state.as_ref().map(|s| s.current_iteration).unwrap_or(0); + state.log_success(format!("Chase completed after {} iterations", total)); + } + } + } + + /// Run the chase to completion + fn run_chase_to_completion(&mut self, state: &mut GuiState) { + let instance_name = match &state.chase_state { + Some(s) => s.instance_name.clone(), + None => return, + }; + + // Get theory name first (immutable borrow) + let theory_name = match state.repl.instances.get(&instance_name) { + Some(e) => e.theory_name.clone(), + None => { + state.log_error(format!("Instance '{}' not found", instance_name)); + return; + } + }; + + let theory = match state.repl.theories.get(&theory_name) { + Some(t) => t.clone(), + None => { + state.log_error(format!("Theory '{}' not found", theory_name)); + return; + } + }; + + // Now get mutable access to entry + let entry = state.repl.instances.get_mut(&instance_name).unwrap(); + + // Run chase to fixpoint + let sig = &theory.theory.signature; + let axioms = &theory.theory.axioms; + + let start = std::time::Instant::now(); + let result = crate::query::chase::chase_fixpoint( + axioms, + &mut entry.structure, + &mut state.repl.store.universe, + sig, + 100, + ); + + match result { + Ok(iterations) => { + let elapsed = start.elapsed(); + if let Some(chase_state) = &mut state.chase_state { + chase_state.mode = ChaseMode::Completed; + chase_state.total_iterations = Some(iterations); + } + state.log_success(format!( + "Chase completed in {} iterations ({:.2}ms)", + iterations, + elapsed.as_secs_f64() * 1000.0 + )); + } + Err(e) => { + state.log_error(format!("Chase error: {}", e)); + } + } + } +} + +impl Default for ChaseVisualization { + fn default() -> Self { + Self::new() + } +} + +/// Observer that records chase events for the GUI +struct GuiChaseObserver<'a> { + events: Vec, + slid_to_name: &'a std::collections::HashMap, + iteration: usize, + step_mode: bool, + steps_remaining: usize, +} + +impl<'a> ChaseObserver for GuiChaseObserver<'a> { + fn on_event(&mut self, event: ChaseEvent<'_>) -> ChaseControl { + match event { + ChaseEvent::IterationStart { iteration } => { + self.iteration = iteration; + ChaseControl::Continue + } + ChaseEvent::AxiomFiring { + axiom_index, + axiom_name, + binding, + violation_count: _, + } => { + // Record the event + let binding_vec: Vec<(String, String)> = binding + .iter() + .map(|(var, slid)| { + let elem_name = self + .slid_to_name + .get(slid) + .cloned() + .unwrap_or_else(|| format!("#{}", slid)); + (var.clone(), elem_name) + }) + .collect(); + + self.events.push(ChaseEventRecord { + iteration: self.iteration, + axiom_index, + axiom_name: axiom_name.map(|s| s.to_string()), + binding: binding_vec, + changed: false, // Will be updated in AxiomFired + }); + + if self.step_mode { + self.steps_remaining = self.steps_remaining.saturating_sub(1); + if self.steps_remaining == 0 { + ChaseControl::Stop + } else { + ChaseControl::Continue + } + } else { + ChaseControl::Continue + } + } + ChaseEvent::AxiomFired { changed, .. } => { + // Update the last event with the changed status + if let Some(last) = self.events.last_mut() { + last.changed = changed; + } + ChaseControl::Continue + } + ChaseEvent::IterationEnd { .. } => ChaseControl::Continue, + ChaseEvent::ChaseComplete { .. } => ChaseControl::Continue, + } + } +} diff --git a/src/gui/visualizations/graph.rs b/src/gui/visualizations/graph.rs new file mode 100644 index 0000000..62192af --- /dev/null +++ b/src/gui/visualizations/graph.rs @@ -0,0 +1,562 @@ +//! Relation graph visualization +//! +//! Displays elements as nodes and relation tuples as edges. + +use eframe::egui; +use std::collections::HashMap; + +use crate::core::RelationStorage; +use crate::gui::state::{CentralView, GuiState}; +use crate::id::{NumericId, Slid}; + +/// A node in the graph +#[derive(Clone, Debug)] +pub struct GraphNode { + pub id: Slid, + pub name: String, + pub sort: String, + pub position: egui::Pos2, + pub color: egui::Color32, +} + +/// An edge in the graph +#[derive(Clone, Debug)] +pub struct GraphEdge { + pub from: Slid, + pub to: Slid, + pub relation: String, + pub label: Option, +} + +/// Graph view panel +pub struct GraphView { + /// Nodes in the graph + nodes: Vec, + /// Edges in the graph + edges: Vec, + /// Node positions (for dragging) + node_positions: HashMap, + /// Currently dragged node + dragged_node: Option, + /// Zoom level + zoom: f32, + /// Pan offset + pan: egui::Vec2, + /// Selected relation filter + selected_relation: Option, + /// Whether we need to recalculate layout + needs_layout: bool, + /// Last instance/relation we rendered + last_instance: Option, + last_relation: Option, +} + +impl GraphView { + pub fn new() -> Self { + Self { + nodes: Vec::new(), + edges: Vec::new(), + node_positions: HashMap::new(), + dragged_node: None, + zoom: 1.0, + pan: egui::Vec2::ZERO, + selected_relation: None, + needs_layout: true, + last_instance: None, + last_relation: None, + } + } + + pub fn show(&mut self, ui: &mut egui::Ui, state: &mut GuiState) { + // Header + ui.horizontal(|ui| { + ui.heading("Graph Visualization"); + + if let Some(instance) = &state.graph_instance { + ui.label(format!("Instance: {}", instance)); + } + if let Some(relation) = &state.graph_relation { + ui.label(format!("Relation: {}", relation)); + } + }); + + ui.separator(); + + // Check if we need to rebuild the graph + if state.graph_instance != self.last_instance || state.graph_relation != self.last_relation { + self.rebuild_graph(state); + } + + // No instance selected + if state.graph_instance.is_none() { + self.show_selection_panel(ui, state); + return; + } + + // Controls + ui.horizontal(|ui| { + // Relation filter dropdown + if let Some(instance_name) = &state.graph_instance { + if let Some(entry) = state.repl.instances.get(instance_name) { + if let Some(theory) = state.repl.theories.get(&entry.theory_name) { + let relations: Vec<&str> = theory + .theory + .signature + .relations + .iter() + .map(|r| r.name.as_str()) + .collect(); + + ui.label("Relation:"); + egui::ComboBox::from_label("") + .selected_text( + self.selected_relation + .as_deref() + .unwrap_or("(all)"), + ) + .show_ui(ui, |ui| { + if ui.selectable_label(self.selected_relation.is_none(), "(all)").clicked() { + self.selected_relation = None; + self.needs_layout = true; + } + for rel in relations { + if ui.selectable_label( + self.selected_relation.as_deref() == Some(rel), + rel, + ).clicked() { + self.selected_relation = Some(rel.to_string()); + self.needs_layout = true; + } + } + }); + } + } + } + + ui.separator(); + + if ui.button("Reset Layout").clicked() { + self.needs_layout = true; + } + + if ui.button("Fit").clicked() { + self.fit_to_view(ui); + } + + // Zoom controls + ui.label("Zoom:"); + if ui.button("-").clicked() { + self.zoom = (self.zoom - 0.1).max(0.1); + } + ui.label(format!("{:.0}%", self.zoom * 100.0)); + if ui.button("+").clicked() { + self.zoom = (self.zoom + 0.1).min(3.0); + } + + ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { + if ui.button("Close").clicked() { + state.graph_instance = None; + state.graph_relation = None; + state.central_view = CentralView::EditorAndInspector; + } + }); + }); + + ui.separator(); + + // Apply layout if needed + if self.needs_layout { + self.apply_layout(ui); + self.needs_layout = false; + } + + // Draw the graph + self.draw_graph(ui); + } + + fn show_selection_panel(&mut self, ui: &mut egui::Ui, state: &mut GuiState) { + ui.label("Select an instance to visualize:"); + ui.add_space(8.0); + + let instances = state.repl.list_instances(); + if instances.is_empty() { + ui.label("No instances defined."); + } else { + for instance in instances { + if ui.button(format!("{} : {}", instance.name, instance.theory_name)).clicked() { + state.graph_instance = Some(instance.name.clone()); + self.needs_layout = true; + } + } + } + + ui.add_space(16.0); + if ui.button("Back to Editor").clicked() { + state.central_view = CentralView::EditorAndInspector; + } + } + + fn rebuild_graph(&mut self, state: &GuiState) { + self.nodes.clear(); + self.edges.clear(); + self.node_positions.clear(); + + let instance_name = match &state.graph_instance { + Some(name) => name, + None => return, + }; + + let entry = match state.repl.instances.get(instance_name) { + Some(e) => e, + None => return, + }; + + let theory = match state.repl.theories.get(&entry.theory_name) { + Some(t) => t, + None => return, + }; + + let sig = &theory.theory.signature; + + // Create nodes for each element + let sort_colors = generate_sort_colors(sig.sorts.len()); + + for (slid_idx, &sort_id) in entry.structure.sorts.iter().enumerate() { + let slid = Slid::from_usize(slid_idx); + let name = entry + .slid_to_name + .get(&slid) + .map(|s| s.clone()) + .unwrap_or_else(|| format!("#{}", slid_idx)); + + let sort_name = sig.sorts.get(sort_id).cloned().unwrap_or_default(); + let color = sort_colors.get(sort_id).copied().unwrap_or(egui::Color32::GRAY); + + self.nodes.push(GraphNode { + id: slid, + name, + sort: sort_name, + position: egui::Pos2::ZERO, // Will be set by layout + color, + }); + } + + // Create edges for relations + for (rel_id, relation) in entry.structure.relations.iter().enumerate() { + if relation.is_empty() { + continue; + } + + let rel_name = sig + .relations + .get(rel_id) + .map(|r| r.name.clone()) + .unwrap_or_else(|| format!("rel#{}", rel_id)); + + // Filter by selected relation + if let Some(selected) = &self.selected_relation { + if &rel_name != selected { + continue; + } + } + + for tuple in relation.iter() { + if tuple.len() >= 2 { + // Binary or higher-arity relation: draw edge from first to last + self.edges.push(GraphEdge { + from: tuple[0], + to: tuple[tuple.len() - 1], + relation: rel_name.clone(), + label: if tuple.len() > 2 { + Some(format!("via {} elements", tuple.len() - 2)) + } else { + None + }, + }); + } else if tuple.len() == 1 { + // Unary relation: self-loop (or just highlight the node) + self.edges.push(GraphEdge { + from: tuple[0], + to: tuple[0], + relation: rel_name.clone(), + label: None, + }); + } + } + } + + self.last_instance = state.graph_instance.clone(); + self.last_relation = state.graph_relation.clone(); + self.needs_layout = true; + } + + fn apply_layout(&mut self, ui: &egui::Ui) { + let available = ui.available_size(); + let center = egui::Pos2::new(available.x / 2.0, available.y / 2.0); + + if self.nodes.is_empty() { + return; + } + + // Simple circular layout + let radius = (available.x.min(available.y) / 2.0 - 50.0).max(100.0); + let count = self.nodes.len(); + + for (i, node) in self.nodes.iter_mut().enumerate() { + let angle = (i as f32 / count as f32) * std::f32::consts::TAU; + let pos = egui::Pos2::new( + center.x + radius * angle.cos(), + center.y + radius * angle.sin(), + ); + node.position = pos; + self.node_positions.insert(node.id, pos); + } + } + + fn fit_to_view(&mut self, ui: &egui::Ui) { + if self.nodes.is_empty() { + return; + } + + // Calculate bounding box + let mut min_x = f32::MAX; + let mut min_y = f32::MAX; + let mut max_x = f32::MIN; + let mut max_y = f32::MIN; + + for node in &self.nodes { + min_x = min_x.min(node.position.x); + min_y = min_y.min(node.position.y); + max_x = max_x.max(node.position.x); + max_y = max_y.max(node.position.y); + } + + let width = max_x - min_x; + let height = max_y - min_y; + let available = ui.available_size(); + + // Calculate zoom to fit + let zoom_x = if width > 0.0 { (available.x - 100.0) / width } else { 1.0 }; + let zoom_y = if height > 0.0 { (available.y - 100.0) / height } else { 1.0 }; + self.zoom = zoom_x.min(zoom_y).clamp(0.1, 2.0); + + // Calculate pan to center + let center_x = (min_x + max_x) / 2.0; + let center_y = (min_y + max_y) / 2.0; + self.pan = egui::Vec2::new( + available.x / 2.0 - center_x * self.zoom, + available.y / 2.0 - center_y * self.zoom, + ); + } + + fn draw_graph(&mut self, ui: &mut egui::Ui) { + let (response, painter) = ui.allocate_painter( + ui.available_size(), + egui::Sense::click_and_drag(), + ); + + let rect = response.rect; + + // Handle panning + if response.dragged() && self.dragged_node.is_none() { + self.pan += response.drag_delta(); + } + + // Handle zooming with scroll + if response.hovered() { + let scroll = ui.input(|i| i.raw_scroll_delta.y); + if scroll != 0.0 { + let old_zoom = self.zoom; + self.zoom = (self.zoom + scroll * 0.001).clamp(0.1, 3.0); + + // Zoom toward mouse position + if let Some(pos) = response.hover_pos() { + let rel_pos = pos - rect.min; + let zoom_factor = self.zoom / old_zoom; + self.pan = rel_pos - (rel_pos - self.pan) * zoom_factor; + } + } + } + + // Transform helper + let transform = |pos: egui::Pos2| -> egui::Pos2 { + egui::Pos2::new( + rect.min.x + pos.x * self.zoom + self.pan.x, + rect.min.y + pos.y * self.zoom + self.pan.y, + ) + }; + + // Draw edges first (behind nodes) + for edge in &self.edges { + let from_pos = self.node_positions.get(&edge.from); + let to_pos = self.node_positions.get(&edge.to); + + if let (Some(&from), Some(&to)) = (from_pos, to_pos) { + let from_screen = transform(from); + let to_screen = transform(to); + + if edge.from == edge.to { + // Self-loop + let offset = 20.0 * self.zoom; + let loop_center = egui::Pos2::new(from_screen.x, from_screen.y - offset); + painter.circle_stroke( + loop_center, + 10.0 * self.zoom, + egui::Stroke::new(1.5, egui::Color32::LIGHT_GRAY), + ); + } else { + // Regular edge + painter.line_segment( + [from_screen, to_screen], + egui::Stroke::new(1.5, egui::Color32::LIGHT_GRAY), + ); + + // Draw arrowhead + let dir = (to_screen - from_screen).normalized(); + let arrow_size = 8.0 * self.zoom; + let node_radius = 20.0 * self.zoom; + let arrow_tip = to_screen - dir * node_radius; + let perp = egui::Vec2::new(-dir.y, dir.x); + + let p1 = arrow_tip; + let p2 = arrow_tip - dir * arrow_size + perp * arrow_size * 0.5; + let p3 = arrow_tip - dir * arrow_size - perp * arrow_size * 0.5; + + painter.add(egui::Shape::convex_polygon( + vec![p1, p2, p3], + egui::Color32::LIGHT_GRAY, + egui::Stroke::NONE, + )); + } + } + } + + // Draw nodes + let node_radius = 20.0 * self.zoom; + + for node in &self.nodes { + let pos = self.node_positions.get(&node.id).copied().unwrap_or(node.position); + let screen_pos = transform(pos); + + // Check if node is being hovered or dragged + let node_rect = egui::Rect::from_center_size( + screen_pos, + egui::Vec2::splat(node_radius * 2.0), + ); + + let is_hovered = response.hovered() + && ui.input(|i| i.pointer.hover_pos()) + .map(|p| node_rect.contains(p)) + .unwrap_or(false); + + // Handle node dragging + if is_hovered && response.drag_started() { + self.dragged_node = Some(node.id); + } + + if self.dragged_node == Some(node.id) { + if response.dragged() { + let delta = response.drag_delta() / self.zoom; + if let Some(pos) = self.node_positions.get_mut(&node.id) { + *pos += delta; + } + } + if response.drag_stopped() { + self.dragged_node = None; + } + } + + // Draw node circle + let fill_color = if is_hovered || self.dragged_node == Some(node.id) { + node.color.linear_multiply(1.3) + } else { + node.color + }; + + painter.circle_filled(screen_pos, node_radius, fill_color); + painter.circle_stroke( + screen_pos, + node_radius, + egui::Stroke::new(2.0, egui::Color32::WHITE), + ); + + // Draw node label + let font_size = (12.0 * self.zoom).max(8.0); + painter.text( + screen_pos, + egui::Align2::CENTER_CENTER, + &node.name, + egui::FontId::proportional(font_size), + egui::Color32::WHITE, + ); + + // Draw sort label below + if is_hovered { + painter.text( + screen_pos + egui::Vec2::new(0.0, node_radius + 5.0), + egui::Align2::CENTER_TOP, + &node.sort, + egui::FontId::proportional(10.0 * self.zoom), + egui::Color32::LIGHT_GRAY, + ); + } + } + + // Show info panel + if self.nodes.is_empty() { + painter.text( + rect.center(), + egui::Align2::CENTER_CENTER, + "No elements to display", + egui::FontId::proportional(16.0), + egui::Color32::GRAY, + ); + } + } +} + +impl Default for GraphView { + fn default() -> Self { + Self::new() + } +} + +/// Generate distinct colors for each sort +fn generate_sort_colors(count: usize) -> Vec { + let mut colors = Vec::with_capacity(count); + + for i in 0..count { + let hue = (i as f32 / count as f32) * 360.0; + let (r, g, b) = hsv_to_rgb(hue, 0.6, 0.8); + colors.push(egui::Color32::from_rgb(r, g, b)); + } + + colors +} + +/// Convert HSV to RGB +fn hsv_to_rgb(h: f32, s: f32, v: f32) -> (u8, u8, u8) { + let c = v * s; + let x = c * (1.0 - ((h / 60.0) % 2.0 - 1.0).abs()); + let m = v - c; + + let (r, g, b) = if h < 60.0 { + (c, x, 0.0) + } else if h < 120.0 { + (x, c, 0.0) + } else if h < 180.0 { + (0.0, c, x) + } else if h < 240.0 { + (0.0, x, c) + } else if h < 300.0 { + (x, 0.0, c) + } else { + (c, 0.0, x) + }; + + ( + ((r + m) * 255.0) as u8, + ((g + m) * 255.0) as u8, + ((b + m) * 255.0) as u8, + ) +} diff --git a/src/gui/visualizations/mod.rs b/src/gui/visualizations/mod.rs new file mode 100644 index 0000000..49afdd0 --- /dev/null +++ b/src/gui/visualizations/mod.rs @@ -0,0 +1,7 @@ +//! Visualization components for the Geolog GUI + +pub mod chase; +pub mod graph; + +pub use chase::ChaseVisualization; +pub use graph::GraphView; diff --git a/src/lib.rs b/src/lib.rs index 1f95507..a0e7d6c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,6 +27,9 @@ pub mod universe; pub mod version; pub mod zerocopy; +#[cfg(feature = "gui")] +pub mod gui; + pub use ast::*; pub use lexer::lexer; pub use parser::parser;