From 4a075d0319fa2118e7709e39a41d3885fff36622 Mon Sep 17 00:00:00 2001 From: Vera Gonzalez Date: Thu, 28 Nov 2024 14:48:48 -0500 Subject: [PATCH 1/6] using prebuilt action (#44) --- .github/workflows/dispatch_update.yml | 17 +++++++++++++++++ .github/workflows/rust.yml | 1 + 2 files changed, 18 insertions(+) diff --git a/.github/workflows/dispatch_update.yml b/.github/workflows/dispatch_update.yml index 8a23294a..cbd44368 100644 --- a/.github/workflows/dispatch_update.yml +++ b/.github/workflows/dispatch_update.yml @@ -3,8 +3,25 @@ on: push: branches: - main + workflow_dispatch: {} + jobs: + check_version: + name: Check version + runs-on: ubuntu-latest + outputs: + changed: ${{ steps.check_version.outputs.changed }} + version: ${{ steps.check_version.outputs.version }} + prev_version: ${{ steps.check_version.outputs.prev_version }} + + steps: + - uses: actions/checkout@v4 + - id: check_version + uses: radumarias/action-check-version-changed-rust@v1 + dispatch: + needs: [check_version] + if: steps.check_version.outputs.changed = 'true' runs-on: ubuntu-latest steps: - name: Dispatch update to Personal Website diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index f9f37adc..0ad92cf3 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -17,6 +17,7 @@ on: env: RUSTC_WRAPPER: sccache SCCACHE_GHA_ENABLED: true + CARGO_TERM_COLOR: always jobs: build: From 07aa98d94df9bb6c00913319bf32a001def869e1 Mon Sep 17 00:00:00 2001 From: Vera Gonzalez Date: Sat, 30 Nov 2024 03:39:51 -0500 Subject: [PATCH 2/6] Conditional dispatch (#45) * using prebuilt action * update dispatch condition * fixed equals sign --- .github/workflows/dispatch_update.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dispatch_update.yml b/.github/workflows/dispatch_update.yml index cbd44368..d065d0c8 100644 --- a/.github/workflows/dispatch_update.yml +++ b/.github/workflows/dispatch_update.yml @@ -21,7 +21,7 @@ jobs: dispatch: needs: [check_version] - if: steps.check_version.outputs.changed = 'true' + if: needs.check_version.outputs.changed == 'true' runs-on: ubuntu-latest steps: - name: Dispatch update to Personal Website From b257a9b63bc6dd97890c29e25622925b82215271 Mon Sep 17 00:00:00 2001 From: Vera Gonzalez Date: Tue, 3 Dec 2024 01:37:23 -0500 Subject: [PATCH 3/6] Matrix (#47) * refactored distance matrix * defined robust Matrix type and Index impls for usage of jagged symmetric matrix * compiling * added Display to Matrix and fixed basic test * fixed PST * fixed cycle-finding * refactor as JagGraph * expanding into conway functionality; cycles * made PST a little prettier * replacing more occurrences of Edge with [VertexId; 2] * more restoration of Conway and Platonic * reimplementing other test cases * fixed pst test process & floyd * fully extricating Edge from PolyGraph * reimplemented conway & preset commands * trying to extricate more cases of Edge * adding graphviz svg capability * fixed split_vertex * further solidifying split_vertex * fixed contract edges; pst::o test working * removed svg files from commits * doing massive refactor * updated the preset setting call heirarchy * compiling again * changing preset code to create new instances rather than modify in place * reorganizing * changed Render to separate pos and speed * reimplemented test cases for Distance * ugh; checkpoint i guess? not rendering * dodec / expand * updating truncation test to be more robust * swapped out graphviz crate to improve legibility of graph structures * fixed truncation! * simplified contract_edges * fixed automatic resizing of Render attributes in Polyhedron on Conway change * trying to revert with no success * updating stuff! * temporarily setting to GL * updates svg as we go * fixed awful bug in position creation; as well as some layout stuff * svg preview; ambod * simplified split_vertex * storing graph svg in memory instead of in files * smart update positions on truncate * working on scope simplifications * nesting project structure * proper nesting * cycles submodule * Cycles::from(&distance) * removed redundant scoping * restored the ability to truncate, this time with nice scoping! * dramatically improved clarity and legibility of Graphviz svg * ambo now rendering * Distance super * Shape super * cleanup svg fn * cleaning up MomentVertices * cleaning up MomentVertices * clippy fix * fixing presets to be run on Polyhedron * printing graphs to console in test cases * somehow truncate is working * removed additional recomputation * terribly slow but correct cycle / face tester * significantly faster solution using eulers polyhedron formula * starting to clean * added primitive chamfer operator * trying to reimplement expand * rewriting expand to use sorted_connections * replacing expansion with aa for now * clippy * fixing clippy warnings * updating wasm dependencies * fixed render call * fmt * Update README.md * update README with warning --- .gitignore | 1 + Cargo.lock | 605 ++++++++++++++++---- Cargo.toml | 9 +- README.md | 11 +- deny.toml | 2 +- src/bones/conway.rs | 336 ----------- src/bones/edge.rs | 91 --- src/bones/face.rs | 152 ----- src/bones/mod.rs | 12 - src/bones/platonic.rs | 95 --- src/bones/polygraph.rs | 468 --------------- src/bones/polyhedron.rs | 183 ------ src/main.rs | 2 +- src/polyhedron/conway.rs | 52 ++ src/polyhedron/mod.rs | 384 +++++++++++++ src/polyhedron/platonic.rs | 61 ++ src/polyhedron/render.rs | 122 ++++ src/polyhedron/shape/conway.rs | 62 ++ src/polyhedron/shape/cycles/cycle.rs | 107 ++++ src/polyhedron/shape/cycles/mod.rs | 227 ++++++++ src/polyhedron/shape/distance/conway.rs | 149 +++++ src/polyhedron/shape/distance/mod.rs | 277 +++++++++ src/polyhedron/shape/distance/platonic.rs | 55 ++ src/polyhedron/shape/distance/svg.rs | 70 +++ src/polyhedron/shape/distance/test.rs | 92 +++ src/polyhedron/shape/mod.rs | 105 ++++ src/polyhedron/shape/platonic.rs | 15 + src/polyhedron/shape/test.rs | 61 ++ src/polyhedron/test.rs | 35 ++ src/{bones => polyhedron}/transaction.rs | 10 +- src/render/app.rs | 17 +- src/render/controls.rs | 6 +- src/render/message.rs | 27 +- src/render/mod.rs | 2 +- src/render/pipeline/buffer/types.rs | 23 +- src/render/pipeline/polyhedron_primitive.rs | 118 +--- src/render/polydex.rs | 11 +- src/render/state.rs | 27 +- 38 files changed, 2440 insertions(+), 1642 deletions(-) delete mode 100644 src/bones/conway.rs delete mode 100644 src/bones/edge.rs delete mode 100644 src/bones/face.rs delete mode 100644 src/bones/mod.rs delete mode 100644 src/bones/platonic.rs delete mode 100644 src/bones/polygraph.rs delete mode 100644 src/bones/polyhedron.rs create mode 100644 src/polyhedron/conway.rs create mode 100644 src/polyhedron/mod.rs create mode 100644 src/polyhedron/platonic.rs create mode 100644 src/polyhedron/render.rs create mode 100644 src/polyhedron/shape/conway.rs create mode 100644 src/polyhedron/shape/cycles/cycle.rs create mode 100644 src/polyhedron/shape/cycles/mod.rs create mode 100644 src/polyhedron/shape/distance/conway.rs create mode 100644 src/polyhedron/shape/distance/mod.rs create mode 100644 src/polyhedron/shape/distance/platonic.rs create mode 100644 src/polyhedron/shape/distance/svg.rs create mode 100644 src/polyhedron/shape/distance/test.rs create mode 100644 src/polyhedron/shape/mod.rs create mode 100644 src/polyhedron/shape/platonic.rs create mode 100644 src/polyhedron/shape/test.rs create mode 100644 src/polyhedron/test.rs rename src/{bones => polyhedron}/transaction.rs (57%) diff --git a/.gitignore b/.gitignore index 7eaa7baf..69bd713d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ **/target **/dist +tests perf.* flamegraph.svg diff --git a/Cargo.lock b/Cargo.lock index e3bed7ae..9dae763d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -50,9 +50,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" [[package]] name = "android-activity" @@ -176,9 +176,9 @@ dependencies = [ [[package]] name = "async-io" -version = "2.3.4" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" +checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" dependencies = [ "async-lock", "cfg-if", @@ -231,7 +231,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -266,7 +266,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -374,9 +374,9 @@ checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" [[package]] name = "bytemuck" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" dependencies = [ "bytemuck_derive", ] @@ -389,7 +389,7 @@ checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -400,9 +400,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "calloop" @@ -432,9 +432,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.31" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" dependencies = [ "jobserver", "libc", @@ -689,9 +689,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -839,6 +839,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[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.89", +] + [[package]] name = "dlib" version = "0.5.2" @@ -854,6 +865,21 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" +[[package]] +name = "dot-generator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aaac7ada45f71873ebce336491d1c1bc4a7c8042c7cea978168ad59e805b871" +dependencies = [ + "dot-structures", +] + +[[package]] +name = "dot-structures" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "675e35c02a51bb4d4618cb4885b3839ce6d1787c97b664474d9208d074742e20" + [[package]] name = "downcast-rs" version = "1.2.1" @@ -935,7 +961,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -1008,24 +1034,24 @@ checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" [[package]] name = "fastrand" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "fdeflate" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8090f921a24b04994d9929e204f50b498a33ea6ba559ffaa05e04f7ee7fb5ab" +checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" dependencies = [ "simd-adler32", ] [[package]] name = "flate2" -version = "1.0.34" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", @@ -1039,9 +1065,9 @@ checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" [[package]] name = "font-types" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dda6e36206148f69fc6ecb1bb6c0dedd7ee469f3db1d0dc2045beea28430ca43" +checksum = "b3971f9a5ca983419cdc386941ba3b9e1feba01a0ab888adf78739feb2798492" dependencies = [ "bytemuck", ] @@ -1101,7 +1127,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -1170,9 +1196,9 @@ checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" dependencies = [ "fastrand", "futures-core", @@ -1189,7 +1215,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -1355,6 +1381,22 @@ dependencies = [ "bitflags 2.6.0", ] +[[package]] +name = "graphviz-rust" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f7892a4538fc9aa3658ae6962774428487c16e11663c58c594357975377c901" +dependencies = [ + "dot-generator", + "dot-structures", + "into-attr", + "into-attr-derive", + "pest", + "pest_derive", + "rand", + "tempfile", +] + [[package]] name = "guillotiere" version = "0.6.2" @@ -1396,9 +1438,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "hassle-rs" @@ -1654,14 +1696,143 @@ dependencies = [ "winit", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] @@ -1677,7 +1848,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.2", ] [[package]] @@ -1689,6 +1860,28 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "into-attr" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18b48c537e49a709e678caec3753a7dba6854661a1eaa27675024283b3f8b376" +dependencies = [ + "dot-structures", +] + +[[package]] +name = "into-attr-derive" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecac7c1ae6cd2c6a3a64d1061a8bdc7f52ff62c26a831a2301e54c1b5d70d5b1" +dependencies = [ + "dot-generator", + "dot-structures", + "into-attr", + "quote", + "syn 1.0.109", +] + [[package]] name = "jni" version = "0.21.1" @@ -1780,9 +1973,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.161" +version = "0.2.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "c2ccc108bbc0b1331bd061864e7cd823c0cab660bbe6970e66e2c0614decde36" [[package]] name = "libloading" @@ -1806,9 +1999,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "libredox" @@ -1833,6 +2026,12 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "lock_api" version = "0.4.12" @@ -2032,7 +2231,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -2328,7 +2527,7 @@ dependencies = [ "by_address", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -2397,6 +2596,51 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pest" +version = "2.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "pest_meta" +version = "2.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + [[package]] name = "phf" version = "0.11.2" @@ -2427,7 +2671,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -2447,29 +2691,29 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -2509,9 +2753,9 @@ dependencies = [ [[package]] name = "polling" -version = "3.7.3" +version = "3.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" dependencies = [ "cfg-if", "concurrent-queue", @@ -2530,6 +2774,7 @@ dependencies = [ "console_error_panic_hook", "console_log", "getrandom", + "graphviz-rust", "iced", "iced_aw", "iced_wgpu", @@ -2576,9 +2821,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.88" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -2677,9 +2922,9 @@ dependencies = [ [[package]] name = "read-fonts" -version = "0.22.3" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb94d9ac780fdcf9b6b252253f7d8f221379b84bd3573131139b383df69f85e1" +checksum = "4a04b892cb6f91951f144c33321843790c8574c825aafdb16d815fd7183b5229" dependencies = [ "bytemuck", "font-types", @@ -2796,9 +3041,9 @@ checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", @@ -2881,22 +3126,22 @@ checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -2907,7 +3152,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -2921,6 +3166,17 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -3092,6 +3348,12 @@ dependencies = [ "bitflags 2.6.0", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -3123,14 +3385,14 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] name = "svg_fmt" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20e16a0f46cf5fd675563ef54f26e83e20f2366bcf027bcb3cc3ed2b98aaf2ca" +checksum = "ce5d813d71d82c4cbc1742135004e4a79fd870214c155443451c139c9470a0aa" [[package]] name = "svgtypes" @@ -3166,29 +3428,40 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + [[package]] name = "sys-locale" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e801cf239ecd6ccd71f03d270d67dd53d13e90aab208bf4b8fe4ad957ea949b0" +checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4" dependencies = [ "libc", ] [[package]] name = "tempfile" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", @@ -3224,7 +3497,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -3235,28 +3508,28 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", "test-case-core", ] [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -3308,6 +3581,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -3353,20 +3636,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -3421,6 +3704,12 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + [[package]] name = "uds_windows" version = "1.1.0" @@ -3462,9 +3751,9 @@ checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-linebreak" @@ -3472,15 +3761,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" -[[package]] -name = "unicode-normalization" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] - [[package]] name = "unicode-properties" version = "0.1.3" @@ -3519,9 +3799,9 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -3555,6 +3835,18 @@ dependencies = [ "xmlwriter", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "valuable" version = "0.1.0" @@ -3605,7 +3897,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", "wasm-bindgen-shared", ] @@ -3639,7 +3931,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3681,9 +3973,9 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.6" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3f45d1222915ef1fd2057220c1d9d9624b7654443ea35c3877f7a52bd0a5a2d" +checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280" dependencies = [ "bitflags 2.6.0", "rustix", @@ -3704,9 +3996,9 @@ dependencies = [ [[package]] name = "wayland-cursor" -version = "0.31.6" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a94697e66e76c85923b0d28a0c251e8f0666f58fc47d316c0f4da6da75d37cb" +checksum = "32b08bc3aafdb0035e7fe0fdf17ba0c09c268732707dca4ae098f60cb28c9e4c" dependencies = [ "rustix", "wayland-client", @@ -3715,9 +4007,9 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.32.4" +version = "0.32.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b5755d77ae9040bb872a25026555ce4cb0ae75fd923e90d25fba07d81057de0" +checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -3727,9 +4019,9 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0a41a6875e585172495f7a96dfa42ca7e0213868f4f15c313f7c33221a7eff" +checksum = "9b31cab548ee68c7eb155517f2212049dc151f7cd7910c2b66abfd31c3ee12bd" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -3740,9 +4032,9 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad87b5fd1b1d3ca2f792df8f686a2a11e3fe1077b71096f7a175ab699f89109" +checksum = "782e12f6cd923c3c316130d56205ebab53f55d6666b7faddfad36cecaeeb4022" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -3927,9 +4219,9 @@ dependencies = [ [[package]] name = "wide" -version = "0.7.28" +version = "0.7.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b828f995bf1e9622031f8009f8481a85406ce1f4d4588ff746d872043e855690" +checksum = "58e6db2670d2be78525979e9a5f9c69d296fd7d670549fe9ebf70f8708cb5019" dependencies = [ "bytemuck", "safe_arch", @@ -4280,6 +4572,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "x11-dl" version = "2.21.0" @@ -4349,9 +4653,9 @@ checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xml-rs" -version = "0.8.22" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26" +checksum = "af310deaae937e48a26602b730250b4949e125f468f11e6990be3e5304ddd96f" [[package]] name = "xmlwriter" @@ -4365,6 +4669,30 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c94451ac9513335b5e23d7a8a2b61a7102398b8cca5160829d313e84c9d98be1" +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", + "synstructure", +] + [[package]] name = "zbus" version = "4.4.0" @@ -4412,7 +4740,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", "zvariant_utils", ] @@ -4451,7 +4779,50 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", ] [[package]] @@ -4476,7 +4847,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", "zvariant_utils", ] @@ -4488,5 +4859,5 @@ checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] diff --git a/Cargo.toml b/Cargo.toml index 928b0733..a2e0e865 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,8 +39,9 @@ webbrowser = { version = "1.0.2" } iced_winit = { version = "0.13" } iced_widget = { version = "0.13", features = ["wgpu"] } iced_wgpu = { version = "0.13", features = ["webgl"] } -log = "0.4.22" -rustc-hash = "2.0.0" +log = { version = "0.4.22" } +rustc-hash = { version = "2.0.0" } +graphviz-rust = { version = "0.9.3" } [dev-dependencies] test-case = { version = "^3.3.0" } @@ -65,3 +66,7 @@ console_log = { version = "1.0" } [profile.release] debug = true + +[features] +default = [] +#graphs = ["dep:layout-rs"] diff --git a/README.md b/README.md index 19df4eb0..5ed24cf7 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,17 @@

+## WARNING +This software is currently broken. Use the release published on crates.io while I fix it, which can be installed using the method below. The main branch is not as functional as it once was, but this will be remedied soon. + +## Installation +```cargo install polyblade``` + +Note that the `webgl` demo is available [here](https://vera.lgbt/software/polyblade/), but is notably less performant than native code. + +### Build from source To run this software, simply clone the repository and use `cargo run --release`. -The `webgl` demo is available, but is notably less performant than native code. +For the `webgl` build, run `trunk serve --release`. #### Conway Roadmap - [x] Ambo diff --git a/deny.toml b/deny.toml index 04972301..ab394f93 100644 --- a/deny.toml +++ b/deny.toml @@ -9,6 +9,7 @@ ignore = ["RUSTSEC-2024-0384"] allow = [ "AGPL-3.0", "Apache-2.0", + "Unicode-3.0", "MIT", "Zlib", "BSL-1.0", @@ -17,7 +18,6 @@ allow = [ "CC0-1.0", "BSD-3-Clause", "BSD-2-Clause", - "Unicode-DFS-2016", ] [bans] diff --git a/src/bones/conway.rs b/src/bones/conway.rs deleted file mode 100644 index 73bbfe22..00000000 --- a/src/bones/conway.rs +++ /dev/null @@ -1,336 +0,0 @@ -use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet}; -use std::collections::VecDeque; -use ultraviolet::Vec3; - -use crate::bones::*; - -impl PolyGraph { - pub fn contract_edge(&mut self, e: impl Into) { - let e: Edge = e.into(); - // Give u all the same connections as v - for w in self.connections(e.v()).into_iter() { - self.connect((w, e.u())); - } - // Delete a - for f in self.cycles.iter_mut() { - f.replace(e.v(), e.u()); - } - - self.edges = self - .edges - .clone() - .into_iter() - .map(|f| { - if let Some(w) = f.other(e.v()) { - (e.u(), w).into() - } else { - f - } - }) - .filter(|e| e.v() != e.u()) - .collect(); - - self.delete(e.v()); - } - - pub fn contract_edges(&mut self, edges: HashSet) { - let mut map = HashMap::::default(); - for e in edges.into_iter() { - let u = e.u(); - let v = e.v(); - let e = match (map.get(&u), map.get(&v)) { - (None, None) => e, - (None, Some(v)) => (&u, v).into(), - (Some(u), None) => (u, &v).into(), - (Some(u), Some(v)) => (u, v).into(), - }; - if e.v() != e.u() { - self.contract_edge(e); - map.insert(e.v(), e.u()); - } - } - - self.cycles = self - .cycles - .clone() - .into_iter() - .filter(|c| c.len() > 2) - .collect(); - } - - pub fn split_vertex(&mut self, v: VertexId) -> HashSet { - let original_position = self.positions[&v]; - let mut connections: VecDeque = self.connections(v).into_iter().collect(); - let mut transformations: HashMap = Default::default(); - let mut new_face = Vec::new(); - - // Remove the vertex - - // connect a new node to every existing connection - while let Some(u) = connections.pop_front() { - // Insert a new node in the same location - let new_vertex = self.insert(); - // Track it in the new face - new_face.push(new_vertex); - // Update pos - self.positions.insert(new_vertex, original_position); - // Reform old connection - self.connect((u, new_vertex)); - // track transformation - transformations.insert(u, new_vertex); - } - - // track the edges that will compose the new face - let mut new_edges = HashSet::default(); - - // upate every face - for i in 0..self.cycles.len() { - // if this face had v in it - if let Some(vi) = self.cycles[i].iter().position(|&x| x == v) { - // indices before and after v in face - let vh = (vi + self.cycles[i].len() - 1) % self.cycles[i].len(); - let vj = (vi + 1) % self.cycles[i].len(); - - let b = transformations[&self.cycles[i][vh]]; - let a = transformations[&self.cycles[i][vj]]; - - self.cycles[i].insert(vi, a); - self.cycles[i].insert(vi, b); - - let e: Edge = (a, b).into(); - new_edges.insert(e); - self.connect(e); - } - } - - self.cycles.push(new_edges.clone().into()); - - self.delete(v); - new_edges - } - - /// `a` ambo - /// Returns a set of edges to contract - pub fn ambo(&mut self) -> HashSet { - // Truncate - let new_edges = self.truncate(None); - self.edges - .clone() - .difference(&new_edges) - .map(Edge::clone) - .collect() - } - - /// `k` kis - pub fn kis(&mut self, degree: Option) -> HashSet { - let edges = self.edges.clone(); - let mut cycles = self.cycles.clone(); - if let Some(degree) = degree { - cycles.retain(|c| c.len() == degree); - } - for cycle in cycles { - let v = self.insert(); - let mut vpos = Vec3::zero(); - - for &u in cycle.iter() { - self.connect((v, u)); - vpos += self.positions[&u]; - } - - self.positions.insert(v, vpos / cycle.len() as f32); - } - self.pst(); - self.find_cycles(); - //self.transactions.insert(1, Transaction::Name('k')); - edges - } - - /// `t` truncate - pub fn truncate(&mut self, degree: Option) -> HashSet { - let mut new_edges = HashSet::default(); - let mut vertices = self.vertices.clone(); - if let Some(degree) = degree { - vertices.retain(|&v| self.connections(v).len() == degree); - } - for v in vertices { - new_edges.extend(self.split_vertex(v)); - } - new_edges - } - - /// `o` ortho - #[allow(dead_code)] - pub fn ortho(&mut self) { - for _c in self.cycles.clone() { - let _v = self.insert(); - } - } - - pub fn ordered_face_indices(&self, v: VertexId) -> Vec { - let relevant = (0..self.cycles.len()) - .filter(|&i| self.cycles[i].containz(&v)) - .collect::>(); - - let mut edges = HashMap::default(); - - for &i in relevant.iter() { - let ui = self.cycles[i].iter().position(|&x| x == v).unwrap(); - let flen = self.cycles[i].len(); - // Find the values that came before and after in the face - let a = self.cycles[i][(ui + flen - 1) % flen]; - let b = self.cycles[i][(ui + 1) % flen]; - edges.insert((a, b).into(), i); - } - - let f: Face = edges.keys().cloned().collect::>().into(); - - let mut ordered_face_indices = vec![]; - for i in 0..f.len() { - let e: Edge = (f[i], f[(i + 1) % f.len()]).into(); - let fi = edges.get(&e).unwrap(); - ordered_face_indices.push(*fi); - } - - ordered_face_indices - } - - /// `e` = `aa` - pub fn expand(&mut self, snub: bool) -> HashSet { - let mut new_edges = HashSet::::default(); - let mut face_edges = HashSet::::default(); - - let ordered_face_indices: HashMap> = self - .vertices - .iter() - .map(|&v| (v, self.ordered_face_indices(v))) - .collect(); - - // For every vertex - for v in self.vertices.clone() { - let original_position = self.positions[&v]; - let mut new_face = Face::default(); - // For every face which contains the vertex - for &i in ordered_face_indices.get(&v).unwrap() { - // Create a new vertex - let u = self.insert(); - // Replace it in the face - self.cycles[i].replace(v, u); - // Now replace - let ui = self.cycles[i].iter().position(|&x| x == u).unwrap(); - let flen = self.cycles[i].len(); - // Find the values that came before and after in the face - let a = self.cycles[i][(ui + flen - 1) % flen]; - let b = self.cycles[i][(ui + 1) % flen]; - // Remove existing edges which may no longer be accurate - new_edges.remove(&(a, v).into()); - new_edges.remove(&(b, v).into()); - // Add the new edges which are so yass - new_edges.insert((a, u).into()); - new_edges.insert((b, u).into()); - // Add u to the new face being formed - new_face.push(u); - // pos - self.positions.insert(u, original_position); - } - for i in 0..new_face.len() { - face_edges.insert((new_face[i], new_face[(i + 1) % new_face.len()]).into()); - } - self.cycles.push(new_face); - self.delete(v); - } - - let mut solved_edges = HashSet::default(); - - // For every triangle / nf edge - for a in face_edges.iter() { - // find the edge which is parallel to it - for b in face_edges.iter() { - if !solved_edges.contains(a) && !solved_edges.contains(b) { - if new_edges.contains(&(a.v(), b.v()).into()) - && new_edges.contains(&(a.u(), b.u()).into()) - { - if snub { - new_edges.insert((a.v(), b.u()).into()); - let m = Face::new(vec![a.v(), b.u(), a.u()]); - let n = Face::new(vec![a.v(), b.u(), b.v()]); - self.cycles.push(m); - self.cycles.push(n); - } else { - let quad = Face::new(vec![b.u(), a.u(), a.v(), b.v()]); - self.cycles.push(quad); - } - - solved_edges.insert(a); - solved_edges.insert(b); - } - - if new_edges.contains(&(a.u(), b.v()).into()) - && new_edges.contains(&(a.v(), b.u()).into()) - { - if snub { - new_edges.insert((a.u(), b.u()).into()); - let m = Face::new(vec![a.u(), b.u(), a.v()]); - let n = Face::new(vec![a.u(), b.u(), b.v()]); - self.cycles.push(m); - self.cycles.push(n); - } else { - let quad = Face::new(vec![a.u(), b.v(), b.u(), a.v()]); - self.cycles.push(quad); - } - solved_edges.insert(a); - solved_edges.insert(b); - } - } - } - } - self.edges = HashSet::default(); - self.edges.extend(new_edges.clone()); - self.edges.extend(face_edges); - new_edges - } - - // `j` join - // `z` zip - // `g` gyro - // `m` meta = `kj` - // `o` ortho = `jj` - // `n` needle - // `k` kis -} - -#[cfg(test)] -mod test { - use crate::bones::PolyGraph; - - #[test] - fn truncate() { - let mut shape = PolyGraph::icosahedron(); - shape.truncate(None); - } - - #[test] - fn contract_edge() { - let mut graph = PolyGraph::prism(4); - assert_eq!(graph.vertices.len(), 8); - assert_eq!(graph.edges.len(), 12); - - graph.contract_edge((0, 1)); - graph.pst(); - - assert_eq!(graph.vertices.len(), 7); - assert_eq!(graph.edges.len(), 11); - } - - #[test] - fn split_vertex() { - let mut graph = PolyGraph::prism(4); - assert_eq!(graph.vertices.len(), 8); - assert_eq!(graph.edges.len(), 12); - - graph.split_vertex(0); - graph.pst(); - - assert_eq!(graph.vertices.len(), 10); - assert_eq!(graph.edges.len(), 15); - } -} diff --git a/src/bones/edge.rs b/src/bones/edge.rs deleted file mode 100644 index ab89e746..00000000 --- a/src/bones/edge.rs +++ /dev/null @@ -1,91 +0,0 @@ -use crate::bones::VertexId; -use std::fmt::Display; - -pub type EdgeId = (VertexId, VertexId); - -#[derive(Debug, Clone, Copy)] -pub struct Edge { - v: VertexId, - u: VertexId, -} - -impl Edge { - pub fn id(&self) -> EdgeId { - if self.v < self.u { - (self.v, self.u) - } else { - (self.u, self.v) - } - } - - pub fn v(&self) -> VertexId { - self.id().0 - } - - pub fn u(&self) -> VertexId { - self.id().1 - } - - pub fn contains(&self, v: VertexId) -> bool { - self.v == v || self.u == v - } - - pub fn other(&self, v: VertexId) -> Option { - if self.v == v { - Some(self.u) - } else if self.u == v { - Some(self.v) - } else { - None - } - } -} - -impl Display for Edge { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_fmt(format_args!("({}, {})", self.id().0, self.id().1)) - } -} - -impl From<(VertexId, VertexId)> for Edge { - fn from(value: (VertexId, VertexId)) -> Self { - Self { - v: value.0, - u: value.1, - } - } -} - -impl From<(&VertexId, &VertexId)> for Edge { - fn from(value: (&VertexId, &VertexId)) -> Self { - Self { - v: *value.0, - u: *value.1, - } - } -} - -impl PartialEq for Edge { - fn eq(&self, other: &Self) -> bool { - self.id() == other.id() - } -} - -impl std::cmp::PartialOrd for Edge { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for Edge { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.id().cmp(&other.id()) - } -} - -impl Eq for Edge {} -impl std::hash::Hash for Edge { - fn hash(&self, state: &mut H) { - self.id().hash(state); - } -} diff --git a/src/bones/face.rs b/src/bones/face.rs deleted file mode 100644 index 6f956a5b..00000000 --- a/src/bones/face.rs +++ /dev/null @@ -1,152 +0,0 @@ -use crate::bones::{Edge, VertexId}; -use rustc_hash::FxHashSet as HashSet; -use std::{ - hash::Hash, - ops::{Index, IndexMut}, - slice::SliceIndex, - vec::IntoIter, -}; - -#[derive(Debug, Default, Clone, PartialOrd, Ord)] -pub struct Face(Vec); - -impl Face { - pub fn new(vertices: Vec) -> Self { - Self(vertices) - } - pub fn contains(&self, other: &Face) -> bool { - other.0.iter().all(|v| self.0.contains(v)) - } - - pub fn containz(&self, value: &VertexId) -> bool { - self.0.contains(value) - } - - pub fn edges(&self) -> HashSet { - let mut edges = HashSet::default(); - for i in 0..self.0.len() { - edges.insert((self.0[i], self.0[(i + 1) % self.0.len()]).into()); - } - edges - } - - pub fn replace(&mut self, old: VertexId, new: VertexId) { - if self.0.contains(&new) && self.0.contains(&old) { - self.remove(self.0.iter().position(|&x| x == old).unwrap()); - } else { - self.0 = self - .0 - .clone() - .into_iter() - .map(|x| if x == old { new } else { x }) - .collect(); - } - } - - #[allow(dead_code)] - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn iter(&self) -> std::slice::Iter { - self.0.iter() - } - - pub fn remove(&mut self, index: usize) -> VertexId { - self.0.remove(index) - } - - pub fn insert(&mut self, index: usize, v: VertexId) { - self.0.insert(index, v) - } - - pub fn push(&mut self, value: VertexId) { - self.0.push(value) - } -} - -impl From> for Face { - fn from(value: HashSet) -> Self { - let mut edges: Vec = value.into_iter().collect(); - let mut first = false; - let mut face = vec![edges[0].v()]; - while !edges.is_empty() { - let v = if first { - *face.first().unwrap() - } else { - *face.last().unwrap() - }; - if let Some(i) = edges.iter().position(|e| e.contains(v)) { - let next = edges[i].other(v).unwrap(); - if !face.contains(&next) { - face.push(next); - } - edges.remove(i); - } else { - first ^= true; - } - } - Self::new(face) - } -} - -impl Index for Face -where - Idx: SliceIndex<[usize]>, -{ - type Output = Idx::Output; - - #[inline(always)] - fn index(&self, index: Idx) -> &Self::Output { - self.0.index(index) - } -} -impl IndexMut for Face -where - Idx: SliceIndex<[usize], Output = usize>, -{ - #[inline] - fn index_mut(&mut self, index: Idx) -> &mut Self::Output { - self.0.index_mut(index) - } -} - -impl IntoIterator for Face { - type Item = VertexId; - type IntoIter = IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } -} - -impl FromIterator for Face { - fn from_iter>(iter: I) -> Self { - let mut c = Face::new(vec![]); - for i in iter { - c.0.push(i); - } - c - } -} - -impl PartialEq for Face { - fn eq(&self, other: &Self) -> bool { - self.contains(other) && self.0.len() == other.0.len() - } -} - -impl Eq for Face {} -impl Hash for Face { - fn hash(&self, state: &mut H) { - let mut edges = self.edges().into_iter().collect::>(); - edges.sort(); - for edge in edges { - edge.hash(state); - } - } -} diff --git a/src/bones/mod.rs b/src/bones/mod.rs deleted file mode 100644 index 8908d120..00000000 --- a/src/bones/mod.rs +++ /dev/null @@ -1,12 +0,0 @@ -mod conway; -mod edge; -mod face; -mod platonic; -mod polygraph; -mod polyhedron; -mod transaction; - -pub use edge::*; -pub use face::*; -pub use polygraph::*; -pub use transaction::*; diff --git a/src/bones/platonic.rs b/src/bones/platonic.rs deleted file mode 100644 index b75a73ca..00000000 --- a/src/bones/platonic.rs +++ /dev/null @@ -1,95 +0,0 @@ -use crate::bones::PolyGraph; - -/* - T = Y3 - O = aT (ambo tetrahedron) - C = jT (join tetrahedron) - I = sT (snub tetrahedron) - D = gT (gyro tetrahedron) -*/ - -// Platonic Solids -impl PolyGraph { - pub fn prism(n: usize) -> PolyGraph { - let mut p = PolyGraph::new_disconnected(n * 2); - p.name = format!("P{n}"); - for i in 0..n { - // Lower polygon - p.connect((i % n, (i + 1) % n)); - // Upper polygon - p.connect(((i % n) + n, ((i + 1) % n) + n)); - // Connect - p.connect(((i % n), (i % n) + n)); - p.connect(((i + 1) % n, ((i + 1) % n) + n)); - } - p.pst(); - p.springs(); - p.find_cycles(); - p.lattice(); - p - } - - pub fn anti_prism(n: usize) -> PolyGraph { - let mut p = PolyGraph::new_disconnected(n * 2); - p.name = format!("A{n}"); - for i in 0..n { - // Lower polygon - p.connect((i % n, (i + 1) % n)); - // Upper polygon - p.connect(((i % n) + n, ((i + 1) % n) + n)); - // Connect - p.connect(((i % n), (i % n) + n)); - p.connect(((i + 1) % n, ((i + 1) % n) + n)); - - p.connect(((i % n), ((i + 1) % n) + n)); - } - p.pst(); - p.springs(); - p.find_cycles(); - p.lattice(); - p - } - - pub fn pyramid(n: usize) -> PolyGraph { - let mut p = PolyGraph::new_disconnected(n + 1); - p.name = format!("Y{n}"); - for i in 0..n { - p.connect((i, (i + 1) % n)); - p.connect((i, n)); - } - p.pst(); - p.springs(); - p.find_cycles(); - p.lattice(); - p - } - - pub fn octahedron() -> PolyGraph { - let mut p = PolyGraph::pyramid(3); - let edges = p.ambo(); - p.contract_edges(edges); - p.pst(); - p.springs(); - p.lattice(); - p.name = "O".into(); - p - } - pub fn dodecahedron() -> PolyGraph { - let mut p = PolyGraph::anti_prism(5); - let edges = p.expand(false); - p.contract_edges(edges); - p.truncate(Some(5)); - p.pst(); - p.springs(); - p.name = "D".into(); - p - } - pub fn icosahedron() -> PolyGraph { - let mut p = PolyGraph::anti_prism(5); - p.kis(Some(5)); - p.pst(); - p.springs(); - p.name = "I".into(); - p - } -} diff --git a/src/bones/polygraph.rs b/src/bones/polygraph.rs deleted file mode 100644 index 1199a494..00000000 --- a/src/bones/polygraph.rs +++ /dev/null @@ -1,468 +0,0 @@ -use crate::bones::*; -use rand::random; -use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet}; -use std::{collections::VecDeque, fmt::Display}; -use ultraviolet::Vec3; -type VertMap = HashMap; -pub type VertexId = usize; - -#[derive(Debug, Clone, Default)] -pub struct PolyGraph { - /// Conway Polyhedron Notation - pub name: String, - - /// [Actual Graph] - pub vertices: HashSet, - /// Vertices that are adjacent - pub edges: HashSet, - - /// All Springs - pub springs: HashSet, - - /// [Derived Properties] - /// Faces are simple cycles - pub cycles: Vec, - /// Distance matrix - pub dist: HashMap, - - /// [Render Properties] - /// Positions in 3D space - pub positions: VertMap, - /// Speeds - pub speeds: VertMap, - /// Edges in the process of contracting visually - pub transactions: Vec, - /// Edge length - pub edge_length: f32, - //pub contractions: HashSet, -} - -impl PolyGraph { - /// New with n vertices - pub fn new_disconnected(vertex_count: usize) -> Self { - Self { - vertices: (0..vertex_count).collect(), - speeds: (0..vertex_count).map(|x| (x, Vec3::zero())).collect(), - edge_length: 1.0, - ..Default::default() - } - } - - // Use a Fibonacci Lattice to spread the points evenly around a sphere - pub fn lattice(&mut self) { - // Use a Fibonacci Lattice to evently distribute starting points on a sphere - let phi = std::f32::consts::PI * (3.0 - 5.0f32.sqrt()); - for (i, v) in self.vertices.iter().enumerate() { - let y = 1.0 - (i as f32 / (self.vertices.len() - 1) as f32); - let radius = (1.0 - y * y).sqrt(); - let theta = (phi * (i as f32)) % (std::f32::consts::PI * 2.0); - let x = theta.cos() * radius; - let z = theta.sin() * radius; - self.positions.insert(*v, Vec3::new(x, y, z)); - } - } - - pub fn connect(&mut self, e: impl Into) { - let e = e.into(); - if e.v() != e.u() { - self.edges.insert(e); - } - } - - pub fn disconnect(&mut self, e: impl Into) { - self.edges.remove(&e.into()); - } - - pub fn insert(&mut self) -> VertexId { - let new_id = self.vertices.iter().max().unwrap() + 1; - self.vertices.insert(new_id); - // Position and speed - self.positions - .insert(new_id, Vec3::new(random(), random(), random()).normalized()); - self.speeds.insert(new_id, Vec3::zero()); - new_id - } - - pub fn delete(&mut self, v: VertexId) { - self.vertices.remove(&v); - - self.edges = self - .edges - .clone() - .into_iter() - .filter(|e| !e.contains(v)) - .collect(); - - self.cycles = self - .cycles - .clone() - .into_iter() - .map(|face| face.into_iter().filter(|&u| u != v).collect()) - .collect(); - - self.positions.remove(&v); - self.speeds.remove(&v); - } - - /// Edges of a vertex - pub fn edges(&self, v: VertexId) -> Vec { - self.edges - .iter() - .filter_map(|e| if e.other(v).is_some() { Some(*e) } else { None }) - .collect() - } - - /// Number of faces - pub fn face_count(&self) -> i64 { - 2 + self.edges.len() as i64 - self.vertices.len() as i64 - } - - // Vertices that are connected to a given vertex - pub fn connections(&self, v: VertexId) -> HashSet { - self.edges.iter().filter_map(|e| e.other(v)).collect() - } - - /// All faces - pub fn find_cycles(&mut self) { - let mut triplets = Vec::::new(); - let mut cycles = HashSet::::default(); - - // find all the triplets - for &u in self.vertices.iter() { - let adj: HashSet = self.connections(u); - for &x in adj.iter() { - for &y in adj.iter() { - if x != y && u < x && x < y { - let new_face = Face::new(vec![x, u, y]); - if self.edges.contains(&(x, y).into()) { - cycles.insert(new_face); - } else { - triplets.push(new_face); - } - } - } - } - } - // while there are unparsed triplets - while !triplets.is_empty() && (cycles.len() as i64) < self.face_count() { - let p = triplets.remove(0); - // for each v adjacent to u_t - for v in self.connections(p[p.len() - 1]) { - if v > p[1] { - let c = self.connections(v); - // if v is not a neighbor of u_2..u_t-1 - if !p[1..p.len() - 1].iter().any(|vi| c.contains(vi)) { - let mut new_face = p.clone(); - new_face.push(v); - if self.connections(p[0]).contains(&v) { - //cycles.remo - cycles.insert(new_face); - } else { - triplets.push(new_face); - } - } - } - } - } - - self.cycles = cycles.into_iter().collect(); - } - - pub fn pst(&mut self) { - if self.edges.is_empty() { - return; - } - - let n = self.vertices.len(); - // Vertex - // - // d-queues associated w each vertex - // maps from v -> ( maps from d -> u ) - let mut dqueue: HashMap> = Default::default(); - // - let mut children: HashMap> = Default::default(); - - // Counters for vertices whos shortest paths have already been obtained - let mut counters: HashMap = - self.vertices.iter().map(|v| (*v, n - 1)).collect(); - - // The element D[i, j] represents the distance from v_i to vj. - let mut dist: HashMap = Default::default(); - - // d = 0 - let mut depth = 1; - // while 0 < |V| - loop { - let verts: HashSet = counters - .iter() - .filter_map(|(v, c)| if *c == 0 { None } else { Some(*v) }) - .collect(); - if verts.is_empty() { - break; - } - - let mut removed = false; - - for v in verts.into_iter() { - // for v in V - // START EXTEND(v, d, D, S) - if depth == 1 { - // - for e in self.edges(v) { - // Connected node - let w = e.other(v).unwrap(); - // D[w.id, v.id] = d - dist.insert(e, 1); - // add w' to v'.children - children.entry(v).or_default().push(w); - // v.que.enque(w', 1) - dqueue.entry(v).or_default().push_back((w, 1)); - dqueue.entry(w).or_default().push_back((v, 1)); - // v.c = v.c + 1 - *counters.entry(v).or_default() -= 1; - //*counters.entry(w).or_default() -= 1; - removed = true; - } - } else { - // w = v.que.deque(d - 1) - // while w is not None: - 'dq: loop { - let vqueue = dqueue.entry(v).or_default(); - if let Some((w, d)) = vqueue.pop_front() { - if d != depth - 1 { - dqueue.entry(v).or_default().push_back((w, d)); - break; - } - // for x in w.children - for x in children.entry(w).or_default().clone() { - let e: Edge = (x, v).into(); - if x != v && !dist.contains_key(&e) { - // D[x.id, v.id] = d; - dist.insert(e, depth); - // add x' to w' children - children.entry(w).or_default().push(x); - // v.que.enque(x', d) - dqueue.entry(v).or_default().push_back((x, depth)); - dqueue.entry(x).or_default().push_back((v, depth)); - // v.c = v.c + 1 - removed = true; - *counters.entry(v).or_default() -= 1; - *counters.entry(x).or_default() -= 1; - // if v.c == n: return - if *counters.entry(x).or_default() == 0 - && *counters.entry(w).or_default() == 0 - && *counters.entry(v).or_default() == 0 - { - break 'dq; - } - } - } - } else { - break; - } - } - } - } - // END EXTEND - // d = d + 1 - depth += 1; - - if !removed { - self.dist = dist; - log::error!("failed distance computation"); - return; - } - } - - self.dist = dist; - } - - pub fn springs(&mut self) { - let diameter = { *self.dist.values().max().unwrap_or(&1) }; - self.springs = self - .vertices - .iter() - .flat_map(|&v| self.vertices.iter().map(move |&u| Edge::from((v, u)))) - .filter(|e| e.u() != e.v()) - .filter(|e| self.dist[e] <= 2 || self.dist[e] >= diameter - 1) - .collect::>(); - - log::debug!( - "v_len: {} | v2: {} | springs: {}", - self.vertices.len(), - (self.vertices.len() as f32).powi(2), - self.springs.len() - ); - } -} - -impl Display for PolyGraph { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut vertices = self.vertices.iter().collect::>(); - vertices.sort(); - let mut adjacents = self.edges.clone().into_iter().collect::>(); - adjacents.sort(); - - f.write_fmt(format_args!( - "name:\t\t{}\nvertices:\t{:?}\nadjacents:\t{}\nfaces:\t\t{}\n", - self.name, - vertices, - adjacents - .iter() - .fold(String::new(), |acc, e| format!("{e}, {acc}")), - self.cycles.iter().fold(String::new(), |acc, f| format!( - "[{}], {acc}", - f.iter().fold(String::new(), |acc, x| format!("{x}, {acc}")) - )) - )) - } -} - -#[cfg(test)] -impl PolyGraph { - pub fn floyd(&mut self) { - // let dist be a |V| × |V| array of minimum distances initialized to ∞ (infinity) - let mut dist: HashMap> = self - .vertices - .iter() - .map(|v| { - ( - *v, - self.vertices - .iter() - .map(|u| { - ( - *u, - if u == v { - 0 - } else if self.edges.contains(&(v, u).into()) { - 1 - } else { - u32::MAX - }, - ) - }) - .collect(), - ) - }) - .collect(); - - for k in self.vertices.iter() { - for i in self.vertices.iter() { - for j in self.vertices.iter() { - if dist[i][k] != u32::MAX && dist[k][j] != u32::MAX { - let nv = dist[i][k] + dist[k][j]; - if dist[i][j] > nv || dist[j][i] > nv { - dist.entry(*i).or_default().insert(*j, nv); - dist.entry(*j).or_default().insert(*i, nv); - } - } - } - } - } - - let mut dd = HashMap::default(); - for v in self.vertices.iter() { - for u in self.vertices.iter() { - let dvu = dist[v][u]; - if dvu != u32::MAX && dvu != 0 { - let e = (v, u).into(); - dd.insert(e, dvu as usize); - } - } - } - - self.dist = dd; - } -} - -#[cfg(test)] -mod test { - use crate::bones::{Face, PolyGraph}; - use std::collections::HashSet; - use test_case::test_case; - - #[test_case(PolyGraph::pyramid(3); "T")] - #[test_case(PolyGraph::prism(4); "C")] - #[test_case(PolyGraph::octahedron(); "O")] - #[test_case(PolyGraph::dodecahedron(); "D")] - #[test_case(PolyGraph::icosahedron(); "I")] - #[test_case({ let mut g = PolyGraph::prism(4); g.truncate(None); g.pst(); g} ; "tC")] - #[test_case({ let mut g = PolyGraph::octahedron(); g.truncate(None); g.pst(); g} ; "tO")] - #[test_case({ let mut g = PolyGraph::dodecahedron(); g.truncate(None); g.pst(); g} ; "tD")] - fn pst(mut graph: PolyGraph) { - let new_dist = graph.dist.clone(); - graph.dist = Default::default(); - graph.floyd(); - let old_dist = graph.dist.clone(); - - //assert_eq!(old_dist, graph.dist); - assert_eq!( - old_dist - .clone() - .into_keys() - .collect::>() - .difference(&new_dist.clone().into_keys().collect::>()) - .collect::>(), - HashSet::new() - ); - - let o1 = old_dist - .clone() - .into_iter() - .map(|(k, v)| (k.id().0, k.id().1, v)) - .collect::>(); - let o2 = &new_dist - .clone() - .into_iter() - .map(|(k, v)| (k.id().0, k.id().1, v)) - .collect::>(); - - assert_eq!( - o1.difference(o2).collect::>(), - o2.difference(&o1).collect::>() - ); - assert_eq!(old_dist, new_dist); - } - - #[test] - fn basics() { - let mut graph = PolyGraph::new_disconnected(4); - // Connect - graph.connect((0, 1)); - graph.connect((0, 2)); - graph.connect((1, 2)); - assert_eq!(graph.connections(0), vec![1, 2].into_iter().collect()); - assert_eq!(graph.connections(1), vec![0, 2].into_iter().collect()); - assert_eq!(graph.connections(2), vec![0, 1].into_iter().collect()); - assert_eq!(graph.connections(3), vec![].into_iter().collect()); - - // Disconnect - graph.disconnect((0, 1)); - assert_eq!(graph.connections(0), vec![2].into_iter().collect()); - assert_eq!(graph.connections(1), vec![2].into_iter().collect()); - - // Delete - graph.delete(1); - assert_eq!(graph.connections(0), vec![2].into_iter().collect()); - assert_eq!(graph.connections(1), vec![].into_iter().collect()); - assert_eq!(graph.connections(2), vec![0].into_iter().collect()); - } - - #[test] - fn chordless_cycles() { - let mut graph = PolyGraph::new_disconnected(4); - // Connect - graph.connect((0, 1)); - graph.connect((1, 2)); - graph.connect((2, 3)); - - graph.pst(); - assert_eq!(graph.cycles.len(), 0); - - graph.connect((2, 0)); - graph.pst(); - graph.find_cycles(); - assert_eq!(graph.cycles, vec![Face::new(vec![0, 1, 2])]); - } -} diff --git a/src/bones/polyhedron.rs b/src/bones/polyhedron.rs deleted file mode 100644 index 0bb4ac9b..00000000 --- a/src/bones/polyhedron.rs +++ /dev/null @@ -1,183 +0,0 @@ -use crate::{ - bones::{Edge, PolyGraph, Transaction}, - render::message::ConwayMessage, -}; -use std::time::{Duration, Instant}; -use ultraviolet::{Lerp, Vec3}; - -const SPEED_DAMPENING: f32 = 0.92; - -// Operations -impl PolyGraph { - fn apply_spring_forces(&mut self, speed: f32, second: f32) { - let diameter = *self.dist.values().max().unwrap_or(&1) as f32; - let diameter_spring_length = self.edge_length * 2.0; - let (edges, contracting): (std::collections::hash_set::Iter, bool) = - if let Some(Transaction::Contraction(edges)) = self.transactions.first() { - (edges.iter(), true) - } else { - (self.springs.iter(), false) - }; - - for e in edges { - let v = e.v(); - let u = e.u(); - let v_position = self.positions[&v]; - let u_position = self.positions[&u]; - let diff = v_position - u_position; - let spring_length = diff.mag(); - if contracting { - let f = ((self.edge_length / speed * second) * 10.0) / spring_length; - *self.positions.entry(v).or_default() = v_position.lerp(u_position, f); - *self.positions.entry(u).or_default() = u_position.lerp(v_position, f); - } else { - let target_length = diameter_spring_length * (self.dist[e] as f32 / diameter); - let f = diff * (target_length - spring_length) / speed * second; - *self.speeds.entry(v).or_default() = (self.speeds[&v] + f) * SPEED_DAMPENING; - *self.speeds.entry(u).or_default() = (self.speeds[&u] - f) * SPEED_DAMPENING; - *self.positions.entry(v).or_default() += self.speeds[&v]; - *self.positions.entry(u).or_default() += self.speeds[&u]; - } - } - } - - fn center(&mut self) { - let shift = - self.positions.values().fold(Vec3::zero(), |a, &b| a + b) / self.vertices.len() as f32; - - for (_, v) in self.positions.iter_mut() { - *v -= shift; - } - } - - fn resize(&mut self, speed: f32, second: f32) { - let mean_length = self.positions.values().map(|p| p.mag()).fold(0.0, f32::max); - let distance = mean_length - 1.0; - self.edge_length -= distance / speed * second; - } - - pub fn update(&mut self, speed: f32, second: f32) { - self.center(); - self.resize(speed, second); - self.apply_spring_forces(speed, second); - self.process_transactions(speed); - } - - pub fn face_positions(&self, face_index: usize) -> Vec { - self.cycles[face_index] - .iter() - .map(|v| self.positions[v]) - .collect() - } - - pub fn face_centroid(&self, face_index: usize) -> Vec3 { - // All vertices associated with this face - let vertices: Vec<_> = self.face_positions(face_index); - vertices.iter().fold(Vec3::zero(), |a, &b| a + b) / vertices.len() as f32 - } - - pub fn process_transactions(&mut self, speed: f32) { - if let Some(transaction) = self.transactions.first().cloned() { - use Transaction::*; - match transaction { - Contraction(edges) => { - if !edges - .iter() - .any(|e| (self.positions[&e.v()] - self.positions[&e.u()]).mag() > 0.02) - { - // Contract them in the graph - self.contract_edges(edges); - self.pst(); - self.springs(); - self.transactions.remove(0); - } - } - Release(edges) => { - for e in edges.into_iter() { - self.disconnect(e); - } - self.pst(); - self.springs(); - self.find_cycles(); - self.transactions.remove(0); - } - Conway(conway) => { - self.transactions.remove(0); - use ConwayMessage::*; - use Transaction::*; - let new_transactions = match conway { - Dual => { - let edges = self.expand(false); - vec![ - Wait(Instant::now() + Duration::from_millis((65.0 * speed) as u64)), - Contraction(edges), - Name('d'), - ] - } - Join => { - let edges = self.kis(Option::None); - vec![ - //Wait(Instant::now() + Duration::from_secs(1)), - Release(edges), - Name('j'), - ] - } - Ambo => { - let edges = self.ambo(); - vec![Contraction(edges), Name('a')] - } - Kis => { - self.kis(Option::None); - vec![Name('k')] - } - Truncate => { - self.truncate(Option::None); - vec![Name('t')] - } - Expand => { - self.expand(false); - vec![Name('e')] - } - Snub => { - self.expand(true); - vec![Name('s')] - } - Bevel => { - vec![ - Conway(Truncate), - Wait(Instant::now() + Duration::from_millis(500)), - Conway(Ambo), - Name('b'), - ] - } - }; - self.cycles.sort_by_key(|c| usize::MAX - c.len()); - self.transactions = [new_transactions, self.transactions.clone()].concat(); - self.pst(); - self.springs(); - } - Name(c) => { - if c == 'b' { - self.name = self.name[2..].to_string(); - } - if c == 'd' && &self.name[0..1] == "d" { - self.name = self.name[1..].to_string(); - } else { - self.name = format!("{c}{}", self.name); - } - self.transactions.remove(0); - } - ShortenName(n) => { - self.name = self.name[n..].to_string(); - self.transactions.remove(0); - } - Wait(instant) => { - if Instant::now() > instant { - self.transactions.remove(0); - } - } - None => {} - } - } - } -} diff --git a/src/main.rs b/src/main.rs index cbb683f0..e2472fcf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -mod bones; +mod polyhedron; mod render; use iced::futures::executor::block_on; use render::{App, Graphics}; diff --git a/src/polyhedron/conway.rs b/src/polyhedron/conway.rs new file mode 100644 index 00000000..af5adcfd --- /dev/null +++ b/src/polyhedron/conway.rs @@ -0,0 +1,52 @@ +use crate::polyhedron::{Polyhedron, VertexId}; + +impl Polyhedron { + pub fn split_vertex(&mut self, v: usize) -> Vec<[usize; 2]> { + let Polyhedron { shape, render, .. } = self; + let edges = shape.split_vertex(v); + render.extend(edges.len() - 1, render.positions[v]); + edges + } + + pub fn truncate(&mut self, d: usize) -> Vec<[VertexId; 2]> { + let mut new_edges = Vec::default(); + for v in self.shape.vertices().rev() { + if d == 0 || self.shape.degree(v) == d { + new_edges.extend(self.split_vertex(v)); + self.shape.recompute(); + } + } + new_edges + } + + /// `a` ambo + /// Returns a set of edges to contract + pub fn ambo(&mut self) -> Vec<[VertexId; 2]> { + // Truncate + let new_edges = self.truncate(0); + // Edges that were already there get contracted + self.shape + .edges() + .filter(|&[v, u]| !new_edges.contains(&[v, u]) && !new_edges.contains(&[u, v])) + .collect() + } + + pub fn contract(&mut self, edges: Vec<[VertexId; 2]>) { + self.shape.contract_edges(edges.clone()); + self.render.contract_edges(edges); + } + + pub fn ambo_contract(&mut self) { + let edges = self.ambo(); + self.contract(edges); + log::info!( + "p: {}, d: {}", + self.render.positions.len(), + self.shape.len() + ); + } + + pub fn chamfer(&mut self) { + self.shape.chamfer(); + } +} diff --git a/src/polyhedron/mod.rs b/src/polyhedron/mod.rs new file mode 100644 index 00000000..d68bfedf --- /dev/null +++ b/src/polyhedron/mod.rs @@ -0,0 +1,384 @@ +mod conway; +mod platonic; +mod render; +mod shape; +mod transaction; +use render::*; +use shape::*; +pub use transaction::*; + +// #[cfg(test)] +// mod test; + +use std::{ + collections::HashMap, + time::{Duration, Instant}, +}; + +use crate::render::{ + message::{ConwayMessage, PresetMessage}, + pipeline::{MomentVertex, ShapeVertex}, +}; +use iced_widget::{ + svg, + svg::{Catalog, Handle}, +}; +use ultraviolet::{Vec3, Vec4}; + +pub type VertexId = usize; + +pub const SPEED_DAMPENING: f32 = 0.92; + +#[derive(Debug, Clone)] +pub struct Polyhedron { + /// Conway Polyhedron Notation + pub name: String, + /// The shape we're rendering + shape: Shape, + /// Position data + pub render: Render, + /// Transaction queue + pub transactions: Vec, +} + +impl Polyhedron { + pub fn shape_vertices(&self) -> Vec { + self.shape.cycles.shape_vertices() + } + pub fn starting_vertex(&self) -> VertexId { + match self.shape.cycles[0].len() { + 3 => 3, + 4 => 6, + n => n * 3, + } + } + + pub fn process_transactions(&mut self, _speed: f32) { + if let Some(transaction) = self.transactions.first().cloned() { + use Transaction::*; + match transaction { + Contraction(edges) => { + let Polyhedron { + shape, + render, + transactions, + .. + } = self; + + let all_completed = !edges + .iter() + .map(|&[v, u]| render.spring_length([v, u])) + .any(|l| l > 0.05); + + if all_completed { + // Contract them in the graph + shape.contract_edges(edges.clone()); + render.contract_edges(edges); + transactions.remove(0); + } + } + Release(edges) => { + self.shape.release(&edges); + self.transactions.remove(0); + } + Conway(conway) => { + self.transactions.remove(0); + use ConwayMessage::*; + use Transaction::*; + let new_transactions = match conway { + Dual => { + // let edges = self.expand(false); + // vec![ + // Wait(Instant::now() + Duration::from_millis((65.0 * speed) as u64)), + // Contraction(edges), + // Name('d'), + // ] + todo!() + } + Join => { + // let edges = self.graph.kis(Option::None); + // vec![ + // //Wait(Instant::now() + Duration::from_secs(1)), + // Release(edges), + // Name('j'), + // ] + todo!() + } + Ambo => { + // let edges = self.shape.ambo(); + // self.shape.recompute(); + let edges = self.ambo(); + vec![Contraction(edges), Name('a')] + } + Chamfer => { + self.chamfer(); + vec![Name('c')] + } + Kis => { + // self.graph.kis(Option::None); + // vec![Name('k')] + todo!() + } + SplitVertex(n) => { + self.split_vertex(n); + self.shape.recompute(); + vec![] + } + Truncate => { + // let mut operations = vec![]; + // for v in self.shape.vertices() { + // operations.extend(vec![ + // Wait(Instant::now() + Duration::from_millis(1000) * v as u32), + // Conway(SplitVertex(v)), + // ]); + // } + // [operations, vec![Name('t')]].concat() + self.truncate(0); + vec![Name('t')] + } + Expand => { + self.ambo_contract(); + let edges = self.ambo(); + // self.shape.expand(false); + vec![Contraction(edges), Name('e')] + } + Snub => { + // self.graph.expand(true); + // vec![Name('s')] + todo!() + } + Bevel => { + vec![ + Conway(Truncate), + Wait(Instant::now() + Duration::from_millis(500)), + Conway(Ambo), + Name('b'), + ] + } + }; + self.render.new_capacity(self.shape.len()); + self.transactions = [new_transactions, self.transactions.clone()].concat(); + } + Name(c) => { + if c == 'b' { + self.name = self.name[2..].to_string(); + } + if c == 'd' && &self.name[0..1] == "d" { + self.name = self.name[1..].to_string(); + } else { + self.name = format!("{c}{}", self.name); + } + self.transactions.remove(0); + } + ShortenName(n) => { + self.name = self.name[n..].to_string(); + self.transactions.remove(0); + } + Wait(instant) => { + if Instant::now() > instant { + self.transactions.remove(0); + } + } + None => {} + }; + self.shape.compute_graph_svg(); + } + } + + pub fn update(&mut self, speed: f32, second: f32) { + self.render.update(speed, second); + self.apply_spring_forces(speed, second); + self.process_transactions(speed); + } + + fn apply_spring_forces(&mut self, speed: f32, second: f32) { + let Polyhedron { + shape, + render, + transactions, + .. + } = self; + //let diameter = shape.diameter(); + let diameter_spring_length = render.edge_length * 2.0; + + // If we're contracting, we end up working with a more narrow set of edges + let (edges, contracting): (std::slice::Iter<[VertexId; 2]>, bool) = + if let Some(Transaction::Contraction(edges)) = transactions.first() { + (edges.iter(), true) + } else { + (shape.springs.iter(), false) + }; + + for &[v, u] in edges { + let spring_length = render.spring_length([v, u]); + if contracting && spring_length > 0.05 { + let f = ((render.edge_length / speed * second) * 10.0) / spring_length; + render.lerp([v, u], f); + } else { + //let diff = render.positions[v] - render.positions[u]; + let target_length = diameter_spring_length * shape.diameter_percent([v, u]); + let f = (target_length - spring_length) / speed * second; + render.apply_scalar([v, u], f); + } + } + } + + // pub fn preset(preset: &PresetMessage) -> Polyhedron { + // let shape = Shape::preset(preset); + // let render = Render::new(shape.len()); + // Polyhedron { + // name: preset.to_string(), + // shape, + // render, + // transactions: vec![], + // } + // } + + pub fn face_centroid(&self, face_index: usize) -> Vec3 { + // All vertices associated with this face + self.shape.cycles[face_index] + .iter() + .map(|&v| self.render.positions[v]) + .fold(Vec3::zero(), |a, b| a + b) + / self.shape.cycles[face_index].len() as f32 + } + + pub fn moment_vertices(&self, colors: &[crate::render::color::RGBA]) -> Vec { + let Polyhedron { shape, render, .. } = self; + + // Polygon side count -> color + let color_map: HashMap = + shape.cycles.iter().fold(HashMap::new(), |mut acc, c| { + if !acc.contains_key(&c.len()) { + acc.insert(c.len(), colors[acc.len() % colors.len()].into()); + } + acc + }); + + shape + .cycles + .iter() + .flat_map(|cycle| { + let positions: Vec = match cycle.len() { + 3 => cycle.iter().map(|&i| render.positions[i]).collect(), + 4 => [0, 1, 2, 2, 3, 0] + .iter() + .map(move |&i| render.positions[cycle[i]]) + .collect(), + _ => { + let centroid: Vec3 = cycle + .iter() + .map(|&c| render.positions[c]) + .fold(Vec3::zero(), std::ops::Add::add) + / cycle.len() as f32; + + (0..cycle.len()) + .flat_map(move |i| { + vec![ + render.positions[cycle[i]], + centroid, + render.positions[cycle[i + 1]], + ] + }) + .collect() + } + }; + + // Colors are determined by cycle length + let color = color_map[&cycle.len()]; + // Map into MomentVertices + positions + .into_iter() + .map(move |position| MomentVertex::new(position, color)) + }) + .collect() + } + + pub fn svg<'a, T: Catalog>(&self) -> iced_widget::Svg<'a, T> { + svg(Handle::from_memory(self.shape.svg.clone())) + } + // fn face_positions(&self, face_index: usize) -> Vec { + // self.shape.cycles[face_index] + // .iter() + // .map(|&v| self.render.vertices[v].position) + // .collect() + // } + // Use a Fibonacci Lattice to spread the points evenly around a sphere + // pub fn connect(&mut self, [v, u]: [VertexId; 2]) { + // self.graph.connect([v, u]); + // } + // + // pub fn disconnect(&mut self, [v, u]: [VertexId; 2]) { + // self.graph.disconnect([v, u]); + // } + // + // pub fn insert(&mut self) -> VertexId { + // self.positions + // .push(Vec3::new(random(), random(), random()).normalized()); + // self.speeds.push(Vec3::zero()); + // self.graph.insert() + // } + + // pub fn delete(&mut self, v: VertexId) { + // self.vertices.remove(&v); + // + // self.edges = self + // .edges + // .clone() + // .into_iter() + // .filter(|e| !e.contains(v)) + // .collect(); + // + // self.cycles = self + // .cycles + // .clone() + // .into_iter() + // .map(|face| face.into_iter().filter(|&u| u != v).collect()) + // .collect(); + // + // self.positions.remove(&v); + // self.speeds.remove(&v); + // } + // + // /// Edges of a vertex + // pub fn edges(&self, v: VertexId) -> Vec { + // let mut edges = vec![]; + // for u in 0..self.dist.len() { + // if self.dist[v][u] == 1 { + // edges.push((v, u).into()); + // } + // } + // edges + // } + + // /// Number of faces + // pub fn face_count(&self) -> i64 { + // 2 + self.edges.len() as i64 - self.vertices.len() as i64 + // } + + // + // + // +} + +// impl Display for PolyGraph { +// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +// let mut vertices = self.vertices.iter().collect::>(); +// vertices.sort(); +// let mut adjacents = self.edges.clone().into_iter().collect::>(); +// adjacents.sort(); +// +// f.write_fmt(format_args!( +// "name:\t\t{}\nvertices:\t{:?}\nadjacents:\t{}\nfaces:\t\t{}\n", +// self.name, +// vertices, +// adjacents +// .iter() +// .fold(String::new(), |acc, e| format!("{e}, {acc}")), +// self.cycles.iter().fold(String::new(), |acc, f| format!( +// "[{}], {acc}", +// f.iter().fold(String::new(), |acc, x| format!("{x}, {acc}")) +// )) +// )) +// } +// } diff --git a/src/polyhedron/platonic.rs b/src/polyhedron/platonic.rs new file mode 100644 index 00000000..6f0dc247 --- /dev/null +++ b/src/polyhedron/platonic.rs @@ -0,0 +1,61 @@ +use super::*; + +impl Polyhedron { + pub fn preset(preset: &PresetMessage) -> Polyhedron { + use PresetMessage::*; + let mut poly = match preset { + Octahedron => Self::octahedron(), + Dodecahedron => Self::dodecahedron(), + Icosahedron => todo!(), + _ => { + let shape = match preset { + Prism(n) => Shape::prism(*n), + AntiPrism(n) => Shape::anti_prism(*n), + Pyramid(n) => Shape::pyramid(*n), + _ => todo!(), + }; + + let render = Render::new(shape.len()); + + Polyhedron { + name: preset.to_string(), + shape, + render, + transactions: vec![], + } + } + }; + poly.shape.compute_graph_svg(); + poly + } + + fn octahedron() -> Polyhedron { + let mut polyhedron = Polyhedron::preset(&PresetMessage::Pyramid(3)); + polyhedron.ambo_contract(); + polyhedron + } + + fn dodecahedron() -> Polyhedron { + // polyhedron.ambo_contract(); + // let edges = polyhedron.truncate(0); + //polyhedron.contract(edges); + // polyhedron.truncate(5); + Polyhedron::preset(&PresetMessage::AntiPrism(5)) + } + + // + // pub fn icosahedron() -> Distance { + // let mut graph = Distance::anti_prism(5); + // graph.kis(Some(5)); + // graph + // } + // + // pub fn icosahedron() -> Distance { + // let dodecahedron = Self::dodecahedron(); + // //let edges = dodecahedron.ambo(); + // //dodecahedron.contract_edges(edges); + // #[cfg(test)] + // dodecahedron.render("tests/", "icosahedron.svg"); + // dodecahedron + // } +} diff --git a/src/polyhedron/render.rs b/src/polyhedron/render.rs new file mode 100644 index 00000000..493bf011 --- /dev/null +++ b/src/polyhedron/render.rs @@ -0,0 +1,122 @@ +use rand::random; +use ultraviolet::{Lerp as _, Vec3}; + +use super::{VertexId, SPEED_DAMPENING}; + +#[derive(Debug, Clone)] +pub struct Render { + /// Positions in 3D space + pub positions: Vec, + /// Speeds in 3D space + pub speeds: Vec, + /// Edge length + pub edge_length: f32, +} + +//impl rand:: +pub fn random_positions(n: usize) -> Vec { + (0..n) + .map(|_| Vec3::new(random(), random(), random()).normalized()) + .collect() +} + +impl Render { + pub fn new(n: usize) -> Self { + Self { + positions: random_positions(n), + speeds: vec![Vec3::zero(); n], + edge_length: 1.0, + } + } + + pub fn update(&mut self, speed: f32, second: f32) { + self.center(); + self.resize(speed, second); + } + + fn center(&mut self) { + let shift = + self.positions.iter().fold(Vec3::zero(), |a, &b| a + b) / self.positions.len() as f32; + log::debug!("shifting all positions by {shift:?}"); + + for p in self.positions.iter_mut() { + *p -= shift; + } + } + + fn resize(&mut self, speed: f32, second: f32) { + let mean_length = self.positions.iter().map(Vec3::mag).fold(0.0, f32::max); + let matrixance = mean_length - 1.0; + self.edge_length -= matrixance / speed * second; + } + + pub fn new_capacity(&mut self, n: usize) { + if n > self.positions.len() { + let difference = n - self.positions.len(); + self.positions.extend(random_positions(difference)); + self.speeds.extend(vec![Vec3::zero(); difference]); + } + } + + pub fn extend(&mut self, n: usize, position: Vec3) { + self.positions.extend(vec![position; n]); + self.speeds.extend(vec![Vec3::zero(); n]); + } + + pub fn spring_length(&self, [v, u]: [VertexId; 2]) -> f32 { + (self.positions[v] - self.positions[u]).mag() + } + + pub fn lerp(&mut self, [v, u]: [VertexId; 2], f: f32) { + self.positions[v] = self.positions[v].lerp(self.positions[u], f); + self.positions[u] = self.positions[u].lerp(self.positions[v], f); + } + + // pub fn lattice(&mut self) { + // self.vertices = vec![]; + // // Use a Fibonacci Lattice to evently distribute starting points on a sphere + // let phi = std::f32::consts::PI * (3.0 - 5.0f32.sqrt()); + // for v in 0..self.graph.len() { + // let y = 1.0 - (v as f32 / (self.graph.len() - 1) as f32); + // let radius = (1.0 - y * y).sqrt(); + // let theta = (phi * (v as f32)) % (std::f32::consts::PI * 2.0); + // let x = theta.cos() * radius; + // let z = theta.sin() * radius; + // self.positions.push(Vec3::new(x, y, z)); + // } + // } + // + + pub fn apply_scalar(&mut self, [v, u]: [VertexId; 2], scalar: f32) { + let diff = self.positions[v] - self.positions[u]; + let delta = diff * scalar; + self.speeds[v] = (self.speeds[v] + delta) * SPEED_DAMPENING; + self.speeds[u] = (self.speeds[u] - delta) * SPEED_DAMPENING; + self.positions[v] += self.speeds[v]; + self.positions[u] += self.speeds[u]; + } + + pub fn contract_edges(&mut self, mut edges: Vec<[VertexId; 2]>) { + // let mut transformed = HashSet::default(); + while !edges.is_empty() { + // Pop an edge + let [w, x] = edges.remove(0); + let v = w.max(x); + let _u = w.min(x); + // if transformed.contains(&v) && transformed.contains(&u) {} + + self.positions.remove(v); + self.speeds.remove(v); + // transformed.insert(v); + + for [x, w] in &mut edges { + if *x > v { + *x -= 1; + } + if *w > v { + *w -= 1; + } + } + } + } +} diff --git a/src/polyhedron/shape/conway.rs b/src/polyhedron/shape/conway.rs new file mode 100644 index 00000000..e60d9f83 --- /dev/null +++ b/src/polyhedron/shape/conway.rs @@ -0,0 +1,62 @@ +use super::{Cycles, Shape}; +use crate::polyhedron::VertexId; + +impl Shape { + pub fn split_vertex(&mut self, v: VertexId) -> Vec<[usize; 2]> { + let sc = self.cycles.sorted_connections(v); + let edges = self.distance.split_vertex(v, sc); + self.cycles = Cycles::from(&self.distance); + edges + } + + pub fn contract_edges(&mut self, edges: Vec<[VertexId; 2]>) { + self.distance.contract_edges(edges); + self.recompute(); + } + + #[allow(dead_code)] + pub fn kis(&mut self, degree: Option) -> Vec<[VertexId; 2]> { + let edges = self.distance.edges().collect(); + // let mut cycles = self.cycles.clone(); + if let Some(degree) = degree { + self.cycles + .iter() + .collect::>() + .retain(|c| c.len() == degree); + } + for cycle in self.cycles.iter() { + let v = self.distance.insert(); + // let mut vpos = Vec3::zero(); + + for &u in cycle.iter() { + self.distance.connect([v, u]); + //vpos += self.positions[&u]; + } + + //self.positions.insert(v, vpos / cycle.len() as f32); + } + + self.recompute(); + edges + } + + pub fn chamfer(&mut self) { + let originals = self.edges().collect::>(); + for cycle in self.cycles.iter() { + let mut new_face = vec![]; + for &v in cycle.iter() { + let u = self.distance.insert(); + new_face.push(u); + self.distance.connect([v, u]); + } + for i in 0..new_face.len() { + self.distance + .connect([new_face[i], new_face[(i + 1) % new_face.len()]]); + } + } + for edge in originals { + self.distance.disconnect(edge); + } + self.recompute(); + } +} diff --git a/src/polyhedron/shape/cycles/cycle.rs b/src/polyhedron/shape/cycles/cycle.rs new file mode 100644 index 00000000..2ad7962d --- /dev/null +++ b/src/polyhedron/shape/cycles/cycle.rs @@ -0,0 +1,107 @@ +use crate::polyhedron::VertexId; +use std::ops::{Index, IndexMut}; + +#[derive(Default, Debug, Clone)] +pub struct Cycle(pub(super) Vec); + +impl Index for Cycle { + type Output = VertexId; + + fn index(&self, index: usize) -> &Self::Output { + &self.0[index.rem_euclid(self.0.len())] + } +} + +impl IndexMut for Cycle { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + let i = index.rem_euclid(self.0.len()); + &mut self.0[i] + } +} + +impl Cycle { + pub fn from(vertices: Vec) -> Self { + Self(vertices) + } + + pub fn len(&self) -> usize { + self.0.len() + } + + #[allow(dead_code)] + pub fn delete(&mut self, v: VertexId) { + self.0 = self + .0 + .clone() + .into_iter() + .filter_map(|u| { + use std::cmp::Ordering::*; + match v.cmp(&u) { + Equal => None, + Less => Some(u - 1), + Greater => Some(u), + } + }) + .collect::>(); + } + + #[allow(dead_code)] + pub fn replace(&mut self, old: VertexId, new: VertexId) { + self.0 = self + .0 + .clone() + .into_iter() + .filter_map(|v| { + if v == new { + None + } else if v == old { + Some(new) + } else { + Some(v) + } + }) + .collect(); + } + + pub fn iter(&self) -> std::slice::Iter<'_, usize> { + self.0.iter() + } + + #[allow(dead_code)] + pub fn contains(&self, v: &VertexId) -> bool { + self.0.contains(v) + } + + #[allow(dead_code)] + pub fn push(&mut self, v: VertexId) { + self.0.push(v); + } +} + +impl From> for Cycle { + fn from(mut edges: Vec<[VertexId; 2]>) -> Self { + let mut first = false; + let mut face = vec![edges[0][0]]; + while !edges.is_empty() { + let v = if first { + *face.first().unwrap() + } else { + *face.last().unwrap() + }; + if let Some(i) = edges.iter().position(|e| e.contains(&v)) { + let next = if edges[i][0] == v { + edges[i][1] + } else { + edges[i][0] + }; + if !face.contains(&next) { + face.push(next); + } + edges.remove(i); + } else { + first ^= true; + } + } + Self(face) + } +} diff --git a/src/polyhedron/shape/cycles/mod.rs b/src/polyhedron/shape/cycles/mod.rs new file mode 100644 index 00000000..e7eb0dc5 --- /dev/null +++ b/src/polyhedron/shape/cycles/mod.rs @@ -0,0 +1,227 @@ +mod cycle; +use crate::{polyhedron::VertexId, render::pipeline::ShapeVertex}; +pub use cycle::*; +use std::{ + collections::HashSet, + ops::{Index, IndexMut}, +}; +use ultraviolet::{Vec3, Vec4}; + +use super::Distance; + +#[derive(Default, Debug, Clone)] +pub(in super::super) struct Cycles { + // Circular lists of Vertex Ids representing faces + cycles: Vec, +} + +impl Cycles { + pub fn new(cycles: Vec>) -> Self { + Self { + cycles: cycles.into_iter().map(Cycle).collect(), + } + } + + #[allow(dead_code)] + pub fn len(&self) -> usize { + self.cycles.len() + } + + pub fn iter(&self) -> std::slice::Iter<'_, Cycle> { + self.cycles.iter() + } + + #[allow(dead_code)] + pub fn into_iter(self) -> std::vec::IntoIter { + self.cycles.into_iter() + } + /// Returns the + pub fn sorted_connections(&self, v: VertexId) -> Vec { + // We only care about cycles that contain the vertex + let mut relevant = self + .iter() + .filter_map(move |cycle| { + cycle + .iter() + .position(|&x| x == v) + .map(|p| [cycle[p + cycle.len() - 1], cycle[p + 1]]) + }) + .collect::>(); + + let mut sorted_connections = vec![relevant[0][0]]; + loop { + let previous = sorted_connections.last().unwrap(); + match relevant + .iter() + .position(|[v, u]| v == previous || u == previous) + { + Some(i) => { + let [v, u] = relevant.remove(i); + let next = if v == *previous { u } else { v }; + sorted_connections.push(next); + } + None => { + break; + } + } + } + + sorted_connections[1..].to_vec() + } + pub fn shape_vertices(&self) -> Vec { + let barycentric = [Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z()]; + self.iter() + .map(|cycle| { + let sides: Vec4 = match cycle.len() { + 3 => Vec3::new(1.0, 1.0, 1.0), + 4 => Vec3::new(1.0, 0.0, 1.0), + _ => Vec3::new(0.0, 1.0, 0.0), + } + .into(); + + let b_shapes: Vec = barycentric + .iter() + .map(|&b| ShapeVertex { + barycentric: b.into(), + sides, + }) + .collect(); + + match cycle.len() { + 3 => b_shapes.clone(), + 4 => (0..6) + .map(|i| ShapeVertex { + barycentric: barycentric[i % 3].into(), + sides, + }) + .collect(), + _ => vec![b_shapes; cycle.len()].concat(), + } + }) + .collect::>>() + .concat() + } +} + +impl Index for Cycles { + type Output = Cycle; + + fn index(&self, index: usize) -> &Self::Output { + &self.cycles[index.rem_euclid(self.cycles.len())] + } +} + +impl IndexMut for Cycles { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + let len = self.cycles.len(); + &mut self.cycles[index.rem_euclid(len)] + } +} + +impl Cycles { + #[allow(dead_code)] + pub fn delete(&mut self, v: VertexId) { + for cycle in &mut self.cycles { + cycle.delete(v); + } + } + + /// Replace all occurrence of one vertex with another + #[allow(dead_code)] + pub fn replace(&mut self, old: VertexId, new: VertexId) { + for cycle in &mut self.cycles { + cycle.replace(old, new); + } + } +} + +impl From<&Distance> for Cycles { + fn from(distance: &Distance) -> Self { + let mut triplets: Vec> = Default::default(); + let mut cycles: HashSet> = Default::default(); + // let mut edge_incidents: Distance = distance.clone(); + // for [v, u] in edge_incidents.vertex_pairs() { + // if edge_incidents[[v, u]] == 1 { + // edge_incidents[[v, u]] = 0; + // } else { + // edge_incidents[[v, u]] = usize::MAX; + // } + // } + // println!("distance:\n{distance}"); + // println!("edge_incidents_starting:\n{edge_incidents}"); + + // find all the triplets + for u in 0..distance.len() { + for x in (u + 1)..distance.len() { + for y in (x + 1)..distance.len() { + if distance[[u, x]] == 1 && distance[[u, y]] == 1 { + if distance[[x, y]] == 1 { + cycles.insert(vec![x, u, y]); + // edge_incidents[[x, u]] += 1; + // edge_incidents[[u, y]] += 1; + // edge_incidents[[y, x]] += 1; + } else { + triplets.push(vec![x, u, y]); + } + } + } + } + } + // find all the triplets + // for u in distance.vertices() { + // let adj: Vec = distance.connections(u); + // for &x in adj.iter() { + // for &y in adj.iter() { + // if u < x && x < y { + // let new_face = vec![x, u, y]; + // if distance[[x, y]] == 1 { + // cycles.insert(new_face); + // } else { + // triplets.push(new_face); + // } + // } + // } + // } + // } + // println!("triplets:\n{triplets:?}"); + // println!("cycles:\n{cycles:?}"); + + // while there are unparsed triplets + while !triplets.is_empty() && (cycles.len() as i64) < distance.face_count() { + let p = triplets.remove(0); + + // for each v adjacent to u_t + for v in distance.connections(p[p.len() - 1]) { + if v > p[1] { + let adj_v = distance.connections(v); + // if v is not a neighbor of u_2..u_t-1 + if !p[1..p.len() - 1].iter().any(|i| adj_v.contains(i)) { + // let mut new_face = p.clone(); + // new_face.push(v); + let new = [p.clone(), vec![v]].concat(); + if distance.connections(p[0]).contains(&v) { + // if edge_incidents[[p[0], v]] >= 2 { + // log::info!("i was about to send {new:?} but [{}, {}] is already greater than 2", p[0], v) + // } else { + // for i in 0..new.len() { + // edge_incidents[[new[i], new[(i + 1) % new.len()]]] += 1; + // } + if distance.cycle_is_face(new.clone()) { + cycles.insert(new); + } else { + // println!("i was going to insert {new:?} but it's not a valid face"); + } + // } + } else { + triplets.push(new); + } + } + } + } + } + + let mut cycles = cycles.into_iter().collect::>(); + cycles.sort_by_key(|c| usize::MAX - c.len()); + Cycles::new(cycles) + } +} diff --git a/src/polyhedron/shape/distance/conway.rs b/src/polyhedron/shape/distance/conway.rs new file mode 100644 index 00000000..15b6a2ff --- /dev/null +++ b/src/polyhedron/shape/distance/conway.rs @@ -0,0 +1,149 @@ +use super::Distance; +use crate::polyhedron::shape::Cycle; +use crate::polyhedron::VertexId; + +impl Distance { + pub(super) fn contract_edge(&mut self, [v, u]: [VertexId; 2]) { + // Give u all the same connections as v + for w in self.connections(v).into_iter() { + self.connect([w, u]); + self.disconnect([w, v]); + } + + // // Delete a + // for cycle in self.cycles.iter_mut() { + // cycle.replace(v, u); + // } + + // Delete v + self.delete(v); + } + + pub fn contract_edges(&mut self, mut edges: Vec<[VertexId; 2]>) { + // let mut transformed = HashSet::default(); + while !edges.is_empty() { + // Pop an edge + let [w, x] = edges.remove(0); + let v = w.max(x); + let u = w.min(x); + + // // If this is not a redundant edge + // if !(transformed.contains(&v) && transformed.contains(&u)) { + + // Contract [v, u], deleting v + self.contract_edge([v, u]); + + // // Mark that this vertex has been transformed + // transformed.insert(v); + + // Decrement the value of every vertex + for [x, w] in &mut edges { + if *x > v { + *x -= 1; + } + if *w > v { + *w -= 1; + } + } + } + } + + // pub fn contract_edges(&mut self, mut edges: Vec<[VertexId; 2]>) { + // let mut map = HashMap::::default(); + // for [v, u] in edges.into_iter() { + // let u = *map.get(&u).unwrap_or(&u); + // let v = *map.get(&v).unwrap_or(&v); + // if v != u { + // //self.contract_edge([v, u]); + // map.insert(v, u); + // } + // } + // println!("map: {map:?}"); + // } + + pub fn split_vertex(&mut self, v: VertexId, connections: Vec) -> Vec<[VertexId; 2]> { + // Remove the vertex + let new_cycle: Cycle = Cycle::from( + vec![v] + .into_iter() + .chain((1..connections.len()).map(|_| self.insert())) + .collect(), + ); + + for c in &connections { + self.disconnect([v, *c]); + } + + for i in 0..new_cycle.len() { + self.connect([new_cycle[i], connections[i]]); + } + + // track the edges that will compose the new face + let mut new_edges = vec![]; + for i in 0..new_cycle.len() { + let edge = [new_cycle[i], new_cycle[i + 1]]; + self.connect(edge); + new_edges.push(edge); + } + + new_edges + } + + pub fn cycle_is_face(&self, mut cycle: Vec) -> bool { + let mut dupe = self.clone(); + while !cycle.is_empty() { + let v = cycle.remove(0); + dupe.delete(v); + for u in &mut cycle { + if *u > v { + *u -= 1; + } + } + } + dupe.is_connected() + } + + // // + // pub fn ordered_face_indices(&self, v: VertexId) -> Vec { + // let relevant = (0..self.cycles.len()) + // .filter(|&i| self.cycles[i].containz(&v)) + // .collect::>(); + // + // let mut edges = HashMap::default(); + // + // for &i in relevant.iter() { + // let ui = self.cycles[i].iter().position(|&x| x == v).unwrap(); + // let flen = self.cycles[i].len(); + // // Find the values that came before and after in the face + // let a = self.cycles[i][(ui + flen - 1) % flen]; + // let b = self.cycles[i][(ui + 1) % flen]; + // edges.insert((a, b).into(), i); + // } + // + // let f: Cycle = edges.keys().cloned().collect::>().into(); + // + // let mut ordered_face_indices = vec![]; + // for i in 0..f.len() { + // let ev = f[i]; + // let eu = f[(i + 1) % f.len()]; + // let fi = edges + // .get(&[ev, eu]) + // .unwrap_or(edges.get(&[eu, ev]).unwrap()); + // ordered_face_indices.push(*fi); + // } + // + // ordered_face_indices + // } + // // + + // /// `e` = `aa` + + // + // `j` join + // `z` zip + // `g` gyro + // `m` meta = `kj` + // `o` ortho = `jj` + // `n` needle + // `k` kis +} diff --git a/src/polyhedron/shape/distance/mod.rs b/src/polyhedron/shape/distance/mod.rs new file mode 100644 index 00000000..d7013e47 --- /dev/null +++ b/src/polyhedron/shape/distance/mod.rs @@ -0,0 +1,277 @@ +mod conway; +mod platonic; +mod svg; + +// #[cfg(test)] +// mod test; + +use crate::polyhedron::VertexId; +use std::collections::HashSet; +use std::{ + collections::VecDeque, + fmt::Display, + ops::{Index, IndexMut, Range}, +}; + +/// Jagged array which represents the symmetrix distance matrix of a given Graph +/// usize::MAX -> disconnected +/// 0 -> identity +/// n -> actual distance +#[derive(Debug, Default, Clone, PartialEq)] +pub(super) struct Distance { + distance: Vec>, +} + +impl Distance { + /// [ 0 ] + /// [ M | 0 ] + /// [ M | M | 0 ] + /// .. + /// [ M | M | M | ... | M | M | M | 0 ] + pub fn new(n: usize) -> Self { + Distance { + distance: (0..n) + .map(|m| [vec![usize::MAX; m], vec![0]].concat()) + .collect(), + } + } +} + +impl Distance { + /// Connect one vertex to another with length one, iff they are note the same point + pub fn connect(&mut self, [v, u]: [VertexId; 2]) { + if self[[v, u]] != 0 { + self[[v, u]] = 1; + } + } + + /// Disconnect one vertex from another iff they are neighbors + pub fn disconnect(&mut self, [v, u]: [VertexId; 2]) { + if self[[v, u]] == 1 { + self[[v, u]] = usize::MAX; + } + } + + /// Inserts a new vertex in the matrix + pub fn insert(&mut self) -> VertexId { + self.distance + .push([vec![usize::MAX; self.len()], vec![0]].concat()); + self.len() - 1 + } + + /// Deletes a vertex from the matrix + pub fn delete(&mut self, v: VertexId) { + for row in &mut self.distance[v..] { + row.remove(v); + } + self.distance.remove(v); + } + + /// Enumerates the vertices connected to v + pub fn connections(&self, v: VertexId) -> Vec { + self.vertices().filter(|&u| self[[v, u]] == 1).collect() + } + + /// Iterable Range representing vertex IDs + pub fn vertices(&self) -> Range { + 0..self.distance.len() + } + + /// All possible compbinations of vertices + pub fn vertex_pairs(&self) -> impl Iterator { + self.vertices().flat_map(|v| (0..v).map(move |u| [v, u])) + } + + /// All actual edges of the graph (D_{ij} = 1) + pub fn edges(&self) -> impl Iterator + use<'_> { + self.vertex_pairs().filter(move |&e| self[e] == 1) + } + + /// Vertex Count + pub fn len(&self) -> usize { + self.distance.len() + } + + /// Maximum distance value + pub fn diameter(&self) -> usize { + self.vertex_pairs().map(|e| self[e]).max().unwrap_or(0) + } + + fn dfs(&self, visited: &mut HashSet, v: usize) { + visited.insert(v); + for u in self.connections(v) { + if !visited.contains(&u) { + self.dfs(visited, u); + } + } + } + + pub fn is_connected(&self) -> bool { + let mut visited = HashSet::new(); + self.dfs(&mut visited, 0); + visited.len() == self.len() + } + + pub fn pst(&mut self) -> Option<()> { + for x in self.vertex_pairs() { + if self[x] != 1 { + self[x] = usize::MAX; + } + } + // if self.edges.is_empty() { + // return; + // } + + let n = self.len(); + // Vertex + // + // d-queues associated w each vertex + // maps from v -> ( maps from d -> u ) + let mut dqueue: Vec> = vec![Default::default(); self.len()]; + // + let mut children: Vec> = vec![Default::default(); self.len()]; + + // Counters for vertices whos shortest paths have already been obtained + let mut counters: Vec = vec![n - 1; self.len()]; + + // The element D[i, j] represents the distance from v_i to vj. + let mut dist: Distance = Distance::new(self.len()); + + // d = 0 + let mut depth = 1; + // while 0 < |V| + loop { + let verts: HashSet = counters + .iter() + .enumerate() + .filter_map(|(v, c)| if *c == 0 { None } else { Some(v) }) + .collect(); + + if verts.is_empty() { + break; + } + + let mut removed = false; + + for v in verts.into_iter() { + // for v in V + // START EXTEND(v, d, D, S) + if depth == 1 { + // + for w in self.connections(v) { + // Connected node + // D[w.id, v.id] = d + dist[[v, w]] = 1; + // add w' to v'.children + children[v].push(w); + // v.que.enque(w', 1) + dqueue[v].push_back((w, 1)); + dqueue[w].push_back((v, 1)); + // v.c = v.c + 1 + counters[v] -= 1; + removed = true; + } + } else { + // w = v.que.deque(d - 1) + // while w is not None: + 'dq: loop { + // let vqueue = dqueue[v]; + let Some((w, d)) = dqueue[v].pop_front() else { + break; + }; + if d != depth - 1 { + dqueue[v].push_back((w, d)); + break; + } + // for x in w.children + for x in children[w].clone() { + //let e: Edge = (x, v).into(); + if x != v && dist[[x, v]] == usize::MAX { + // D[x.id, v.id] = d; + dist[[x, v]] = depth; + // add x' to w' children + children[w].push(x); + // v.que.enque(x', d) + dqueue[v].push_back((x, depth)); + dqueue[x].push_back((v, depth)); + // v.c = v.c + 1 + removed = true; + counters[v] -= 1; + counters[x] -= 1; + // if v.c == n: return + if counters[x] == 0 && counters[w] == 0 && counters[v] == 0 { + break 'dq; + } + } + } + } + } + } + // END EXTEND + // d = d + 1 + depth += 1; + + if !removed { + *self = dist; + log::error!("failed distance computation"); + return None; + } + } + + *self = dist; + Some(()) + } + + pub fn springs(&self) -> Vec<[VertexId; 2]> { + let diameter = self.diameter(); + self.vertex_pairs() + .filter(|&[v, u]| v != u && (self[[v, u]] <= 2 || self[[v, u]] >= diameter - 1)) + .collect::>() + } + + /// Number of faces + pub fn face_count(&self) -> i64 { + 2 + self.edges().count() as i64 - self.len() as i64 + } +} + +impl Index<[VertexId; 2]> for Distance { + type Output = usize; + + fn index(&self, index: [VertexId; 2]) -> &Self::Output { + &self.distance[index[0].max(index[1])][index[0].min(index[1])] + } +} + +impl IndexMut<[VertexId; 2]> for Distance { + fn index_mut(&mut self, index: [VertexId; 2]) -> &mut Self::Output { + &mut self.distance[index[0].max(index[1])][index[0].min(index[1])] + } +} + +impl Display for Distance { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!("\t|"))?; + for i in 0..self.len() { + f.write_fmt(format_args!(" {i} |"))?; + } + f.write_fmt(format_args!("\n\t"))?; + for _ in 0..self.len() { + f.write_fmt(format_args!("____"))?; + } + f.write_fmt(format_args!("\n"))?; + for v in self.vertices() { + f.write_fmt(format_args!("{v}:\t|"))?; + for u in self.vertices() { + let value = if self[[v, u]] == usize::MAX { + String::from("_") + } else { + self[[v, u]].to_string() + }; + f.write_fmt(format_args!(" {value} |"))?; + } + f.write_fmt(format_args!("\n"))?; + } + Ok(()) + } +} diff --git a/src/polyhedron/shape/distance/platonic.rs b/src/polyhedron/shape/distance/platonic.rs new file mode 100644 index 00000000..7a859445 --- /dev/null +++ b/src/polyhedron/shape/distance/platonic.rs @@ -0,0 +1,55 @@ +// use crate::render::message::PresetMessage; + +use super::*; +/* + T = Y3 + O = aT (ambo tetrahedron) + C = jT (join tetrahedron) + I = sT (snub tetrahedron) + D = gT (gyro tetrahedron) +*/ + +// Platonic Solids +impl Distance { + pub fn prism(n: usize) -> Distance { + let mut graph = Distance::new(n * 2); + //p.name = format!("P{n}"); + for i in 0..n { + // Lower polygon + graph.connect([i % n, (i + 1) % n]); + // Upper polygon + graph.connect([(i % n) + n, ((i + 1) % n) + n]); + // Connect + graph.connect([(i % n), (i % n) + n]); + graph.connect([(i + 1) % n, ((i + 1) % n) + n]); + } + graph + } + + pub fn anti_prism(n: usize) -> Distance { + let mut graph = Distance::new(n * 2); + //p.name = format!("A{n}"); + for i in 0..n { + // Lower polygon + graph.connect([i % n, (i + 1) % n]); + // Upper polygon + graph.connect([(i % n) + n, ((i + 1) % n) + n]); + // Connect + graph.connect([(i % n), (i % n) + n]); + graph.connect([(i + 1) % n, ((i + 1) % n) + n]); + + graph.connect([(i % n), ((i + 1) % n) + n]); + } + graph + } + + pub fn pyramid(n: usize) -> Distance { + let mut graph = Distance::new(n + 1); + //graph.name = format!("Y{n}"); + for i in 0..n { + graph.connect([i, (i + 1) % n]); + graph.connect([i, n]); + } + graph + } +} diff --git a/src/polyhedron/shape/distance/svg.rs b/src/polyhedron/shape/distance/svg.rs new file mode 100644 index 00000000..fbe2270f --- /dev/null +++ b/src/polyhedron/shape/distance/svg.rs @@ -0,0 +1,70 @@ +use super::Distance; +use graphviz_rust::{cmd::Format, exec, parse, printer::PrinterContext}; + +const LAYOUT_PREFIX: &str = r#" + graph G { + node [ + penwidth=2 + label="" + style=filled + fillcolor=lightblue + color=black + shape=circle + width=0.25 + fixedsize=true + fontsize=10 + ]; + edge [penwidth=2]; + overlap="scale"; + layout="neato"; + normalize=0; + bgcolor="transparent"; +"#; + +impl Distance { + pub fn graphviz(&self) -> String { + let mut layout = LAYOUT_PREFIX.to_string(); + + // #[cfg(test)] + for v in self.vertices() { + layout.push_str(&format!("\tV{v} [label=\"{}\"];\n", v)); + } + + for [v, u] in self.edges() { + layout.push_str(&format!("\tV{v} -- V{u};\n")); + } + + layout.push('}'); + // println!("graphviz:\n{layout}"); + layout + } + + pub fn svg(&self) -> Option> { + let Ok(graph) = parse(&self.graphviz()) else { + log::warn!("failed to parse Graphviz"); + return None; + }; + exec( + graph, + &mut PrinterContext::default(), + vec![Format::Svg.into()], + ) + .ok() + } + + // #[cfg(test)] + #[allow(dead_code)] + pub fn png(&self) -> Option> { + let Ok(graph) = parse(&self.graphviz()) else { + log::warn!("failed to parse Graphviz"); + panic!("[sdfkjasdlfkj]"); + }; + + exec( + graph, + &mut PrinterContext::default(), + vec![Format::Png.into()], + ) + .ok() + } +} diff --git a/src/polyhedron/shape/distance/test.rs b/src/polyhedron/shape/distance/test.rs new file mode 100644 index 00000000..9dfff095 --- /dev/null +++ b/src/polyhedron/shape/distance/test.rs @@ -0,0 +1,92 @@ +use std::fs::create_dir_all; + +use super::*; +use crate::render::message::PresetMessage::{self, *}; +use test_case::test_case; + +impl Distance { + pub fn floyd(&mut self) { + // let dist be a |V| × |V| array of minimum distances initialized to ∞ (infinity) + let mut graph: Distance = Distance::new(self.distance.len()); + for e in self.edges() { + graph[e] = 1; + } + for k in graph.vertices() { + for i in graph.vertices() { + for j in graph.vertices() { + if graph[[i, k]] != usize::MAX && graph[[k, j]] != usize::MAX { + let nv = graph[[i, k]] + graph[[k, j]]; + if graph[[i, j]] > nv || graph[[j, i]] > nv { + graph[[i, j]] = nv; + } + } + } + } + } + *self = graph; + } + + /// Hardcoded Tetrahedron construction to isolate testing + pub fn tetrahedron() -> Self { + let mut tetra = Distance::new(4); + tetra[[0, 1]] = 1; + tetra[[0, 2]] = 1; + tetra[[0, 3]] = 1; + tetra[[1, 2]] = 1; + tetra[[1, 3]] = 1; + tetra[[2, 3]] = 1; + tetra + } +} + +#[test] +fn basics() { + let mut graph = Distance::new(4); + println!("basics:"); + // Connect + graph.connect([0, 1]); + graph.connect([0, 2]); + graph.connect([1, 2]); + assert_eq!(graph.connections(0), vec![1, 2]); + assert_eq!(graph.connections(1), vec![0, 2]); + assert_eq!(graph.connections(2), vec![0, 1]); + assert_eq!(graph.connections(3), vec![]); + + // Disconnect + graph.disconnect([0, 1]); + assert_eq!(graph.connections(0), vec![2]); + assert_eq!(graph.connections(1), vec![2]); + + // Delete + graph.delete(1); + assert_eq!(graph.connections(0), vec![1]); + assert_eq!(graph.connections(2), vec![]); + assert_eq!(graph.connections(1), vec![0]); +} + +#[test] +fn chordless_cycles() { + let mut graph = Distance::new(4); + // Connect + graph.connect([0, 1]); + graph.connect([1, 2]); + graph.connect([2, 3]); + + println!("chordless_cycles:"); + println!("{graph}"); + graph.pst(); + println!("{graph}"); + + graph.connect([2, 0]); +} + +#[test] +fn contract_edge() { + let mut graph = Distance::tetrahedron(); + graph.contract_edge([0, 2]); + let mut triangle = Distance::new(3); + triangle[[0, 1]] = 1; + triangle[[1, 2]] = 1; + triangle[[2, 0]] = 1; + assert_eq!(graph, triangle); +} diff --git a/src/polyhedron/shape/mod.rs b/src/polyhedron/shape/mod.rs new file mode 100644 index 00000000..d023e224 --- /dev/null +++ b/src/polyhedron/shape/mod.rs @@ -0,0 +1,105 @@ +mod conway; +mod cycles; +mod distance; +mod platonic; +use std::{fmt::Display, ops::Range}; + +use cycles::*; +use distance::*; + +// #[cfg(test)] +// mod test; + +use crate::polyhedron::*; + +/// Contains all properties that need to be computed iff the structure of the graph changes +#[derive(Default, Clone)] +pub(super) struct Shape { + /// Graph, represented as Distance matrix + distance: Distance, + /// Cycles in the graph + pub cycles: Cycles, + /// Faces / chordless cycles + pub springs: Vec<[VertexId; 2]>, + /// SVG string of graph representation + pub svg: Vec, +} + +impl PartialEq for Shape { + fn eq(&self, other: &Self) -> bool { + self.distance == other.distance + } +} + +impl std::fmt::Debug for Shape { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.distance.to_string()) + } +} + +impl Display for Shape { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.distance.to_string()) + } +} + +impl Shape { + pub fn len(&self) -> usize { + self.distance.len() + } + + pub fn degree(&self, v: usize) -> usize { + self.distance.connections(v).len() + } + + pub fn edges(&self) -> impl Iterator + use<'_> { + self.distance.edges() + } + + pub fn vertices(&self) -> Range { + self.distance.vertices() + } + + pub fn recompute(&mut self) { + // log::info!("new distance:\n{}", self.distance); + // Update the distance matrix in place + self.distance.pst(); + // Find and save cycles + self.cycles = Cycles::from(&self.distance); + // log::info!("new cycles:\n{:?}", self.cycles); + // Find and save springs + self.springs = self.distance.springs(); + } + + #[allow(dead_code)] + pub fn compute_springs(&mut self) { + self.springs = self.distance.springs(); + } + + pub fn compute_graph_svg(&mut self) { + self.svg = self.distance.svg().unwrap_or_default(); + } + + pub fn release(&mut self, edges: &[[VertexId; 2]]) { + for &edge in edges { + self.distance.disconnect(edge); + } + self.recompute(); + } + + /// Given a vertex pairing, what is their distance in G divided by the diameter of G + pub fn diameter_percent(&self, [v, u]: [VertexId; 2]) -> f32 { + self.distance[[v, u]] as f32 / self.distance.diameter() as f32 + } +} + +impl From for Shape { + fn from(distance: Distance) -> Self { + let mut shape = Shape { + distance, + ..Default::default() + }; + shape.recompute(); + shape + } +} diff --git a/src/polyhedron/shape/platonic.rs b/src/polyhedron/shape/platonic.rs new file mode 100644 index 00000000..0bbcc8b7 --- /dev/null +++ b/src/polyhedron/shape/platonic.rs @@ -0,0 +1,15 @@ +use super::{Distance, Shape}; + +impl Shape { + pub fn prism(n: usize) -> Shape { + Shape::from(Distance::prism(n)) + } + + pub fn anti_prism(n: usize) -> Shape { + Shape::from(Distance::anti_prism(n)) + } + + pub fn pyramid(n: usize) -> Shape { + Shape::from(Distance::pyramid(n)) + } +} diff --git a/src/polyhedron/shape/test.rs b/src/polyhedron/shape/test.rs new file mode 100644 index 00000000..c80f0d14 --- /dev/null +++ b/src/polyhedron/shape/test.rs @@ -0,0 +1,61 @@ +use super::*; +use crate::render::message::PresetMessage::{self, *}; +use std::fs::create_dir_all; + +use test_case::test_case; + +impl Shape { + pub fn tetrahedron() -> Shape { + Shape::from(Distance::tetrahedron()) + } +} + +// #[test] +// fn truncate_contract() { +// let prefix = "tests/truncate_contract/"; +// create_dir_all(prefix).unwrap(); +// let mut shape = Shape::from(Distance::tetrahedron()); +// //shape.distance.render(prefix, "tetrahedron.svg"); +// let edges = shape.truncate(None); +// println!("edges: {edges:?}"); +// //shape.distance.render(prefix, "truncated_tetrahedron.svg"); +// shape.distance.contract_edges(edges); +// // shape +// // .distance +// // .render(prefix, "contracted_truncated_tetrahedron.svg"); +// assert_eq!(Distance::tetrahedron(), shape.distance); +// } +// +#[test] +#[ignore] +fn split_vertex_contract() { + let mut control = Distance::new(6); + // Original outline + control[[1, 2]] = 1; + control[[2, 3]] = 1; + control[[3, 1]] = 1; + // Connections + control[[0, 1]] = 1; + control[[4, 2]] = 1; + control[[5, 3]] = 1; + // New face + control[[0, 4]] = 1; + control[[4, 5]] = 1; + control[[5, 0]] = 1; + let mut test = Shape::from(Distance::tetrahedron()); + let edges = test.split_vertex(0)[1..].to_vec(); + test.distance.contract_edges(edges); + assert_eq!(Distance::tetrahedron(), test.distance); +} + +// #[test] +// fn ambo() { +// // let prefix = "tests/ambo/"; +// // create_dir_all(prefix).unwrap(); +// let tetrahedron = Shape::from(Distance::tetrahedron()); +// +// assert_eq!( +// tetrahedron.ambod(), +// Distance::preset(&PresetMessage::Octahedron) +// ); +// } diff --git a/src/polyhedron/test.rs b/src/polyhedron/test.rs new file mode 100644 index 00000000..fd5170dd --- /dev/null +++ b/src/polyhedron/test.rs @@ -0,0 +1,35 @@ +use super::*; +use crate::render::message::PresetMessage::{self}; +use std::fs::create_dir_all; +// +// use test_case::test_case; +// #[test_case(Polyhedron::preset(&Pyramid(3)); "T")] +// #[test_case(Polyhedron::preset(&Prism(4)); "C")] +// #[test_case(Polyhedron::preset(&Octahedron); "O")] +// #[test_case(Polyhedron::preset(&Dodecahedron); "D")] +// #[test_case(Polyhedron::preset(&Icosahedron); "I")] +// #[test_case({ let mut g = Polyhedron::preset(&Prism(4)); g.truncate(); g} ; "tC")] +// #[test_case({ let mut g = Polyhedron::preset(&Octahedron); g.truncate(); g} ; "tO")] +// #[test_case({ let mut g = Polyhedron::preset(&Dodecahedron); g.truncate(); g} ; "tD")] +// fn polytope_pst(shape: Polyhedron) { +// // let mut pst = shape.clone(); +// // shape.shape +// // pst.distance.pst(); +// // let mut floyd = shape.clone(); +// // floyd.distance.floyd(); +// // assert_eq!(floyd.distance, pst.distance); +// } + +#[test] +fn ambo() { + use PresetMessage::*; + let prefix = "tests/ambo/"; + create_dir_all(prefix).unwrap(); + let mut polyhedron = Polyhedron::preset(&Pyramid(3)); + polyhedron.shape.png(); + polyhedron.ambo_contract(); + polyhedron.shape.png(); + let octahedron = Polyhedron::preset(&Octahedron); + octahedron.shape.png(); + assert_eq!(polyhedron.shape, octahedron.shape); +} diff --git a/src/bones/transaction.rs b/src/polyhedron/transaction.rs similarity index 57% rename from src/bones/transaction.rs rename to src/polyhedron/transaction.rs index cf81b676..d9344f7f 100644 --- a/src/bones/transaction.rs +++ b/src/polyhedron/transaction.rs @@ -1,11 +1,13 @@ -use crate::{bones::Edge, render::message::ConwayMessage}; -use rustc_hash::FxHashSet as HashSet; +use crate::render::message::ConwayMessage; use std::time::Instant; +use super::VertexId; + #[derive(Debug, Clone)] pub enum Transaction { - Contraction(HashSet), - Release(HashSet), + Contraction(Vec<[VertexId; 2]>), + #[allow(dead_code)] + Release(Vec<[VertexId; 2]>), Conway(ConwayMessage), #[allow(dead_code)] ShortenName(usize), diff --git a/src/render/app.rs b/src/render/app.rs index 3b550e39..b6477cf6 100644 --- a/src/render/app.rs +++ b/src/render/app.rs @@ -194,7 +194,8 @@ impl App<'_> { .moment_buf .resize(&self.graphics.device, moments.len()); - let shapes = primitive.shape_vertices(); + let shapes = primitive.model.polyhedron.shape_vertices(); + //log::error!("shapes: {shapes:?}"); scene.shape_buf.resize(&self.graphics.device, shapes.len()); scene.shape_buf.write_slice(&self.graphics.queue, &shapes); } @@ -216,11 +217,7 @@ impl App<'_> { // Write Frag Uniforms scene.frag_buf.write_data( &self.graphics.queue, - &FragUniforms { - line_thickness: primitive.render.line_thickness, - line_mode: 1.0, - ..Default::default() - }, + &FragUniforms::new(primitive.render.line_thickness, 1.0), ); self.graphics.window.request_redraw(); } @@ -244,11 +241,7 @@ impl App<'_> { // Ignore the whole first polygon if we're in schlegel mode let starting_vertex = if program.state.render.schlegel { // Determines how many vertices are actually used to render the polygon - match program.state.model.polyhedron.cycles[0].len() { - 3 => 3, - 4 => 6, - n => n * 3, - } + program.state.model.polyhedron.starting_vertex() } else { 0 } as u32; @@ -322,7 +315,6 @@ impl ApplicationHandler for App<'_> { return; } - //self.graphics.update(); match self.render() { Ok(_) => {} // Reconfigure the surface if it's lost or outdated @@ -381,6 +373,7 @@ impl ApplicationHandler for App<'_> { "a" => Some(Ambo), "t" => Some(Truncate), "b" => Some(Bevel), + "c" => Some(Chamfer), _ => None, } .map(PolybladeMessage::Conway) diff --git a/src/render/controls.rs b/src/render/controls.rs index d705bed2..0dba407c 100644 --- a/src/render/controls.rs +++ b/src/render/controls.rs @@ -1,7 +1,7 @@ use iced::{alignment::Vertical, Length}; use iced_aw::{menu::Item, menu_bar}; use iced_wgpu::Renderer; -use iced_widget::{button, column, container, row, text, Row}; +use iced_widget::{button, column, container, row, text, Row, Space}; use iced_winit::{ core::{Color, Element, Theme}, runtime::{Program, Task}, @@ -75,7 +75,9 @@ impl Program for Controls { column![ menu_bar.align_y(Vertical::Top), button_row, - iced_widget::Space::new(Length::Fill, Length::Fill), + Space::new(Length::Fill, Length::Fill), + self.state.model.polyhedron.svg(), + Space::new(Length::Fill, Length::Fill), button(text(self.state.info.name())).on_press(self.state.info.wiki_message()), container( row![ diff --git a/src/render/message.rs b/src/render/message.rs index 72562862..84a6dd64 100644 --- a/src/render/message.rs +++ b/src/render/message.rs @@ -1,5 +1,5 @@ use crate::{ - bones::{PolyGraph, Transaction}, + polyhedron::{Polyhedron, Transaction}, render::camera::Camera, Instant, }; @@ -77,6 +77,7 @@ pub enum ConwayMessage { Kis, // Needle, // Zip, + SplitVertex(usize), Truncate, // 4 //Ortho, @@ -87,6 +88,8 @@ pub enum ConwayMessage { // // 6 // Meta, Bevel, + + Chamfer, } #[derive(Debug, Clone)] @@ -152,26 +155,7 @@ pub trait ProcessMessage { impl ProcessMessage for PresetMessage { fn process(&self, state: &mut ModelState) -> Task { - use PresetMessage::*; - match &self { - Prism(n) => { - state.polyhedron = PolyGraph::prism(*n); - if n == &4 { - state.polyhedron.name = "C".into(); - } - } - AntiPrism(n) => state.polyhedron = PolyGraph::anti_prism(*n), - Pyramid(n) => { - state.polyhedron = PolyGraph::pyramid(*n); - if n == &3 { - state.polyhedron.name = "T".into(); - } - } - Octahedron => state.polyhedron = PolyGraph::octahedron(), - Dodecahedron => state.polyhedron = PolyGraph::dodecahedron(), - Icosahedron => state.polyhedron = PolyGraph::icosahedron(), - } - + state.polyhedron = Polyhedron::preset(self); Task::none() } } @@ -262,6 +246,7 @@ impl ProcessMessage for ColorPickerMessage { impl ProcessMessage for PolybladeMessage { fn process(&self, state: &mut AppState) -> Task { + //println!("processing message: {self:?} for state {state:?}"); use PolybladeMessage::*; match self { Tick(time) => { diff --git a/src/render/mod.rs b/src/render/mod.rs index 5bfc5242..55a389a8 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -1,6 +1,6 @@ mod app; mod camera; -mod color; +pub mod color; mod controls; mod menu; pub(crate) mod message; diff --git a/src/render/pipeline/buffer/types.rs b/src/render/pipeline/buffer/types.rs index d9d35ae1..8189b84d 100644 --- a/src/render/pipeline/buffer/types.rs +++ b/src/render/pipeline/buffer/types.rs @@ -1,41 +1,54 @@ use ultraviolet::{Mat4, Vec3, Vec4}; #[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] -#[repr(C, align(16))] +#[repr(C)] pub struct MomentVertex { pub position: Vec3, pub color: Vec4, pub _padding: f32, + // #[cfg(target_arch = "wasm32")] } impl MomentVertex { pub fn new(position: Vec3, color: Vec4) -> MomentVertex { Self { position, + _padding: 123.4, color, - _padding: 0.0, } } } #[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] -#[repr(C, align(16))] +//#[repr(C, align(16))] +#[repr(C)] pub struct ShapeVertex { pub barycentric: Vec4, pub sides: Vec4, } #[derive(Copy, Default, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] -#[repr(C, align(16))] +//#[repr(C, align(16))] +#[repr(C)] pub struct ModelUniforms { pub(crate) model_mat: Mat4, pub(crate) view_projection_mat: Mat4, } #[derive(Copy, Default, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] -#[repr(C, align(16))] +//#[repr(C, align(16))] +#[repr(C)] pub struct FragUniforms { pub(crate) line_thickness: f32, pub(crate) line_mode: f32, pub _padding: [f32; 2], } +impl FragUniforms { + pub fn new(line_thickness: f32, line_mode: f32) -> Self { + Self { + line_thickness, + line_mode, + _padding: [123.4; 2], + } + } +} diff --git a/src/render/pipeline/polyhedron_primitive.rs b/src/render/pipeline/polyhedron_primitive.rs index 9d958a4c..dba7a7cb 100644 --- a/src/render/pipeline/polyhedron_primitive.rs +++ b/src/render/pipeline/polyhedron_primitive.rs @@ -1,11 +1,7 @@ -use std::collections::HashMap; - use crate::render::{ - message::ColorMethodMessage, - pipeline::{MomentVertex, ShapeVertex}, + pipeline::MomentVertex, state::{ModelState, RenderState}, }; -use ultraviolet::{Vec3, Vec4}; #[derive(Debug)] pub struct PolyhedronPrimitive { @@ -18,120 +14,10 @@ impl PolyhedronPrimitive { Self { model, render } } - #[allow(dead_code)] - pub fn surface_area(&self, face_index: usize) -> f32 { - let positions: Vec = self.model.polyhedron.cycles[face_index] - .iter() - .map(|i| self.model.polyhedron.positions[i]) - .collect(); - let mut area = 0.0; - for i in 0..positions.len() / 3 { - let j = i * 3; - let a = (positions[j] - positions[j + 1]).mag(); - let b = (positions[j + 1] - positions[j + 2]).mag(); - let c = (positions[j + 2] - positions[j]).mag(); - let s = (a + b + c) / 2.0; - area += (s * (s - a) * (s - b) * (s - c)).sqrt(); - } - area - } - /// All the vertices that will change moment to moment pub fn moment_vertices(&self) -> Vec { let polyhedron = &self.model.polyhedron; let colors = &self.render.picker.palette.colors; - - match self.render.method { - ColorMethodMessage::Vertex => todo!(), - ColorMethodMessage::Edge => todo!(), - ColorMethodMessage::Polygon => { - // Polygon side count -> color - let color_map: HashMap = - polyhedron.cycles.iter().fold(HashMap::new(), |mut acc, c| { - if !acc.contains_key(&c.len()) { - acc.insert(c.len(), colors[acc.len() % colors.len()].into()); - } - acc - }); - polyhedron - .cycles - .iter() - .map(|cycle| { - let color = *color_map.get(&cycle.len()).unwrap(); - let positions: Vec = - cycle.iter().map(|&c| polyhedron.positions[&c]).collect(); - - match cycle.len() { - 3 => positions - .iter() - .map(|&position| MomentVertex::new(position, color)) - .collect(), - 4 => [0usize, 1, 2, 2, 3, 0] - .iter() - .map(|&i| positions[i]) - .map(|position| MomentVertex::new(position, color)) - .collect(), - _ => { - let centroid: Vec3 = - positions.iter().fold(Vec3::zero(), |a, &b| a + b) - / positions.len() as f32; - (0..cycle.len()) - .map(|i| { - vec![ - positions[i], - centroid, - positions[(i + 1) % positions.len()], - ] - .into_iter() - .map(|position| MomentVertex::new(position, color)) - .collect() - }) - .collect::>>() - .concat() - } - } - }) - .collect::>>() - .concat() - } - ColorMethodMessage::Face => todo!(), - } - } - - pub fn shape_vertices(&self) -> Vec { - let barycentric = [Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z()]; - self.model - .polyhedron - .cycles - .iter() - .map(|cycle| { - let sides: Vec4 = match cycle.len() { - 3 => Vec3::new(1.0, 1.0, 1.0), - 4 => Vec3::new(1.0, 0.0, 1.0), - _ => Vec3::new(0.0, 1.0, 0.0), - } - .into(); - - let b_shapes: Vec = barycentric - .iter() - .map(|&b| ShapeVertex { - barycentric: b.into(), - sides, - }) - .collect(); - - match cycle.len() { - 3 => b_shapes.clone(), - 4 => (0..6) - .map(|i| ShapeVertex { - barycentric: barycentric[i % 3].into(), - sides, - }) - .collect(), - _ => vec![b_shapes; cycle.len()].concat(), - } - }) - .collect::>>() - .concat() + polyhedron.moment_vertices(colors) } } diff --git a/src/render/polydex.rs b/src/render/polydex.rs index 507e1efe..5902bcd4 100644 --- a/src/render/polydex.rs +++ b/src/render/polydex.rs @@ -1,4 +1,4 @@ -use crate::{bones::PolyGraph, render::message::PolybladeMessage, Instant}; +use crate::{polyhedron::Polyhedron, render::message::PolybladeMessage, Instant}; use serde::{Deserialize, Serialize}; pub type Polydex = Vec; @@ -11,6 +11,7 @@ pub struct Entry { pub wiki: String, } +#[derive(Debug, Default)] pub struct InfoBox { pub conway: String, pub faces: usize, @@ -40,14 +41,14 @@ impl InfoBox { } } -impl PolyGraph { +impl Polyhedron { pub fn polydex_entry(&self, polydex: &Polydex) -> InfoBox { let entry = polydex.iter().find(|entry| entry.conway == self.name); InfoBox { conway: self.name.clone(), - faces: self.cycles.len(), - edges: self.edges.len(), - vertices: self.vertices.len(), + faces: 0, //self.shape.cycles.len(), + edges: 0, //self.shape.edges().count(), + vertices: 0, //self.shape.len(), name: entry.map(|e| e.name.clone()), bowers: entry.map(|e| e.bowers.clone()), wiki: entry.map(|e| e.wiki.clone()), diff --git a/src/render/state.rs b/src/render/state.rs index 3835646b..26eaa64f 100644 --- a/src/render/state.rs +++ b/src/render/state.rs @@ -1,8 +1,8 @@ use crate::{ - bones::PolyGraph, + polyhedron::Polyhedron, render::{ camera::Camera, - message::ColorMethodMessage, + message::{ColorMethodMessage, PresetMessage}, palette::Palette, polydex::{Entry, InfoBox, Polydex}, }, @@ -13,6 +13,7 @@ use iced::{time::Duration, Color}; use std::{f32::consts::PI, io::Read as _}; use ultraviolet::Mat4; +#[derive(Debug, Default)] pub struct AppState { pub model: ModelState, pub render: RenderState, @@ -76,19 +77,22 @@ impl Default for ColorPickerState { #[derive(Debug, Clone)] pub struct ModelState { - pub polyhedron: PolyGraph, + pub polyhedron: Polyhedron, pub transform: Mat4, } impl Default for ModelState { fn default() -> Self { + //log::error!("poly: {:?}", x.polyhedron); Self { - polyhedron: PolyGraph::dodecahedron(), + //polyhedron: { Polyhedron::preset(&PresetMessage::Octahedron) }, + polyhedron: { Polyhedron::preset(&PresetMessage::Pyramid(3)) }, transform: Mat4::identity(), } } } +#[allow(dead_code)] pub fn load_polydex() -> Result> { let mut polydex = std::fs::File::open("assets/polydex.ron")?; let mut polydex_str = String::new(); @@ -97,26 +101,15 @@ pub fn load_polydex() -> Result> { Ok(polydex) } -impl Default for AppState { - fn default() -> Self { - let info = PolyGraph::default().polydex_entry(&vec![]); - Self { - model: ModelState::default(), - render: RenderState::default(), - polydex: load_polydex().unwrap_or_default(), - info, - } - } -} - impl AppState { pub fn update_state(&mut self, time: Instant) { // Update the polyhedron using the difference in time between this and the previous frame let frame_difference = time.duration_since(self.render.frame).as_secs_f32(); let framerate = 1.0 / 60.0; + //sleep_ms(800); // Fraction of a second since the previous frame rendered let second = if frame_difference > 1.0 / 60.0 { - log::warn!("took more than 1/60th of a second to render that frame"); + // log::warn!("took more than 1/60th of a second to render that frame"); framerate } else { frame_difference From b74fa20e491752d4bb2e7dd624a7d8ca2a7ffcdd Mon Sep 17 00:00:00 2001 From: Vera Gonzalez Date: Tue, 3 Dec 2024 01:53:53 -0500 Subject: [PATCH 4/6] Single dimension (#48) * Update README.md * Matrix (#42) * refactored distance matrix * defined robust Matrix type and Index impls for usage of jagged symmetric matrix * compiling * added Display to Matrix and fixed basic test * fixed PST * fixed cycle-finding * refactor as JagGraph * expanding into conway functionality; cycles * made PST a little prettier * replacing more occurrences of Edge with [VertexId; 2] * more restoration of Conway and Platonic * reimplementing other test cases * fixed pst test process & floyd * fully extricating Edge from PolyGraph * reimplemented conway & preset commands * trying to extricate more cases of Edge * adding graphviz svg capability * fixed split_vertex * further solidifying split_vertex * fixed contract edges; pst::o test working * removed svg files from commits * doing massive refactor * updated the preset setting call heirarchy * compiling again * changing preset code to create new instances rather than modify in place * reorganizing * changed Render to separate pos and speed * reimplemented test cases for Distance * ugh; checkpoint i guess? not rendering * dodec / expand * updating truncation test to be more robust * swapped out graphviz crate to improve legibility of graph structures * fixed truncation! * simplified contract_edges * fixed automatic resizing of Render attributes in Polyhedron on Conway change * trying to revert with no success * updating stuff! * temporarily setting to GL * updates svg as we go * fixed awful bug in position creation; as well as some layout stuff * svg preview; ambod * simplified split_vertex * storing graph svg in memory instead of in files * smart update positions on truncate * working on scope simplifications * nesting project structure * proper nesting * cycles submodule * Cycles::from(&distance) * removed redundant scoping * restored the ability to truncate, this time with nice scoping! * dramatically improved clarity and legibility of Graphviz svg * ambo now rendering * Distance super * Shape super * cleanup svg fn * cleaning up MomentVertices * cleaning up MomentVertices * clippy fix * fixing presets to be run on Polyhedron * printing graphs to console in test cases * somehow truncate is working * removed additional recomputation * terribly slow but correct cycle / face tester * significantly faster solution using eulers polyhedron formula * starting to clean * added primitive chamfer operator * trying to reimplement expand * rewriting expand to use sorted_connections * replacing expansion with aa for now * clippy * fixing clippy warnings * updating wasm dependencies * fixed render call * fmt * update README with warning * using 1 dimensional array; truncate working again * replaced PST with much simpler BFS apsp * reimplementing apsp tests * fixed truncation * clippy * moved test case; reimplemented icosahedron * ignoring broken tests; succinctness on kis * cleanup * clippy and fmt * fix tests clippy --- src/polyhedron/conway.rs | 2 +- src/polyhedron/mod.rs | 17 +-- src/polyhedron/platonic.rs | 37 ++--- src/polyhedron/shape/conway.rs | 29 ++-- src/polyhedron/shape/cycles/mod.rs | 55 +------ src/polyhedron/shape/distance/conway.rs | 78 +--------- src/polyhedron/shape/distance/mod.rs | 191 ++++++++---------------- src/polyhedron/shape/distance/test.rs | 58 ++++--- src/polyhedron/shape/mod.rs | 19 +-- src/polyhedron/shape/test.rs | 36 +---- src/polyhedron/test.rs | 50 ++++--- src/render/app.rs | 2 +- 12 files changed, 184 insertions(+), 390 deletions(-) diff --git a/src/polyhedron/conway.rs b/src/polyhedron/conway.rs index af5adcfd..c703a52d 100644 --- a/src/polyhedron/conway.rs +++ b/src/polyhedron/conway.rs @@ -42,7 +42,7 @@ impl Polyhedron { log::info!( "p: {}, d: {}", self.render.positions.len(), - self.shape.len() + self.shape.order() ); } diff --git a/src/polyhedron/mod.rs b/src/polyhedron/mod.rs index d68bfedf..41e72d1d 100644 --- a/src/polyhedron/mod.rs +++ b/src/polyhedron/mod.rs @@ -7,8 +7,8 @@ use render::*; use shape::*; pub use transaction::*; -// #[cfg(test)] -// mod test; +#[cfg(test)] +mod test; use std::{ collections::HashMap, @@ -156,7 +156,7 @@ impl Polyhedron { ] } }; - self.render.new_capacity(self.shape.len()); + self.render.new_capacity(self.shape.order()); self.transactions = [new_transactions, self.transactions.clone()].concat(); } Name(c) => { @@ -223,17 +223,6 @@ impl Polyhedron { } } - // pub fn preset(preset: &PresetMessage) -> Polyhedron { - // let shape = Shape::preset(preset); - // let render = Render::new(shape.len()); - // Polyhedron { - // name: preset.to_string(), - // shape, - // render, - // transactions: vec![], - // } - // } - pub fn face_centroid(&self, face_index: usize) -> Vec3 { // All vertices associated with this face self.shape.cycles[face_index] diff --git a/src/polyhedron/platonic.rs b/src/polyhedron/platonic.rs index 6f0dc247..05ca5d5d 100644 --- a/src/polyhedron/platonic.rs +++ b/src/polyhedron/platonic.rs @@ -1,12 +1,13 @@ use super::*; +use PresetMessage::*; impl Polyhedron { pub fn preset(preset: &PresetMessage) -> Polyhedron { use PresetMessage::*; let mut poly = match preset { Octahedron => Self::octahedron(), - Dodecahedron => Self::dodecahedron(), - Icosahedron => todo!(), + Dodecahedron => todo!(), + Icosahedron => Self::icosahedron(), _ => { let shape = match preset { Prism(n) => Shape::prism(*n), @@ -15,7 +16,7 @@ impl Polyhedron { _ => todo!(), }; - let render = Render::new(shape.len()); + let render = Render::new(shape.order()); Polyhedron { name: preset.to_string(), @@ -30,32 +31,14 @@ impl Polyhedron { } fn octahedron() -> Polyhedron { - let mut polyhedron = Polyhedron::preset(&PresetMessage::Pyramid(3)); + let mut polyhedron = Polyhedron::preset(&Pyramid(3)); polyhedron.ambo_contract(); polyhedron } - - fn dodecahedron() -> Polyhedron { - // polyhedron.ambo_contract(); - // let edges = polyhedron.truncate(0); - //polyhedron.contract(edges); - // polyhedron.truncate(5); - Polyhedron::preset(&PresetMessage::AntiPrism(5)) + pub fn icosahedron() -> Polyhedron { + let mut graph = Polyhedron::preset(&AntiPrism(5)); + graph.shape.kis(Some(5)); + graph.render.new_capacity(graph.shape.order()); + graph } - - // - // pub fn icosahedron() -> Distance { - // let mut graph = Distance::anti_prism(5); - // graph.kis(Some(5)); - // graph - // } - // - // pub fn icosahedron() -> Distance { - // let dodecahedron = Self::dodecahedron(); - // //let edges = dodecahedron.ambo(); - // //dodecahedron.contract_edges(edges); - // #[cfg(test)] - // dodecahedron.render("tests/", "icosahedron.svg"); - // dodecahedron - // } } diff --git a/src/polyhedron/shape/conway.rs b/src/polyhedron/shape/conway.rs index e60d9f83..968c9899 100644 --- a/src/polyhedron/shape/conway.rs +++ b/src/polyhedron/shape/conway.rs @@ -1,4 +1,4 @@ -use super::{Cycles, Shape}; +use super::{Cycle, Cycles, Shape}; use crate::polyhedron::VertexId; impl Shape { @@ -11,20 +11,29 @@ impl Shape { pub fn contract_edges(&mut self, edges: Vec<[VertexId; 2]>) { self.distance.contract_edges(edges); + // Delete a + // for + // for i in 0..self.cycles.len() { + // self.cycles[i].replace(v, u); + // } self.recompute(); } - #[allow(dead_code)] pub fn kis(&mut self, degree: Option) -> Vec<[VertexId; 2]> { let edges = self.distance.edges().collect(); - // let mut cycles = self.cycles.clone(); - if let Some(degree) = degree { - self.cycles - .iter() - .collect::>() - .retain(|c| c.len() == degree); - } - for cycle in self.cycles.iter() { + let cycles: Vec<&Cycle> = self + .cycles + .iter() + .filter(move |cycle| { + if let Some(degree) = degree { + cycle.len() == degree + } else { + true + } + }) + .collect(); + + for cycle in cycles { let v = self.distance.insert(); // let mut vpos = Vec3::zero(); diff --git a/src/polyhedron/shape/cycles/mod.rs b/src/polyhedron/shape/cycles/mod.rs index e7eb0dc5..3008686a 100644 --- a/src/polyhedron/shape/cycles/mod.rs +++ b/src/polyhedron/shape/cycles/mod.rs @@ -139,27 +139,13 @@ impl From<&Distance> for Cycles { fn from(distance: &Distance) -> Self { let mut triplets: Vec> = Default::default(); let mut cycles: HashSet> = Default::default(); - // let mut edge_incidents: Distance = distance.clone(); - // for [v, u] in edge_incidents.vertex_pairs() { - // if edge_incidents[[v, u]] == 1 { - // edge_incidents[[v, u]] = 0; - // } else { - // edge_incidents[[v, u]] = usize::MAX; - // } - // } - // println!("distance:\n{distance}"); - // println!("edge_incidents_starting:\n{edge_incidents}"); - // find all the triplets - for u in 0..distance.len() { - for x in (u + 1)..distance.len() { - for y in (x + 1)..distance.len() { + for u in 0..distance.order() { + for x in (u + 1)..distance.order() { + for y in (x + 1)..distance.order() { if distance[[u, x]] == 1 && distance[[u, y]] == 1 { if distance[[x, y]] == 1 { cycles.insert(vec![x, u, y]); - // edge_incidents[[x, u]] += 1; - // edge_incidents[[u, y]] += 1; - // edge_incidents[[y, x]] += 1; } else { triplets.push(vec![x, u, y]); } @@ -167,51 +153,22 @@ impl From<&Distance> for Cycles { } } } - // find all the triplets - // for u in distance.vertices() { - // let adj: Vec = distance.connections(u); - // for &x in adj.iter() { - // for &y in adj.iter() { - // if u < x && x < y { - // let new_face = vec![x, u, y]; - // if distance[[x, y]] == 1 { - // cycles.insert(new_face); - // } else { - // triplets.push(new_face); - // } - // } - // } - // } - // } - // println!("triplets:\n{triplets:?}"); - // println!("cycles:\n{cycles:?}"); // while there are unparsed triplets while !triplets.is_empty() && (cycles.len() as i64) < distance.face_count() { let p = triplets.remove(0); // for each v adjacent to u_t - for v in distance.connections(p[p.len() - 1]) { + for v in distance.neighbors(p[p.len() - 1]) { if v > p[1] { - let adj_v = distance.connections(v); + let adj_v = distance.neighbors(v); // if v is not a neighbor of u_2..u_t-1 if !p[1..p.len() - 1].iter().any(|i| adj_v.contains(i)) { - // let mut new_face = p.clone(); - // new_face.push(v); let new = [p.clone(), vec![v]].concat(); - if distance.connections(p[0]).contains(&v) { - // if edge_incidents[[p[0], v]] >= 2 { - // log::info!("i was about to send {new:?} but [{}, {}] is already greater than 2", p[0], v) - // } else { - // for i in 0..new.len() { - // edge_incidents[[new[i], new[(i + 1) % new.len()]]] += 1; - // } + if distance.neighbors(p[0]).contains(&v) { if distance.cycle_is_face(new.clone()) { cycles.insert(new); - } else { - // println!("i was going to insert {new:?} but it's not a valid face"); } - // } } else { triplets.push(new); } diff --git a/src/polyhedron/shape/distance/conway.rs b/src/polyhedron/shape/distance/conway.rs index 15b6a2ff..02b1b979 100644 --- a/src/polyhedron/shape/distance/conway.rs +++ b/src/polyhedron/shape/distance/conway.rs @@ -5,37 +5,23 @@ use crate::polyhedron::VertexId; impl Distance { pub(super) fn contract_edge(&mut self, [v, u]: [VertexId; 2]) { // Give u all the same connections as v - for w in self.connections(v).into_iter() { + for w in self.neighbors(v).into_iter() { self.connect([w, u]); self.disconnect([w, v]); } - - // // Delete a - // for cycle in self.cycles.iter_mut() { - // cycle.replace(v, u); - // } - // Delete v self.delete(v); } pub fn contract_edges(&mut self, mut edges: Vec<[VertexId; 2]>) { - // let mut transformed = HashSet::default(); while !edges.is_empty() { // Pop an edge let [w, x] = edges.remove(0); let v = w.max(x); let u = w.min(x); - // // If this is not a redundant edge - // if !(transformed.contains(&v) && transformed.contains(&u)) { - // Contract [v, u], deleting v self.contract_edge([v, u]); - - // // Mark that this vertex has been transformed - // transformed.insert(v); - // Decrement the value of every vertex for [x, w] in &mut edges { if *x > v { @@ -48,19 +34,6 @@ impl Distance { } } - // pub fn contract_edges(&mut self, mut edges: Vec<[VertexId; 2]>) { - // let mut map = HashMap::::default(); - // for [v, u] in edges.into_iter() { - // let u = *map.get(&u).unwrap_or(&u); - // let v = *map.get(&v).unwrap_or(&v); - // if v != u { - // //self.contract_edge([v, u]); - // map.insert(v, u); - // } - // } - // println!("map: {map:?}"); - // } - pub fn split_vertex(&mut self, v: VertexId, connections: Vec) -> Vec<[VertexId; 2]> { // Remove the vertex let new_cycle: Cycle = Cycle::from( @@ -89,55 +62,6 @@ impl Distance { new_edges } - pub fn cycle_is_face(&self, mut cycle: Vec) -> bool { - let mut dupe = self.clone(); - while !cycle.is_empty() { - let v = cycle.remove(0); - dupe.delete(v); - for u in &mut cycle { - if *u > v { - *u -= 1; - } - } - } - dupe.is_connected() - } - - // // - // pub fn ordered_face_indices(&self, v: VertexId) -> Vec { - // let relevant = (0..self.cycles.len()) - // .filter(|&i| self.cycles[i].containz(&v)) - // .collect::>(); - // - // let mut edges = HashMap::default(); - // - // for &i in relevant.iter() { - // let ui = self.cycles[i].iter().position(|&x| x == v).unwrap(); - // let flen = self.cycles[i].len(); - // // Find the values that came before and after in the face - // let a = self.cycles[i][(ui + flen - 1) % flen]; - // let b = self.cycles[i][(ui + 1) % flen]; - // edges.insert((a, b).into(), i); - // } - // - // let f: Cycle = edges.keys().cloned().collect::>().into(); - // - // let mut ordered_face_indices = vec![]; - // for i in 0..f.len() { - // let ev = f[i]; - // let eu = f[(i + 1) % f.len()]; - // let fi = edges - // .get(&[ev, eu]) - // .unwrap_or(edges.get(&[eu, ev]).unwrap()); - // ordered_face_indices.push(*fi); - // } - // - // ordered_face_indices - // } - // // - - // /// `e` = `aa` - // // `j` join // `z` zip diff --git a/src/polyhedron/shape/distance/mod.rs b/src/polyhedron/shape/distance/mod.rs index d7013e47..1cfd4853 100644 --- a/src/polyhedron/shape/distance/mod.rs +++ b/src/polyhedron/shape/distance/mod.rs @@ -2,13 +2,12 @@ mod conway; mod platonic; mod svg; -// #[cfg(test)] -// mod test; +#[cfg(test)] +mod test; use crate::polyhedron::VertexId; use std::collections::HashSet; use std::{ - collections::VecDeque, fmt::Display, ops::{Index, IndexMut, Range}, }; @@ -19,7 +18,9 @@ use std::{ /// n -> actual distance #[derive(Debug, Default, Clone, PartialEq)] pub(super) struct Distance { - distance: Vec>, + /// The order is the number of vertices + order: usize, + distance: Vec, } impl Distance { @@ -30,8 +31,9 @@ impl Distance { /// [ M | M | M | ... | M | M | M | 0 ] pub fn new(n: usize) -> Self { Distance { + order: n, distance: (0..n) - .map(|m| [vec![usize::MAX; m], vec![0]].concat()) + .flat_map(|m| [vec![usize::MAX; m], vec![0]].concat()) .collect(), } } @@ -55,26 +57,34 @@ impl Distance { /// Inserts a new vertex in the matrix pub fn insert(&mut self) -> VertexId { self.distance - .push([vec![usize::MAX; self.len()], vec![0]].concat()); - self.len() - 1 + .extend([vec![usize::MAX; self.order], vec![0]].concat()); + self.order += 1; + self.order - 1 } /// Deletes a vertex from the matrix pub fn delete(&mut self, v: VertexId) { - for row in &mut self.distance[v..] { - row.remove(v); + let mut distance = Distance::new(self.order - 1); + for i in 0..self.order { + for j in i..self.order { + if i != v && j != v { + let x = if i > v { i - 1 } else { i }; + let y = if j > v { j - 1 } else { j }; + distance[[x, y]] = self[[i, j]]; + } + } } - self.distance.remove(v); + *self = distance; } /// Enumerates the vertices connected to v - pub fn connections(&self, v: VertexId) -> Vec { + pub fn neighbors(&self, v: VertexId) -> Vec { self.vertices().filter(|&u| self[[v, u]] == 1).collect() } /// Iterable Range representing vertex IDs pub fn vertices(&self) -> Range { - 0..self.distance.len() + 0..self.order } /// All possible compbinations of vertices @@ -88,8 +98,8 @@ impl Distance { } /// Vertex Count - pub fn len(&self) -> usize { - self.distance.len() + pub fn order(&self) -> usize { + self.order } /// Maximum distance value @@ -99,127 +109,52 @@ impl Distance { fn dfs(&self, visited: &mut HashSet, v: usize) { visited.insert(v); - for u in self.connections(v) { + for u in self.neighbors(v) { if !visited.contains(&u) { self.dfs(visited, u); } } } - pub fn is_connected(&self) -> bool { + fn is_connected(&self) -> bool { let mut visited = HashSet::new(); self.dfs(&mut visited, 0); - visited.len() == self.len() - } - - pub fn pst(&mut self) -> Option<()> { - for x in self.vertex_pairs() { - if self[x] != 1 { - self[x] = usize::MAX; + visited.len() == self.order() + } + + /// This functiona and the helpers it relies on should soon be superceded by + /// a proper plane embedding. + pub fn cycle_is_face(&self, mut cycle: Vec) -> bool { + let mut dupe = self.clone(); + while !cycle.is_empty() { + let v = cycle.remove(0); + dupe.delete(v); + for u in &mut cycle { + if *u > v { + *u -= 1; + } } } - // if self.edges.is_empty() { - // return; - // } - - let n = self.len(); - // Vertex - // - // d-queues associated w each vertex - // maps from v -> ( maps from d -> u ) - let mut dqueue: Vec> = vec![Default::default(); self.len()]; - // - let mut children: Vec> = vec![Default::default(); self.len()]; - - // Counters for vertices whos shortest paths have already been obtained - let mut counters: Vec = vec![n - 1; self.len()]; - - // The element D[i, j] represents the distance from v_i to vj. - let mut dist: Distance = Distance::new(self.len()); - - // d = 0 - let mut depth = 1; - // while 0 < |V| - loop { - let verts: HashSet = counters - .iter() - .enumerate() - .filter_map(|(v, c)| if *c == 0 { None } else { Some(v) }) - .collect(); - - if verts.is_empty() { - break; - } - - let mut removed = false; - - for v in verts.into_iter() { - // for v in V - // START EXTEND(v, d, D, S) - if depth == 1 { - // - for w in self.connections(v) { - // Connected node - // D[w.id, v.id] = d - dist[[v, w]] = 1; - // add w' to v'.children - children[v].push(w); - // v.que.enque(w', 1) - dqueue[v].push_back((w, 1)); - dqueue[w].push_back((v, 1)); - // v.c = v.c + 1 - counters[v] -= 1; - removed = true; - } - } else { - // w = v.que.deque(d - 1) - // while w is not None: - 'dq: loop { - // let vqueue = dqueue[v]; - let Some((w, d)) = dqueue[v].pop_front() else { - break; - }; - if d != depth - 1 { - dqueue[v].push_back((w, d)); - break; - } - // for x in w.children - for x in children[w].clone() { - //let e: Edge = (x, v).into(); - if x != v && dist[[x, v]] == usize::MAX { - // D[x.id, v.id] = d; - dist[[x, v]] = depth; - // add x' to w' children - children[w].push(x); - // v.que.enque(x', d) - dqueue[v].push_back((x, depth)); - dqueue[x].push_back((v, depth)); - // v.c = v.c + 1 - removed = true; - counters[v] -= 1; - counters[x] -= 1; - // if v.c == n: return - if counters[x] == 0 && counters[w] == 0 && counters[v] == 0 { - break 'dq; - } - } - } + dupe.is_connected() + } + + /// Use a simple BFS to compute the shortest paths for all pairs + pub fn bfs_apsp(&mut self) { + for source in self.vertices() { + let mut visited = vec![false; self.order()]; + let mut queue = vec![source]; + visited[source] = true; + while !queue.is_empty() { + let current = queue.remove(0); + for neighbor in self.neighbors(current) { + if !visited[neighbor] { + self[[source, neighbor]] = self[[source, current]] + 1; + queue.push(neighbor); + visited[neighbor] = true; } } } - // END EXTEND - // d = d + 1 - depth += 1; - - if !removed { - *self = dist; - log::error!("failed distance computation"); - return None; - } } - - *self = dist; - Some(()) } pub fn springs(&self) -> Vec<[VertexId; 2]> { @@ -231,7 +166,7 @@ impl Distance { /// Number of faces pub fn face_count(&self) -> i64 { - 2 + self.edges().count() as i64 - self.len() as i64 + 2 + self.edges().count() as i64 - self.order() as i64 } } @@ -239,24 +174,28 @@ impl Index<[VertexId; 2]> for Distance { type Output = usize; fn index(&self, index: [VertexId; 2]) -> &Self::Output { - &self.distance[index[0].max(index[1])][index[0].min(index[1])] + let x = index[0].max(index[1]); + let y = index[0].min(index[1]); + &self.distance[(x * (x + 1)) / 2 + y] } } impl IndexMut<[VertexId; 2]> for Distance { fn index_mut(&mut self, index: [VertexId; 2]) -> &mut Self::Output { - &mut self.distance[index[0].max(index[1])][index[0].min(index[1])] + let x = index[0].max(index[1]); + let y = index[0].min(index[1]); + &mut self.distance[(x * (x + 1)) / 2 + y] } } impl Display for Distance { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_fmt(format_args!("\t|"))?; - for i in 0..self.len() { + for i in 0..self.order() { f.write_fmt(format_args!(" {i} |"))?; } f.write_fmt(format_args!("\n\t"))?; - for _ in 0..self.len() { + for _ in 0..self.order() { f.write_fmt(format_args!("____"))?; } f.write_fmt(format_args!("\n"))?; diff --git a/src/polyhedron/shape/distance/test.rs b/src/polyhedron/shape/distance/test.rs index 9dfff095..9f11c554 100644 --- a/src/polyhedron/shape/distance/test.rs +++ b/src/polyhedron/shape/distance/test.rs @@ -1,13 +1,10 @@ -use std::fs::create_dir_all; - use super::*; -use crate::render::message::PresetMessage::{self, *}; -use test_case::test_case; + impl Distance { pub fn floyd(&mut self) { // let dist be a |V| × |V| array of minimum distances initialized to ∞ (infinity) - let mut graph: Distance = Distance::new(self.distance.len()); + let mut graph: Distance = Distance::new(self.order); for e in self.edges() { graph[e] = 1; } @@ -47,21 +44,23 @@ fn basics() { graph.connect([0, 1]); graph.connect([0, 2]); graph.connect([1, 2]); - assert_eq!(graph.connections(0), vec![1, 2]); - assert_eq!(graph.connections(1), vec![0, 2]); - assert_eq!(graph.connections(2), vec![0, 1]); - assert_eq!(graph.connections(3), vec![]); + assert_eq!(graph.neighbors(0), vec![1, 2]); + assert_eq!(graph.neighbors(1), vec![0, 2]); + assert_eq!(graph.neighbors(2), vec![0, 1]); + assert_eq!(graph.neighbors(3), vec![]); // Disconnect graph.disconnect([0, 1]); - assert_eq!(graph.connections(0), vec![2]); - assert_eq!(graph.connections(1), vec![2]); + assert_eq!(graph.neighbors(0), vec![2]); + assert_eq!(graph.neighbors(1), vec![2]); // Delete + println!("graph: {graph}"); graph.delete(1); - assert_eq!(graph.connections(0), vec![1]); - assert_eq!(graph.connections(2), vec![]); - assert_eq!(graph.connections(1), vec![0]); + println!("graph: {graph}"); + assert_eq!(graph.neighbors(0), vec![1]); + assert_eq!(graph.neighbors(2), vec![]); + assert_eq!(graph.neighbors(1), vec![0]); } #[test] @@ -73,20 +72,43 @@ fn chordless_cycles() { graph.connect([2, 3]); println!("chordless_cycles:"); - println!("{graph}"); - graph.pst(); - println!("{graph}"); - + graph.bfs_apsp(); graph.connect([2, 0]); } #[test] fn contract_edge() { let mut graph = Distance::tetrahedron(); + println!("tetrahedron: {graph}"); + println!("contracting [0, 2]......"); graph.contract_edge([0, 2]); + println!("contracted: {graph}"); let mut triangle = Distance::new(3); triangle[[0, 1]] = 1; triangle[[1, 2]] = 1; triangle[[2, 0]] = 1; + println!("expectation: {triangle}"); assert_eq!(graph, triangle); } + +#[test] +fn bfs_apsp() { + let mut distance = Distance::new(4); + distance.connect([0, 1]); + distance.connect([1, 2]); + distance.connect([2, 3]); + distance.bfs_apsp(); + assert_eq!(distance[[0, 2]], 2); + assert_eq!(distance[[1, 3]], 2); + assert_eq!(distance[[0, 3]], 3); + + /* + * + [ + [0, 1, -1, -1], + [1, 0, 1, -1], + [-1, 1, 0, 1], + [-1, -1, 1, 0], + ] + */ +} diff --git a/src/polyhedron/shape/mod.rs b/src/polyhedron/shape/mod.rs index d023e224..e4f3a763 100644 --- a/src/polyhedron/shape/mod.rs +++ b/src/polyhedron/shape/mod.rs @@ -7,8 +7,8 @@ use std::{fmt::Display, ops::Range}; use cycles::*; use distance::*; -// #[cfg(test)] -// mod test; +#[cfg(test)] +mod test; use crate::polyhedron::*; @@ -44,12 +44,12 @@ impl Display for Shape { } impl Shape { - pub fn len(&self) -> usize { - self.distance.len() + pub fn order(&self) -> usize { + self.distance.order() } pub fn degree(&self, v: usize) -> usize { - self.distance.connections(v).len() + self.distance.neighbors(v).len() } pub fn edges(&self) -> impl Iterator + use<'_> { @@ -61,21 +61,14 @@ impl Shape { } pub fn recompute(&mut self) { - // log::info!("new distance:\n{}", self.distance); // Update the distance matrix in place - self.distance.pst(); + self.distance.bfs_apsp(); // Find and save cycles self.cycles = Cycles::from(&self.distance); - // log::info!("new cycles:\n{:?}", self.cycles); // Find and save springs self.springs = self.distance.springs(); } - #[allow(dead_code)] - pub fn compute_springs(&mut self) { - self.springs = self.distance.springs(); - } - pub fn compute_graph_svg(&mut self) { self.svg = self.distance.svg().unwrap_or_default(); } diff --git a/src/polyhedron/shape/test.rs b/src/polyhedron/shape/test.rs index c80f0d14..8e7e9392 100644 --- a/src/polyhedron/shape/test.rs +++ b/src/polyhedron/shape/test.rs @@ -1,31 +1,11 @@ use super::*; -use crate::render::message::PresetMessage::{self, *}; -use std::fs::create_dir_all; - -use test_case::test_case; impl Shape { - pub fn tetrahedron() -> Shape { - Shape::from(Distance::tetrahedron()) + pub fn floyd(&mut self) { + self.distance.floyd(); } } -// #[test] -// fn truncate_contract() { -// let prefix = "tests/truncate_contract/"; -// create_dir_all(prefix).unwrap(); -// let mut shape = Shape::from(Distance::tetrahedron()); -// //shape.distance.render(prefix, "tetrahedron.svg"); -// let edges = shape.truncate(None); -// println!("edges: {edges:?}"); -// //shape.distance.render(prefix, "truncated_tetrahedron.svg"); -// shape.distance.contract_edges(edges); -// // shape -// // .distance -// // .render(prefix, "contracted_truncated_tetrahedron.svg"); -// assert_eq!(Distance::tetrahedron(), shape.distance); -// } -// #[test] #[ignore] fn split_vertex_contract() { @@ -47,15 +27,3 @@ fn split_vertex_contract() { test.distance.contract_edges(edges); assert_eq!(Distance::tetrahedron(), test.distance); } - -// #[test] -// fn ambo() { -// // let prefix = "tests/ambo/"; -// // create_dir_all(prefix).unwrap(); -// let tetrahedron = Shape::from(Distance::tetrahedron()); -// -// assert_eq!( -// tetrahedron.ambod(), -// Distance::preset(&PresetMessage::Octahedron) -// ); -// } diff --git a/src/polyhedron/test.rs b/src/polyhedron/test.rs index fd5170dd..2f10a1a2 100644 --- a/src/polyhedron/test.rs +++ b/src/polyhedron/test.rs @@ -1,35 +1,45 @@ use super::*; -use crate::render::message::PresetMessage::{self}; +use crate::render::message::PresetMessage::{self, *}; use std::fs::create_dir_all; // -// use test_case::test_case; -// #[test_case(Polyhedron::preset(&Pyramid(3)); "T")] -// #[test_case(Polyhedron::preset(&Prism(4)); "C")] -// #[test_case(Polyhedron::preset(&Octahedron); "O")] + +impl Polyhedron {} + +use test_case::test_case; +#[test_case(Polyhedron::preset(&Pyramid(3)); "T")] +#[test_case(Polyhedron::preset(&Prism(4)); "C")] +#[test_case(Polyhedron::preset(&Octahedron); "O")] // #[test_case(Polyhedron::preset(&Dodecahedron); "D")] -// #[test_case(Polyhedron::preset(&Icosahedron); "I")] -// #[test_case({ let mut g = Polyhedron::preset(&Prism(4)); g.truncate(); g} ; "tC")] -// #[test_case({ let mut g = Polyhedron::preset(&Octahedron); g.truncate(); g} ; "tO")] -// #[test_case({ let mut g = Polyhedron::preset(&Dodecahedron); g.truncate(); g} ; "tD")] -// fn polytope_pst(shape: Polyhedron) { -// // let mut pst = shape.clone(); -// // shape.shape -// // pst.distance.pst(); -// // let mut floyd = shape.clone(); -// // floyd.distance.floyd(); -// // assert_eq!(floyd.distance, pst.distance); -// } +#[test_case(Polyhedron::preset(&Icosahedron); "I")] +// #[test_case({ let mut g = Polyhedron::preset(&Prism(4)); g.truncate(0); g} ; "tC")] +// #[test_case({ let mut g = Polyhedron::preset(&Octahedron); g.truncate(0); g} ; "tO")] +// #[test_case({ let mut g = Polyhedron::preset(&Dodecahedron); g.truncate(0); g} ; "tD")] +fn polytope_apsp(poly: Polyhedron) { + let mut bfs = poly.clone(); + bfs.shape.recompute(); + let mut floyd = poly.clone(); + floyd.shape.floyd(); + assert_eq!(bfs.shape, poly.shape); + assert_eq!(bfs.shape, floyd.shape); +} + +#[test] +#[ignore] +fn truncate_contract() { + let mut shape = Polyhedron::preset(&Pyramid(3)); + let edges = shape.truncate(0); + shape.contract(edges); + assert_eq!(Polyhedron::preset(&Pyramid(3)).shape, shape.shape); +} #[test] +#[ignore] fn ambo() { use PresetMessage::*; let prefix = "tests/ambo/"; create_dir_all(prefix).unwrap(); let mut polyhedron = Polyhedron::preset(&Pyramid(3)); - polyhedron.shape.png(); polyhedron.ambo_contract(); - polyhedron.shape.png(); let octahedron = Polyhedron::preset(&Octahedron); - octahedron.shape.png(); assert_eq!(polyhedron.shape, octahedron.shape); } diff --git a/src/render/app.rs b/src/render/app.rs index b6477cf6..c2fd62f9 100644 --- a/src/render/app.rs +++ b/src/render/app.rs @@ -367,7 +367,7 @@ impl ApplicationHandler for App<'_> { // Operations "e" => Some(Expand), "d" => Some(Dual), - "s" => Some(Snub), + "s" => Some(SplitVertex(0)), "k" => Some(Kis), "j" => Some(Join), "a" => Some(Ambo), From fa6bd3e338a4ba7c0bb3f6e507888a3de4e46186 Mon Sep 17 00:00:00 2001 From: Vera Gonzalez Date: Tue, 3 Dec 2024 01:57:52 -0500 Subject: [PATCH 5/6] updated cargo version --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9dae763d..e08accd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "ab_glyph" @@ -2768,7 +2768,7 @@ dependencies = [ [[package]] name = "polyblade" -version = "0.1.0" +version = "0.2.0" dependencies = [ "bytemuck", "console_error_panic_hook", diff --git a/Cargo.toml b/Cargo.toml index a2e0e865..67593347 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polyblade" -version = "0.1.0" +version = "0.2.0" authors = ["Vera Gonzalez "] edition = "2021" license-file = "LICENSE" From 2ea4dd5ec00798ff39c7bf60edf87ffa6229c63d Mon Sep 17 00:00:00 2001 From: Vera Gonzalez Date: Wed, 22 Oct 2025 14:22:29 -0400 Subject: [PATCH 6/6] cargo update --- Cargo.lock | 1475 +++++++++++++++++++++++++++------------------------- 1 file changed, 752 insertions(+), 723 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e08accd4..3c9b1729 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "ab_glyph" -version = "0.2.29" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0" +checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -14,15 +14,15 @@ dependencies = [ [[package]] name = "ab_glyph_rasterizer" -version = "0.1.8" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" +checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "ahash" @@ -30,19 +30,19 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom", + "getrandom 0.2.16", "once_cell", "version_check", ] [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom", + "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -50,9 +50,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android-activity" @@ -61,7 +61,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", - "bitflags 2.6.0", + "bitflags 2.10.0", "cc", "cesu8", "jni", @@ -128,9 +128,9 @@ dependencies = [ [[package]] name = "async-broadcast" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" dependencies = [ "event-listener", "event-listener-strategy", @@ -140,9 +140,9 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.3.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" dependencies = [ "concurrent-queue", "event-listener-strategy", @@ -152,22 +152,23 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.13.1" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" dependencies = [ "async-task", "concurrent-queue", "fastrand", "futures-lite", + "pin-project-lite", "slab", ] [[package]] name = "async-fs" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" +checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5" dependencies = [ "async-lock", "blocking", @@ -176,28 +177,27 @@ dependencies = [ [[package]] name = "async-io" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" dependencies = [ - "async-lock", + "autocfg", "cfg-if", "concurrent-queue", "futures-io", "futures-lite", "parking", "polling", - "rustix", + "rustix 1.1.2", "slab", - "tracing", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "async-lock" -version = "3.4.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" dependencies = [ "event-listener", "event-listener-strategy", @@ -206,9 +206,9 @@ dependencies = [ [[package]] name = "async-process" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" dependencies = [ "async-channel", "async-io", @@ -219,8 +219,7 @@ dependencies = [ "cfg-if", "event-listener", "futures-lite", - "rustix", - "tracing", + "rustix 1.1.2", ] [[package]] @@ -231,14 +230,14 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] name = "async-signal" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" +checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" dependencies = [ "async-io", "async-lock", @@ -246,10 +245,10 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix", + "rustix 1.1.2", "signal-hook-registry", "slab", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -260,13 +259,13 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.83" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] @@ -277,9 +276,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "base64" @@ -316,11 +315,11 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -344,14 +343,14 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "objc2", + "objc2 0.5.2", ] [[package]] name = "blocking" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" dependencies = [ "async-channel", "async-task", @@ -362,9 +361,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "by_address" @@ -374,35 +373,29 @@ checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" [[package]] name = "bytemuck" -version = "1.20.0" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.8.0" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" -version = "1.8.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "calloop" @@ -410,10 +403,10 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "log", "polling", - "rustix", + "rustix 0.38.44", "slab", "thiserror", ] @@ -425,17 +418,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" dependencies = [ "calloop", - "rustix", + "rustix 0.38.44", "wayland-backend", "wayland-client", ] [[package]] name = "cc" -version = "1.2.1" +version = "1.2.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -449,9 +443,9 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -467,9 +461,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "clipboard-win" -version = "5.4.0" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" +checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" dependencies = [ "error-code", ] @@ -480,9 +474,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b7f4aaa047ba3c3630b080bb9860894732ff23e2aee290a418909aa6d5df38f" dependencies = [ - "objc2", + "objc2 0.5.2", "objc2-app-kit", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -602,9 +596,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ "core-foundation-sys", "libc", @@ -635,8 +629,8 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" dependencies = [ - "bitflags 2.6.0", - "core-foundation 0.10.0", + "bitflags 2.10.0", + "core-foundation 0.10.1", "core-graphics-types 0.2.0", "foreign-types", "libc", @@ -659,8 +653,8 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.6.0", - "core-foundation 0.10.0", + "bitflags 2.10.0", + "core-foundation 0.10.1", "libc", ] @@ -670,7 +664,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59fd57d82eb4bfe7ffa9b1cec0c05e2fd378155b47f255a67983cb4afe0e80c2" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "fontdb 0.16.2", "log", "rangemap", @@ -689,27 +683,27 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -726,15 +720,15 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-common" @@ -754,9 +748,9 @@ checksum = "1f791803201ab277ace03903de1594460708d2d54df6053f2d9e82f592b19e3b" [[package]] name = "cursor-icon" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" [[package]] name = "d3d12" @@ -764,8 +758,8 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e3d747f100290a1ca24b752186f61f6637e1deffe3bf6320de6fcb29510a307" dependencies = [ - "bitflags 2.6.0", - "libloading 0.8.5", + "bitflags 2.10.0", + "libloading 0.8.9", "winapi", ] @@ -787,9 +781,9 @@ dependencies = [ [[package]] name = "data-url" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" +checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" [[package]] name = "dconf_rs" @@ -847,7 +841,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] @@ -856,7 +850,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading 0.8.5", + "libloading 0.8.9", ] [[package]] @@ -876,9 +870,9 @@ dependencies = [ [[package]] name = "dot-structures" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "675e35c02a51bb4d4618cb4885b3839ce6d1787c97b664474d9208d074742e20" +checksum = "498cfcded997a93eb31edd639361fa33fd229a8784e953b37d71035fe3890b7b" [[package]] name = "downcast-rs" @@ -888,9 +882,9 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dpi" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" [[package]] name = "drm" @@ -898,11 +892,11 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98888c4bbd601524c11a7ed63f814b8825f420514f78e96f752c437ae9cbb5d1" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "bytemuck", "drm-ffi", "drm-fourcc", - "rustix", + "rustix 0.38.44", ] [[package]] @@ -912,7 +906,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97c98727e48b7ccb4f4aea8cfe881e5b07f702d17b7875991881b41af7278d53" dependencies = [ "drm-sys", - "rustix", + "rustix 0.38.44", ] [[package]] @@ -933,9 +927,9 @@ dependencies = [ [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "endi" @@ -945,9 +939,9 @@ checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" [[package]] name = "enumflags2" -version = "0.7.10" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" dependencies = [ "enumflags2_derive", "serde", @@ -955,42 +949,42 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.10" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "error-code" -version = "3.3.1" +version = "3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f" +checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" [[package]] name = "etagere" -version = "0.2.13" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e2f1e3be19fb10f549be8c1bf013e8675b4066c445e36eb76d2ebb2f54ee495" +checksum = "fc89bf99e5dc15954a60f707c1e09d7540e5cd9af85fa75caa0b510bc08c5342" dependencies = [ "euclid", "svg_fmt", @@ -1007,9 +1001,9 @@ dependencies = [ [[package]] name = "event-listener" -version = "5.3.1" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ "concurrent-queue", "parking", @@ -1018,9 +1012,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ "event-listener", "pin-project-lite", @@ -1034,24 +1028,30 @@ checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" [[package]] name = "fastrand" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fdeflate" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" dependencies = [ "simd-adler32", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" + [[package]] name = "flate2" -version = "1.0.35" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9" dependencies = [ "crc32fast", "miniz_oxide", @@ -1074,9 +1074,9 @@ dependencies = [ [[package]] name = "fontconfig-parser" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fcfcd44ca6e90c921fee9fa665d530b21ef1327a4c1a6c5250ea44b776ada7" +checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646" dependencies = [ "roxmltree", ] @@ -1127,7 +1127,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] @@ -1138,9 +1138,9 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -1196,9 +1196,9 @@ checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ "fastrand", "futures-core", @@ -1215,7 +1215,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] @@ -1250,9 +1250,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -1260,19 +1260,19 @@ dependencies = [ [[package]] name = "gethostname" -version = "0.4.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" dependencies = [ - "libc", - "windows-targets 0.48.5", + "rustix 1.1.2", + "windows-link", ] [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "js-sys", @@ -1281,11 +1281,23 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + [[package]] name = "gif" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +checksum = "4ae047235e33e2829703574b54fdec96bfbad892062d97fed2f76022287de61b" dependencies = [ "color_quant", "weezl", @@ -1335,7 +1347,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "gpu-alloc-types", ] @@ -1345,7 +1357,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", ] [[package]] @@ -1367,7 +1379,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "gpu-descriptor-types", "hashbrown 0.14.5", ] @@ -1378,14 +1390,14 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bf0b36e6f090b7e1d8a4b49c0cb81c1f8376f72198c65dd3ad9ff3556b8b78c" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", ] [[package]] name = "graphviz-rust" -version = "0.9.3" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f7892a4538fc9aa3658ae6962774428487c16e11663c58c594357975377c901" +checksum = "db134cb611668917cabf340af9a39518426f9a10827b4cedcb4cdcf84443f6d0" dependencies = [ "dot-generator", "dot-structures", @@ -1393,7 +1405,7 @@ dependencies = [ "into-attr-derive", "pest", "pest_derive", - "rand", + "rand 0.9.2", "tempfile", ] @@ -1409,12 +1421,13 @@ dependencies = [ [[package]] name = "half" -version = "2.4.1" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", + "zerocopy", ] [[package]] @@ -1432,15 +1445,15 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.12", "allocator-api2", ] [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" [[package]] name = "hassle-rs" @@ -1448,10 +1461,10 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "com", "libc", - "libloading 0.8.5", + "libloading 0.8.9", "thiserror", "widestring", "winapi", @@ -1465,15 +1478,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hex" @@ -1487,15 +1494,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys 0.52.0", -] - [[package]] name = "iced" version = "0.13.1" @@ -1527,7 +1525,7 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0013a238275494641bf8f1732a23a808196540dc67b22ff97099c044ae4c8a1c" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "bytes", "dark-light", "glam", @@ -1535,7 +1533,7 @@ dependencies = [ "num-traits", "once_cell", "palette", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "smol_str", "thiserror", "web-time", @@ -1559,7 +1557,7 @@ dependencies = [ "futures", "iced_core", "log", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "wasm-bindgen-futures", "wasm-timer", ] @@ -1573,7 +1571,7 @@ dependencies = [ "cosmic-text", "etagere", "lru", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "wgpu", ] @@ -1583,7 +1581,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba25a18cfa6d5cc160aca7e1b34f73ccdff21680fa8702168c09739767b6c66f" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "bytemuck", "cosmic-text", "half", @@ -1592,7 +1590,7 @@ dependencies = [ "log", "once_cell", "raw-window-handle", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "thiserror", "unicode-segmentation", ] @@ -1635,7 +1633,7 @@ dependencies = [ "kurbo 0.10.4", "log", "resvg", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "softbuffer", "tiny-skia", ] @@ -1646,7 +1644,7 @@ version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15708887133671d2bcc6c1d01d1f176f43a64d6cdc3b2bf893396c3ee498295f" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "bytemuck", "futures", "glam", @@ -1656,7 +1654,7 @@ dependencies = [ "log", "once_cell", "resvg", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "thiserror", "wgpu", ] @@ -1671,7 +1669,7 @@ dependencies = [ "iced_runtime", "num-traits", "once_cell", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "thiserror", "unicode-segmentation", ] @@ -1686,7 +1684,7 @@ dependencies = [ "iced_graphics", "iced_runtime", "log", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "thiserror", "tracing", "wasm-bindgen-futures", @@ -1698,21 +1696,22 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", + "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" dependencies = [ "displaydoc", "litemap", @@ -1721,31 +1720,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ "displaydoc", "icu_collections", @@ -1753,72 +1732,59 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "potential_utf", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", + "icu_locale_core", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.89", -] - [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -1827,9 +1793,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -1843,12 +1809,12 @@ checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284" [[package]] name = "indexmap" -version = "2.6.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.16.0", ] [[package]] @@ -1906,25 +1872,27 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ + "getrandom 0.3.4", "libc", ] [[package]] name = "jpeg-decoder" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" +checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07" [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -1935,7 +1903,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" dependencies = [ "libc", - "libloading 0.8.5", + "libloading 0.8.9", "pkg-config", ] @@ -1957,11 +1925,12 @@ dependencies = [ [[package]] name = "kurbo" -version = "0.11.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89234b2cc610a7dd927ebde6b41dd1a5d4214cffaef4cf1fb2195d592f92518f" +checksum = "c62026ae44756f8a599ba21140f350303d4f08dcdcc71b5ad9c9bb8128c13c62" dependencies = [ "arrayvec", + "euclid", "smallvec", ] @@ -1973,9 +1942,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.166" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ccc108bbc0b1331bd061864e7cd823c0cab660bbe6970e66e2c0614decde36" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libloading" @@ -1989,36 +1958,36 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-link", ] [[package]] name = "libm" -version = "0.2.11" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.3" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "libc", - "redox_syscall 0.5.7", + "redox_syscall 0.5.18", ] [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "linux-raw-sys" @@ -2026,27 +1995,32 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7" +[[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.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.22" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "lru" @@ -2065,15 +2039,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memmap2" -version = "0.9.5" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" dependencies = [ "libc", ] @@ -2093,7 +2067,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "block", "core-graphics-types 0.1.3", "foreign-types", @@ -2104,9 +2078,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.8.0" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", "simd-adler32", @@ -2119,7 +2093,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50e3524642f53d9af419ab5e8dd29d3ba155708267667c2f3f06c88c9e130843" dependencies = [ "bit-set", - "bitflags 2.6.0", + "bitflags 2.10.0", "codespan-reporting", "hexf-parse", "indexmap", @@ -2138,7 +2112,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "jni-sys", "log", "ndk-sys 0.6.0+11769913", @@ -2177,7 +2151,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "cfg-if", "cfg_aliases 0.2.1", "libc", @@ -2186,12 +2160,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "overload", - "winapi", + "windows-sys 0.61.2", ] [[package]] @@ -2205,33 +2178,34 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", ] [[package]] name = "num_enum" -version = "0.7.3" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" dependencies = [ "num_enum_derive", + "rustversion", ] [[package]] name = "num_enum_derive" -version = "0.7.3" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] @@ -2260,19 +2234,28 @@ dependencies = [ "objc2-encode", ] +[[package]] +name = "objc2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" +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.6.0", + "bitflags 2.10.0", "block2", "libc", - "objc2", + "objc2 0.5.2", "objc2-core-data", "objc2-core-image", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-quartz-core", ] @@ -2282,11 +2265,11 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "block2", - "objc2", + "objc2 0.5.2", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -2296,8 +2279,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" dependencies = [ "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -2306,10 +2289,10 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -2319,8 +2302,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", "objc2-metal", ] @@ -2331,16 +2314,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" dependencies = [ "block2", - "objc2", + "objc2 0.5.2", "objc2-contacts", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] name = "objc2-encode" -version = "4.0.3" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" [[package]] name = "objc2-foundation" @@ -2348,11 +2331,21 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "block2", "dispatch", "libc", - "objc2", + "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.3", ] [[package]] @@ -2362,9 +2355,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" dependencies = [ "block2", - "objc2", + "objc2 0.5.2", "objc2-app-kit", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -2373,10 +2366,10 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -2385,10 +2378,10 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", "objc2-metal", ] @@ -2398,8 +2391,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" dependencies = [ - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -2408,14 +2401,14 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "block2", - "objc2", + "objc2 0.5.2", "objc2-cloud-kit", "objc2-core-data", "objc2-core-image", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-link-presentation", "objc2-quartz-core", "objc2-symbols", @@ -2430,8 +2423,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" dependencies = [ "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -2440,11 +2433,11 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "block2", - "objc2", + "objc2 0.5.2", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -2458,9 +2451,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "orbclient" @@ -2491,19 +2484,13 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "owned_ttf_parser" -version = "0.25.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" +checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b" dependencies = [ - "ttf-parser 0.25.0", + "ttf-parser 0.25.1", ] [[package]] @@ -2527,7 +2514,7 @@ dependencies = [ "by_address", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] @@ -2549,12 +2536,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", - "parking_lot_core 0.9.10", + "parking_lot_core 0.9.12", ] [[package]] @@ -2573,15 +2560,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.7", + "redox_syscall 0.5.18", "smallvec", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -2592,26 +2579,25 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.7.14" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +checksum = "989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4" dependencies = [ "memchr", - "thiserror", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.14" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" +checksum = "187da9a3030dbafabbbfb20cb323b976dc7b7ce91fcd84f2f74d6e31d378e2de" dependencies = [ "pest", "pest_generator", @@ -2619,33 +2605,32 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.14" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" +checksum = "49b401d98f5757ebe97a26085998d6c0eecec4995cad6ab7fc30ffdf4b052843" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] name = "pest_meta" -version = "2.7.14" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" +checksum = "72f27a2cfee9f9039c4d86faa5af122a0ac3851441a34865b8a043b46be0065a" dependencies = [ - "once_cell", "pest", "sha2", ] [[package]] name = "phf" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ "phf_macros", "phf_shared", @@ -2653,34 +2638,34 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", - "rand", + "rand 0.8.5", ] [[package]] name = "phf_macros" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" dependencies = [ "phf_generator", "phf_shared", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] name = "phf_shared" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ - "siphasher 0.3.11", + "siphasher", ] [[package]] @@ -2691,29 +2676,29 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.1.7" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.7" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] name = "pin-project-lite" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -2734,15 +2719,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "png" -version = "0.17.14" +version = "0.17.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -2753,17 +2738,16 @@ dependencies = [ [[package]] name = "polling" -version = "3.7.4" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi 0.4.0", + "hermit-abi", "pin-project-lite", - "rustix", - "tracing", - "windows-sys 0.59.0", + "rustix 1.1.2", + "windows-sys 0.61.2", ] [[package]] @@ -2773,7 +2757,7 @@ dependencies = [ "bytemuck", "console_error_panic_hook", "console_log", - "getrandom", + "getrandom 0.2.16", "graphviz-rust", "iced", "iced_aw", @@ -2781,9 +2765,9 @@ dependencies = [ "iced_widget", "iced_winit", "log", - "rand", + "rand 0.8.5", "ron", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "serde", "strum", "strum_macros", @@ -2795,11 +2779,20 @@ dependencies = [ "webbrowser", ] +[[package]] +name = "potential_utf" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +dependencies = [ + "zerovec", +] + [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ "zerocopy", ] @@ -2812,46 +2805,52 @@ checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" [[package]] name = "proc-macro-crate" -version = "3.2.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] [[package]] name = "profiling" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" +checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" [[package]] name = "quick-xml" -version = "0.36.2" +version = "0.37.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" +checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" dependencies = [ "memchr", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "rand" version = "0.8.5" @@ -2859,8 +2858,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "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 0.9.0", + "rand_core 0.9.3", ] [[package]] @@ -2870,7 +2879,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -2879,20 +2898,29 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.4", ] [[package]] name = "range-alloc" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab" +checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde" [[package]] name = "rangemap" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684" +checksum = "f93e7e49bb0bf967717f7bd674458b3d6b0c5f48ec7e3038166026a69fc22223" [[package]] name = "raw-window-handle" @@ -2902,9 +2930,9 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "rayon" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -2912,9 +2940,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -2922,9 +2950,9 @@ dependencies = [ [[package]] name = "read-fonts" -version = "0.22.5" +version = "0.22.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a04b892cb6f91951f144c33321843790c8574c825aafdb16d815fd7183b5229" +checksum = "69aacb76b5c29acfb7f90155d39759a29496aebb49395830e928a9703d2eec2f" dependencies = [ "bytemuck", "font-types", @@ -2950,11 +2978,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", ] [[package]] @@ -2963,7 +2991,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom", + "getrandom 0.2.16", "libredox", "thiserror", ] @@ -2992,9 +3020,9 @@ dependencies = [ [[package]] name = "rgb" -version = "0.8.50" +version = "0.8.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" +checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce" dependencies = [ "bytemuck", ] @@ -3006,7 +3034,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64 0.21.7", - "bitflags 2.6.0", + "bitflags 2.10.0", "serde", "serde_derive", ] @@ -3035,28 +3063,41 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustix" -version = "0.38.41" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "errno", "libc", - "linux-raw-sys 0.4.14", - "windows-sys 0.52.0", + "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 2.10.0", + "errno", + "libc", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.2", ] [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "rustybuzz" @@ -3064,7 +3105,7 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "bytemuck", "libm", "smallvec", @@ -3077,9 +3118,9 @@ dependencies = [ [[package]] name = "safe_arch" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3460605018fdc9612bce72735cba0d27efbcd9904780d44c7e3a9948f96148a" +checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" dependencies = [ "bytemuck", ] @@ -3120,39 +3161,49 @@ dependencies = [ [[package]] name = "self_cell" -version = "1.0.4" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" +checksum = "16c2f82143577edb4921b71ede051dac62ca3c16084e918bf7b40c96ae10eb33" [[package]] name = "serde" -version = "1.0.215" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] name = "serde_repr" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] @@ -3168,9 +3219,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -3194,9 +3245,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" dependencies = [ "libc", ] @@ -3209,19 +3260,13 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "simplecss" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a11be7c62927d9427e9f40f3444d5499d868648e2edbc4e2116de69e7ec0e89d" +checksum = "7a9c6883ca9c3c7c90e888de77b7a5c849c779d25d74a1269b0218b14e8b136c" dependencies = [ "log", ] -[[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - [[package]] name = "siphasher" version = "1.0.1" @@ -3240,12 +3285,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "slotmap" @@ -3258,9 +3300,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.2" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "smithay-client-toolkit" @@ -3268,14 +3310,14 @@ version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "calloop", "calloop-wayland-source", "cursor-icon", "libc", "log", "memmap2", - "rustix", + "rustix 0.38.44", "thiserror", "wayland-backend", "wayland-client", @@ -3323,12 +3365,12 @@ dependencies = [ "js-sys", "log", "memmap2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", "objc2-quartz-core", "raw-window-handle", - "redox_syscall 0.5.7", - "rustix", + "redox_syscall 0.5.18", + "rustix 0.38.44", "tiny-xlib", "wasm-bindgen", "wayland-backend", @@ -3345,14 +3387,14 @@ version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", ] [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "static_assertions" @@ -3385,23 +3427,23 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] name = "svg_fmt" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce5d813d71d82c4cbc1742135004e4a79fd870214c155443451c139c9470a0aa" +checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb" [[package]] name = "svgtypes" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794de53cc48eaabeed0ab6a3404a65f40b3e38c067e4435883a65d2aa4ca000e" +checksum = "68c7541fff44b35860c1a7a47a7cadf3e4a304c457b58f9870d9706ece028afc" dependencies = [ - "kurbo 0.11.1", - "siphasher 1.0.1", + "kurbo 0.11.3", + "siphasher", ] [[package]] @@ -3428,9 +3470,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.89" +version = "2.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b" dependencies = [ "proc-macro2", "quote", @@ -3439,13 +3481,13 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] @@ -3459,15 +3501,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.14.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ - "cfg-if", "fastrand", + "getrandom 0.3.4", "once_cell", - "rustix", - "windows-sys 0.59.0", + "rustix 1.1.2", + "windows-sys 0.61.2", ] [[package]] @@ -3497,7 +3539,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] @@ -3508,7 +3550,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", "test-case-core", ] @@ -3529,17 +3571,16 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] name = "thread_local" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -3570,22 +3611,22 @@ dependencies = [ [[package]] name = "tiny-xlib" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d52f22673960ad13af14ff4025997312def1223bfa7c8e4949d099e6b3d5d1c" +checksum = "0324504befd01cab6e0c994f34b2ffa257849ee019d3fb3b64fb2c858887d89e" dependencies = [ "as-raw-xcb-connection", "ctor-lite", - "libloading 0.8.5", + "libloading 0.8.9", "pkg-config", "tracing", ] [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", @@ -3593,9 +3634,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" dependencies = [ "tinyvec_macros", ] @@ -3608,26 +3649,39 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +dependencies = [ + "serde_core", +] [[package]] name = "toml_edit" -version = "0.22.22" +version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" dependencies = [ "indexmap", "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +dependencies = [ "winnow", ] [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -3636,20 +3690,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.28" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", "valuable", @@ -3668,9 +3722,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "nu-ansi-term", "sharded-slab", @@ -3694,15 +3748,15 @@ checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" [[package]] name = "ttf-parser" -version = "0.25.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5902c5d130972a0000f60860bfbf46f7ca3db5391eddfedd1b8728bd9dc96c0e" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" [[package]] name = "typenum" -version = "1.17.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "ucd-trie" @@ -3733,9 +3787,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-bidi-mirroring" @@ -3751,9 +3805,9 @@ checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656" [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" [[package]] name = "unicode-linebreak" @@ -3799,13 +3853,14 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -3819,13 +3874,13 @@ dependencies = [ "flate2", "fontdb 0.18.0", "imagesize", - "kurbo 0.11.1", + "kurbo 0.11.3", "log", "pico-args", "roxmltree", "rustybuzz", "simplecss", - "siphasher 1.0.1", + "siphasher", "strict-num", "svgtypes", "tiny-skia-path", @@ -3835,12 +3890,6 @@ dependencies = [ "xmlwriter", ] -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -3849,9 +3898,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "valuable" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "version_check" @@ -3871,53 +3920,64 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3925,22 +3985,25 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" +dependencies = [ + "unicode-ident", +] [[package]] name = "wasm-timer" @@ -3959,13 +4022,13 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.3.7" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" +checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35" dependencies = [ "cc", "downcast-rs", - "rustix", + "rustix 1.1.2", "scoped-tls", "smallvec", "wayland-sys", @@ -3973,12 +4036,12 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.7" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280" +checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" dependencies = [ - "bitflags 2.6.0", - "rustix", + "bitflags 2.10.0", + "rustix 1.1.2", "wayland-backend", "wayland-scanner", ] @@ -3989,29 +4052,29 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "cursor-icon", "wayland-backend", ] [[package]] name = "wayland-cursor" -version = "0.31.7" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b08bc3aafdb0035e7fe0fdf17ba0c09c268732707dca4ae098f60cb28c9e4c" +checksum = "447ccc440a881271b19e9989f75726d60faa09b95b0200a9b7eb5cc47c3eeb29" dependencies = [ - "rustix", + "rustix 1.1.2", "wayland-client", "xcursor", ] [[package]] name = "wayland-protocols" -version = "0.32.5" +version = "0.32.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e" +checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -4019,11 +4082,11 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b31cab548ee68c7eb155517f2212049dc151f7cd7910c2b66abfd31c3ee12bd" +checksum = "a07a14257c077ab3279987c4f8bb987851bf57081b93710381daea94f2c2c032" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -4032,11 +4095,11 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "782e12f6cd923c3c316130d56205ebab53f55d6666b7faddfad36cecaeeb4022" +checksum = "efd94963ed43cf9938a090ca4f7da58eb55325ec8200c3848963e98dc25b78ec" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -4045,9 +4108,9 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.5" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" +checksum = "54cb1e9dc49da91950bdfd8b848c49330536d9d1fb03d4bfec8cae50caa50ae3" dependencies = [ "proc-macro2", "quick-xml", @@ -4056,9 +4119,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.31.5" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" +checksum = "34949b42822155826b41db8e5d0c1be3a2bd296c747577a43a3e6daefc296142" dependencies = [ "dlib", "log", @@ -4068,9 +4131,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" dependencies = [ "js-sys", "wasm-bindgen", @@ -4088,27 +4151,25 @@ dependencies = [ [[package]] name = "webbrowser" -version = "1.0.2" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5f07fb9bc8de2ddfe6b24a71a75430673fd679e568c48b52716cef1cfae923" +checksum = "00f1243ef785213e3a32fa0396093424a3a6ea566f9948497e5a2309261a4c97" dependencies = [ - "block2", - "core-foundation 0.10.0", - "home", + "core-foundation 0.10.1", "jni", "log", "ndk-context", - "objc2", - "objc2-foundation", + "objc2 0.6.3", + "objc2-foundation 0.3.2", "url", "web-sys", ] [[package]] name = "weezl" -version = "0.1.8" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" +checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" [[package]] name = "wgpu" @@ -4122,7 +4183,7 @@ dependencies = [ "js-sys", "log", "naga", - "parking_lot 0.12.3", + "parking_lot 0.12.5", "profiling", "raw-window-handle", "smallvec", @@ -4143,14 +4204,14 @@ checksum = "28b94525fc99ba9e5c9a9e24764f2bc29bad0911a7446c12f446a8277369bf3a" dependencies = [ "arrayvec", "bit-vec", - "bitflags 2.6.0", + "bitflags 2.10.0", "cfg_aliases 0.1.1", "codespan-reporting", "indexmap", "log", "naga", "once_cell", - "parking_lot 0.12.3", + "parking_lot 0.12.5", "profiling", "raw-window-handle", "rustc-hash 1.1.0", @@ -4171,7 +4232,7 @@ dependencies = [ "arrayvec", "ash", "bit-set", - "bitflags 2.6.0", + "bitflags 2.10.0", "block", "cfg_aliases 0.1.1", "core-graphics-types 0.1.3", @@ -4185,14 +4246,14 @@ dependencies = [ "js-sys", "khronos-egl", "libc", - "libloading 0.8.5", + "libloading 0.8.9", "log", "metal", "naga", "ndk-sys 0.5.0+25.2.9519653", "objc", "once_cell", - "parking_lot 0.12.3", + "parking_lot 0.12.5", "profiling", "range-alloc", "raw-window-handle", @@ -4212,16 +4273,16 @@ version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b671ff9fb03f78b46ff176494ee1ebe7d603393f42664be55b64dc8d53969805" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "js-sys", "web-sys", ] [[package]] name = "wide" -version = "0.7.30" +version = "0.7.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e6db2670d2be78525979e9a5f9c69d296fd7d670549fe9ebf70f8708cb5019" +checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" dependencies = [ "bytemuck", "safe_arch", @@ -4229,9 +4290,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" [[package]] name = "winapi" @@ -4251,11 +4312,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -4297,6 +4358,12 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-sys" version = "0.45.0" @@ -4324,6 +4391,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -4339,21 +4415,6 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - [[package]] name = "windows-targets" version = "0.52.6" @@ -4376,12 +4437,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -4394,12 +4449,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -4412,12 +4461,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -4436,12 +4479,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -4454,12 +4491,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -4472,12 +4503,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -4490,12 +4515,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -4504,14 +4523,14 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winit" -version = "0.30.5" +version = "0.30.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0be9e76a1f1077e04a411f0b989cbd3c93339e1771cb41e71ac4aee95bfd2c67" +checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.12", "android-activity", "atomic-waker", - "bitflags 2.6.0", + "bitflags 2.10.0", "block2", "bytemuck", "calloop", @@ -4525,16 +4544,16 @@ dependencies = [ "libc", "memmap2", "ndk", - "objc2", + "objc2 0.5.2", "objc2-app-kit", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-ui-kit", "orbclient", "percent-encoding", "pin-project", "raw-window-handle", "redox_syscall 0.4.1", - "rustix", + "rustix 0.38.44", "sctk-adwaita", "smithay-client-toolkit", "smol_str", @@ -4556,9 +4575,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.20" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] @@ -4573,16 +4592,16 @@ dependencies = [ ] [[package]] -name = "write16" -version = "1.0.0" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "x11-dl" @@ -4597,30 +4616,30 @@ dependencies = [ [[package]] name = "x11rb" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" dependencies = [ "as-raw-xcb-connection", "gethostname", "libc", - "libloading 0.8.5", + "libloading 0.8.9", "once_cell", - "rustix", + "rustix 1.1.2", "x11rb-protocol", ] [[package]] name = "x11rb-protocol" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" [[package]] name = "xcursor" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" +checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b" [[package]] name = "xdg-home" @@ -4638,7 +4657,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.10.0", "dlib", "log", "once_cell", @@ -4653,9 +4672,9 @@ checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xml-rs" -version = "0.8.23" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af310deaae937e48a26602b730250b4949e125f468f11e6990be3e5304ddd96f" +checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7" [[package]] name = "xmlwriter" @@ -4671,9 +4690,9 @@ checksum = "c94451ac9513335b5e23d7a8a2b61a7102398b8cca5160829d313e84c9d98be1" [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" dependencies = [ "serde", "stable_deref_trait", @@ -4683,13 +4702,13 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", "synstructure", ] @@ -4717,7 +4736,7 @@ dependencies = [ "hex", "nix", "ordered-stream", - "rand", + "rand 0.8.5", "serde", "serde_repr", "sha1", @@ -4740,7 +4759,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", "zvariant_utils", ] @@ -4763,51 +4782,61 @@ checksum = "dd15f8e0dbb966fd9245e7498c7e9e5055d9e5c8b676b95bd67091cd11a1e697" [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ - "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] name = "zerofrom" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", "synstructure", ] +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + [[package]] name = "zerovec" -version = "0.10.4" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" dependencies = [ "yoke", "zerofrom", @@ -4816,13 +4845,13 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ] [[package]] @@ -4847,7 +4876,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", "zvariant_utils", ] @@ -4859,5 +4888,5 @@ checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.107", ]