diff --git a/.changeset/retire-log-viewer.md b/.changeset/retire-log-viewer.md new file mode 100644 index 00000000..2835675f --- /dev/null +++ b/.changeset/retire-log-viewer.md @@ -0,0 +1,28 @@ +--- +"@smooai/logger": minor +--- + +Retire the deprecated egui log viewer and remove its install-time binary download. + +`@smooai/logger`'s `postinstall` ran `bundle-log-viewer`, which downloaded +`https://github.com/SmooAI/logger/releases/latest/download/smooai-log-viewer--` +and `chmod 0755`'d it on **every** `npm i @smooai/logger` — an unpinned, unverified remote +binary fetch (`latest`, not the installed version, with no checksum or signature), silently +falling back to `cargo build` when the download failed. The Python distribution did the same +thing from `poe build` / `poe publish`. + +The binary it fetched was the egui log viewer, which `log-viewer/DEPRECATED.md` declared gone as +of `studio-v0.1.0` — superseded by SmooAI Observability Studio in +[SmooAI/observability](https://github.com/SmooAI/observability) (`desktop/`). + +Removed: + +- the `postinstall` hook and both `bundle-log-viewer` scripts (Node + Python) +- the `smooai-log-viewer` bin (npm) and console script (PyPI) and their wrappers +- the `log-viewer/` crate source and the `build-log-viewer.yml` release workflow +- 97 MB of tracked build artifacts (`python/log-viewer/{linux-x64,darwin-arm64}` binaries and a + stale `smooai-logger-3.1.2.tgz`), now gitignored +- an unreferenced `log-viewer/README.md` entry in `files`, and the unused `@oclif/core` devDep + +`log-viewer/DEPRECATED.md` stays as the tombstone pointing at the replacement. The logging API +itself is unchanged in every language. diff --git a/.github/workflows/build-log-viewer.yml b/.github/workflows/build-log-viewer.yml deleted file mode 100644 index a43e07c2..00000000 --- a/.github/workflows/build-log-viewer.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Build Log Viewer Binaries - -on: - release: - types: [published] - -env: - FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" - -jobs: - build: - strategy: - fail-fast: false - matrix: - include: - - os: macos-latest - asset_name: smooai-log-viewer-darwin-arm64 - binary_name: smooai-log-viewer - - os: macos-15-intel - asset_name: smooai-log-viewer-darwin-x64 - binary_name: smooai-log-viewer - - os: ubuntu-latest - asset_name: smooai-log-viewer-linux-x64 - binary_name: smooai-log-viewer - - os: windows-latest - asset_name: smooai-log-viewer-win32-x64.exe - binary_name: smooai-log-viewer.exe - - runs-on: ${{ matrix.os }} - permissions: - contents: write - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Rust toolchain - uses: dtolnay/rust-toolchain@stable - - - name: Cache Rust build artifacts - uses: Swatinem/rust-cache@v2 - with: - workspaces: log-viewer -> log-viewer/target - cache-on-failure: true - - - name: Build log-viewer binary - run: cargo build --release --manifest-path log-viewer/Cargo.toml - - - name: Rename binary for upload - shell: bash - run: cp "log-viewer/target/release/${{ matrix.binary_name }}" "${{ matrix.asset_name }}" - - - name: Upload release asset - uses: softprops/action-gh-release@v2 - with: - files: ${{ matrix.asset_name }} diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 75837f0a..dbae639e 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -39,9 +39,7 @@ jobs: - name: Cache Rust build artifacts uses: Swatinem/rust-cache@v2 with: - workspaces: | - rust/logger -> rust/logger/target - log-viewer -> log-viewer/target + workspaces: rust/logger -> rust/logger/target cache-on-failure: true - name: Setup Go diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 35b19487..547cd678 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,9 +44,7 @@ jobs: - name: Cache Rust build artifacts uses: Swatinem/rust-cache@v2 with: - workspaces: | - rust/logger -> rust/logger/target - log-viewer -> log-viewer/target + workspaces: rust/logger -> rust/logger/target cache-on-failure: true - name: Set up Python diff --git a/.gitignore b/.gitignore index 41e166fe..d2c67a8d 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,7 @@ dotnet/**/obj/ dotnet/dist/ *.nupkg *.snupkg + +# Never commit release tarballs or downloaded binaries +*.tgz +python/log-viewer/ diff --git a/README.md b/README.md index 5500c85b..84ebafa3 100644 --- a/README.md +++ b/README.md @@ -273,7 +273,7 @@ The wire schema is shared; port depth is not identical. Here's the honest status ## 🔎 Looking for the desktop Log Viewer? -It moved. The Rust/egui log viewer that used to live in [`log-viewer/`](log-viewer/) has been rebuilt as **SmooAI Observability Studio** — a Dioxus native desktop client for SmooAI logs, errors, and metrics — and lives in the [SmooAI/observability](https://github.com/SmooAI/observability) repo (`desktop/`), with builds on its [releases page](https://github.com/SmooAI/observability/releases). The egui implementation here is gone as of `studio-v0.1.0`; see [`log-viewer/DEPRECATED.md`](log-viewer/DEPRECATED.md) for the migration story. +It moved. The Rust/egui log viewer that used to live here has been rebuilt as **SmooAI Observability Studio** — a Dioxus native desktop client for SmooAI logs, errors, and metrics — and lives in the [SmooAI/observability](https://github.com/SmooAI/observability) repo (`desktop/`), with builds on its [releases page](https://github.com/SmooAI/observability/releases). The crate has been deleted from this repo; see [`log-viewer/DEPRECATED.md`](log-viewer/DEPRECATED.md) for the migration story. ## 🧩 Part of Smoo AI diff --git a/log-viewer/ABOUT.md b/log-viewer/ABOUT.md deleted file mode 100644 index 2d65ff2f..00000000 --- a/log-viewer/ABOUT.md +++ /dev/null @@ -1,168 +0,0 @@ -# smooai-log-viewer - -> ⚠️ **DEPRECATED — see [`DEPRECATED.md`](./DEPRECATED.md).** This crate has moved to [`SmooAI/observability`](https://github.com/SmooAI/observability) under `rust/log-viewer/` as part of SMOODEV-1175. The copy here is preserved only to keep the existing release pipeline working during the transition; new work happens in the new location. - -`smooai-log-viewer` is a desktop GUI application written in Rust. It loads structured log files from multiple services, normalizes them, and renders them in a responsive table using the `egui` immediate-mode UI toolkit. The following sections walk through the code layout and the main concepts a new Rust developer will encounter while exploring the project. - ---- - -## 1. Project layout - -``` -log-viewer/ -├── Cargo.toml # Rust package manifest -├── src/ -│ ├── main.rs # Application entry point and UI logic -│ └── theme.rs # Shared color palette + egui styling helpers -└── target/ # Build artifacts (generated) -``` - -The application is a single binary crate. When you run `cargo build --release`, Cargo compiles everything under `src/` into `target/release/smooai-log-viewer`. - ---- - -## 2. Core dependencies - -The `Cargo.toml` manifest declares the crate name, version, and dependencies: - -```toml -[dependencies] -eframe = { version = "0.28", features = ["persistence"] } -egui = "0.28" -egui_extras = "0.28" -anyhow = "1" # ergonomic error handling -rayon = "1.10" # parallel file parsing -memmap2 = "0.9" # memory-map log files for fast scanning -serde / serde_json # parse & manipulate JSON log entries -duckdb = { version = "0.9.2", features = ["bundled"] } -rfd = "0.15" # native file chooser dialogs -``` - -Key crates (with docs): - -- [`eframe`](https://docs.rs/eframe/latest/eframe/) – wraps `egui` and handles native window creation. -- [`egui`](https://docs.rs/egui/latest/egui/) / [`egui_extras`](https://docs.rs/egui_extras/latest/egui_extras/) – immediate-mode UI widgets and helpers like `TableBuilder`. -- [`anyhow`](https://docs.rs/anyhow/latest/anyhow/) – ergonomic error propagation. -- [`rayon`](https://docs.rs/rayon/latest/rayon/) – data-parallel iterators used when parsing many log files. -- [`memmap2`](https://docs.rs/memmap2/latest/memmap2/) – memory maps large log files so we can scan them without loading everything into RAM. -- [`serde`](https://docs.rs/serde/latest/serde/) / [`serde_json`](https://docs.rs/serde_json/latest/serde_json/) – parse JSON log payloads and flatten them into key/value maps. -- [`duckdb`](https://docs.rs/duckdb/latest/duckdb/) – embedded analytics database that stores the parsed rows for fast filtering. -- [`rfd`](https://docs.rs/rfd/latest/rfd/) – cross-platform native file/folder pickers. - ---- - -## 3. Entry point (main.rs) - -Rust executables start in `fn main()`. In `src/main.rs` the `main` function configures the `eframe::NativeOptions`, loads the application icon, and calls `eframe::run_native` with `App::default()`: - -```rust -fn main() -> Result<()> { - let native_options = eframe::NativeOptions { /* ... */ }; - eframe::run_native( - "Smoo AI Log Viewer", - native_options, - Box::new(|_cc| Ok(Box::new(App::default()))), - )? -``` - -`App` implements the `eframe::App` trait, so the `update` method is called every frame to draw the UI and process events. - -### Struct `App` - -`App` stores all runtime state: parsed catalog, filters, pagination, watcher thread handles, etc. New Rustaceans will notice that the struct mixes owned data (`Vec`, `HashMap`, etc.) with `Option>` channels. Rust’s ownership rules enforce that we move data into the background threads and only mutate the UI state on the main thread. - -Key fields: - -- `catalog: Catalog` – parsed logs + deduplicated column metadata. -- `filtered: Vec` – row indices after applying search filters. -- `index_rx: Option>` – channel for background indexing progress. -- `watch_handle`, `watch_stop` – thread handles / flags for filesystem watching. -- `visible_columns`, `column_widths` – dynamic column selection and sizing. -- `index_progress: Option<(usize, usize)>` – progress bar state. - -### UI frame (`update`) - -The `update` method orchestrates everything each frame: - -1. Apply light/dark themes (`theme::apply_visuals`). -2. Drain any file watcher notifications and schedule reindexing if necessary. -3. Consume background indexing events; render a progress bar while indexing and merge the new catalog when finished. -4. Draw the top toolbar, left filter panel, and central table using `egui` widgets. -5. Draw the status bar with a “Live/Indexing” indicator and the latest status message. - -Understanding borrowing rules is essential here: the code clones rows out of the catalog before rendering to avoid holding long-lived borrows while drawing each cell. - ---- - -## 4. Parsing logs (Catalog + background indexer) - -`Catalog` aggregates: - -```rust -struct Catalog { - files: Vec, // paths + sanitized lines - rows: Vec, // flattened log entries across all files - columns: Vec, // unique keys discovered in JSON payloads - duckdb_path: Option, -} -``` - -The function `index_monorepo(root: &Path, progress_tx: Option>)` does the heavy work. It: - -1. Walks the filesystem rooting at `root`, gathering every `.smooai-logs` directory. -2. Uses `rayon::par_iter()` to memory-map each log file (`memmap2::Mmap`), split it into lines, and attempt to parse JSON blocks. Each block is flattened into key/value pairs (stored in `Row::flat`), and common columns (`time`, `level`, `msg`, `error`, etc.) are extracted into typed fields. -3. Sorts rows by timestamp, writes them into an embedded DuckDB table, and returns the finished `Catalog`. - -An indexing thread sends `IndexEvent::Progress` updates over an `mpsc::Sender`, which the UI consumes to update the progress bar while the background job runs. - ---- - -## 5. Rendering the log table - -The table lives in `render_log_table`. Important ideas for Rust newcomers: - -- `TableBuilder` from `egui_extras` builds a multi-column layout declaratively. Column widths are stored in a `HashMap` so a user’s adjustments persist through reindexes. -- `indices: Vec` clones the filtered row indices so we can iterate without holding a borrow into `self.filtered` while mutably updating the UI. -- Each cell is an `egui::Label`. For error fields we tint the text red (`theme::smoo::RED`), and we truncate long values but preserve tooltips via `response.on_hover_text(value.clone())`. -- Selecting a row stores its index in `self.selected` and drives the context view below the table. - -Managing ownership and borrowing is the central lesson: clone the `Row` before rendering so you can move values into closures without fighting the borrow checker. - ---- - -## 6. Context view & actions - -Below the table, `render_context_panel` shows the source file, surrounding lines, and JSON view for the selected row. Buttons let you navigate to previous/next matches. Copying JSON uses `ui.output_mut(|o| o.copied_text = ...)`. The context menu on each cell (`response.context_menu`) provides “Open file” and “Open with…” actions; on macOS the latter runs `open -t` to launch the default text editor. - ---- - -## 7. File watching & live mode - -`watch_root` spawns a thread that scans `.smooai-logs` directories, tracking file modification times and sizes. When it detects a change it sends a `WatchEvent::FileChanged(path)` or `WatchEvent::FileRemoved(path)` over `watch_rx`. In **live mode** (the default) the main thread collects these events and `process_live_events` incrementally re-parses only the changed files—avoiding a full reindex. When live mode is disabled, changes are noted in the status bar but not applied until the user clicks **Reindex**. A full reindex can still be triggered manually at any time. - ---- - -## 8. Theming (`theme.rs`) - -`theme.rs` collects color constants and utility functions. New Rust devs will notice heavy use of `const fn` and `match` to map log levels to colors. `apply_visuals` modifies the global `egui::Context` styling: background colors, widget rounding, spacing, etc., keeping the UI consistent between light/dark modes. - ---- - -## 9. Building & running locally - -1. Install Rust + Cargo (`rustup` recommended). -2. `cd log-viewer` -3. `cargo run --release` - -Because the project pulls in C dependencies (DuckDB bundles LLVM bits), the first build can take several minutes, but subsequent `cargo run` invocations are fast thanks to incremental compilation. - ---- - -## 10. Next steps for newcomers - -- Read through `render_log_table` with `rust-analyzer` (VS Code/VSCodium) to see how borrow checking is resolved. Hovering a symbol shows lifetime information and types. -- Experiment with adding a new filter field: update `Filters`, wire it into `apply_filters`, and add a `TextEdit` in the sidebar. -- Try enabling the `simd-json` feature (`cargo run --release --features simd`) to learn how feature flags change dependencies. -- Investigate `index_monorepo` to practice parallel iterators and error handling with `anyhow::Result`. - -The codebase purposefully keeps most logic in two files so beginners can follow the flow without bouncing between many modules. As you get comfortable with ownership, channels, and `egui`, you can start breaking out pieces (e.g., parsing, DuckDB integration, UI widgets) into dedicated modules for long-term maintainability. diff --git a/log-viewer/Cargo.lock b/log-viewer/Cargo.lock deleted file mode 100644 index 9ca135da..00000000 --- a/log-viewer/Cargo.lock +++ /dev/null @@ -1,6432 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "ab_glyph" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2" -dependencies = [ - "ab_glyph_rasterizer", - "owned_ttf_parser", -] - -[[package]] -name = "ab_glyph_rasterizer" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" - -[[package]] -name = "accesskit" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74a4b14f3d99c1255dcba8f45621ab1a2e7540a0009652d33989005a4d0bfc6b" -dependencies = [ - "enumn", - "serde", -] - -[[package]] -name = "accesskit_consumer" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c17cca53c09fbd7288667b22a201274b9becaa27f0b91bf52a526db95de45e6" -dependencies = [ - "accesskit", -] - -[[package]] -name = "accesskit_macos" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3b6ae1eabbfbced10e840fd3fce8a93ae84f174b3e4ba892ab7bcb42e477a7" -dependencies = [ - "accesskit", - "accesskit_consumer", - "objc2 0.3.0-beta.3.patch-leaks.3", - "once_cell", -] - -[[package]] -name = "accesskit_unix" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f46c18d99ba61ad7123dd13eeb0c104436ab6af1df6a1cd8c11054ed394a08" -dependencies = [ - "accesskit", - "accesskit_consumer", - "async-channel", - "async-once-cell", - "atspi", - "futures-lite 1.13.0", - "once_cell", - "serde", - "zbus 3.15.2", -] - -[[package]] -name = "accesskit_windows" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afcae27ec0974fc7c3b0b318783be89fd1b2e66dd702179fe600166a38ff4a0b" -dependencies = [ - "accesskit", - "accesskit_consumer", - "once_cell", - "paste", - "static_assertions", - "windows 0.48.0", -] - -[[package]] -name = "accesskit_winit" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5284218aca17d9e150164428a0ebc7b955f70e3a9a78b4c20894513aabf98a67" -dependencies = [ - "accesskit", - "accesskit_macos", - "accesskit_unix", - "accesskit_windows", - "winit", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "ahash" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" -dependencies = [ - "getrandom 0.2.17", - "once_cell", - "version_check", -] - -[[package]] -name = "ahash" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" -dependencies = [ - "cfg-if", - "const-random", - "getrandom 0.3.4", - "once_cell", - "serde", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" -dependencies = [ - "memchr", -] - -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[package]] -name = "android-activity" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" -dependencies = [ - "android-properties", - "bitflags 2.11.0", - "cc", - "cesu8", - "jni", - "jni-sys", - "libc", - "log", - "ndk", - "ndk-context", - "ndk-sys", - "num_enum", - "thiserror 1.0.69", -] - -[[package]] -name = "android-properties" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anyhow" -version = "1.0.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" - -[[package]] -name = "arbitrary" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" -dependencies = [ - "derive_arbitrary", -] - -[[package]] -name = "arboard" -version = "3.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0348a1c054491f4bfe6ab86a7b6ab1e44e45d899005de92f58b3df180b36ddaf" -dependencies = [ - "clipboard-win", - "log", - "objc2 0.6.3", - "objc2-app-kit 0.3.2", - "objc2-foundation 0.3.2", - "parking_lot", - "percent-encoding", - "windows-sys 0.60.2", - "x11rb", -] - -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - -[[package]] -name = "arrow" -version = "56.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e833808ff2d94ed40d9379848a950d995043c7fb3e81a30b383f4c6033821cc" -dependencies = [ - "arrow-arith", - "arrow-array", - "arrow-buffer", - "arrow-cast", - "arrow-data", - "arrow-ord", - "arrow-row", - "arrow-schema", - "arrow-select", - "arrow-string", -] - -[[package]] -name = "arrow-arith" -version = "56.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad08897b81588f60ba983e3ca39bda2b179bdd84dced378e7df81a5313802ef8" -dependencies = [ - "arrow-array", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "chrono", - "num", -] - -[[package]] -name = "arrow-array" -version = "56.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8548ca7c070d8db9ce7aa43f37393e4bfcf3f2d3681df278490772fd1673d08d" -dependencies = [ - "ahash 0.8.12", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "chrono", - "half", - "hashbrown 0.16.1", - "num", -] - -[[package]] -name = "arrow-buffer" -version = "56.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e003216336f70446457e280807a73899dd822feaf02087d31febca1363e2fccc" -dependencies = [ - "bytes", - "half", - "num", -] - -[[package]] -name = "arrow-cast" -version = "56.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919418a0681298d3a77d1a315f625916cb5678ad0d74b9c60108eb15fd083023" -dependencies = [ - "arrow-array", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "arrow-select", - "atoi", - "base64 0.22.1", - "chrono", - "comfy-table", - "half", - "lexical-core", - "num", - "ryu", -] - -[[package]] -name = "arrow-data" -version = "56.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5c64fff1d142f833d78897a772f2e5b55b36cb3e6320376f0961ab0db7bd6d0" -dependencies = [ - "arrow-buffer", - "arrow-schema", - "half", - "num", -] - -[[package]] -name = "arrow-ord" -version = "56.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c8f82583eb4f8d84d4ee55fd1cb306720cddead7596edce95b50ee418edf66f" -dependencies = [ - "arrow-array", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "arrow-select", -] - -[[package]] -name = "arrow-row" -version = "56.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d07ba24522229d9085031df6b94605e0f4b26e099fb7cdeec37abd941a73753" -dependencies = [ - "arrow-array", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "half", -] - -[[package]] -name = "arrow-schema" -version = "56.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3aa9e59c611ebc291c28582077ef25c97f1975383f1479b12f3b9ffee2ffabe" -dependencies = [ - "bitflags 2.11.0", -] - -[[package]] -name = "arrow-select" -version = "56.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c41dbbd1e97bfcaee4fcb30e29105fb2c75e4d82ae4de70b792a5d3f66b2e7a" -dependencies = [ - "ahash 0.8.12", - "arrow-array", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "num", -] - -[[package]] -name = "arrow-string" -version = "56.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53f5183c150fbc619eede22b861ea7c0eebed8eaac0333eaa7f6da5205fd504d" -dependencies = [ - "arrow-array", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "arrow-select", - "memchr", - "num", - "regex", - "regex-syntax", -] - -[[package]] -name = "as-raw-xcb-connection" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" - -[[package]] -name = "ash" -version = "0.37.3+1.3.251" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" -dependencies = [ - "libloading 0.7.4", -] - -[[package]] -name = "ashpd" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f3f79755c74fd155000314eb349864caa787c6592eace6c6882dad873d9c39" -dependencies = [ - "async-fs 2.2.0", - "async-net", - "enumflags2", - "futures-channel", - "futures-util", - "rand 0.9.2", - "raw-window-handle 0.6.2", - "serde", - "serde_repr", - "url", - "wayland-backend", - "wayland-client", - "wayland-protocols 0.32.10", - "zbus 5.14.0", -] - -[[package]] -name = "async-broadcast" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" -dependencies = [ - "event-listener 2.5.3", - "futures-core", -] - -[[package]] -name = "async-broadcast" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" -dependencies = [ - "event-listener 5.4.1", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-channel" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand 2.3.0", - "futures-lite 2.6.1", - "pin-project-lite", - "slab", -] - -[[package]] -name = "async-fs" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" -dependencies = [ - "async-lock 2.8.0", - "autocfg", - "blocking", - "futures-lite 1.13.0", -] - -[[package]] -name = "async-fs" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5" -dependencies = [ - "async-lock 3.4.2", - "blocking", - "futures-lite 2.6.1", -] - -[[package]] -name = "async-io" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" -dependencies = [ - "async-lock 2.8.0", - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-lite 1.13.0", - "log", - "parking", - "polling 2.8.0", - "rustix 0.37.28", - "slab", - "socket2 0.4.10", - "waker-fn", -] - -[[package]] -name = "async-io" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" -dependencies = [ - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite 2.6.1", - "parking", - "polling 3.11.0", - "rustix 1.1.4", - "slab", - "windows-sys 0.61.2", -] - -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener 2.5.3", -] - -[[package]] -name = "async-lock" -version = "3.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" -dependencies = [ - "event-listener 5.4.1", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-net" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" -dependencies = [ - "async-io 2.6.0", - "blocking", - "futures-lite 2.6.1", -] - -[[package]] -name = "async-once-cell" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288f83726785267c6f2ef073a3d83dc3f9b81464e9f99898240cced85fce35a" - -[[package]] -name = "async-process" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" -dependencies = [ - "async-io 1.13.0", - "async-lock 2.8.0", - "async-signal", - "blocking", - "cfg-if", - "event-listener 3.1.0", - "futures-lite 1.13.0", - "rustix 0.38.44", - "windows-sys 0.48.0", -] - -[[package]] -name = "async-process" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" -dependencies = [ - "async-channel", - "async-io 2.6.0", - "async-lock 3.4.2", - "async-signal", - "async-task", - "blocking", - "cfg-if", - "event-listener 5.4.1", - "futures-lite 2.6.1", - "rustix 1.1.4", -] - -[[package]] -name = "async-recursion" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "async-signal" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" -dependencies = [ - "async-io 2.6.0", - "async-lock 3.4.2", - "atomic-waker", - "cfg-if", - "futures-core", - "futures-io", - "rustix 1.1.4", - "signal-hook-registry", - "slab", - "windows-sys 0.61.2", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - -[[package]] -name = "async-trait" -version = "0.1.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "atoi" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" -dependencies = [ - "num-traits", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "atspi" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6059f350ab6f593ea00727b334265c4dfc7fd442ee32d264794bd9bdc68e87ca" -dependencies = [ - "atspi-common", - "atspi-connection", - "atspi-proxies", -] - -[[package]] -name = "atspi-common" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92af95f966d2431f962bc632c2e68eda7777330158bf640c4af4249349b2cdf5" -dependencies = [ - "enumflags2", - "serde", - "static_assertions", - "zbus 3.15.2", - "zbus_names 2.6.1", - "zvariant 3.15.2", -] - -[[package]] -name = "atspi-connection" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c65e7d70f86d4c0e3b2d585d9bf3f979f0b19d635a336725a88d279f76b939" -dependencies = [ - "atspi-common", - "atspi-proxies", - "futures-lite 1.13.0", - "zbus 3.15.2", -] - -[[package]] -name = "atspi-proxies" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6495661273703e7a229356dcbe8c8f38223d697aacfaf0e13590a9ac9977bb52" -dependencies = [ - "atspi-common", - "serde", - "zbus 3.15.2", -] - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" -dependencies = [ - "serde_core", -] - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-sys" -version = "0.1.0-beta.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa55741ee90902547802152aaf3f8e5248aab7e21468089560d4c8840561146" -dependencies = [ - "objc-sys 0.2.0-beta.2", -] - -[[package]] -name = "block-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7" -dependencies = [ - "objc-sys 0.3.5", -] - -[[package]] -name = "block2" -version = "0.2.0-alpha.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dd9e63c1744f755c2f60332b88de39d341e5e86239014ad839bd71c106dec42" -dependencies = [ - "block-sys 0.1.0-beta.1", - "objc2-encode 2.0.0-pre.2", -] - -[[package]] -name = "block2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" -dependencies = [ - "block-sys 0.2.1", - "objc2 0.4.1", -] - -[[package]] -name = "block2" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" -dependencies = [ - "objc2 0.5.2", -] - -[[package]] -name = "block2" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" -dependencies = [ - "objc2 0.6.3", -] - -[[package]] -name = "blocking" -version = "1.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" -dependencies = [ - "async-channel", - "async-task", - "futures-io", - "futures-lite 2.6.1", - "piper", -] - -[[package]] -name = "borsh" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" -dependencies = [ - "borsh-derive", - "cfg_aliases 0.2.1", -] - -[[package]] -name = "borsh-derive" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" -dependencies = [ - "once_cell", - "proc-macro-crate 3.4.0", - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "bumpalo" -version = "3.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" - -[[package]] -name = "bytecheck" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" -dependencies = [ - "bytecheck_derive", - "ptr_meta", - "simdutf8", -] - -[[package]] -name = "bytecheck_derive" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "bytemuck" -version = "1.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "byteorder-lite" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" - -[[package]] -name = "bytes" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" - -[[package]] -name = "calloop" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" -dependencies = [ - "bitflags 2.11.0", - "log", - "polling 3.11.0", - "rustix 0.38.44", - "slab", - "thiserror 1.0.69", -] - -[[package]] -name = "calloop" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dbf9978365bac10f54d1d4b04f7ce4427e51f71d61f2fe15e3fed5166474df7" -dependencies = [ - "bitflags 2.11.0", - "polling 3.11.0", - "rustix 1.1.4", - "slab", - "tracing", -] - -[[package]] -name = "calloop-wayland-source" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" -dependencies = [ - "calloop 0.12.4", - "rustix 0.38.44", - "wayland-backend", - "wayland-client", -] - -[[package]] -name = "calloop-wayland-source" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138efcf0940a02ebf0cc8d1eff41a1682a46b431630f4c52450d6265876021fa" -dependencies = [ - "calloop 0.14.4", - "rustix 1.1.4", - "wayland-backend", - "wayland-client", -] - -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - -[[package]] -name = "cc" -version = "1.2.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" -dependencies = [ - "find-msvc-tools", - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "cgl" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" -dependencies = [ - "libc", -] - -[[package]] -name = "chrono" -version = "0.4.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" -dependencies = [ - "iana-time-zone", - "js-sys", - "num-traits", - "serde", - "wasm-bindgen", - "windows-link", -] - -[[package]] -name = "clipboard-win" -version = "5.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" -dependencies = [ - "error-code", -] - -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width 0.1.14", -] - -[[package]] -name = "colored" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" -dependencies = [ - "lazy_static", - "windows-sys 0.59.0", -] - -[[package]] -name = "com" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6" -dependencies = [ - "com_macros", -] - -[[package]] -name = "com_macros" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5" -dependencies = [ - "com_macros_support", - "proc-macro2", - "syn 1.0.109", -] - -[[package]] -name = "com_macros_support" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "combine" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "memchr", -] - -[[package]] -name = "comfy-table" -version = "7.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0d05af1e006a2407bedef5af410552494ce5be9090444dbbcb57258c1af3d56" -dependencies = [ - "strum 0.26.3", - "strum_macros 0.26.4", - "unicode-width 0.2.2", -] - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "const-random" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" -dependencies = [ - "const-random-macro", -] - -[[package]] -name = "const-random-macro" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" -dependencies = [ - "getrandom 0.2.17", - "once_cell", - "tiny-keccak", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "core-graphics" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "core-graphics-types", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "libc", -] - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crunchy" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" - -[[package]] -name = "crypto-common" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "cursor-icon" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_arbitrary" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "directories" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - -[[package]] -name = "dispatch" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" - -[[package]] -name = "dispatch2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" -dependencies = [ - "bitflags 2.11.0", - "block2 0.6.2", - "libc", - "objc2 0.6.3", -] - -[[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.117", -] - -[[package]] -name = "dlib" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" -dependencies = [ - "libloading 0.8.9", -] - -[[package]] -name = "document-features" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" -dependencies = [ - "litrs", -] - -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - -[[package]] -name = "duckdb" -version = "1.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8685352ce688883098b61a361e86e87df66fc8c444f4a2411e884c16d5243a65" -dependencies = [ - "arrow", - "cast", - "fallible-iterator", - "fallible-streaming-iterator", - "hashlink", - "libduckdb-sys", - "num-integer", - "rust_decimal", - "strum 0.27.2", -] - -[[package]] -name = "ecolor" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e6b451ff1143f6de0f33fc7f1b68fecfd2c7de06e104de96c4514de3f5396f8" -dependencies = [ - "bytemuck", - "emath", - "serde", -] - -[[package]] -name = "eframe" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6490ef800b2e41ee129b1f32f9ac15f713233fe3bc18e241a1afe1e4fb6811e0" -dependencies = [ - "ahash 0.8.12", - "bytemuck", - "directories", - "document-features", - "egui", - "egui-wgpu", - "egui-winit", - "egui_glow", - "glow", - "glutin", - "glutin-winit", - "image", - "js-sys", - "log", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", - "parking_lot", - "percent-encoding", - "raw-window-handle 0.5.2", - "raw-window-handle 0.6.2", - "ron", - "serde", - "static_assertions", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "web-time 0.2.4", - "winapi", - "winit", -] - -[[package]] -name = "egui" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20c97e70a2768de630f161bb5392cbd3874fcf72868f14df0e002e82e06cb798" -dependencies = [ - "accesskit", - "ahash 0.8.12", - "emath", - "epaint", - "log", - "nohash-hasher", - "ron", - "serde", -] - -[[package]] -name = "egui-wgpu" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c7a7c707877c3362a321ebb4f32be811c0b91f7aebf345fb162405c0218b4c" -dependencies = [ - "ahash 0.8.12", - "bytemuck", - "document-features", - "egui", - "epaint", - "log", - "thiserror 1.0.69", - "type-map", - "web-time 0.2.4", - "wgpu", - "winit", -] - -[[package]] -name = "egui-winit" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fac4e066af341bf92559f60dbdf2020b2a03c963415349af5f3f8d79ff7a4926" -dependencies = [ - "accesskit_winit", - "ahash 0.8.12", - "arboard", - "egui", - "log", - "raw-window-handle 0.6.2", - "serde", - "smithay-clipboard", - "web-time 0.2.4", - "webbrowser", - "winit", -] - -[[package]] -name = "egui_extras" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb783d9fa348f69ed5c340aa25af78b5472043090e8b809040e30960cc2a746" -dependencies = [ - "ahash 0.8.12", - "egui", - "enum-map", - "log", - "mime_guess2", - "serde", -] - -[[package]] -name = "egui_glow" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2bdc8b38cfa17cc712c4ae079e30c71c00cd4c2763c9e16dc7860a02769103" -dependencies = [ - "ahash 0.8.12", - "bytemuck", - "egui", - "glow", - "log", - "memoffset 0.9.1", - "wasm-bindgen", - "web-sys", - "winit", -] - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "emath" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6a21708405ea88f63d8309650b4d77431f4bc28fb9d8e6f77d3963b51249e6" -dependencies = [ - "bytemuck", - "serde", -] - -[[package]] -name = "endi" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" - -[[package]] -name = "enum-map" -version = "2.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" -dependencies = [ - "enum-map-derive", - "serde", -] - -[[package]] -name = "enum-map-derive" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "enumflags2" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" -dependencies = [ - "enumflags2_derive", - "serde", -] - -[[package]] -name = "enumflags2_derive" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "enumn" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "epaint" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0dcc0a0771e7500e94cd1cb797bd13c9f23b9409bdc3c824e2cbc562b7fa01" -dependencies = [ - "ab_glyph", - "ahash 0.8.12", - "bytemuck", - "ecolor", - "emath", - "log", - "nohash-hasher", - "parking_lot", - "serde", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "error-code" -version = "3.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" - -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - -[[package]] -name = "event-listener" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener" -version = "5.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" -dependencies = [ - "event-listener 5.4.1", - "pin-project-lite", -] - -[[package]] -name = "fallible-iterator" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" - -[[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" - -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "fdeflate" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" -dependencies = [ - "simd-adler32", -] - -[[package]] -name = "filetime" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" -dependencies = [ - "cfg-if", - "libc", - "libredox", -] - -[[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "flate2" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" -dependencies = [ - "crc32fast", - "miniz_oxide", - "zlib-rs", -] - -[[package]] -name = "float-cmp" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" -dependencies = [ - "num-traits", -] - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "foreign-types" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" -dependencies = [ - "foreign-types-macros", - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "foreign-types-shared" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures-channel" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" - -[[package]] -name = "futures-io" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" - -[[package]] -name = "futures-lite" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - -[[package]] -name = "futures-lite" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" -dependencies = [ - "fastrand 2.3.0", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - -[[package]] -name = "futures-macro" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "futures-sink" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" - -[[package]] -name = "futures-task" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" - -[[package]] -name = "futures-util" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" -dependencies = [ - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "gethostname" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" -dependencies = [ - "rustix 1.1.4", - "windows-link", -] - -[[package]] -name = "getrandom" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi", - "wasip2", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasip2", - "wasip3", -] - -[[package]] -name = "gl_generator" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" -dependencies = [ - "khronos_api", - "log", - "xml-rs", -] - -[[package]] -name = "glow" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" -dependencies = [ - "js-sys", - "slotmap", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "glutin" -version = "0.31.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fcd4ae4e86d991ad1300b8f57166e5be0c95ef1f63f3f5b827f8a164548746" -dependencies = [ - "bitflags 2.11.0", - "cfg_aliases 0.1.1", - "cgl", - "core-foundation 0.9.4", - "dispatch", - "glutin_egl_sys", - "glutin_glx_sys", - "glutin_wgl_sys", - "icrate", - "libloading 0.8.9", - "objc2 0.4.1", - "once_cell", - "raw-window-handle 0.5.2", - "wayland-sys", - "windows-sys 0.48.0", - "x11-dl", -] - -[[package]] -name = "glutin-winit" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebcdfba24f73b8412c5181e56f092b5eff16671c514ce896b258a0a64bd7735" -dependencies = [ - "cfg_aliases 0.1.1", - "glutin", - "raw-window-handle 0.5.2", - "winit", -] - -[[package]] -name = "glutin_egl_sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77cc5623f5309ef433c3dd4ca1223195347fe62c413da8e2fdd0eb76db2d9bcd" -dependencies = [ - "gl_generator", - "windows-sys 0.48.0", -] - -[[package]] -name = "glutin_glx_sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a165fd686c10dcc2d45380b35796e577eacfd43d4660ee741ec8ebe2201b3b4f" -dependencies = [ - "gl_generator", - "x11-dl", -] - -[[package]] -name = "glutin_wgl_sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" -dependencies = [ - "gl_generator", -] - -[[package]] -name = "gpu-alloc" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" -dependencies = [ - "bitflags 2.11.0", - "gpu-alloc-types", -] - -[[package]] -name = "gpu-alloc-types" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" -dependencies = [ - "bitflags 2.11.0", -] - -[[package]] -name = "gpu-allocator" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f56f6318968d03c18e1bcf4857ff88c61157e9da8e47c5f29055d60e1228884" -dependencies = [ - "log", - "presser", - "thiserror 1.0.69", - "winapi", - "windows 0.52.0", -] - -[[package]] -name = "gpu-descriptor" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" -dependencies = [ - "bitflags 2.11.0", - "gpu-descriptor-types", - "hashbrown 0.15.5", -] - -[[package]] -name = "gpu-descriptor-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" -dependencies = [ - "bitflags 2.11.0", -] - -[[package]] -name = "half" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" -dependencies = [ - "cfg-if", - "crunchy", - "num-traits", - "zerocopy", -] - -[[package]] -name = "halfbrown" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8588661a8607108a5ca69cab034063441a0413a0b041c13618a7dd348021ef6f" -dependencies = [ - "hashbrown 0.14.5", - "serde", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash 0.7.8", -] - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash 0.8.12", - "allocator-api2", -] - -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash", -] - -[[package]] -name = "hashbrown" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" - -[[package]] -name = "hashlink" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" -dependencies = [ - "hashbrown 0.15.5", -] - -[[package]] -name = "hassle-rs" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" -dependencies = [ - "bitflags 2.11.0", - "com", - "libc", - "libloading 0.8.9", - "thiserror 1.0.69", - "widestring", - "winapi", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hexf-parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" - -[[package]] -name = "http" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" -dependencies = [ - "bytes", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "hyper" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "http", - "http-body", - "httparse", - "itoa", - "pin-project-lite", - "pin-utils", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" -dependencies = [ - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", - "webpki-roots", -] - -[[package]] -name = "hyper-util" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "hyper", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2 0.6.2", - "tokio", - "tower-service", - "tracing", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core 0.62.2", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "icrate" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" -dependencies = [ - "block2 0.3.0", - "dispatch", - "objc2 0.4.1", -] - -[[package]] -name = "icu_collections" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" - -[[package]] -name = "icu_properties" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" - -[[package]] -name = "icu_provider" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "image" -version = "0.25.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6506c6c10786659413faa717ceebcb8f70731c0a60cbae39795fdf114519c1a" -dependencies = [ - "bytemuck", - "byteorder-lite", - "moxcms", - "num-traits", - "png", -] - -[[package]] -name = "indexmap" -version = "2.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" -dependencies = [ - "equivalent", - "hashbrown 0.16.1", - "serde", - "serde_core", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.9", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "itoa" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" - -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if", - "combine", - "jni-sys", - "log", - "thiserror 1.0.69", - "walkdir", - "windows-sys 0.45.0", -] - -[[package]] -name = "jni-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" - -[[package]] -name = "jobserver" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" -dependencies = [ - "getrandom 0.3.4", - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14dc6f6450b3f6d4ed5b16327f38fed626d375a886159ca555bd7822c0c3a5a6" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "khronos-egl" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" -dependencies = [ - "libc", - "libloading 0.8.9", - "pkg-config", -] - -[[package]] -name = "khronos_api" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - -[[package]] -name = "lexical-core" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d8d125a277f807e55a77304455eb7b1cb52f2b18c143b60e766c120bd64a594" -dependencies = [ - "lexical-parse-float", - "lexical-parse-integer", - "lexical-util", - "lexical-write-float", - "lexical-write-integer", -] - -[[package]] -name = "lexical-parse-float" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a9f232fbd6f550bc0137dcb5f99ab674071ac2d690ac69704593cb4abbea56" -dependencies = [ - "lexical-parse-integer", - "lexical-util", -] - -[[package]] -name = "lexical-parse-integer" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a7a039f8fb9c19c996cd7b2fcce303c1b2874fe1aca544edc85c4a5f8489b34" -dependencies = [ - "lexical-util", -] - -[[package]] -name = "lexical-util" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2604dd126bb14f13fb5d1bd6a66155079cb9fa655b37f875b3a742c705dbed17" - -[[package]] -name = "lexical-write-float" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c438c87c013188d415fbabbb1dceb44249ab81664efbd31b14ae55dabb6361" -dependencies = [ - "lexical-util", - "lexical-write-integer", -] - -[[package]] -name = "lexical-write-integer" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "409851a618475d2d5796377cad353802345cba92c867d9fbcde9cf4eac4e14df" -dependencies = [ - "lexical-util", -] - -[[package]] -name = "libc" -version = "0.2.182" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" - -[[package]] -name = "libduckdb-sys" -version = "1.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78bacb8933586cee3b550c39b610d314f9b7a48701ac7a914a046165a4ad8da" -dependencies = [ - "cc", - "flate2", - "pkg-config", - "reqwest", - "serde", - "serde_json", - "tar", - "vcpkg", - "zip", -] - -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - -[[package]] -name = "libloading" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link", -] - -[[package]] -name = "libm" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" - -[[package]] -name = "libredox" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" -dependencies = [ - "bitflags 2.11.0", - "libc", - "redox_syscall 0.7.2", -] - -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" - -[[package]] -name = "litemap" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" - -[[package]] -name = "litrs" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" - -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - -[[package]] -name = "memchr" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" - -[[package]] -name = "memmap2" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" -dependencies = [ - "libc", -] - -[[package]] -name = "memoffset" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" -dependencies = [ - "autocfg", -] - -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "metal" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5637e166ea14be6063a3f8ba5ccb9a4159df7d8f6d61c02fc3d480b1f90dcfcb" -dependencies = [ - "bitflags 2.11.0", - "block", - "core-graphics-types", - "foreign-types", - "log", - "objc", - "paste", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "mime_guess2" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1706dc14a2e140dec0a7a07109d9a3d5890b81e85bd6c60b906b249a77adf0ca" -dependencies = [ - "mime", - "phf", - "phf_shared", - "unicase", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - -[[package]] -name = "mio" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", -] - -[[package]] -name = "moxcms" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9557c559cd6fc9867e122e20d2cbefc9ca29d80d027a8e39310920ed2f0a97" -dependencies = [ - "num-traits", - "pxfm", -] - -[[package]] -name = "naga" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e536ae46fcab0876853bd4a632ede5df4b1c2527a58f6c5a4150fe86be858231" -dependencies = [ - "arrayvec", - "bit-set", - "bitflags 2.11.0", - "codespan-reporting", - "hexf-parse", - "indexmap", - "log", - "num-traits", - "rustc-hash 1.1.0", - "spirv", - "termcolor", - "thiserror 1.0.69", - "unicode-xid", -] - -[[package]] -name = "ndk" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" -dependencies = [ - "bitflags 2.11.0", - "jni-sys", - "log", - "ndk-sys", - "num_enum", - "raw-window-handle 0.5.2", - "raw-window-handle 0.6.2", - "thiserror 1.0.69", -] - -[[package]] -name = "ndk-context" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" - -[[package]] -name = "ndk-sys" -version = "0.5.0+25.2.9519653" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" -dependencies = [ - "jni-sys", -] - -[[package]] -name = "nix" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", - "memoffset 0.7.1", -] - -[[package]] -name = "nohash-hasher" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" - -[[package]] -name = "num" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "num_enum" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" -dependencies = [ - "num_enum_derive", - "rustversion", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" -dependencies = [ - "proc-macro-crate 3.4.0", - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - -[[package]] -name = "objc-sys" -version = "0.2.0-beta.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7" - -[[package]] -name = "objc-sys" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" - -[[package]] -name = "objc2" -version = "0.3.0-beta.3.patch-leaks.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e01640f9f2cb1220bbe80325e179e532cb3379ebcd1bf2279d703c19fe3a468" -dependencies = [ - "block2 0.2.0-alpha.6", - "objc-sys 0.2.0-beta.2", - "objc2-encode 2.0.0-pre.2", -] - -[[package]] -name = "objc2" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" -dependencies = [ - "objc-sys 0.3.5", - "objc2-encode 3.0.0", -] - -[[package]] -name = "objc2" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" -dependencies = [ - "objc-sys 0.3.5", - "objc2-encode 4.1.0", -] - -[[package]] -name = "objc2" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" -dependencies = [ - "objc2-encode 4.1.0", -] - -[[package]] -name = "objc2-app-kit" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" -dependencies = [ - "bitflags 2.11.0", - "block2 0.5.1", - "libc", - "objc2 0.5.2", - "objc2-core-data", - "objc2-core-image", - "objc2-foundation 0.2.2", - "objc2-quartz-core", -] - -[[package]] -name = "objc2-app-kit" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" -dependencies = [ - "bitflags 2.11.0", - "block2 0.6.2", - "objc2 0.6.3", - "objc2-core-graphics", - "objc2-foundation 0.3.2", -] - -[[package]] -name = "objc2-core-data" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" -dependencies = [ - "bitflags 2.11.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-core-foundation" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" -dependencies = [ - "bitflags 2.11.0", - "dispatch2", - "objc2 0.6.3", -] - -[[package]] -name = "objc2-core-graphics" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" -dependencies = [ - "bitflags 2.11.0", - "dispatch2", - "objc2 0.6.3", - "objc2-core-foundation", - "objc2-io-surface", -] - -[[package]] -name = "objc2-core-image" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" -dependencies = [ - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-metal", -] - -[[package]] -name = "objc2-encode" -version = "2.0.0-pre.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abfcac41015b00a120608fdaa6938c44cb983fee294351cc4bac7638b4e50512" -dependencies = [ - "objc-sys 0.2.0-beta.2", -] - -[[package]] -name = "objc2-encode" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" - -[[package]] -name = "objc2-encode" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" - -[[package]] -name = "objc2-foundation" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" -dependencies = [ - "bitflags 2.11.0", - "block2 0.5.1", - "libc", - "objc2 0.5.2", -] - -[[package]] -name = "objc2-foundation" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" -dependencies = [ - "bitflags 2.11.0", - "objc2 0.6.3", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-io-surface" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" -dependencies = [ - "bitflags 2.11.0", - "objc2 0.6.3", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-metal" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" -dependencies = [ - "bitflags 2.11.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-quartz-core" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" -dependencies = [ - "bitflags 2.11.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-metal", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "orbclient" -version = "0.3.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ad2c6bae700b7aa5d1cc30c59bdd3a1c180b09dbaea51e2ae2b8e1cf211fdd" -dependencies = [ - "libc", - "libredox", -] - -[[package]] -name = "ordered-stream" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" -dependencies = [ - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "owned_ttf_parser" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b" -dependencies = [ - "ttf-parser", -] - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.5.18", - "smallvec", - "windows-link", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "phf" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" -dependencies = [ - "phf_macros", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" -dependencies = [ - "phf_shared", - "rand 0.8.5", -] - -[[package]] -name = "phf_macros" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" -dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro2", - "quote", - "syn 2.0.117", - "unicase", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher", - "unicase", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "piper" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" -dependencies = [ - "atomic-waker", - "fastrand 2.3.0", - "futures-io", -] - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "png" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" -dependencies = [ - "bitflags 2.11.0", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - -[[package]] -name = "polling" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" -dependencies = [ - "autocfg", - "bitflags 1.3.2", - "cfg-if", - "concurrent-queue", - "libc", - "log", - "pin-project-lite", - "windows-sys 0.48.0", -] - -[[package]] -name = "polling" -version = "3.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" -dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi 0.5.2", - "pin-project-lite", - "rustix 1.1.4", - "windows-sys 0.61.2", -] - -[[package]] -name = "pollster" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" - -[[package]] -name = "potential_utf" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" -dependencies = [ - "zerovec", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "presser" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" - -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn 2.0.117", -] - -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - -[[package]] -name = "proc-macro-crate" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" -dependencies = [ - "toml_edit 0.23.10+spec-1.0.0", -] - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "profiling" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" - -[[package]] -name = "ptr_meta" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" -dependencies = [ - "ptr_meta_derive", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "pxfm" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7186d3822593aa4393561d186d1393b3923e9d6163d3fbfd6e825e3e6cf3e6a8" -dependencies = [ - "num-traits", -] - -[[package]] -name = "quick-xml" -version = "0.38.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" -dependencies = [ - "memchr", -] - -[[package]] -name = "quinn" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" -dependencies = [ - "bytes", - "cfg_aliases 0.2.1", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash 2.1.1", - "rustls", - "socket2 0.6.2", - "thiserror 2.0.18", - "tokio", - "tracing", - "web-time 1.1.0", -] - -[[package]] -name = "quinn-proto" -version = "0.11.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" -dependencies = [ - "bytes", - "getrandom 0.3.4", - "lru-slab", - "rand 0.9.2", - "ring", - "rustc-hash 2.1.1", - "rustls", - "rustls-pki-types", - "slab", - "thiserror 2.0.18", - "tinyvec", - "tracing", - "web-time 1.1.0", -] - -[[package]] -name = "quinn-udp" -version = "0.5.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" -dependencies = [ - "cfg_aliases 0.2.1", - "libc", - "once_cell", - "socket2 0.6.2", - "tracing", - "windows-sys 0.60.2", -] - -[[package]] -name = "quote" -version = "1.0.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" -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 = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.5", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -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.5", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.17", -] - -[[package]] -name = "rand_core" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" -dependencies = [ - "getrandom 0.3.4", -] - -[[package]] -name = "raw-window-handle" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" - -[[package]] -name = "raw-window-handle" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" - -[[package]] -name = "rayon" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags 2.11.0", -] - -[[package]] -name = "redox_syscall" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d94dd2f7cd932d4dc02cc8b2b50dfd38bd079a4e5d79198b99743d7fcf9a4b4" -dependencies = [ - "bitflags 2.11.0", -] - -[[package]] -name = "redox_users" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" -dependencies = [ - "getrandom 0.2.17", - "libredox", - "thiserror 1.0.69", -] - -[[package]] -name = "ref-cast" -version = "1.0.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" -dependencies = [ - "ref-cast-impl", -] - -[[package]] -name = "ref-cast-impl" -version = "1.0.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "regex" -version = "1.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" - -[[package]] -name = "rend" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" -dependencies = [ - "bytecheck", -] - -[[package]] -name = "renderdoc-sys" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" - -[[package]] -name = "reqwest" -version = "0.12.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "js-sys", - "log", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-rustls", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots", -] - -[[package]] -name = "rfd" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2bee61e6cffa4635c72d7d81a84294e28f0930db0ddcb0f66d10244674ebed" -dependencies = [ - "ashpd", - "block2 0.6.2", - "dispatch2", - "js-sys", - "log", - "objc2 0.6.3", - "objc2-app-kit 0.3.2", - "objc2-core-foundation", - "objc2-foundation 0.3.2", - "pollster", - "raw-window-handle 0.6.2", - "urlencoding", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "windows-sys 0.59.0", -] - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.17", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rkyv" -version = "0.7.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2297bf9c81a3f0dc96bc9521370b88f054168c29826a75e89c55ff196e7ed6a1" -dependencies = [ - "bitvec", - "bytecheck", - "bytes", - "hashbrown 0.12.3", - "ptr_meta", - "rend", - "rkyv_derive", - "seahash", - "tinyvec", - "uuid", -] - -[[package]] -name = "rkyv_derive" -version = "0.7.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84d7b42d4b8d06048d3ac8db0eb31bcb942cbeb709f0b5f2b2ebde398d3038f5" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ron" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" -dependencies = [ - "base64 0.21.7", - "bitflags 2.11.0", - "serde", - "serde_derive", -] - -[[package]] -name = "rust_decimal" -version = "1.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61f703d19852dbf87cbc513643fa81428361eb6940f1ac14fd58155d295a3eb0" -dependencies = [ - "arrayvec", - "borsh", - "bytes", - "num-traits", - "rand 0.8.5", - "rkyv", - "serde", - "serde_json", -] - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - -[[package]] -name = "rustix" -version = "0.37.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "519165d378b97752ca44bbe15047d5d3409e875f39327546b42ac81d7e18c1b6" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.11.0", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustix" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" -dependencies = [ - "bitflags 2.11.0", - "errno", - "libc", - "linux-raw-sys 0.12.1", - "windows-sys 0.61.2", -] - -[[package]] -name = "rustls" -version = "0.23.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" -dependencies = [ - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-pki-types" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" -dependencies = [ - "web-time 1.1.0", - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "ryu" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sctk-adwaita" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70b31447ca297092c5a9916fc3b955203157b37c19ca8edde4f52e9843e602c7" -dependencies = [ - "ab_glyph", - "log", - "memmap2", - "smithay-client-toolkit 0.18.1", - "tiny-skia", -] - -[[package]] -name = "seahash" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" - -[[package]] -name = "semver" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" - -[[package]] -name = "serde" -version = "1.0.228" -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 = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "serde_json" -version = "1.0.149" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" -dependencies = [ - "indexmap", - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", -] - -[[package]] -name = "serde_repr" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" -dependencies = [ - "errno", - "libc", -] - -[[package]] -name = "simd-adler32" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" - -[[package]] -name = "simd-json" -version = "0.13.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0228a564470f81724e30996bbc2b171713b37b15254a6440c7e2d5449b95691" -dependencies = [ - "getrandom 0.2.17", - "halfbrown", - "lexical-core", - "ref-cast", - "serde", - "serde_json", - "simdutf8", - "value-trait", -] - -[[package]] -name = "simdutf8" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" - -[[package]] -name = "siphasher" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" - -[[package]] -name = "slab" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - -[[package]] -name = "slotmap" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" -dependencies = [ - "version_check", -] - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "smithay-client-toolkit" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" -dependencies = [ - "bitflags 2.11.0", - "calloop 0.12.4", - "calloop-wayland-source 0.2.0", - "cursor-icon", - "libc", - "log", - "memmap2", - "rustix 0.38.44", - "thiserror 1.0.69", - "wayland-backend", - "wayland-client", - "wayland-csd-frame", - "wayland-cursor", - "wayland-protocols 0.31.2", - "wayland-protocols-wlr 0.2.0", - "wayland-scanner", - "xkeysym", -] - -[[package]] -name = "smithay-client-toolkit" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0" -dependencies = [ - "bitflags 2.11.0", - "calloop 0.14.4", - "calloop-wayland-source 0.4.1", - "cursor-icon", - "libc", - "log", - "memmap2", - "rustix 1.1.4", - "thiserror 2.0.18", - "wayland-backend", - "wayland-client", - "wayland-csd-frame", - "wayland-cursor", - "wayland-protocols 0.32.10", - "wayland-protocols-experimental", - "wayland-protocols-misc", - "wayland-protocols-wlr 0.3.10", - "wayland-scanner", - "xkeysym", -] - -[[package]] -name = "smithay-clipboard" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71704c03f739f7745053bde45fa203a46c58d25bc5c4efba1d9a60e9dba81226" -dependencies = [ - "libc", - "smithay-client-toolkit 0.20.0", - "wayland-backend", -] - -[[package]] -name = "smol_str" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" -dependencies = [ - "serde", -] - -[[package]] -name = "smooai-log-viewer" -version = "3.1.2" -dependencies = [ - "anyhow", - "chrono", - "duckdb", - "eframe", - "egui", - "egui_extras", - "image", - "memmap2", - "rayon", - "regex", - "rfd", - "serde", - "serde_json", - "simd-json", - "smooai-logger", - "walkdir", -] - -[[package]] -name = "smooai-logger" -version = "3.1.2" -dependencies = [ - "chrono", - "colored", - "once_cell", - "parking_lot", - "serde", - "serde_json", - "url", - "uuid", -] - -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "socket2" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" -dependencies = [ - "libc", - "windows-sys 0.60.2", -] - -[[package]] -name = "spirv" -version = "0.3.0+sdk-1.3.268.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" -dependencies = [ - "bitflags 2.11.0", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strict-num" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" - -[[package]] -name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" - -[[package]] -name = "strum" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" -dependencies = [ - "strum_macros 0.27.2", -] - -[[package]] -name = "strum_macros" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.117", -] - -[[package]] -name = "strum_macros" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "tar" -version = "0.4.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" -dependencies = [ - "filetime", - "libc", - "xattr", -] - -[[package]] -name = "tempfile" -version = "3.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0" -dependencies = [ - "fastrand 2.3.0", - "getrandom 0.4.1", - "once_cell", - "rustix 1.1.4", - "windows-sys 0.61.2", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - -[[package]] -name = "thiserror" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" -dependencies = [ - "thiserror-impl 2.0.18", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tiny-skia" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" -dependencies = [ - "arrayref", - "arrayvec", - "bytemuck", - "cfg-if", - "log", - "tiny-skia-path", -] - -[[package]] -name = "tiny-skia-path" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" -dependencies = [ - "arrayref", - "bytemuck", - "strict-num", -] - -[[package]] -name = "tinystr" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tinyvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.49.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" -dependencies = [ - "bytes", - "libc", - "mio", - "pin-project-lite", - "socket2 0.6.2", - "windows-sys 0.61.2", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" - -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", -] - -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap", - "toml_datetime 0.6.11", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.23.10+spec-1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" -dependencies = [ - "indexmap", - "toml_datetime 0.7.5+spec-1.1.0", - "toml_parser", - "winnow 0.7.14", -] - -[[package]] -name = "toml_parser" -version = "1.0.9+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" -dependencies = [ - "winnow 0.7.14", -] - -[[package]] -name = "tower" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-http" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" -dependencies = [ - "bitflags 2.11.0", - "bytes", - "futures-util", - "http", - "http-body", - "iri-string", - "pin-project-lite", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" -dependencies = [ - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "tracing-core" -version = "0.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "ttf-parser" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" - -[[package]] -name = "type-map" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90" -dependencies = [ - "rustc-hash 2.1.1", -] - -[[package]] -name = "typenum" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" - -[[package]] -name = "uds_windows" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" -dependencies = [ - "memoffset 0.9.1", - "tempfile", - "winapi", -] - -[[package]] -name = "unicase" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unicode-width" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", - "serde_derive", -] - -[[package]] -name = "urlencoding" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "uuid" -version = "1.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" -dependencies = [ - "getrandom 0.4.1", - "js-sys", - "serde_core", - "wasm-bindgen", -] - -[[package]] -name = "value-trait" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad8db98c1e677797df21ba03fca7d3bf9bec3ca38db930954e4fe6e1ea27eb4" -dependencies = [ - "float-cmp", - "halfbrown", - "itoa", - "ryu", -] - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "waker-fn" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasip2" -version = "1.0.2+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60722a937f594b7fde9adb894d7c092fc1bb6612897c46368d18e7a20208eff2" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a89f4650b770e4521aa6573724e2aed4704372151bd0de9d16a3bbabb87441a" -dependencies = [ - "cfg-if", - "futures-util", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac8c6395094b6b91c4af293f4c79371c163f9a6f56184d2c9a85f5a95f3950" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3fabce6159dc20728033842636887e4877688ae94382766e00b180abac9d60" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn 2.0.117", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0e091bdb824da87dc01d967388880d017a0a9bc4f3bdc0d86ee9f9336e3bb5" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags 2.11.0", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - -[[package]] -name = "wayland-backend" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee64194ccd96bf648f42a65a7e589547096dfa702f7cadef84347b66ad164f9" -dependencies = [ - "cc", - "downcast-rs", - "rustix 1.1.4", - "scoped-tls", - "smallvec", - "wayland-sys", -] - -[[package]] -name = "wayland-client" -version = "0.31.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e6faa537fbb6c186cb9f1d41f2f811a4120d1b57ec61f50da451a0c5122bec" -dependencies = [ - "bitflags 2.11.0", - "rustix 1.1.4", - "wayland-backend", - "wayland-scanner", -] - -[[package]] -name = "wayland-csd-frame" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" -dependencies = [ - "bitflags 2.11.0", - "cursor-icon", - "wayland-backend", -] - -[[package]] -name = "wayland-cursor" -version = "0.31.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5864c4b5b6064b06b1e8b74ead4a98a6c45a285fe7a0e784d24735f011fdb078" -dependencies = [ - "rustix 1.1.4", - "wayland-client", - "xcursor", -] - -[[package]] -name = "wayland-protocols" -version = "0.31.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" -dependencies = [ - "bitflags 2.11.0", - "wayland-backend", - "wayland-client", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols" -version = "0.32.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baeda9ffbcfc8cd6ddaade385eaf2393bd2115a69523c735f12242353c3df4f3" -dependencies = [ - "bitflags 2.11.0", - "wayland-backend", - "wayland-client", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-experimental" -version = "20250721.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1" -dependencies = [ - "bitflags 2.11.0", - "wayland-backend", - "wayland-client", - "wayland-protocols 0.32.10", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-misc" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791c58fdeec5406aa37169dd815327d1e47f334219b523444bc26d70ceb4c34e" -dependencies = [ - "bitflags 2.11.0", - "wayland-backend", - "wayland-client", - "wayland-protocols 0.32.10", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-plasma" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" -dependencies = [ - "bitflags 2.11.0", - "wayland-backend", - "wayland-client", - "wayland-protocols 0.31.2", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-wlr" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" -dependencies = [ - "bitflags 2.11.0", - "wayland-backend", - "wayland-client", - "wayland-protocols 0.31.2", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-wlr" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9597cdf02cf0c34cd5823786dce6b5ae8598f05c2daf5621b6e178d4f7345f3" -dependencies = [ - "bitflags 2.11.0", - "wayland-backend", - "wayland-client", - "wayland-protocols 0.32.10", - "wayland-scanner", -] - -[[package]] -name = "wayland-scanner" -version = "0.31.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5423e94b6a63e68e439803a3e153a9252d5ead12fd853334e2ad33997e3889e3" -dependencies = [ - "proc-macro2", - "quick-xml", - "quote", -] - -[[package]] -name = "wayland-sys" -version = "0.31.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6dbfc3ac5ef974c92a2235805cc0114033018ae1290a72e474aa8b28cbbdfd" -dependencies = [ - "dlib", - "log", - "once_cell", - "pkg-config", -] - -[[package]] -name = "web-sys" -version = "0.3.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "705eceb4ce901230f8625bd1d665128056ccbe4b7408faa625eec1ba80f59a97" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web-time" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webbrowser" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f00bb839c1cf1e3036066614cbdcd035ecf215206691ea646aa3c60a24f68f2" -dependencies = [ - "core-foundation 0.10.1", - "jni", - "log", - "ndk-context", - "objc2 0.6.3", - "objc2-foundation 0.3.2", - "url", - "web-sys", -] - -[[package]] -name = "webpki-roots" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "wgpu" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e37c7b9921b75dfd26dd973fdcbce36f13dfa6e2dc82aece584e0ed48c355c" -dependencies = [ - "arrayvec", - "cfg-if", - "cfg_aliases 0.1.1", - "document-features", - "js-sys", - "log", - "parking_lot", - "profiling", - "raw-window-handle 0.6.2", - "smallvec", - "static_assertions", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "wgpu-core", - "wgpu-hal", - "wgpu-types", -] - -[[package]] -name = "wgpu-core" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50819ab545b867d8a454d1d756b90cd5f15da1f2943334ca314af10583c9d39" -dependencies = [ - "arrayvec", - "bit-vec", - "bitflags 2.11.0", - "cfg_aliases 0.1.1", - "codespan-reporting", - "document-features", - "indexmap", - "log", - "naga", - "once_cell", - "parking_lot", - "profiling", - "raw-window-handle 0.6.2", - "rustc-hash 1.1.0", - "smallvec", - "thiserror 1.0.69", - "web-sys", - "wgpu-hal", - "wgpu-types", -] - -[[package]] -name = "wgpu-hal" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "172e490a87295564f3fcc0f165798d87386f6231b04d4548bca458cbbfd63222" -dependencies = [ - "android_system_properties", - "arrayvec", - "ash", - "bitflags 2.11.0", - "cfg_aliases 0.1.1", - "core-graphics-types", - "glow", - "glutin_wgl_sys", - "gpu-alloc", - "gpu-allocator", - "gpu-descriptor", - "hassle-rs", - "js-sys", - "khronos-egl", - "libc", - "libloading 0.8.9", - "log", - "metal", - "naga", - "ndk-sys", - "objc", - "once_cell", - "parking_lot", - "profiling", - "raw-window-handle 0.6.2", - "renderdoc-sys", - "rustc-hash 1.1.0", - "smallvec", - "thiserror 1.0.69", - "wasm-bindgen", - "web-sys", - "wgpu-types", - "winapi", -] - -[[package]] -name = "wgpu-types" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1353d9a46bff7f955a680577f34c69122628cc2076e1d6f3a9be6ef00ae793ef" -dependencies = [ - "bitflags 2.11.0", - "js-sys", - "web-sys", -] - -[[package]] -name = "widestring" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" -dependencies = [ - "windows-implement 0.48.0", - "windows-interface 0.48.0", - "windows-targets 0.48.5", -] - -[[package]] -name = "windows" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" -dependencies = [ - "windows-core 0.52.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement 0.60.2", - "windows-interface 0.59.3", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-implement" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e2ee588991b9e7e6c8338edf3333fbe4da35dc72092643958ebb43f0ab2c49c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "windows-interface" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6fb8df20c9bcaa8ad6ab513f7b40104840c8867d5751126e4df3b08388d0cc7" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "winit" -version = "0.29.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d59ad965a635657faf09c8f062badd885748428933dad8e8bdd64064d92e5ca" -dependencies = [ - "ahash 0.8.12", - "android-activity", - "atomic-waker", - "bitflags 2.11.0", - "bytemuck", - "calloop 0.12.4", - "cfg_aliases 0.1.1", - "core-foundation 0.9.4", - "core-graphics", - "cursor-icon", - "icrate", - "js-sys", - "libc", - "log", - "memmap2", - "ndk", - "ndk-sys", - "objc2 0.4.1", - "once_cell", - "orbclient", - "percent-encoding", - "raw-window-handle 0.5.2", - "raw-window-handle 0.6.2", - "redox_syscall 0.3.5", - "rustix 0.38.44", - "sctk-adwaita", - "smithay-client-toolkit 0.18.1", - "smol_str", - "unicode-segmentation", - "wasm-bindgen", - "wasm-bindgen-futures", - "wayland-backend", - "wayland-client", - "wayland-protocols 0.31.2", - "wayland-protocols-plasma", - "web-sys", - "web-time 0.2.4", - "windows-sys 0.48.0", - "x11-dl", - "x11rb", - "xkbcommon-dl", -] - -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "0.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" -dependencies = [ - "memchr", -] - -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn 2.0.117", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn 2.0.117", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags 2.11.0", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] - -[[package]] -name = "writeable" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "x11-dl" -version = "2.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" -dependencies = [ - "libc", - "once_cell", - "pkg-config", -] - -[[package]] -name = "x11rb" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" -dependencies = [ - "as-raw-xcb-connection", - "gethostname", - "libc", - "libloading 0.8.9", - "once_cell", - "rustix 1.1.4", - "x11rb-protocol", -] - -[[package]] -name = "x11rb-protocol" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" - -[[package]] -name = "xattr" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" -dependencies = [ - "libc", - "rustix 1.1.4", -] - -[[package]] -name = "xcursor" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b" - -[[package]] -name = "xdg-home" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "xkbcommon-dl" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" -dependencies = [ - "bitflags 2.11.0", - "dlib", - "log", - "once_cell", - "xkeysym", -] - -[[package]] -name = "xkeysym" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" - -[[package]] -name = "xml-rs" -version = "0.8.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" - -[[package]] -name = "yoke" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", - "synstructure", -] - -[[package]] -name = "zbus" -version = "3.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" -dependencies = [ - "async-broadcast 0.5.1", - "async-executor", - "async-fs 1.6.0", - "async-io 1.13.0", - "async-lock 2.8.0", - "async-process 1.8.1", - "async-recursion", - "async-task", - "async-trait", - "blocking", - "byteorder", - "derivative", - "enumflags2", - "event-listener 2.5.3", - "futures-core", - "futures-sink", - "futures-util", - "hex", - "nix", - "once_cell", - "ordered-stream", - "rand 0.8.5", - "serde", - "serde_repr", - "sha1", - "static_assertions", - "tracing", - "uds_windows", - "winapi", - "xdg-home", - "zbus_macros 3.15.2", - "zbus_names 2.6.1", - "zvariant 3.15.2", -] - -[[package]] -name = "zbus" -version = "5.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca82f95dbd3943a40a53cfded6c2d0a2ca26192011846a1810c4256ef92c60bc" -dependencies = [ - "async-broadcast 0.7.2", - "async-executor", - "async-io 2.6.0", - "async-lock 3.4.2", - "async-process 2.5.0", - "async-recursion", - "async-task", - "async-trait", - "blocking", - "enumflags2", - "event-listener 5.4.1", - "futures-core", - "futures-lite 2.6.1", - "hex", - "libc", - "ordered-stream", - "rustix 1.1.4", - "serde", - "serde_repr", - "tracing", - "uds_windows", - "uuid", - "windows-sys 0.61.2", - "winnow 0.7.14", - "zbus_macros 5.14.0", - "zbus_names 4.3.1", - "zvariant 5.10.0", -] - -[[package]] -name = "zbus_macros" -version = "3.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "regex", - "syn 1.0.109", - "zvariant_utils 1.0.1", -] - -[[package]] -name = "zbus_macros" -version = "5.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897e79616e84aac4b2c46e9132a4f63b93105d54fe8c0e8f6bffc21fa8d49222" -dependencies = [ - "proc-macro-crate 3.4.0", - "proc-macro2", - "quote", - "syn 2.0.117", - "zbus_names 4.3.1", - "zvariant 5.10.0", - "zvariant_utils 3.3.0", -] - -[[package]] -name = "zbus_names" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d" -dependencies = [ - "serde", - "static_assertions", - "zvariant 3.15.2", -] - -[[package]] -name = "zbus_names" -version = "4.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f" -dependencies = [ - "serde", - "winnow 0.7.14", - "zvariant 5.10.0", -] - -[[package]] -name = "zerocopy" -version = "0.8.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" - -[[package]] -name = "zerotrie" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "zip" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb2a05c7c36fde6c09b08576c9f7fb4cda705990f73b58fe011abf7dfb24168b" -dependencies = [ - "arbitrary", - "crc32fast", - "flate2", - "indexmap", - "memchr", - "zopfli", -] - -[[package]] -name = "zlib-rs" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c745c48e1007337ed136dc99df34128b9faa6ed542d80a1c673cf55a6d7236c8" - -[[package]] -name = "zmij" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" - -[[package]] -name = "zopfli" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" -dependencies = [ - "bumpalo", - "crc32fast", - "log", - "simd-adler32", -] - -[[package]] -name = "zvariant" -version = "3.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" -dependencies = [ - "byteorder", - "enumflags2", - "libc", - "serde", - "static_assertions", - "zvariant_derive 3.15.2", -] - -[[package]] -name = "zvariant" -version = "5.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5708299b21903bbe348e94729f22c49c55d04720a004aa350f1f9c122fd2540b" -dependencies = [ - "endi", - "enumflags2", - "serde", - "url", - "winnow 0.7.14", - "zvariant_derive 5.10.0", - "zvariant_utils 3.3.0", -] - -[[package]] -name = "zvariant_derive" -version = "3.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 1.0.109", - "zvariant_utils 1.0.1", -] - -[[package]] -name = "zvariant_derive" -version = "5.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b59b012ebe9c46656f9cc08d8da8b4c726510aef12559da3e5f1bf72780752c" -dependencies = [ - "proc-macro-crate 3.4.0", - "proc-macro2", - "quote", - "syn 2.0.117", - "zvariant_utils 3.3.0", -] - -[[package]] -name = "zvariant_utils" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "zvariant_utils" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f75c23a64ef8f40f13a6989991e643554d9bef1d682a281160cf0c1bc389c5e9" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "syn 2.0.117", - "winnow 0.7.14", -] diff --git a/log-viewer/Cargo.toml b/log-viewer/Cargo.toml deleted file mode 100644 index 930b8ce9..00000000 --- a/log-viewer/Cargo.toml +++ /dev/null @@ -1,42 +0,0 @@ -[package] -name = "smooai-log-viewer" -version = "3.1.2" -edition = "2021" -description = "A desktop application for viewing and analyzing SmooAI contextual logs with rich filtering and visualization capabilities" -license = "MIT" -repository = "https://github.com/SmooAI/logger" -homepage = "https://github.com/SmooAI/logger" -keywords = ["logging", "log-viewer", "smooai", "observability", "gui"] -categories = ["development-tools::debugging", "gui", "visualization"] -readme = "ABOUT.md" -authors = ["SmooAI "] - -[dependencies] -smooai-logger = { path = "../rust/logger" } -anyhow = "1" -walkdir = "2.5" -memmap2 = "0.9" -rayon = "1.10" -serde = { version = "1", features = ["derive"] } -serde_json = "1" -regex = "1.10" -chrono = { version = "0.4", features = ["serde"] } -rfd = "0.15" -eframe = { version = "0.28", features = ["persistence"] } -egui = "0.28" -egui_extras = "0.28" -image = { version = "0.25", default-features = false, features = ["png"] } -duckdb = { version = "1.4", features = ["bundled"] } - -[dependencies.simd-json] -version = "0.13" -optional = true - -[features] -default = [] -simd = ["simd-json"] - -[profile.release] -lto = "thin" -codegen-units = 1 -panic = "abort" diff --git a/log-viewer/DEPRECATED.md b/log-viewer/DEPRECATED.md index e8d40e9f..901d7164 100644 --- a/log-viewer/DEPRECATED.md +++ b/log-viewer/DEPRECATED.md @@ -38,4 +38,8 @@ The viewer is an observability **consumer**, not a logger feature. Its natural h The original `smooai-log-viewer` egui crate was deleted in [observability `SMOODEV-1255-rm-egui`](https://github.com/SmooAI/observability/pull/) once the Dioxus port reached parity (logs / errors / metrics views — local-file ingestion was the only feature not ported, and that workflow is better served by running the AWS / CloudWatch source through the new Settings → Add Org flow against `api.smoo.ai`). -If you depended on the old egui binary specifically, pin to a [SmooAI/logger v4.x release](https://github.com/SmooAI/logger/releases) that predates this deprecation note — but expect no further updates on that line. +The `log-viewer/` crate source, the `smooai-log-viewer` npm/PyPI console scripts, and the +`build-log-viewer.yml` release workflow have all been removed from this repo. The source is +still in git history if you need it (`git log -- log-viewer/src`). + +If you depended on the old egui binary specifically, pin to a [SmooAI/logger v4.3.0 or earlier release](https://github.com/SmooAI/logger/releases) — the last releases whose assets include it — but expect no further updates on that line. diff --git a/log-viewer/assets/app-icon.png b/log-viewer/assets/app-icon.png deleted file mode 100644 index ea8f58c9..00000000 Binary files a/log-viewer/assets/app-icon.png and /dev/null differ diff --git a/log-viewer/assets/smoo-logo.png b/log-viewer/assets/smoo-logo.png deleted file mode 100644 index ea8f58c9..00000000 Binary files a/log-viewer/assets/smoo-logo.png and /dev/null differ diff --git a/log-viewer/rustfmt.toml b/log-viewer/rustfmt.toml deleted file mode 100644 index 0cac0a77..00000000 --- a/log-viewer/rustfmt.toml +++ /dev/null @@ -1,3 +0,0 @@ -edition = "2021" -max_width = 160 -use_field_init_shorthand = true diff --git a/log-viewer/src/main.rs b/log-viewer/src/main.rs deleted file mode 100644 index 83f110bb..00000000 --- a/log-viewer/src/main.rs +++ /dev/null @@ -1,2198 +0,0 @@ -mod theme; - -use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; -use std::fs::File; -use std::path::{Path, PathBuf}; -use std::process::Command; -use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; -use std::sync::{mpsc, Arc}; -use std::thread; -use std::time::{Duration, SystemTime, UNIX_EPOCH}; - -use anyhow::{anyhow, Context, Result}; -use chrono::{DateTime, Utc}; -use duckdb::{params, Connection}; -use eframe::egui::{self, Color32, ColorImage, IconData, Image, Key, RichText, Sense, TextEdit, TextWrapMode, TextureHandle, TextureOptions, Vec2}; -use egui_extras::{Column, TableBuilder}; -use memmap2::Mmap; -use rayon::prelude::*; -use regex::Regex; -use rfd::FileDialog; -use serde_json::{json, Value}; -use walkdir::WalkDir; - -mod keys { - pub const LEVEL: &str = "level"; - pub const LOG_LEVEL: &str = "LogLevel"; - pub const TIME: &str = "time"; - pub const MESSAGE: &str = "msg"; - - pub const CORRELATION_ID: &str = "correlationId"; - pub const REQUEST_ID: &str = "requestId"; - pub const TRACE_ID: &str = "traceId"; - pub const NAME: &str = "name"; - pub const NAMESPACE: &str = "namespace"; - pub const SERVICE: &str = "service"; -} - -const APP_ICON_BYTES: &[u8] = include_bytes!("../assets/app-icon.png"); -const LOGO_BYTES: &[u8] = include_bytes!("../assets/smoo-logo.png"); - -const BASE_COLUMNS: [(&str, &str); 9] = [ - ("time", "Timestamp"), - ("level", "Level"), - ("name", "Name"), - ("namespace", "Namespace"), - ("msg", "Message"), - ("error", "Error"), - ("errorDetails", "Error Details"), - ("correlationId", "Correlation ID"), - ("service", "Service"), -]; - -const BASE_COLUMN_DEFAULT_WIDTHS: &[(&str, f32)] = &[ - ("time", 200.0), - ("level", 90.0), - ("correlationId", 190.0), - ("name", 200.0), - ("namespace", 210.0), - ("service", 170.0), - ("msg", 320.0), - ("error", 220.0), - ("errorDetails", 240.0), -]; - -fn is_base_column(name: &str) -> bool { - BASE_COLUMNS.iter().any(|(key, _)| key.eq_ignore_ascii_case(name)) -} - -fn default_column_widths() -> HashMap { - let mut map = HashMap::new(); - for (key, width) in BASE_COLUMN_DEFAULT_WIDTHS { - map.insert((*key).to_string(), *width); - } - map -} - -fn default_width_for_column(key: &str) -> f32 { - BASE_COLUMN_DEFAULT_WIDTHS - .iter() - .find(|(name, _)| name.eq_ignore_ascii_case(key)) - .map(|(_, width)| *width) - .unwrap_or(180.0) -} - -fn header_label_for(key: &str) -> String { - BASE_COLUMNS - .iter() - .find(|(name, _)| name.eq_ignore_ascii_case(key)) - .map(|(_, label)| (*label).to_string()) - .unwrap_or_else(|| key.to_string()) -} - -type ParsedFile = (PathBuf, Vec, Vec, BTreeSet); - -enum IndexEvent { - Progress { processed: usize, total: usize }, - Finished(Result), -} - -enum WatchEvent { - FileChanged(PathBuf), - FileRemoved(PathBuf), -} - -#[derive(Debug, Clone)] -struct FileEntry { - path: PathBuf, - sanitized_lines: Vec, -} - -#[derive(Debug, Clone)] -struct Row { - file_id: usize, - line_start: usize, - line_end: usize, - ts: Option>, - level: Option, - corr: Option, - name: Option, - msg: Option, - service: Option, - namespace: Option, - trace_id: Option, - request_id: Option, - flat: BTreeMap, - raw_json: String, -} - -#[derive(Default, Clone)] -struct Catalog { - files: Vec, - rows: Vec, - columns: Vec, - duckdb_path: Option, -} - -#[derive(Clone)] -struct Extractor; - -impl Extractor { - fn new() -> Self { - Self - } - - #[cfg(feature = "simd")] - fn parse_json(&self, slice: &str) -> Option { - simd_json::serde::from_str(slice).ok() - } - - #[cfg(not(feature = "simd"))] - fn parse_json(&self, slice: &str) -> Option { - serde_json::from_str(slice).ok() - } - - fn pick_str<'a>(&self, obj: &'a Value, key: &str) -> Option<&'a str> { - obj.get(key).and_then(|value| value.as_str()) - } - - fn pick_level<'a>(&self, obj: &'a Value) -> Option<&'a str> { - self.pick_str(obj, keys::LEVEL).or_else(|| self.pick_str(obj, keys::LOG_LEVEL)) - } - - fn pick_ts(&self, obj: &Value) -> Option> { - let raw = self.pick_str(obj, keys::TIME)?; - if let Ok(dt) = raw.parse::>() { - return Some(dt); - } - if !raw.ends_with('Z') { - if let Ok(dt) = format!("{raw}Z").parse::>() { - return Some(dt); - } - } - if let Ok(numeric) = raw.parse::() { - if numeric > 10_000_000_000 { - let secs = numeric / 1_000; - let ns = (numeric % 1_000) * 1_000_000; - return DateTime::::from_timestamp(secs, ns as u32); - } - return DateTime::::from_timestamp(numeric, 0); - } - None - } - - #[allow(clippy::type_complexity)] - fn extract( - &self, - obj: &Value, - ) -> ( - Option>, - Option, - Option, - Option, - Option, - Option, - Option, - Option, - Option, - ) { - let ts = self.pick_ts(obj); - let level = self.pick_level(obj).map(|s| s.to_string()); - let corr = self.pick_str(obj, keys::CORRELATION_ID).map(|s| s.to_string()); - let name = self.pick_str(obj, keys::NAME).map(|s| s.to_string()); - let msg = self.pick_str(obj, keys::MESSAGE).map(|s| s.to_string()); - let service = self.pick_str(obj, keys::SERVICE).map(|s| s.to_string()); - let namespace = self.pick_str(obj, keys::NAMESPACE).map(|s| s.to_string()); - let trace_id = self.pick_str(obj, keys::TRACE_ID).map(|s| s.to_string()); - let request_id = self.pick_str(obj, keys::REQUEST_ID).map(|s| s.to_string()); - (ts, level, corr, name, msg, service, namespace, trace_id, request_id) - } -} - -#[derive(Default, Clone)] -struct Filters { - text: String, - level: String, - corr: String, - service: String, - namespace: String, - trace: String, - request: String, - regex_mode: bool, -} - -enum ColumnAddResult { - Added(String), - AlreadyVisible(String), - BaseColumn(String), - NotFound(String), - Empty, -} - -struct App { - root: PathBuf, - pending_root: PathBuf, - catalog: Catalog, - filtered: Vec, - selected: Option, - page: usize, - page_size: usize, - ctx_before: usize, - ctx_after: usize, - status: String, - sort_desc: bool, - filters: Filters, - re_cache: HashMap, - dark_mode: bool, - logo_image: Option, - logo_texture: Option, - logo_size: Vec2, - index_rx: Option>, - indexing: bool, - show_startup_modal: bool, - watch_rx: Option>, - watch_handle: Option>, - watch_stop: Option>, - pending_reindex: bool, - live_mode: bool, - pending_watch_events: Vec, - visible_columns: Vec, - column_search: String, - expanded_rows: HashSet, - column_widths: HashMap, - index_progress: Option<(usize, usize)>, - db_conn: Option, -} - -impl Default for App { - fn default() -> Self { - let root = std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")); - let (logo_image, logo_size) = match load_logo_image() { - Some((image, size)) => (Some(image), size), - None => (None, Vec2::splat(64.0)), - }; - Self { - root: root.clone(), - pending_root: root, - catalog: Catalog::default(), - filtered: Vec::new(), - selected: None, - page: 0, - page_size: 200, - ctx_before: 2, - ctx_after: 2, - status: "Choose a directory to index".into(), - sort_desc: true, - filters: Filters::default(), - re_cache: HashMap::new(), - dark_mode: true, - logo_image, - logo_texture: None, - logo_size, - index_rx: None, - indexing: false, - show_startup_modal: true, - watch_rx: None, - watch_handle: None, - watch_stop: None, - pending_reindex: false, - live_mode: true, - pending_watch_events: Vec::new(), - visible_columns: vec!["traceId".into(), "requestId".into()], - column_search: String::new(), - expanded_rows: HashSet::new(), - column_widths: default_column_widths(), - index_progress: None, - db_conn: None, - } - } -} - -impl App { - fn start_index(&mut self, path: PathBuf, ctx: &egui::Context) { - self.status = format!("Indexing {}…", path.display()); - self.index_progress = None; - self.pending_watch_events.clear(); - let (tx, rx) = mpsc::channel(); - self.index_rx = Some(rx); - self.indexing = true; - let ctx_clone = ctx.clone(); - let progress_sender = tx.clone(); - thread::spawn(move || { - let result = index_monorepo(&path, Some(progress_sender)); - let _ = tx.send(IndexEvent::Finished(result)); - ctx_clone.request_repaint(); - }); - } - - fn apply_filters(&mut self) { - // Try DuckDB-backed filtering first - if let Some(conn) = self.db_conn.take() { - let result = Self::duckdb_filter_query(&conn, &self.filters, self.sort_desc); - self.db_conn = Some(conn); - if let Some(filtered) = result { - self.filtered = filtered; - self.page = 0; - self.selected = None; - self.status = format!("{} matches", self.filtered.len()); - return; - } - } - // Fall back to in-memory filtering - self.apply_filters_memory(); - } - - fn duckdb_filter_query(conn: &Connection, filters: &Filters, sort_desc: bool) -> Option> { - let escape = |s: &str| s.replace('\'', "''"); - - let mut sql = String::from("SELECT row_id FROM logs"); - let mut conditions: Vec = Vec::new(); - - macro_rules! add_column_filter { - ($filter_val:expr, $column:expr) => { - if !$filter_val.is_empty() { - let escaped = escape(&$filter_val); - if filters.regex_mode { - conditions.push(format!("regexp_matches({}, '{}')", $column, escaped)); - } else { - conditions.push(format!("{} ILIKE '%{}%'", $column, escaped)); - } - } - }; - } - - add_column_filter!(filters.level, "level"); - add_column_filter!(filters.corr, "corr"); - add_column_filter!(filters.service, "service"); - add_column_filter!(filters.namespace, "namespace"); - add_column_filter!(filters.trace, "trace_id"); - add_column_filter!(filters.request, "request_id"); - - if !filters.text.is_empty() { - let escaped = escape(&filters.text); - let haystack = "COALESCE(msg,'') || ' ' || COALESCE(corr,'') || ' ' || COALESCE(level,'') || ' ' || COALESCE(service,'') || ' ' || COALESCE(namespace,'') || ' ' || COALESCE(trace_id,'') || ' ' || COALESCE(request_id,'') || ' ' || COALESCE(flat_json,'')"; - if filters.regex_mode { - conditions.push(format!("regexp_matches({haystack}, '{escaped}')")); - } else { - conditions.push(format!("{haystack} ILIKE '%{escaped}%'")); - } - } - - if !conditions.is_empty() { - sql.push_str(" WHERE "); - sql.push_str(&conditions.join(" AND ")); - } - - if sort_desc { - sql.push_str(" ORDER BY ts DESC NULLS LAST, file_id ASC, line_start ASC"); - } else { - sql.push_str(" ORDER BY ts ASC NULLS FIRST, file_id ASC, line_start ASC"); - } - - let mut stmt = conn.prepare(&sql).ok()?; - let rows = stmt.query_map([], |row| row.get::<_, i64>(0)).ok()?; - let filtered: Vec = rows.filter_map(|r| r.ok()).map(|id| id as usize).collect(); - Some(filtered) - } - - fn apply_filters_memory(&mut self) { - let filters = self.filters.clone(); - - let re_text = if filters.regex_mode { self.compile(&filters.text) } else { None }; - let re_level = if filters.regex_mode { self.compile(&filters.level) } else { None }; - let re_corr = if filters.regex_mode { self.compile(&filters.corr) } else { None }; - let re_service = if filters.regex_mode { self.compile(&filters.service) } else { None }; - let re_namespace = if filters.regex_mode { self.compile(&filters.namespace) } else { None }; - let re_trace = if filters.regex_mode { self.compile(&filters.trace) } else { None }; - let re_request = if filters.regex_mode { self.compile(&filters.request) } else { None }; - - let lowercase = |input: &str| input.to_ascii_lowercase(); - let text = lowercase(&filters.text); - let level = lowercase(&filters.level); - let corr = lowercase(&filters.corr); - let service = lowercase(&filters.service); - let namespace = lowercase(&filters.namespace); - let trace = lowercase(&filters.trace); - let request = lowercase(&filters.request); - - self.filtered.clear(); - - for (idx, row) in self.catalog.rows.iter().enumerate() { - if !filters.level.is_empty() { - let matches = row.level.as_ref().is_some_and(|value| { - if let Some(re) = &re_level { - re.is_match(value) - } else { - value.to_ascii_lowercase().contains(&level) - } - }); - if !matches { - continue; - } - } - - if !filters.corr.is_empty() { - let matches = row.corr.as_ref().is_some_and(|value| { - if let Some(re) = &re_corr { - re.is_match(value) - } else { - value.to_ascii_lowercase().contains(&corr) - } - }); - if !matches { - continue; - } - } - - if !filters.service.is_empty() { - let matches = row.service.as_ref().is_some_and(|value| { - if let Some(re) = &re_service { - re.is_match(value) - } else { - value.to_ascii_lowercase().contains(&service) - } - }); - if !matches { - continue; - } - } - - if !filters.namespace.is_empty() { - let matches = row.namespace.as_ref().is_some_and(|value| { - if let Some(re) = &re_namespace { - re.is_match(value) - } else { - value.to_ascii_lowercase().contains(&namespace) - } - }); - if !matches { - continue; - } - } - - if !filters.trace.is_empty() { - let matches = row.trace_id.as_ref().is_some_and(|value| { - if let Some(re) = &re_trace { - re.is_match(value) - } else { - value.to_ascii_lowercase().contains(&trace) - } - }); - if !matches { - continue; - } - } - - if !filters.request.is_empty() { - let matches = row.request_id.as_ref().is_some_and(|value| { - if let Some(re) = &re_request { - re.is_match(value) - } else { - value.to_ascii_lowercase().contains(&request) - } - }); - if !matches { - continue; - } - } - - if !filters.text.is_empty() { - let mut haystack = String::new(); - if let Some(value) = row.msg.as_ref() { - haystack.push_str(value); - haystack.push(' '); - } - if let Some(value) = row.corr.as_ref() { - haystack.push_str(value); - haystack.push(' '); - } - if let Some(value) = row.level.as_ref() { - haystack.push_str(value); - haystack.push(' '); - } - if let Some(value) = row.service.as_ref() { - haystack.push_str(value); - haystack.push(' '); - } - if let Some(value) = row.namespace.as_ref() { - haystack.push_str(value); - haystack.push(' '); - } - if let Some(value) = row.trace_id.as_ref() { - haystack.push_str(value); - haystack.push(' '); - } - if let Some(value) = row.request_id.as_ref() { - haystack.push_str(value); - haystack.push(' '); - } - for value in row.flat.values() { - haystack.push_str(value); - haystack.push(' '); - } - let matches = if let Some(re) = &re_text { - re.is_match(&haystack) - } else { - haystack.to_ascii_lowercase().contains(&text) - }; - if !matches { - continue; - } - } - - self.filtered.push(idx); - } - - // catalog.rows is always in ASC order; reverse filtered indices for DESC display - if self.sort_desc { - self.filtered.reverse(); - } - - self.page = 0; - self.selected = None; - self.status = format!("{} matches", self.filtered.len()); - } - - fn compile(&mut self, source: &str) -> Option { - if source.is_empty() { - return None; - } - if let Some(cached) = self.re_cache.get(source) { - return Some(cached.clone()); - } - Regex::new(source) - .inspect(|regex| { - self.re_cache.insert(source.to_string(), regex.clone()); - }) - .ok() - } - - fn has_rows(&self) -> bool { - !self.filtered.is_empty() - } - - fn dynamic_columns(&self) -> Vec { - if self.catalog.columns.is_empty() { - return Vec::new(); - } - let available: HashSet<&str> = self.catalog.columns.iter().map(|c| c.as_str()).collect(); - let mut seen = HashSet::new(); - self.visible_columns - .iter() - .filter_map(|column| { - if is_base_column(column) { - return None; - } - if !available.contains(column.as_str()) { - return None; - } - let lower = column.to_ascii_lowercase(); - if !seen.insert(lower) { - return None; - } - Some(column.clone()) - }) - .collect() - } - - fn prune_visible_columns(&mut self) { - if self.catalog.columns.is_empty() { - self.visible_columns.clear(); - return; - } - let mut normalized = Vec::new(); - let mut seen = HashSet::new(); - for column in &self.visible_columns { - if is_base_column(column) { - continue; - } - if let Some(canonical) = self.catalog.columns.iter().find(|candidate| candidate.eq_ignore_ascii_case(column)).cloned() { - let lower = canonical.to_ascii_lowercase(); - if seen.insert(lower) { - normalized.push(canonical); - } - } - } - self.visible_columns = normalized; - } - - fn add_visible_column(&mut self, column: &str) -> bool { - if is_base_column(column) { - return false; - } - if self.visible_columns.iter().any(|existing| existing.eq_ignore_ascii_case(column)) { - return false; - } - self.visible_columns.push(column.to_string()); - true - } - - fn remove_visible_column(&mut self, column: &str) { - self.visible_columns.retain(|existing| !existing.eq_ignore_ascii_case(column)); - } - - fn process_live_events(&mut self, ctx: &egui::Context) { - if !self.live_mode || self.indexing || self.pending_watch_events.is_empty() { - return; - } - - let mut changed = BTreeSet::new(); - let mut removed = BTreeSet::new(); - - for event in self.pending_watch_events.drain(..) { - match event { - WatchEvent::FileChanged(path) => { - if !removed.contains(&path) { - changed.insert(path); - } - } - WatchEvent::FileRemoved(path) => { - changed.remove(&path); - removed.insert(path); - } - } - } - - if changed.is_empty() && removed.is_empty() { - return; - } - - let extractor = Extractor::new(); - let mut updated_files = 0usize; - let mut removed_files = 0usize; - let mut errors = Vec::new(); - - for path in removed { - if self.remove_file_by_path(&path) { - removed_files += 1; - } - } - - for path in changed { - match self.refresh_file_from_disk(&path, &extractor) { - Ok(true) => { - updated_files += 1; - } - Ok(false) => {} - Err(error) => { - errors.push((path, error)); - } - } - } - - if updated_files > 0 || removed_files > 0 { - self.sync_after_catalog_changes(); - let mut parts = Vec::new(); - if updated_files > 0 { - parts.push(format!("updated {} file{}", updated_files, if updated_files == 1 { "" } else { "s" })); - } - if removed_files > 0 { - parts.push(format!("removed {} file{}", removed_files, if removed_files == 1 { "" } else { "s" })); - } - self.status = format!("Live update: {}", parts.join(", ")); - ctx.request_repaint(); - } - - if let Some((path, error)) = errors.first() { - self.status = format!("Live update error for {}: {:#}", path.display(), error); - } - } - - fn refresh_file_from_disk(&mut self, path: &Path, extractor: &Extractor) -> Result { - let existing_index = self.catalog.files.iter().position(|file| file.path == *path); - let file_id = existing_index.unwrap_or(self.catalog.files.len()); - - let (sanitized_lines, mut rows) = index_single_file(file_id, path, extractor)?; - for row in &mut rows { - row.file_id = file_id; - } - - if let Some(idx) = existing_index { - if self.catalog.files[idx].sanitized_lines == sanitized_lines { - return Ok(false); - } - } - - self.catalog.rows.retain(|row| row.file_id != file_id); - - if let Some(idx) = existing_index { - self.catalog.files[idx].sanitized_lines = sanitized_lines; - } else { - self.catalog.files.push(FileEntry { - path: path.to_path_buf(), - sanitized_lines, - }); - } - - self.catalog.rows.extend(rows); - Ok(true) - } - - fn remove_file_by_path(&mut self, path: &Path) -> bool { - if let Some(index) = self.catalog.files.iter().position(|file| file.path == *path) { - self.catalog.files.remove(index); - self.catalog.rows.retain(|row| row.file_id != index); - for row in &mut self.catalog.rows { - if row.file_id > index { - row.file_id -= 1; - } - } - true - } else { - false - } - } - - fn sync_after_catalog_changes(&mut self) { - self.catalog.rows.sort_by(|left, right| { - left.ts - .cmp(&right.ts) - .then_with(|| left.file_id.cmp(&right.file_id)) - .then_with(|| left.line_start.cmp(&right.line_start)) - }); - - let mut column_set = BTreeSet::new(); - for row in &self.catalog.rows { - for key in row.flat.keys() { - column_set.insert(key.clone()); - } - } - self.catalog.columns = column_set.into_iter().collect(); - self.prune_visible_columns(); - self.rebuild_duckdb(); - self.filtered.clear(); - self.apply_filters(); - self.selected = None; - self.page = 0; - } - - fn rebuild_duckdb(&mut self) { - self.db_conn = None; - if let Some(old_path) = self.catalog.duckdb_path.take() { - let _ = std::fs::remove_file(old_path); - } - match populate_duckdb(&self.catalog.rows) { - Ok(db_path) => match Connection::open(&db_path) { - Ok(conn) => { - self.db_conn = Some(conn); - self.catalog.duckdb_path = Some(db_path); - } - Err(e) => { - eprintln!("Failed to open rebuilt DuckDB: {e}"); - let _ = std::fs::remove_file(db_path); - } - }, - Err(e) => { - eprintln!("Failed to rebuild DuckDB: {e}"); - } - } - } - - fn open_file_with_dialog(&mut self, file_id: usize) { - let file = &self.catalog.files[file_id]; - if let Some(app_path) = FileDialog::new().set_title("Choose application").pick_file() { - match open_file_with_app(&file.path, &app_path) { - Ok(_) => { - self.status = format!("Opened {} with {}", file.path.display(), app_path.display()); - } - Err(error) => { - self.status = format!("Failed to open with app: {error}"); - } - } - } - } - - fn column_width_for(&mut self, key: &str) -> f32 { - let default = default_width_for_column(key); - *self.column_widths.entry(key.to_string()).or_insert(default) - } - - fn update_column_width_entry(&mut self, key: &str, width: f32) { - let entry = self.column_widths.entry(key.to_string()).or_insert(width); - if (width - *entry).abs() > 0.5 { - *entry = width; - } - } - - fn handle_header_response(&mut self, ctx: &egui::Context, key: &str, response: &egui::Response) { - let width = response.rect.width().max(60.0); - self.update_column_width_entry(key, width); - if response.double_clicked() { - let target = self.auto_column_width(ctx, key); - self.column_widths.insert(key.to_string(), target); - ctx.request_repaint(); - } - } - - fn auto_column_width(&self, ctx: &egui::Context, key: &str) -> f32 { - let mut max_width = 0.0; - let header_text = header_label_for(key); - let rows = &self.catalog.rows; - let sample = rows.len().min(1500); - ctx.fonts(|fonts| { - let font_id = ctx.style().text_styles[&egui::TextStyle::Body].clone(); - max_width = fonts.layout_no_wrap(header_text.clone(), font_id.clone(), Color32::WHITE).rect.width(); - - for row in rows.iter().take(sample) { - let value = resolve_row_value(row, key); - if value.is_empty() { - continue; - } - let width = fonts.layout_no_wrap(value, font_id.clone(), Color32::WHITE).rect.width(); - if width > max_width { - max_width = width; - } - } - }); - - (max_width + 32.0).clamp(80.0, 1024.0) - } - - fn render_log_table(&mut self, ui: &mut egui::Ui, ctx: &egui::Context) { - let extra_columns = self.dynamic_columns(); - - egui::ScrollArea::both().auto_shrink([false, false]).show(ui, |ui| { - ui.set_width(ui.available_width()); - let available = ui.available_height(); - - let mut table = TableBuilder::new(ui).striped(true).min_scrolled_height(available.max(200.0)); - table = table.column(Column::initial(28.0).resizable(false).clip(true)); - table = table.sense(egui::Sense::click()); - - for (key, _) in BASE_COLUMNS.iter() { - let width = self.column_width_for(key); - let min_width = match *key { - "msg" => 220.0, - "name" => 160.0, - _ => 110.0, - }; - table = table.column(Column::initial(width).resizable(true).clip(true).at_least(min_width)); - } - - for column in &extra_columns { - let width = self.column_width_for(column.as_str()); - table = table.column(Column::initial(width).resizable(true).clip(true).at_least(140.0)); - } - - let header_bg = theme::header_background(self.dark_mode); - let grid_stroke = theme::grid_stroke(self.dark_mode); - - table - .header(28.0, |mut header| { - header.col(|ui| { - let response = ui.label(RichText::new(" ").background_color(header_bg)); - ui.painter().rect_stroke(response.rect, 0.0, grid_stroke); - }); - - for (key, label) in BASE_COLUMNS.iter() { - header.col(|ui| { - let response = ui.add(egui::Label::new(RichText::new(*label).strong().background_color(header_bg)).sense(Sense::click())); - ui.painter().rect_stroke(response.rect, 0.0, grid_stroke); - self.handle_header_response(ctx, key, &response); - }); - } - - for column in &extra_columns { - header.col(|ui| { - let response = ui.add(egui::Label::new(RichText::new(column).strong().background_color(header_bg)).sense(Sense::click())); - ui.painter().rect_stroke(response.rect, 0.0, grid_stroke); - self.handle_header_response(ctx, column.as_str(), &response); - }); - } - }) - .body(|mut body| { - let start = self.page * self.page_size; - let end = (start + self.page_size).min(self.filtered.len()); - let indices: Vec = self.filtered[start..end].to_vec(); - - for (row_offset, row_idx) in indices.into_iter().enumerate() { - let filtered_idx = start + row_offset; - - // Pre-extract all values from the row by reference to - // avoid cloning the entire Row struct. - let row = &self.catalog.rows[row_idx]; - let file_id = row.file_id; - let ts_value = resolve_row_value(row, "time"); - let level_value = resolve_row_value(row, "level"); - let corr_value = resolve_row_value(row, "correlationId"); - let name_value = resolve_row_value(row, "name"); - let namespace_value = resolve_row_value(row, "namespace"); - let service_value = resolve_row_value(row, "service"); - let msg_value = resolve_row_value(row, "msg"); - let msg_display = shorten_for_display(&msg_value, 180); - let error_value = resolve_row_value(row, "error"); - let error_display = shorten_for_display(&error_value, 160); - let error_details_value = resolve_row_value(row, "errorDetails"); - let error_details_display = shorten_for_display(&error_details_value, 160); - let extra_values: Vec<(String, String)> = extra_columns - .iter() - .map(|column| { - let full = resolve_row_value(row, column); - let short = shorten_for_display(&full, 160); - (full, short) - }) - .collect(); - - let is_expanded = self.expanded_rows.contains(&row_idx); - let (pretty_json, json_lines) = if is_expanded { - let (formatted, lines) = format_json_for_display(&row.raw_json); - (Some(formatted), lines) - } else { - (None, 0) - }; - let extra_height = if is_expanded { - ((json_lines as f32) * 18.0 + 12.0).clamp(54.0, 360.0) - } else { - 0.0 - }; - let row_height = 22.0 + extra_height; - - let mut open_file_request = false; - let mut open_with_request = false; - - body.row(row_height, |mut row_ui| { - let mut row_clicked = false; - - row_ui.col(|ui| { - let symbol = if is_expanded { "⌄" } else { "›" }; - let response = ui.add(egui::Label::new(RichText::new(symbol).color(Color32::from_gray(180))).sense(Sense::click())); - if response.clicked() { - if is_expanded { - self.expanded_rows.remove(&row_idx); - } else { - self.expanded_rows.insert(row_idx); - } - } - }); - - let mut process_response = |response: egui::Response, row_clicked: &mut bool| { - if response.clicked() { - *row_clicked = true; - } - if response.secondary_clicked() { - open_file_request = true; - } - let _ = response.context_menu(|ui| { - if ui.button("Open file").clicked() { - open_file_request = true; - ui.close_menu(); - } - if ui.button("Open with…").clicked() { - open_with_request = true; - ui.close_menu(); - } - }); - }; - - for (key, _) in BASE_COLUMNS.iter() { - let raw_value = match *key { - "time" => ts_value.clone(), - "level" => level_value.clone(), - "correlationId" => corr_value.clone(), - "name" => name_value.clone(), - "namespace" => namespace_value.clone(), - "service" => service_value.clone(), - "msg" => msg_value.clone(), - "error" => error_value.clone(), - "errorDetails" => error_details_value.clone(), - _ => String::new(), - }; - - let display_value = match *key { - "msg" => msg_display.clone(), - "error" => error_display.clone(), - "errorDetails" => error_details_display.clone(), - _ => raw_value.clone(), - }; - - let mut rich = RichText::new(display_value.clone()); - if *key == "level" && !raw_value.is_empty() { - rich = rich.color(theme::level_color(&raw_value)); - } else if matches!(*key, "error" | "errorDetails") && !raw_value.trim().is_empty() { - rich = rich.color(theme::smoo::RED); - } - - row_ui.col(|ui| { - let response = ui.add(egui::Label::new(rich.clone()).truncate().sense(Sense::click())); - let response = response.on_hover_text(raw_value.clone()); - process_response(response, &mut row_clicked); - - if *key == "msg" && is_expanded { - if let Some(json) = pretty_json.as_ref() { - ui.add_space(6.0); - let max_height = ((json_lines as f32) * 18.0 + 12.0).clamp(54.0, 360.0); - egui::ScrollArea::vertical().max_height(max_height).show(ui, |ui| { - ui.scope(|ui| { - ui.style_mut().wrap_mode = Some(TextWrapMode::Extend); - ui.monospace(json); - }); - }); - } - } - }); - } - - for (full_value, short_value) in &extra_values { - row_ui.col(|ui| { - let response = ui.add(egui::Label::new(RichText::new(short_value.clone())).truncate().sense(Sense::click())); - let response = response.on_hover_text(full_value.clone()); - process_response(response, &mut row_clicked); - }); - } - - if row_clicked { - self.selected = Some(filtered_idx); - } - }); - - if open_file_request { - let file = &self.catalog.files[file_id]; - match open_file_with_default(&file.path) { - Ok(_) => { - self.status = format!("Opened {}", file.path.display()); - } - Err(error) => { - self.status = format!("Failed to open file: {error}"); - } - } - } - - if open_with_request { - self.open_file_with_dialog(file_id); - } - } - }); - }); - } - - fn render_context_panel(&mut self, ui: &mut egui::Ui) { - ui.heading("Context (within the same file)"); - - if let Some(selected_idx) = self.selected { - let row_idx = self.filtered[selected_idx]; - let row = &self.catalog.rows[row_idx]; - let (start, end) = self.context_range(row); - let file = &self.catalog.files[row.file_id]; - let highlight = if self.dark_mode { - theme::dark_theme().ring - } else { - theme::light_theme().ring - }; - - egui::ScrollArea::vertical().show(ui, |ui| { - ui.monospace(format!("File: {}", file.path.display())); - for idx in start..end { - let line = file.sanitized_lines.get(idx).map(|s| s.as_str()).unwrap_or(""); - if idx >= row.line_start && idx <= row.line_end { - ui.colored_label(highlight, line); - } else { - ui.colored_label(theme::smoo::GRAY_400, line); - } - } - }); - - if let Ok(json_value) = serde_json::from_str::(&row.raw_json) { - ui.separator(); - ui.heading("JSON"); - render_json_root(ui, &json_value); - } - - ui.horizontal(|ui| { - if ui.button("⟸ Prev match").clicked() && selected_idx > 0 { - self.selected = Some(selected_idx - 1); - } - if ui.button("Next match ⟹").clicked() && selected_idx + 1 < self.filtered.len() { - self.selected = Some(selected_idx + 1); - } - if ui.button("Copy selected JSON").clicked() { - ui.output_mut(|output| output.copied_text = row.raw_json.clone()); - self.status = "Copied".into(); - } - }); - } else { - ui.label("Select a row to view context."); - } - } - - fn resolve_column_name(&self, input: &str) -> Option { - let query = input.trim(); - if query.is_empty() { - return None; - } - if self.catalog.columns.is_empty() { - return None; - } - - if let Some(exact) = self.catalog.columns.iter().find(|column| column == &query) { - return Some(exact.clone()); - } - - if let Some(case_insensitive) = self.catalog.columns.iter().find(|column| column.eq_ignore_ascii_case(query)) { - return Some(case_insensitive.clone()); - } - - let lowered_query = query.to_ascii_lowercase(); - let mut prefix_match: Option = None; - let mut substring_match: Option = None; - let mut best_distance: Option<(String, usize)> = None; - - for column in &self.catalog.columns { - let lowered = column.to_ascii_lowercase(); - if prefix_match.is_none() && lowered.starts_with(&lowered_query) { - prefix_match = Some(column.clone()); - } - if substring_match.is_none() && lowered.contains(&lowered_query) { - substring_match = Some(column.clone()); - } - let distance = levenshtein(&lowered, &lowered_query); - if distance <= 3 { - match &best_distance { - Some((_, best)) if distance >= *best => {} - _ => best_distance = Some((column.clone(), distance)), - } - } - } - - prefix_match.or(substring_match).or(best_distance.map(|(column, _)| column)) - } - - fn column_suggestions(&self) -> Vec { - if self.catalog.columns.is_empty() { - return Vec::new(); - } - let query = self.column_search.trim().to_ascii_lowercase(); - let mut suggestions = Vec::new(); - - for column in &self.catalog.columns { - if is_base_column(column) { - continue; - } - if self.visible_columns.iter().any(|visible| visible.eq_ignore_ascii_case(column)) { - continue; - } - let lowered = column.to_ascii_lowercase(); - if query.is_empty() || lowered.starts_with(&query) || lowered.contains(&query) { - suggestions.push(column.clone()); - } - } - - if suggestions.is_empty() && !query.is_empty() { - if let Some(resolved) = self.resolve_column_name(&self.column_search) { - if !is_base_column(&resolved) && !self.visible_columns.iter().any(|visible| visible.eq_ignore_ascii_case(&resolved)) { - suggestions.push(resolved); - } - } - } - - suggestions.truncate(5); - suggestions - } - - fn try_add_column_from_search(&mut self) -> ColumnAddResult { - let query = self.column_search.trim().to_string(); - if query.is_empty() { - return ColumnAddResult::Empty; - } - if let Some(resolved) = self.resolve_column_name(&query) { - if is_base_column(&resolved) { - return ColumnAddResult::BaseColumn(resolved); - } - if self.visible_columns.iter().any(|visible| visible.eq_ignore_ascii_case(&resolved)) { - self.column_search.clear(); - return ColumnAddResult::AlreadyVisible(resolved); - } - self.visible_columns.push(resolved.clone()); - self.column_search.clear(); - ColumnAddResult::Added(resolved) - } else { - ColumnAddResult::NotFound(query) - } - } - - fn context_range(&self, row: &Row) -> (usize, usize) { - let file = &self.catalog.files[row.file_id]; - let total = file.sanitized_lines.len(); - let start = row.line_start.saturating_sub(self.ctx_before); - let mut end = row.line_end + 1 + self.ctx_after; - if end > total { - end = total; - } - (start, end) - } - - fn ensure_logo_texture(&mut self, ctx: &egui::Context) { - if self.logo_texture.is_some() { - return; - } - if let Some(image) = self.logo_image.clone() { - let texture = ctx.load_texture("smoo-logo", image, TextureOptions::LINEAR); - self.logo_texture = Some(texture); - self.logo_image = None; - } - } - - fn watch_root(&mut self, path: PathBuf) { - if let Some(stop) = self.watch_stop.take() { - stop.store(false, Ordering::SeqCst); - } - if let Some(handle) = self.watch_handle.take() { - let _ = handle.join(); - } - - let (tx, rx) = mpsc::channel(); - self.watch_rx = Some(rx); - - let stop_flag = Arc::new(AtomicBool::new(true)); - let thread_flag = stop_flag.clone(); - - let handle = thread::spawn(move || { - let mut known: HashMap = HashMap::new(); - for dir in find_smooai_log_dirs(&path) { - for file in list_log_files(&dir) { - if let Ok(metadata) = std::fs::metadata(&file) { - if let Ok(modified) = metadata.modified() { - known.insert(file.clone(), (modified, metadata.len())); - } - } - } - } - - while thread_flag.load(Ordering::SeqCst) { - let mut seen = HashSet::new(); - for dir in find_smooai_log_dirs(&path) { - for file in list_log_files(&dir) { - seen.insert(file.clone()); - if let Ok(metadata) = std::fs::metadata(&file) { - if let Ok(modified) = metadata.modified() { - let len = metadata.len(); - match known.get(&file) { - Some((prev_mod, prev_len)) if *prev_mod >= modified && *prev_len == len => {} - _ => { - known.insert(file.clone(), (modified, len)); - let _ = tx.send(WatchEvent::FileChanged(file.clone())); - } - } - } - } - } - } - let removed: Vec = known.keys().filter(|path| !seen.contains(*path)).cloned().collect(); - for path in removed { - known.remove(&path); - let _ = tx.send(WatchEvent::FileRemoved(path)); - } - thread::sleep(Duration::from_secs(2)); - } - }); - - self.watch_stop = Some(stop_flag); - self.watch_handle = Some(handle); - } - - fn stop_watch(&mut self) { - if let Some(stop) = self.watch_stop.take() { - stop.store(false, Ordering::SeqCst); - } - if let Some(handle) = self.watch_handle.take() { - let _ = handle.join(); - } - self.watch_rx = None; - self.pending_watch_events.clear(); - } -} - -impl Drop for App { - fn drop(&mut self) { - self.stop_watch(); - self.db_conn = None; - if let Some(path) = self.catalog.duckdb_path.take() { - let _ = std::fs::remove_file(path); - } - } -} - -impl eframe::App for App { - fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - theme::apply_visuals(ctx, self.dark_mode); - self.ensure_logo_texture(ctx); - - if let Some(rx) = &self.watch_rx { - while let Ok(event) = rx.try_recv() { - if self.live_mode { - self.pending_watch_events.push(event); - } else { - self.status = "Log changes detected while live mode is off. Reindex to refresh.".into(); - } - } - } - - let mut finished_event: Option> = None; - if let Some(receiver) = self.index_rx.as_ref() { - while let Ok(event) = receiver.try_recv() { - match event { - IndexEvent::Progress { processed, total } => { - let capped_total = total.max(1); - let capped_processed = processed.min(capped_total); - self.index_progress = Some((capped_processed, total)); - self.status = format!("Indexing {}/{} files", capped_processed, total); - ctx.request_repaint(); - } - IndexEvent::Finished(result) => { - finished_event = Some(result); - break; - } - } - } - } - - if let Some(result) = finished_event { - self.indexing = false; - self.index_rx = None; - self.index_progress = None; - match result { - Ok(catalog) => { - // Close old DuckDB connection and file - self.db_conn = None; - if let Some(old) = self.catalog.duckdb_path.take() { - let _ = std::fs::remove_file(old); - } - self.catalog = catalog; - // Open DuckDB connection for querying - if let Some(ref path) = self.catalog.duckdb_path { - match Connection::open(path) { - Ok(conn) => self.db_conn = Some(conn), - Err(e) => eprintln!("Failed to open DuckDB: {e}"), - } - } - self.prune_visible_columns(); - self.expanded_rows.clear(); - self.filtered = (0..self.catalog.rows.len()).collect(); - self.selected = None; - self.page = 0; - self.apply_filters(); - self.status = format!("Indexed {} files, {} rows", self.catalog.files.len(), self.catalog.rows.len()); - } - Err(error) => { - self.status = format!("Index error: {error:#}"); - } - } - } - - if self.pending_reindex && !self.indexing { - self.pending_reindex = false; - let root = self.root.clone(); - self.start_index(root, ctx); - } - - if !self.indexing { - self.process_live_events(ctx); - } - - if self.show_startup_modal { - egui::Window::new("Choose log directory") - .anchor(egui::Align2::CENTER_CENTER, [0.0, 0.0]) - .collapsible(false) - .resizable(false) - .show(ctx, |ui| { - ui.label("Select the root folder containing `.smooai-logs/`."); - let mut path_string = self.pending_root.display().to_string(); - ui.add_enabled(false, TextEdit::singleline(&mut path_string)); - if ui.button("Browse…").clicked() { - if let Some(dir) = FileDialog::new().set_directory(&self.pending_root).pick_folder() { - self.pending_root = dir; - } - } - if ui.button("Start watching").clicked() { - self.root = self.pending_root.clone(); - self.show_startup_modal = false; - if self.live_mode { - self.watch_root(self.root.clone()); - } else { - self.stop_watch(); - } - self.start_index(self.root.clone(), ctx); - } - }); - } - - egui::TopBottomPanel::top("top").show(ctx, |ui| { - ui.horizontal_wrapped(|ui| { - if let Some(texture) = &self.logo_texture { - let target = 36.0_f32; - let scale = target / self.logo_size.x.max(1.0); - let display_size = self.logo_size * scale; - let response = ui.add(Image::new(texture).fit_to_exact_size(display_size)).on_hover_text("Smoo AI"); - if response.clicked() { - open_url("https://smoo.ai"); - } - ui.separator(); - } - if ui.button("Change Root…").clicked() { - if let Some(dir) = FileDialog::new().set_directory(&self.root).pick_folder() { - self.pending_root = dir.clone(); - self.root = dir.clone(); - if self.live_mode { - self.watch_root(dir.clone()); - } else { - self.stop_watch(); - } - self.start_index(dir, ctx); - } - } - if ui.button("Reindex").clicked() { - self.start_index(self.root.clone(), ctx); - } - if ui.checkbox(&mut self.live_mode, "Live mode").changed() { - if self.live_mode { - self.watch_root(self.root.clone()); - self.status = "Live mode enabled. Watching for log deltas.".into(); - } else { - self.stop_watch(); - self.status = "Live mode disabled.".into(); - } - ctx.request_repaint(); - } - ui.separator(); - ui.label(RichText::new(self.root.display().to_string()).color(Color32::from_gray(170))); - ui.separator(); - ui.checkbox(&mut self.sort_desc, "Newest first"); - if ui.button("Apply sort").clicked() { - self.apply_filters(); - } - ui.separator(); - ui.toggle_value(&mut self.dark_mode, "🌙 Dark"); - ui.separator(); - }); - }); - - egui::SidePanel::left("filters").resizable(true).default_width(330.0).show(ctx, |ui| { - ui.heading("Filters"); - let mut any_filter_lost_focus = false; - let r = ui.add(TextEdit::singleline(&mut self.filters.text).hint_text("search across fields")); - any_filter_lost_focus |= r.lost_focus(); - let r = ui.add(TextEdit::singleline(&mut self.filters.level).hint_text("level / LogLevel")); - any_filter_lost_focus |= r.lost_focus(); - let r = ui.add(TextEdit::singleline(&mut self.filters.corr).hint_text("correlationId")); - any_filter_lost_focus |= r.lost_focus(); - let r = ui.add(TextEdit::singleline(&mut self.filters.service).hint_text("service")); - any_filter_lost_focus |= r.lost_focus(); - let r = ui.add(TextEdit::singleline(&mut self.filters.namespace).hint_text("namespace")); - any_filter_lost_focus |= r.lost_focus(); - let r = ui.add(TextEdit::singleline(&mut self.filters.trace).hint_text("traceId")); - any_filter_lost_focus |= r.lost_focus(); - let r = ui.add(TextEdit::singleline(&mut self.filters.request).hint_text("requestId")); - any_filter_lost_focus |= r.lost_focus(); - ui.checkbox(&mut self.filters.regex_mode, "Regex mode"); - let enter_pressed = ui.input(|i| i.key_pressed(Key::Enter)); - if ui.button("Apply filters").clicked() || (any_filter_lost_focus && enter_pressed) { - self.apply_filters(); - } - - ui.separator(); - ui.heading("Pagination"); - ui.add(egui::Slider::new(&mut self.page_size, 50..=3000).text("rows/page")); - ui.horizontal(|ui| { - if ui.button("Prev").clicked() && self.page > 0 { - self.page -= 1; - } - let total_pages = ((self.filtered.len() + self.page_size - 1) / self.page_size.max(1)).max(1); - ui.label(format!("Page {} / {}", self.page + 1, total_pages)); - if ui.button("Next").clicked() && self.page + 1 < total_pages { - self.page += 1; - } - }); - - ui.separator(); - ui.heading("Context"); - ui.add(egui::Slider::new(&mut self.ctx_before, 0..=50).text("lines before")); - ui.add(egui::Slider::new(&mut self.ctx_after, 0..=50).text("lines after")); - - ui.separator(); - ui.heading("Columns"); - ui.label("Select extra fields to render on demand."); - - let mut request_add = false; - ui.horizontal(|ui| { - let response = ui.add(TextEdit::singleline(&mut self.column_search).hint_text("add column…")); - if response.lost_focus() && ui.input(|i| i.key_pressed(Key::Enter)) { - request_add = true; - } - if ui.button("Add").clicked() { - request_add = true; - } - }); - - let add_feedback = if request_add { Some(self.try_add_column_from_search()) } else { None }; - - if let Some(result) = add_feedback { - match result { - ColumnAddResult::Added(name) => { - ui.colored_label(Color32::from_rgb(120, 200, 120), format!("Added column '{name}'.")); - } - ColumnAddResult::AlreadyVisible(name) => { - ui.colored_label(Color32::from_rgb(200, 180, 30), format!("Column '{name}' is already visible.")); - } - ColumnAddResult::BaseColumn(name) => { - ui.colored_label(Color32::from_rgb(200, 100, 60), format!("'{name}' is part of the default view.")); - } - ColumnAddResult::NotFound(name) => { - ui.colored_label(Color32::from_rgb(200, 100, 60), format!("No column matched '{name}'.")); - } - ColumnAddResult::Empty => {} - } - } - - let suggestions = self.column_suggestions(); - if !suggestions.is_empty() { - ui.label("Suggestions:"); - ui.horizontal_wrapped(|ui| { - for suggestion in suggestions { - if ui.button(format!("+ {suggestion}")).clicked() && self.add_visible_column(&suggestion) { - self.column_search.clear(); - } - } - }); - } - - let extras = self.dynamic_columns(); - if extras.is_empty() { - ui.label("No additional columns selected."); - } else { - ui.label("Visible extra columns:"); - ui.horizontal_wrapped(|ui| { - for column in extras { - if ui.button(format!("{column} ✕")).clicked() { - self.remove_visible_column(&column); - } - } - }); - } - }); - - egui::CentralPanel::default().show(ctx, |ui| { - if self.indexing { - ui.vertical_centered(|ui| { - ui.add_space(200.0); - if let Some((processed, total)) = self.index_progress { - let total = total.max(1); - let processed = processed.min(total); - let fraction = (processed as f32 / total as f32).clamp(0.0, 1.0); - let text = format!("Indexing {processed}/{total} files"); - ui.add(egui::ProgressBar::new(fraction).show_percentage().text(text)); - } else { - ui.spinner(); - } - ui.add_space(12.0); - ui.label(&self.status); - }); - return; - } - - if !self.has_rows() { - ui.label("Index your monorepo (finds all `.smooai-logs/`) to begin."); - return; - } - - // Split the central area into resizable top (table) and bottom (context) sections - egui::TopBottomPanel::bottom("context_panel") - .resizable(true) - .default_height(300.0) - .min_height(150.0) - .show_inside(ui, |ui| { - self.render_context_panel(ui); - }); - - egui::CentralPanel::default().show_inside(ui, |ui| { - self.render_log_table(ui, ctx); - }); - }); - } -} - -fn flatten_json_map(value: &Value) -> BTreeMap { - let mut map = BTreeMap::new(); - if let Value::Object(obj) = value { - for (key, val) in obj { - flatten_value(val, key, &mut map); - } - } - map -} - -fn flatten_value(value: &Value, prefix: &str, out: &mut BTreeMap) { - match value { - Value::Object(obj) => { - for (key, val) in obj { - let new_prefix = if prefix.is_empty() { key.to_string() } else { format!("{prefix}.{key}") }; - flatten_value(val, &new_prefix, out); - } - } - Value::Array(arr) => { - for (idx, val) in arr.iter().enumerate() { - let new_prefix = if prefix.is_empty() { format!("[{idx}]") } else { format!("{prefix}[{idx}]") }; - flatten_value(val, &new_prefix, out); - } - } - _ => { - if !prefix.is_empty() { - out.insert(prefix.to_string(), value_to_string(value)); - } - } - } -} - -fn value_to_string(value: &Value) -> String { - match value { - Value::Null => "null".to_string(), - Value::Bool(b) => b.to_string(), - Value::Number(n) => n.to_string(), - Value::String(s) => s.clone(), - Value::Array(_) | Value::Object(_) => serde_json::to_string(value).unwrap_or_default(), - } -} - -fn resolve_row_value(row: &Row, key: &str) -> String { - match key { - "time" => row.ts.map(|t| t.to_rfc3339()).unwrap_or_default(), - "level" => row.level.clone().unwrap_or_default(), - "msg" => row.msg.clone().unwrap_or_default(), - "correlationId" => row.corr.clone().unwrap_or_default(), - "name" => row.name.clone().unwrap_or_default(), - "service" => row.service.clone().unwrap_or_default(), - "namespace" => row.namespace.clone().unwrap_or_default(), - "traceId" => row.trace_id.clone().unwrap_or_default(), - "requestId" => row.request_id.clone().unwrap_or_default(), - "error" | "errorDetails" => row - .flat - .get(key) - .cloned() - .or_else(|| row.flat.get(&format!("@{key}")).cloned()) - .unwrap_or_default(), - _ => row.flat.get(key).cloned().unwrap_or_default(), - } -} - -fn format_json_for_display(raw: &str) -> (String, usize) { - if let Ok(value) = serde_json::from_str::(raw) { - if let Ok(pretty) = serde_json::to_string_pretty(&value) { - let lines = pretty.lines().count().max(1); - return (pretty, lines); - } - } - let fallback = raw.to_string(); - let lines = fallback.lines().count().max(1); - (fallback, lines) -} - -#[cfg(target_os = "macos")] -fn open_file_with_default(path: &Path) -> Result<()> { - Command::new("open") - .args(["-t", path.to_string_lossy().as_ref()]) - .status() - .with_context(|| format!("open {path:?}"))? - .success() - .then_some(()) - .ok_or_else(|| anyhow!("open command failed")) -} - -#[cfg(target_os = "macos")] -fn open_file_with_app(path: &Path, app: &Path) -> Result<()> { - Command::new("open") - .arg("-a") - .arg(app) - .arg(path) - .status() - .with_context(|| format!("open {path:?} with {app:?}"))? - .success() - .then_some(()) - .ok_or_else(|| anyhow!("open command failed")) -} - -#[cfg(target_os = "linux")] -fn open_file_with_default(path: &Path) -> Result<()> { - Command::new("xdg-open") - .arg(path) - .status() - .with_context(|| format!("open {path:?}"))? - .success() - .then_some(()) - .ok_or_else(|| anyhow!("xdg-open command failed")) -} - -#[cfg(target_os = "linux")] -fn open_file_with_app(path: &Path, app: &Path) -> Result<()> { - Command::new(app) - .arg(path) - .status() - .with_context(|| format!("launch {app:?} {path:?}"))? - .success() - .then_some(()) - .ok_or_else(|| anyhow!("application command failed")) -} - -#[cfg(target_os = "windows")] -fn open_file_with_default(path: &Path) -> Result<()> { - Command::new("cmd") - .args(["/C", "start", "", path.to_string_lossy().as_ref()]) - .status() - .with_context(|| format!("open {path:?}"))? - .success() - .then_some(()) - .ok_or_else(|| anyhow!("start command failed")) -} - -#[cfg(target_os = "windows")] -fn open_file_with_app(path: &Path, app: &Path) -> Result<()> { - Command::new(app) - .arg(path) - .status() - .with_context(|| format!("launch {app:?} {path:?}"))? - .success() - .then_some(()) - .ok_or_else(|| anyhow!("application command failed")) -} - -#[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))] -fn open_file_with_default(_path: &Path) -> Result<()> { - Err(anyhow!("opening files is not supported on this platform")) -} - -#[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))] -fn open_file_with_app(_path: &Path, _app: &Path) -> Result<()> { - Err(anyhow!("opening files with specific app is not supported on this platform")) -} - -fn index_single_file(file_id: usize, path: &Path, extractor: &Extractor) -> Result<(Vec, Vec)> { - let mmap = mmap_file(path)?; - let lines = scan_lines(&mmap); - let sanitized_lines = sanitize_lines(&mmap, &lines); - let (rows, _columns) = parse_rows(file_id, path, &lines, &sanitized_lines, extractor); - Ok((sanitized_lines, rows)) -} - -fn index_monorepo(root: &Path, progress_tx: Option>) -> Result { - let log_dirs = find_smooai_log_dirs(root); - let mut catalog = Catalog::default(); - - if log_dirs.is_empty() { - return Ok(catalog); - } - - let files: Vec = log_dirs.iter().flat_map(|dir| list_log_files(dir)).collect(); - - let total_files = files.len(); - if let Some(tx) = &progress_tx { - let _ = tx.send(IndexEvent::Progress { - processed: 0, - total: total_files, - }); - } - - let extractor = Extractor::new(); - - let processed_files = AtomicUsize::new(0); - let mut tmp_files: Vec = files - .par_iter() - .enumerate() - .map(|(file_id, path)| { - let mmap = mmap_file(path); - if mmap.is_err() { - return (path.clone(), Vec::new(), Vec::new(), BTreeSet::new()); - } - let mmap = mmap.unwrap(); - let lines = scan_lines(&mmap); - let sanitized_lines = sanitize_lines(&mmap, &lines); - let (rows, columns) = parse_rows(file_id, path, &lines, &sanitized_lines, &extractor); - if let Some(tx) = &progress_tx { - let current = processed_files.fetch_add(1, Ordering::SeqCst) + 1; - let _ = tx.send(IndexEvent::Progress { - processed: current.min(total_files), - total: total_files, - }); - } - (path.clone(), sanitized_lines, rows, columns) - }) - .collect(); - - tmp_files.sort_by(|a, b| a.0.cmp(&b.0)); - - let mut column_set = BTreeSet::new(); - for (path, sanitized_lines, mut rows, cols) in tmp_files { - column_set.extend(cols); - catalog.files.push(FileEntry { path, sanitized_lines }); - catalog.rows.append(&mut rows); - } - - catalog.rows.sort_by(|left, right| { - left.ts - .cmp(&right.ts) - .then_with(|| left.file_id.cmp(&right.file_id)) - .then_with(|| left.line_start.cmp(&right.line_start)) - }); - - catalog.columns = column_set.into_iter().collect(); - - catalog.duckdb_path = Some(populate_duckdb(&catalog.rows)?); - - Ok(catalog) -} - -fn populate_duckdb(rows: &[Row]) -> Result { - let mut db_path = std::env::temp_dir(); - let unique = SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_millis(); - db_path.push(format!("smooai-log-viewer-{unique}.duckdb")); - - let conn = Connection::open(&db_path).context("open duckdb database")?; - conn.execute( - "CREATE TABLE IF NOT EXISTS logs ( - row_id BIGINT PRIMARY KEY, - file_id BIGINT, - line_start BIGINT, - line_end BIGINT, - ts TIMESTAMP, - ts_text TEXT, - level TEXT, - corr TEXT, - name TEXT, - msg TEXT, - service TEXT, - namespace TEXT, - trace_id TEXT, - request_id TEXT, - raw_json TEXT, - flat_json TEXT - )", - [], - )?; - - for (row_id, row) in rows.iter().enumerate() { - let ts_string = row.ts.map(|t| t.to_rfc3339()); - let flat_json = serde_json::to_string(&row.flat).unwrap_or_else(|_| "{}".into()); - conn.execute( - "INSERT INTO logs ( - row_id, file_id, line_start, line_end, ts, ts_text, level, corr, name, msg, - service, namespace, trace_id, request_id, raw_json, flat_json - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - params![ - row_id as i64, - row.file_id as i64, - row.line_start as i64, - row.line_end as i64, - ts_string.as_deref(), - ts_string.as_deref(), - row.level.as_deref(), - row.corr.as_deref(), - row.name.as_deref(), - row.msg.as_deref(), - row.service.as_deref(), - row.namespace.as_deref(), - row.trace_id.as_deref(), - row.request_id.as_deref(), - row.raw_json, - flat_json, - ], - )?; - } - - Ok(db_path) -} - -fn parse_rows(file_id: usize, _path: &Path, lines: &[LineHeader], sanitized_lines: &[String], extractor: &Extractor) -> (Vec, BTreeSet) { - let mut rows = Vec::new(); - let mut columns = BTreeSet::new(); - let mut idx = 0; - - while idx < lines.len() { - let sanitized_trim = sanitized_lines[idx].trim(); - if sanitized_trim.is_empty() || sanitized_trim.chars().all(|c| c == '-') { - idx += 1; - continue; - } - - let mut block = String::new(); - let mut end_idx = idx; - let mut parsed_value: Option = None; - - while end_idx < lines.len() { - if !block.is_empty() { - block.push('\n'); - } - block.push_str(sanitized_lines[end_idx].as_str()); - let trimmed = block.trim(); - if trimmed.is_empty() { - end_idx += 1; - continue; - } - if let Some(value) = extractor.parse_json(trimmed) { - parsed_value = Some(value); - break; - } - end_idx += 1; - } - - let (value, raw_text) = if let Some(value) = parsed_value { - (value, block.trim().to_string()) - } else { - let raw = block.trim().to_string(); - (json!({ "msg": raw.clone() }), raw) - }; - - let (ts, level, corr, name, msg, service, namespace, trace_id, request_id) = extractor.extract(&value); - let flat = flatten_json_map(&value); - for key in flat.keys() { - columns.insert(key.clone()); - } - - rows.push(Row { - file_id, - line_start: idx, - line_end: end_idx, - ts, - level, - corr, - name, - msg, - service, - namespace, - trace_id, - request_id, - flat, - raw_json: raw_text.clone(), - }); - - idx = end_idx + 1; - } - - (rows, columns) -} - -fn shorten_for_display(input: &str, max: usize) -> String { - if input.chars().count() <= max { - return input.to_string(); - } - let trimmed: String = input.chars().take(max).collect(); - format!("{}...", trimmed) -} - -fn levenshtein(left: &str, right: &str) -> usize { - if left == right { - return 0; - } - if left.is_empty() { - return right.len(); - } - if right.is_empty() { - return left.len(); - } - - let left_bytes = left.as_bytes(); - let right_bytes = right.as_bytes(); - - let mut previous: Vec = (0..=right_bytes.len()).collect(); - let mut current = vec![0; right_bytes.len() + 1]; - - for (i, &left_byte) in left_bytes.iter().enumerate() { - current[0] = i + 1; - for (j, &right_byte) in right_bytes.iter().enumerate() { - let cost = if left_byte == right_byte { 0 } else { 1 }; - current[j + 1] = (current[j] + 1).min(previous[j + 1] + 1).min(previous[j] + cost); - } - previous.copy_from_slice(¤t); - } - - previous[right_bytes.len()] -} - -fn strip_ansi_codes(input: &[u8]) -> Vec { - let mut output = Vec::with_capacity(input.len()); - let mut i = 0; - while i < input.len() { - if input[i] == 0x1B { - i += 1; - if i < input.len() && (input[i] == b'[' || input[i] == b']') { - i += 1; - while i < input.len() && !(input[i] >= 0x40 && input[i] <= 0x7E) { - i += 1; - } - if i < input.len() { - i += 1; - } - } - } else { - output.push(input[i]); - i += 1; - } - } - output -} - -fn sanitize_lines(mmap: &Mmap, headers: &[LineHeader]) -> Vec { - let bytes = &mmap[..]; - let mut lines = Vec::with_capacity(headers.len()); - for header in headers { - let start = header.offset as usize; - let end = start + header.len as usize; - let slice = &bytes[start..end]; - let sanitized = strip_ansi_codes(slice); - let mut text = String::from_utf8_lossy(&sanitized).to_string(); - if text.ends_with('\r') { - text.pop(); - } - lines.push(text); - } - lines -} - -fn find_smooai_log_dirs(root: &Path) -> Vec { - WalkDir::new(root) - .into_iter() - .filter_map(|entry| entry.ok()) - .filter(|entry| entry.file_type().is_dir() && entry.file_name() == ".smooai-logs") - .map(|entry| entry.path().to_path_buf()) - .collect() -} - -fn list_log_files(dir: &Path) -> Vec { - WalkDir::new(dir) - .max_depth(1) - .into_iter() - .filter_map(|entry| entry.ok()) - .filter(|entry| { - entry.file_type().is_file() - && entry - .path() - .extension() - .map(|ext| ext == "ansi" || ext == "log" || ext == "json" || ext == "jsonl") - .unwrap_or(false) - }) - .map(|entry| entry.path().to_path_buf()) - .collect() -} - -fn scan_lines(mmap: &Mmap) -> Vec { - let bytes = &mmap[..]; - let mut lines = Vec::with_capacity(1024); - let mut start = 0usize; - - for (idx, byte) in bytes.iter().enumerate() { - if *byte == b'\n' { - if idx > start { - lines.push(LineHeader { - offset: start as u64, - len: (idx - start) as u32, - }); - } - start = idx + 1; - } - } - - if start < bytes.len() { - lines.push(LineHeader { - offset: start as u64, - len: (bytes.len() - start) as u32, - }); - } - - lines -} - -fn mmap_file(path: &Path) -> Result { - let file = File::open(path).with_context(|| format!("open {path:?}"))?; - unsafe { Mmap::map(&file).context("mmap") } -} - -#[derive(Debug, Clone, Copy)] -struct LineHeader { - offset: u64, - len: u32, -} - -fn render_json_root(ui: &mut egui::Ui, value: &Value) { - match value { - Value::Object(map) => { - for (key, val) in map { - render_json_node(ui, key.to_string(), val); - } - } - Value::Array(items) => { - for (idx, val) in items.iter().enumerate() { - render_json_node(ui, format!("[{idx}]"), val); - } - } - _ => { - ui.label(value_to_string(value)); - } - } -} - -fn render_json_node(ui: &mut egui::Ui, label: String, value: &Value) { - match value { - Value::Object(map) => { - egui::CollapsingHeader::new(label).default_open(false).show(ui, |ui| { - for (key, val) in map { - render_json_node(ui, key.to_string(), val); - } - }); - } - Value::Array(items) => { - egui::CollapsingHeader::new(label).default_open(false).show(ui, |ui| { - for (idx, val) in items.iter().enumerate() { - render_json_node(ui, format!("[{idx}]"), val); - } - }); - } - _ => { - ui.label(format!("{label}: {}", value_to_string(value))); - } - } -} - -fn open_url(url: &str) { - #[cfg(target_os = "macos")] - let mut command = Command::new("open"); - #[cfg(target_os = "linux")] - let mut command = Command::new("xdg-open"); - #[cfg(target_os = "windows")] - let mut command = { - let mut c = Command::new("rundll32"); - c.arg("url.dll,FileProtocolHandler"); - c - }; - - #[cfg(not(target_os = "windows"))] - command.arg(url); - #[cfg(target_os = "windows")] - command.arg(url); - - let _ = command.spawn(); -} - -fn load_logo_image() -> Option<(ColorImage, Vec2)> { - let image = image::load_from_memory(LOGO_BYTES).ok()?.into_rgba8(); - let (width, height) = image.dimensions(); - let size = Vec2::new(width as f32, height as f32); - Some((ColorImage::from_rgba_unmultiplied([width as usize, height as usize], &image), size)) -} - -fn load_app_icon() -> Option { - let image = image::load_from_memory(APP_ICON_BYTES).ok()?.into_rgba8(); - let (width, height) = image.dimensions(); - Some(IconData { - rgba: image.into_raw(), - width, - height, - }) -} - -fn main() -> Result<()> { - let mut viewport = egui::ViewportBuilder::default().with_inner_size([1380.0, 900.0]); - if let Some(icon) = load_app_icon() { - viewport = viewport.with_icon(icon); - } - let native_options = eframe::NativeOptions { - viewport, - ..Default::default() - }; - eframe::run_native("Smoo AI Log Viewer", native_options, Box::new(|_cc| Ok(Box::new(App::default())))).map_err(|err| anyhow!(err.to_string()))?; - Ok(()) -} diff --git a/log-viewer/src/theme.rs b/log-viewer/src/theme.rs deleted file mode 100644 index 92032f51..00000000 --- a/log-viewer/src/theme.rs +++ /dev/null @@ -1,185 +0,0 @@ -#![allow(dead_code)] -use eframe::egui::{self, Color32, Margin, Rounding, Stroke, Visuals}; -use smooai_logger::Level; - -/// Brand color palette derived from the Tailwind theme configuration. -pub mod smoo { - use eframe::egui::Color32; - - pub const WHITE: Color32 = color(0xf8fafc); - pub const DARK_BLUE: Color32 = color(0x020618); - pub const GREEN: Color32 = color(0x00a6a6); - pub const RED: Color32 = color(0xff6b6c); - pub const ORANGE: Color32 = color(0xf49f0a); - pub const BLUE: Color32 = color(0xbbdef0); - pub const ROSE: Color32 = color(0xf0e2e7); - - pub const GRAY_50: Color32 = color(0xf3f3f3); - pub const GRAY_100: Color32 = color(0xe8e8e8); - pub const GRAY_200: Color32 = color(0xcfcfcf); - pub const GRAY_300: Color32 = color(0xb9b9b9); - pub const GRAY_400: Color32 = color(0xa3a3a3); - pub const GRAY_500: Color32 = color(0x868686); - pub const GRAY_600: Color32 = color(0x6a6a6a); - pub const GRAY_700: Color32 = color(0x4e4e4e); - pub const GRAY_800: Color32 = color(0x353535); - pub const GRAY_900: Color32 = color(0x1d1d1d); - pub const GRAY_950: Color32 = color(0x131313); - - pub const BLUE_400: Color32 = color(0x5fb1dc); - pub const BLUE_700: Color32 = color(0x1a5878); - - pub const fn color(hex: u32) -> Color32 { - let r = ((hex >> 16) & 0xff) as u8; - let g = ((hex >> 8) & 0xff) as u8; - let b = (hex & 0xff) as u8; - Color32::from_rgb(r, g, b) - } -} - -#[derive(Clone, Copy)] -pub struct SmooTheme { - pub background: Color32, - pub foreground: Color32, - pub primary: Color32, - pub primary_fg: Color32, - pub secondary: Color32, - pub secondary_fg: Color32, - pub accent: Color32, - pub accent_fg: Color32, - pub border: Color32, - pub input: Color32, - pub ring: Color32, - pub muted: Color32, - pub muted_fg: Color32, - pub destructive: Color32, - pub destructive_fg: Color32, -} - -pub fn light_theme() -> SmooTheme { - SmooTheme { - background: smoo::WHITE, - foreground: smoo::DARK_BLUE, - primary: smoo::GREEN, - primary_fg: smoo::WHITE, - secondary: smoo::RED, - secondary_fg: smoo::WHITE, - accent: smoo::ORANGE, - accent_fg: smoo::WHITE, - border: smoo::BLUE_400, - input: smoo::BLUE_700, - ring: smoo::BLUE_400, - muted: smoo::BLUE, - muted_fg: smoo::GRAY_400, - destructive: smoo::color(0x8b1d1d), - destructive_fg: smoo::WHITE, - } -} - -pub fn dark_theme() -> SmooTheme { - SmooTheme { - background: smoo::DARK_BLUE, - foreground: smoo::WHITE, - primary: smoo::GREEN, - primary_fg: smoo::WHITE, - secondary: smoo::RED, - secondary_fg: smoo::WHITE, - accent: smoo::ORANGE, - accent_fg: smoo::WHITE, - border: smoo::BLUE_400, - input: smoo::BLUE_700, - ring: smoo::BLUE_400, - muted: smoo::BLUE, - muted_fg: smoo::GRAY_400, - destructive: smoo::color(0x8b1d1d), - destructive_fg: smoo::WHITE, - } -} - -pub fn apply_visuals(ctx: &egui::Context, dark: bool) { - let theme = if dark { dark_theme() } else { light_theme() }; - - let mut visuals = if dark { Visuals::dark() } else { Visuals::light() }; - visuals.extreme_bg_color = theme.background; - visuals.faint_bg_color = stripe_background(dark); - visuals.panel_fill = theme.background; - visuals.window_fill = theme.background; - visuals.override_text_color = Some(theme.foreground); - visuals.selection.bg_fill = selection_background(dark); - visuals.selection.stroke = Stroke { - width: 1.0, - color: theme.border, - }; - visuals.hyperlink_color = theme.primary; - - let rounding = Rounding::same(8.0); - visuals.widgets.noninteractive.rounding = rounding; - visuals.widgets.inactive.rounding = rounding; - visuals.widgets.hovered.rounding = rounding; - visuals.widgets.active.rounding = rounding; - visuals.widgets.open.rounding = rounding; - - visuals.window_stroke = Stroke { - width: 1.0, - color: theme.border, - }; - visuals.widgets.noninteractive.bg_fill = theme.background; - visuals.widgets.inactive.bg_fill = lerp(theme.background, theme.muted, 0.05); - visuals.widgets.hovered.bg_fill = lerp(theme.background, theme.muted, 0.10); - visuals.widgets.active.bg_fill = lerp(theme.background, theme.muted, 0.15); - - ctx.set_visuals(visuals.clone()); - - let mut style = (*ctx.style()).clone(); - style.visuals = visuals; - style.spacing.item_spacing = egui::vec2(8.0, 6.0); - style.spacing.window_margin = Margin::same(12.0); - style.visuals.window_rounding = rounding; - ctx.set_style(style); -} - -pub fn stripe_background(dark: bool) -> Color32 { - let theme = if dark { dark_theme() } else { light_theme() }; - lerp(theme.background, theme.muted, if dark { 0.14 } else { 0.08 }) -} - -pub fn selection_background(dark: bool) -> Color32 { - let theme = if dark { dark_theme() } else { light_theme() }; - lerp(theme.ring, theme.background, if dark { 0.45 } else { 0.6 }) -} - -pub fn header_background(dark: bool) -> Color32 { - let theme = if dark { dark_theme() } else { light_theme() }; - lerp(theme.background, theme.muted, if dark { 0.12 } else { 0.10 }) -} - -pub fn grid_stroke(dark: bool) -> Stroke { - let color = if dark { - lerp(smoo::GRAY_800, smoo::GRAY_600, 0.35) - } else { - lerp(smoo::GRAY_100, smoo::GRAY_300, 0.45) - }; - Stroke { width: 1.0, color } -} - -pub fn level_color(level: &str) -> Color32 { - match Level::parse_level(level) { - Some(Level::Error) | Some(Level::Fatal) => smoo::RED, - Some(Level::Warn) => smoo::ORANGE, - Some(Level::Info) => smoo::BLUE_400, - Some(Level::Debug) => smoo::GRAY_500, - Some(Level::Trace) => smoo::GRAY_400, - _ => smoo::GRAY_400, - } -} - -pub fn lerp(a: Color32, b: Color32, t: f32) -> Color32 { - let to_f = |c: Color32| (c.r() as f32, c.g() as f32, c.b() as f32); - let (ar, ag, ab) = to_f(a); - let (br, bg, bb) = to_f(b); - Color32::from_rgb( - ((1.0 - t) * ar + t * br) as u8, - ((1.0 - t) * ag + t * bg) as u8, - ((1.0 - t) * ab + t * bb) as u8, - ) -} diff --git a/package.json b/package.json index 0f1200a7..aac957ff 100644 --- a/package.json +++ b/package.json @@ -16,16 +16,9 @@ "type": "git", "url": "https://github.com/SmooAI/logger.git" }, - "bin": { - "smooai-log-viewer": "./dist/cli/log-viewer.cjs" - }, "files": [ "dist/**", - "scripts/**/*.mjs", - "log-viewer/Cargo.toml", - "log-viewer/Cargo.lock", - "log-viewer/README.md", - "log-viewer/src/**" + "scripts/**/*.mjs" ], "main": "./dist/index.cjs", "module": "./dist/index.mjs", @@ -90,30 +83,17 @@ }, "scripts": { "aibranch": "pnpm generate-git-branch", - "build": "pnpm tsdown && cp src/decycle.cjs dist/ && pnpm run python:build && pnpm run rust:build && pnpm run go:build && pnpm run log-viewer:bundle", - "check-all": "pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run rust:fmt:check && pnpm run rust:lint && pnpm run rust:test && pnpm run go:fmt:check && pnpm run go:lint && pnpm run go:test && pnpm run log-viewer:validate && pnpm run build", + "build": "pnpm tsdown && cp src/decycle.cjs dist/ && pnpm run python:build && pnpm run rust:build && pnpm run go:build", + "check-all": "pnpm run typecheck && pnpm run lint && pnpm run test && pnpm run rust:fmt:check && pnpm run rust:lint && pnpm run rust:test && pnpm run go:fmt:check && pnpm run go:lint && pnpm run go:test && pnpm run build", "ci:publish": "node scripts/ci-publish.mjs", - "format": "oxfmt --write . && pnpm run python:format && pnpm run rust:fmt && pnpm run go:fmt && pnpm run log-viewer:format", + "format": "oxfmt --write . && pnpm run python:format && pnpm run rust:fmt && pnpm run go:fmt", "go:build": "(cd go && go build ./...)", "go:fmt": "(cd go && gofmt -w .)", "go:fmt:check": "(cd go && test -z \"$(gofmt -l .)\")", "go:lint": "(cd go && go vet ./...)", "go:test": "(cd go && go test -v ./...)", - "postinstall": "pnpm run log-viewer:bundle", - "lint": "oxlint . && pnpm run python:lint && pnpm run rust:lint && pnpm run go:lint && pnpm run log-viewer:lint", - "lint:fix": "oxlint --fix . && pnpm run python:lint:fix && pnpm run log-viewer:lint", - "log-viewer": "cargo run --release --manifest-path log-viewer/Cargo.toml", - "log-viewer:bundle": "node scripts/bundle-log-viewer.mjs", - "log-viewer:check:all": "pnpm run log-viewer:fmt:check && pnpm run log-viewer:lint && pnpm run log-viewer:typecheck && pnpm run log-viewer:test", - "log-viewer:fmt": "cargo fmt --manifest-path log-viewer/Cargo.toml", - "log-viewer:fmt:check": "cargo fmt --manifest-path log-viewer/Cargo.toml --all -- --check", - "log-viewer:format": "cargo fmt --manifest-path log-viewer/Cargo.toml", - "log-viewer:format:check": "cargo fmt --manifest-path log-viewer/Cargo.toml --all -- --check", - "log-viewer:lint": "cargo clippy --manifest-path log-viewer/Cargo.toml --all-targets -- -D warnings", - "log-viewer:lint:simd": "cargo clippy --manifest-path log-viewer/Cargo.toml --all-targets --features simd -- -D warnings", - "log-viewer:test": "cargo test --manifest-path log-viewer/Cargo.toml", - "log-viewer:typecheck": "cargo check --manifest-path log-viewer/Cargo.toml --all-targets", - "log-viewer:validate": "pnpm run log-viewer:fmt:check && pnpm run log-viewer:lint && pnpm run log-viewer:check", + "lint": "oxlint . && pnpm run python:lint && pnpm run rust:lint && pnpm run go:lint", + "lint:fix": "oxlint --fix . && pnpm run python:lint:fix", "pre-commit-check": "(zsh .husky/pre-commit)", "python:build": "(cd python && uv run poe build)", "python:format": "(cd python && uv run poe format)", @@ -130,8 +110,8 @@ "rust:fmt:check": "(cd rust/logger && cargo fmt --all -- --check)", "rust:lint": "(cd rust/logger && cargo clippy --all-targets -- -D warnings)", "rust:test": "(cd rust/logger && cargo test)", - "test": "vitest run --passWithNoTests && pnpm python:test && pnpm rust:test && pnpm go:test && pnpm log-viewer:test", - "typecheck": "tsc --noEmit --skipLibCheck && pnpm run python:typecheck:errors && pnpm run rust:check && pnpm run go:build && pnpm run log-viewer:typecheck", + "test": "vitest run --passWithNoTests && pnpm python:test && pnpm rust:test && pnpm go:test", + "typecheck": "tsc --noEmit --skipLibCheck && pnpm run python:typecheck:errors && pnpm run rust:check && pnpm run go:build", "version:sync": "node scripts/sync-versions.mjs", "watch": "tsdown --watch" }, @@ -152,7 +132,6 @@ }, "devDependencies": { "@changesets/cli": "^2.28.1", - "@oclif/core": "^4.2.9", "@opentelemetry/context-async-hooks": "^1.30.0", "@opentelemetry/sdk-logs": "^0.55.0", "@opentelemetry/sdk-trace-base": "^1.30.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d8b25cd5..c65b731f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -52,9 +52,6 @@ importers: '@changesets/cli': specifier: ^2.28.1 version: 2.28.1 - '@oclif/core': - specifier: ^4.2.9 - version: 4.2.9 '@opentelemetry/api': specifier: ^1.9.0 version: 1.9.1 diff --git a/python/log-viewer/darwin-arm64/smooai-log-viewer b/python/log-viewer/darwin-arm64/smooai-log-viewer deleted file mode 100755 index 2eccde5b..00000000 Binary files a/python/log-viewer/darwin-arm64/smooai-log-viewer and /dev/null differ diff --git a/python/log-viewer/linux-x64/smooai-log-viewer b/python/log-viewer/linux-x64/smooai-log-viewer deleted file mode 100755 index 422bac71..00000000 Binary files a/python/log-viewer/linux-x64/smooai-log-viewer and /dev/null differ diff --git a/python/pyproject.toml b/python/pyproject.toml index 73151543..bd416a10 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -30,9 +30,6 @@ Homepage = "https://github.com/SmooAI/logger" Repository = "https://github.com/SmooAI/logger" Issues = "https://github.com/SmooAI/logger/issues" -[project.scripts] -smooai-log-viewer = "smooai_logger.cli.log_viewer:main" - [build-system] requires = ["hatchling"] build-backend = "hatchling.build" @@ -44,16 +41,12 @@ dev = ["poethepoet>=0.29.0", "pytest>=8.3.0", "ruff>=0.11.6,<0.12", "basedpyrigh [tool.poe.tasks.install-dev] cmd = "uv sync --locked --group dev" -[tool.poe.tasks."log-viewer:bundle"] -cmd = "python scripts/bundle-log-viewer.py" - [tool.poe.tasks.build] -sequence = [{ cmd = "python scripts/bundle-log-viewer.py" }, { cmd = "uv build --wheel --sdist" }] +cmd = "uv build --wheel --sdist" [tool.poe.tasks.publish] sequence = [ { shell = "rm -rf dist/" }, - { cmd = "python scripts/bundle-log-viewer.py" }, { cmd = "uv build --wheel --sdist" }, { cmd = "uv publish" }, ] diff --git a/python/scripts/bundle-log-viewer.py b/python/scripts/bundle-log-viewer.py deleted file mode 100755 index 5a81b57a..00000000 --- a/python/scripts/bundle-log-viewer.py +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/env python3 -"""Bundle the log-viewer binary for Python distribution.""" - -import platform -import shutil -import subprocess -import sys -import urllib.request -from pathlib import Path - -GITHUB_REPO = "SmooAI/logger" - -# Map Python platform names to npm format -PLATFORM_MAPPING = {"darwin": "darwin", "linux": "linux", "windows": "win32"} -ARCH_MAPPING = {"x86_64": "x64", "amd64": "x64", "arm64": "arm64", "aarch64": "arm64"} - - -def try_download(dest_binary: Path, mapped_platform: str, mapped_arch: str) -> bool: - """Try to download a pre-built binary from GitHub Releases.""" - try: - ext = ".exe" if mapped_platform == "win32" else "" - asset_name = f"smooai-log-viewer-{mapped_platform}-{mapped_arch}{ext}" - url = f"https://github.com/{GITHUB_REPO}/releases/latest/download/{asset_name}" - - print(f"bundle-log-viewer: attempting to download pre-built binary from {url}") - req = urllib.request.Request(url, method="GET") - with urllib.request.urlopen(req, timeout=60) as response: - data = response.read() - - dest_binary.parent.mkdir(parents=True, exist_ok=True) - dest_binary.write_bytes(data) - if mapped_platform != "win32": - dest_binary.chmod(0o755) - return True - except Exception as e: - print(f"bundle-log-viewer: download failed ({e}), falling back to cargo build", file=sys.stderr) - return False - - -def main() -> None: - """Bundle the log-viewer binary into the Python package.""" - python_dir = Path(__file__).parent.parent - root_dir = python_dir.parent - - current_platform = platform.system().lower() - current_arch = platform.machine().lower() - - mapped_platform = PLATFORM_MAPPING.get(current_platform) - mapped_arch = ARCH_MAPPING.get(current_arch) - - if not mapped_platform or not mapped_arch: - print(f"bundle-log-viewer: unsupported platform {current_platform}/{current_arch}", file=sys.stderr) - sys.exit(1) - - binary_name = "smooai-log-viewer.exe" if mapped_platform == "win32" else "smooai-log-viewer" - dest_dir = python_dir / "log-viewer" / f"{mapped_platform}-{mapped_arch}" - dest_binary = dest_dir / binary_name - - # Try to download pre-built binary first - if try_download(dest_binary, mapped_platform, mapped_arch): - print(f"bundle-log-viewer: downloaded pre-built binary to {dest_binary}") - return - - # Fall back to cargo build - manifest_path = root_dir / "log-viewer" / "Cargo.toml" - if not manifest_path.exists(): - print("bundle-log-viewer: manifest not found and no pre-built binary available, skipping", file=sys.stderr) - return - - try: - result = subprocess.run(["cargo", "--version"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - if result.returncode != 0: - raise subprocess.CalledProcessError(result.returncode, "cargo --version") - except (subprocess.CalledProcessError, FileNotFoundError): - print("bundle-log-viewer: cargo not detected and no pre-built binary available, skipping", file=sys.stderr) - return - - print("bundle-log-viewer: no pre-built binary found, building from source...") - build_result = subprocess.run(["cargo", "build", "--release", "--manifest-path", str(manifest_path)], cwd=root_dir) - - if build_result.returncode != 0: - print("bundle-log-viewer: cargo build failed", file=sys.stderr) - sys.exit(build_result.returncode) - - source_binary = root_dir / "log-viewer" / "target" / "release" / binary_name - if not source_binary.exists(): - print(f"bundle-log-viewer: expected binary at {source_binary} but none was found", file=sys.stderr) - sys.exit(1) - - dest_dir.mkdir(parents=True, exist_ok=True) - shutil.copy2(source_binary, dest_binary) - if mapped_platform != "win32": - dest_binary.chmod(0o755) - - print(f"bundle-log-viewer: built and packaged {dest_binary}") - - -if __name__ == "__main__": - main() diff --git a/python/src/smooai_logger/cli/__init__.py b/python/src/smooai_logger/cli/__init__.py deleted file mode 100644 index c7b1cc59..00000000 --- a/python/src/smooai_logger/cli/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""CLI module for smooai-logger.""" diff --git a/python/src/smooai_logger/cli/log_viewer.py b/python/src/smooai_logger/cli/log_viewer.py deleted file mode 100644 index a0e6aaa1..00000000 --- a/python/src/smooai_logger/cli/log_viewer.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python3 -"""Python wrapper for the smooai-log-viewer binary.""" - -import platform -import subprocess -import sys -from pathlib import Path - - -def find_binary() -> Path: - """Find the log-viewer binary for the current platform.""" - current_platform = platform.system().lower() - current_arch = platform.machine().lower() - - # Map Python platform names to the format used in the npm package - platform_mapping = {"darwin": "darwin", "linux": "linux", "windows": "win32"} - - # Map Python arch names to npm format - arch_mapping = {"x86_64": "x64", "amd64": "x64", "arm64": "arm64", "aarch64": "arm64"} - - mapped_platform = platform_mapping.get(current_platform) - mapped_arch = arch_mapping.get(current_arch) - - if not mapped_platform or not mapped_arch: - raise RuntimeError(f"Unsupported platform: {current_platform}/{current_arch}") - - binary_name = "smooai-log-viewer.exe" if mapped_platform == "win32" else "smooai-log-viewer" - - # Look for the binary in the package directory structure - package_dir = Path(__file__).parent.parent.parent.parent - binary_path = package_dir / "log-viewer" / f"{mapped_platform}-{mapped_arch}" / binary_name - - if not binary_path.exists(): - raise RuntimeError( - f"[smooai-log-viewer] No binary found for {mapped_platform}/{mapped_arch}. Expected to find:\n" - f" {binary_path}\n" - f"[smooai-log-viewer] Ensure Rust is installed and the binary has been built for your platform." - ) - - return binary_path - - -def main() -> None: - """Main entry point for the log-viewer CLI.""" - try: - binary_path = find_binary() - - # Execute the binary with the same arguments - result = subprocess.run([str(binary_path)] + sys.argv[1:], stdout=sys.stdout, stderr=sys.stderr, stdin=sys.stdin) - - sys.exit(result.returncode) - - except KeyboardInterrupt: - sys.exit(130) # Standard exit code for SIGINT - except RuntimeError as e: - print(str(e), file=sys.stderr) - sys.exit(1) - except Exception as e: - print(f"[smooai-log-viewer] Failed to launch the log viewer binary: {e}", file=sys.stderr) - sys.exit(1) - - -if __name__ == "__main__": - main() diff --git a/scripts/bundle-log-viewer.mjs b/scripts/bundle-log-viewer.mjs deleted file mode 100644 index 5a8c6f13..00000000 --- a/scripts/bundle-log-viewer.mjs +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env node -import { spawnSync } from "node:child_process"; -import { chmodSync, copyFileSync, existsSync, mkdirSync, writeFileSync } from "node:fs"; -import { resolve } from "node:path"; -import process from "node:process"; - -const GITHUB_REPO = "SmooAI/logger"; -const root = process.cwd(); - -const binaryName = process.platform === "win32" ? "smooai-log-viewer.exe" : "smooai-log-viewer"; -const destinationDir = resolve(root, "dist", "log-viewer", `${process.platform}-${process.arch}`); -mkdirSync(destinationDir, { recursive: true }); -const destinationBinary = resolve(destinationDir, binaryName); - -// Try to download pre-built binary first -const downloaded = await tryDownload(); -if (downloaded) { - console.log(`bundle-log-viewer: downloaded pre-built binary to ${destinationBinary}`); - process.exit(0); -} - -// Fall back to cargo build -const manifestPath = resolve(root, "log-viewer", "Cargo.toml"); - -if (!existsSync(manifestPath)) { - console.warn("bundle-log-viewer: manifest not found and no pre-built binary available, skipping"); - process.exit(0); -} - -const cargoCheck = spawnSync("cargo", ["--version"], { stdio: "ignore" }); -if (cargoCheck.status !== 0) { - console.warn("bundle-log-viewer: cargo not detected and no pre-built binary available, skipping"); - process.exit(0); -} - -console.log("bundle-log-viewer: no pre-built binary found, building from source..."); -const build = spawnSync("cargo", ["build", "--release", "--manifest-path", manifestPath], { - stdio: "inherit", - cwd: root, -}); - -if (build.status !== 0) { - console.error("bundle-log-viewer: cargo build failed"); - process.exit(build.status ?? 1); -} - -const sourceBinary = resolve(root, "log-viewer", "target", "release", binaryName); - -if (!existsSync(sourceBinary)) { - console.error(`bundle-log-viewer: expected binary at ${sourceBinary} but none was found`); - process.exit(1); -} - -copyFileSync(sourceBinary, destinationBinary); -if (process.platform !== "win32") { - chmodSync(destinationBinary, 0o755); -} - -console.log(`bundle-log-viewer: built and packaged ${destinationBinary}`); - -async function tryDownload() { - try { - const ext = process.platform === "win32" ? ".exe" : ""; - const assetName = `smooai-log-viewer-${process.platform}-${process.arch}${ext}`; - const url = `https://github.com/${GITHUB_REPO}/releases/latest/download/${assetName}`; - - console.log(`bundle-log-viewer: attempting to download pre-built binary from ${url}`); - const response = await fetch(url, { redirect: "follow" }); - if (!response.ok) { - console.log( - `bundle-log-viewer: download returned ${response.status}, falling back to cargo build`, - ); - return false; - } - - const buffer = Buffer.from(await response.arrayBuffer()); - writeFileSync(destinationBinary, buffer); - if (process.platform !== "win32") { - chmodSync(destinationBinary, 0o755); - } - return true; - } catch (error) { - console.log( - `bundle-log-viewer: download failed (${error.message}), falling back to cargo build`, - ); - return false; - } -} diff --git a/scripts/sync-versions.mjs b/scripts/sync-versions.mjs index 495ae01e..89060e22 100644 --- a/scripts/sync-versions.mjs +++ b/scripts/sync-versions.mjs @@ -45,26 +45,6 @@ const updates = [ return content.replace(pattern, `$1${version}$3`); }, }, - { - path: "log-viewer/Cargo.toml", - apply(content) { - const pattern = /^(version\s*=\s*")([^"]+)(")/m; - if (!pattern.test(content)) { - throw new Error("Version line not found in log-viewer/Cargo.toml"); - } - return content.replace(pattern, `$1${version}$3`); - }, - }, - { - path: "log-viewer/Cargo.lock", - apply(content) { - const pattern = /(name\s*=\s*"smooai-log-viewer"\s*\nversion\s*=\s*")([^"]+)(")/; - if (!pattern.test(content)) { - throw new Error("Version block not found in log-viewer/Cargo.lock"); - } - return content.replace(pattern, `$1${version}$3`); - }, - }, { path: "go/version.go", apply(content) { diff --git a/smooai-logger-3.1.2.tgz b/smooai-logger-3.1.2.tgz deleted file mode 100644 index b8875f48..00000000 Binary files a/smooai-logger-3.1.2.tgz and /dev/null differ diff --git a/src/cli/log-viewer.ts b/src/cli/log-viewer.ts deleted file mode 100644 index 93529eb6..00000000 --- a/src/cli/log-viewer.ts +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env node -import { spawn } from "node:child_process"; -import { existsSync } from "node:fs"; -import { resolve } from "node:path"; -import process from "node:process"; - -const platform = process.platform; -const arch = process.arch; -const binaryName = platform === "win32" ? "smooai-log-viewer.exe" : "smooai-log-viewer"; -const binaryPath = resolve(__dirname, "..", "log-viewer", `${platform}-${arch}`, binaryName); - -if (!existsSync(binaryPath)) { - console.error( - `[smooai-log-viewer] No binary found for ${platform}/${arch}. Expected to find:`, - `\n ${binaryPath}`, - ); - console.error( - '[smooai-log-viewer] Ensure Rust is installed and run "pnpm run log-viewer:bundle" to build the desktop viewer.', - ); - process.exit(1); -} - -const child = spawn(binaryPath, process.argv.slice(2), { - stdio: "inherit", -}); - -child.on("exit", (code, signal) => { - if (typeof code === "number") { - process.exit(code); - } - - if (signal) { - process.kill(process.pid, signal); - } else { - process.exit(0); - } -}); - -child.on("error", (error) => { - console.error("[smooai-log-viewer] Failed to launch the log viewer binary."); - console.error(error); - process.exit(1); -}); diff --git a/tsdown.config.ts b/tsdown.config.ts index 833a0d11..b0844fcd 100644 --- a/tsdown.config.ts +++ b/tsdown.config.ts @@ -43,17 +43,4 @@ const browserConfig: Options = { ], } satisfies Options; -const cliConfig: Options = { - entry: ["src/cli/log-viewer.ts"], - outDir: "dist/cli", - clean: false, - format: ["cjs"], - platform: "node", - target: "node18", - sourcemap: false, - dts: false, - treeshake: false, - shims: false, -} satisfies Options; - -export default defineConfig([coreConfig, browserConfig, cliConfig]); +export default defineConfig([coreConfig, browserConfig]);