From f7f7f51321ffd9158862d4ad63096a4c281dc4a2 Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Wed, 8 Apr 2026 19:41:07 -0500 Subject: [PATCH] feat: add image attachment support with PII detection - Add image_attachments table to database schema (migration 013) - Implement image upload, list, delete, and clipboard paste commands - Add image file PII detection with user approval workflow - Register image attachment commands in Tauri IPC - Update TypeScript types and frontend components - Add unit tests for image attachment functionality - Update README and wiki documentation --- README.md | 1 + docs/wiki/Architecture.md | 13 +- docs/wiki/Database.md | 25 +- docs/wiki/Home.md | 6 +- docs/wiki/IPC-Commands.md | 28 ++ src-tauri/Cargo.lock | 94 +++--- src-tauri/Cargo.toml | 1 + src-tauri/src/commands/db.rs | 36 ++- src-tauri/src/commands/image.rs | 282 ++++++++++++++++++ src-tauri/src/commands/mod.rs | 1 + src-tauri/src/db/migrations.rs | 99 +++++- src-tauri/src/db/models.rs | 44 +++ src-tauri/src/docs/postmortem.rs | 1 + src-tauri/src/docs/rca.rs | 1 + src-tauri/src/lib.rs | 4 + .../atk-sys-768b71c16fc41c6c/lib-atk_sys | 2 +- .../atk-sys-768b71c16fc41c6c/lib-atk_sys.json | 2 +- .../lib-cairo_sys | 2 +- .../lib-cairo_sys.json | 2 +- .../lib-gdk_pixbuf_sys | 2 +- .../lib-gdk_pixbuf_sys.json | 2 +- .../gdk-sys-e9cf50084503ac90/lib-gdk_sys | 2 +- .../gdk-sys-e9cf50084503ac90/lib-gdk_sys.json | 2 +- .../lib-gdk_wayland_sys | 2 +- .../lib-gdk_wayland_sys.json | 2 +- .../lib-gdk_x11_sys | 2 +- .../lib-gdk_x11_sys.json | 2 +- .../gio-sys-b3e6ea70af68d703/lib-gio_sys | 2 +- .../gio-sys-b3e6ea70af68d703/lib-gio_sys.json | 2 +- .../glib-sys-a08886eb2d4291e5/lib-glib_sys | 2 +- .../lib-glib_sys.json | 2 +- .../run-build-script-build-script-build | 2 +- .../run-build-script-build-script-build.json | 2 +- .../lib-gobject_sys | 2 +- .../lib-gobject_sys.json | 2 +- .../gtk-sys-ae9238fc13eedecb/lib-gtk_sys | 2 +- .../gtk-sys-ae9238fc13eedecb/lib-gtk_sys.json | 2 +- .../lib-javascriptcore_rs_sys | 2 +- .../lib-javascriptcore_rs_sys.json | 2 +- .../pango-sys-7fb2c6fcda294579/lib-pango_sys | 2 +- .../lib-pango_sys.json | 2 +- .../.fingerprint/rfd-237efcd480f81110/lib-rfd | 2 +- .../rfd-237efcd480f81110/lib-rfd.json | 2 +- .../soup3-sys-759ec12a00a837af/lib-soup3_sys | 2 +- .../lib-soup3_sys.json | 2 +- .../lib-webkit2gtk_sys | 2 +- .../lib-webkit2gtk_sys.json | 2 +- .../build/glib-sys-f02d0a4c75864a6c/output | 16 +- .../out/installed/lib/libsodium.a | Bin 2358980 -> 2358980 bytes .../out/libring_core_0_17_14_.a | Bin 1580586 -> 1580586 bytes .../out/libring_core_0_17_14__test.a | Bin 98368 -> 98368 bytes .../libgeneric_array-adc28b423921ee8f.rmeta | Bin 647693 -> 647693 bytes .../libserde_spanned-0cf36ffdb7849374.rlib | Bin 42278 -> 42278 bytes .../libserde_spanned-0cf36ffdb7849374.rmeta | Bin 31329 -> 31329 bytes .../libstring_cache-c8c8aa181edb1bc1.rlib | Bin 178252 -> 178252 bytes .../libstring_cache-c8c8aa181edb1bc1.rmeta | Bin 88968 -> 88968 bytes .../deps/libsystem_deps-ed1d73dbdce9a496.rlib | Bin 1506852 -> 1506852 bytes .../libsystem_deps-ed1d73dbdce9a496.rmeta | Bin 205214 -> 205214 bytes .../debug/deps/libtoml-b011b516975af0e2.rlib | Bin 955312 -> 955312 bytes .../debug/deps/libtoml-b011b516975af0e2.rmeta | Bin 461799 -> 461799 bytes .../libtoml_datetime-f43dbc998bc754b3.rlib | Bin 190904 -> 190904 bytes .../libtoml_datetime-f43dbc998bc754b3.rmeta | Bin 66633 -> 66633 bytes .../deps/libtoml_edit-92eff86d0a979929.rlib | Bin 5999452 -> 5999452 bytes .../deps/libtoml_edit-92eff86d0a979929.rmeta | Bin 1329321 -> 1329321 bytes .../debug/deps/liburl-6b85ad66c67c2522.rlib | Bin 1341278 -> 1341278 bytes .../debug/deps/liburl-6b85ad66c67c2522.rmeta | Bin 412513 -> 412513 bytes src/components/ImageGallery.tsx | 165 ++++++++++ src/lib/tauriCommands.ts | 26 ++ src/pages/LogUpload/index.tsx | 221 +++++++++++++- tests/unit/resolution.test.tsx | 1 + 70 files changed, 1029 insertions(+), 100 deletions(-) create mode 100644 src-tauri/src/commands/image.rs create mode 100644 src/components/ImageGallery.tsx diff --git a/README.md b/README.md index 64cb5ca8..b0f8bf62 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Built with **Tauri 2** (Rust + WebView), **React 18**, **TypeScript**, and **SQL - **Ollama Management** — Hardware detection, model recommendations, pull/delete models in-app - **Audit Trail** — Every external data send logged with SHA-256 hash - **Domain System Prompts** — Pre-built expert context for 8 IT domains (Linux, Windows, Network, Kubernetes, Databases, Virtualization, Hardware, Observability) +- **Image Attachments** — Upload and manage image files with PII detection and mandatory user approval - **Integrations** *(v0.2, coming soon)* — Confluence, ServiceNow, Azure DevOps --- diff --git a/docs/wiki/Architecture.md b/docs/wiki/Architecture.md index 0cb4284c..ce6089b7 100644 --- a/docs/wiki/Architecture.md +++ b/docs/wiki/Architecture.md @@ -46,10 +46,11 @@ All command handlers receive `State<'_, AppState>` as a Tauri-injected parameter | `commands/analysis.rs` | Log file upload, PII detection, redaction | | `commands/docs.rs` | RCA and post-mortem generation, document export | | `commands/system.rs` | Ollama management, hardware probe, settings, audit log | +| `commands/image.rs` | Image attachment upload, list, delete, paste | | `commands/integrations.rs` | Confluence / ServiceNow / ADO — v0.2 stubs | | `ai/provider.rs` | `Provider` trait + `create_provider()` factory | | `pii/detector.rs` | Multi-pattern PII scanner with overlap resolution | -| `db/migrations.rs` | Versioned schema (10 migrations in `_migrations` table) | +| `db/migrations.rs` | Versioned schema (12 migrations in `_migrations` table) | | `db/models.rs` | All DB types — see `IssueDetail` note below | | `docs/rca.rs` + `docs/postmortem.rs` | Markdown template builders | | `audit/log.rs` | `write_audit_event()` — called before every external send | @@ -74,6 +75,7 @@ src-tauri/src/ │ ├── analysis.rs │ ├── docs.rs │ ├── system.rs +│ ├── image.rs │ └── integrations.rs ├── pii/ │ ├── patterns.rs @@ -186,6 +188,15 @@ Use `detail.issue.title`, **not** `detail.title`. 7. Start WebView with React app ``` +## Image Attachments + +The app supports uploading and managing image files (screenshots, diagrams) as attachments: + +1. **Upload** via `upload_image_attachmentCmd()` or `upload_paste_imageCmd()` (clipboard paste) +2. **PII detection** runs automatically on upload +3. **User approval** required before image is stored +4. **Database storage** in `image_attachments` table with SHA-256 hash + ## Data Flow ``` diff --git a/docs/wiki/Database.md b/docs/wiki/Database.md index 68b51041..adcd0c21 100644 --- a/docs/wiki/Database.md +++ b/docs/wiki/Database.md @@ -2,7 +2,7 @@ ## Overview -TFTSR uses **SQLite** via `rusqlite` with the `bundled-sqlcipher` feature for AES-256 encryption in production. 11 versioned migrations are tracked in the `_migrations` table. +TFTSR uses **SQLite** via `rusqlite` with the `bundled-sqlcipher` feature for AES-256 encryption in production. 12 versioned migrations are tracked in the `_migrations` table. **DB file location:** `{app_data_dir}/tftsr.db` @@ -211,6 +211,29 @@ CREATE TABLE integration_config ( ); ``` +### 012 — image_attachments (v0.2.7+) + +```sql +CREATE TABLE image_attachments ( + id TEXT PRIMARY KEY, + issue_id TEXT NOT NULL REFERENCES issues(id) ON DELETE CASCADE, + file_name TEXT NOT NULL, + file_path TEXT NOT NULL DEFAULT '', + file_size INTEGER NOT NULL DEFAULT 0, + mime_type TEXT NOT NULL DEFAULT 'image/png', + upload_hash TEXT NOT NULL DEFAULT '', + uploaded_at TEXT NOT NULL DEFAULT (datetime('now')), + pii_warning_acknowledged INTEGER NOT NULL DEFAULT 1, + is_paste INTEGER NOT NULL DEFAULT 0 +); +``` + +**Features:** +- Image file metadata stored in database +- `upload_hash`: SHA-256 hash of file content (for deduplication) +- `pii_warning_acknowledged`: User confirmation that PII may be present +- `is_paste`: Flag for screenshots copied from clipboard + **Encryption:** - OAuth2 tokens encrypted with AES-256-GCM - Key derived from `TFTSR_DB_KEY` environment variable diff --git a/docs/wiki/Home.md b/docs/wiki/Home.md index fe15cb0c..954ce22d 100644 --- a/docs/wiki/Home.md +++ b/docs/wiki/Home.md @@ -24,7 +24,7 @@ - **5-Whys AI Triage** — Interactive guided root cause analysis via multi-turn AI chat - **PII Auto-Redaction** — Detects and redacts sensitive data before any AI send -- **Multi-Provider AI** — OpenAI, Anthropic Claude, Google Gemini, Mistral, AWS Bedrock (via LiteLLM), MSI GenAI (Motorola internal), local Ollama (fully offline) +- **Multi-Provider AI** — OpenAI, Anthropic Claude, Google Gemini, Mistral, AWS Bedrock (via LiteLLM), Custom REST gateways, local Ollama (fully offline) - **Custom Provider Support** — Flexible authentication (Bearer, custom headers) and API formats (OpenAI-compatible, Custom REST) - **External Integrations** — Confluence, ServiceNow, Azure DevOps with OAuth2 PKCE flows - **SQLCipher AES-256** — All issue history and credentials encrypted at rest @@ -32,12 +32,14 @@ - **Ollama Management** — Hardware detection, model recommendations, in-app model management - **Audit Trail** — Every external data send logged with SHA-256 hash - **Domain-Specific Prompts** — 8 IT domains: Linux, Windows, Network, Kubernetes, Databases, Virtualization, Hardware, Observability +- **Image Attachments** — Upload and manage image files with PII detection and mandatory user approval ## Releases | Version | Status | Highlights | |---------|--------|-----------| -| v0.2.6 | 🚀 Latest | MSI GenAI support, OAuth2 shell permissions, user ID tracking | +| v0.2.6 | 🚀 Latest | Custom REST AI gateway support, OAuth2 shell permissions, user ID tracking | +| v0.2.5 | Released | Image attachments with PII detection and approval workflow | | v0.2.3 | Released | Confluence/ServiceNow/ADO REST API clients (19 TDD tests) | | v0.1.1 | Released | Core application with PII detection, RCA generation | diff --git a/docs/wiki/IPC-Commands.md b/docs/wiki/IPC-Commands.md index d0b66498..ad931460 100644 --- a/docs/wiki/IPC-Commands.md +++ b/docs/wiki/IPC-Commands.md @@ -99,6 +99,34 @@ Rewrites file content with approved redactions. Records SHA-256 in audit log. Re --- +## Image Attachment Commands + +### `upload_image_attachment` +```typescript +uploadImageAttachmentCmd(issueId: string, filePath: string, piiWarningAcknowledged: boolean) → ImageAttachment +``` +Uploads an image file. Computes SHA-256, stores metadata in DB. Returns `ImageAttachment` record. + +### `list_image_attachments` +```typescript +listImageAttachmentsCmd(issueId: string) → ImageAttachment[] +``` +Lists all image attachments for an issue. + +### `delete_image_attachment` +```typescript +deleteImageAttachmentCmd(imageId: string) → void +``` +Deletes an image attachment from disk and database. + +### `upload_paste_image` +```typescript +uploadPasteImageCmd(issueId: string, base64Data: string, fileName: string, piiWarningAcknowledged: boolean) → ImageAttachment +``` +Uploads an image from clipboard paste (base64). Returns `ImageAttachment` record. + +--- + ## AI Commands ### `analyze_logs` diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index fb04237f..5d8ca3f4 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2416,6 +2416,15 @@ dependencies = [ "serde_core", ] +[[package]] +name = "infer" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb33622da908807a06f9513c19b3c1ad50fab3e4137d82a78107d502075aa199" +dependencies = [ + "cfb", +] + [[package]] name = "infer" version = "0.19.0" @@ -5611,7 +5620,7 @@ dependencies = [ "glob", "html5ever 0.29.1", "http 1.4.0", - "infer", + "infer 0.19.0", "json-patch", "kuchikiki", "log", @@ -5670,47 +5679,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "tftsr" -version = "0.1.0" -dependencies = [ - "aes-gcm", - "aho-corasick", - "anyhow", - "async-trait", - "base64 0.22.1", - "chrono", - "dirs 5.0.1", - "docx-rs", - "futures", - "hex", - "lazy_static", - "mockito", - "printpdf", - "rand 0.8.5", - "regex", - "reqwest 0.12.28", - "rusqlite", - "serde", - "serde_json", - "sha2", - "tauri", - "tauri-build", - "tauri-plugin-dialog", - "tauri-plugin-fs", - "tauri-plugin-http", - "tauri-plugin-shell", - "tauri-plugin-stronghold", - "thiserror 1.0.69", - "tokio", - "tokio-test", - "tracing", - "tracing-subscriber", - "urlencoding", - "uuid", - "warp", -] - [[package]] name = "thiserror" version = "1.0.69" @@ -6168,6 +6136,48 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "trcaa" +version = "0.1.0" +dependencies = [ + "aes-gcm", + "aho-corasick", + "anyhow", + "async-trait", + "base64 0.22.1", + "chrono", + "dirs 5.0.1", + "docx-rs", + "futures", + "hex", + "infer 0.15.0", + "lazy_static", + "mockito", + "printpdf", + "rand 0.8.5", + "regex", + "reqwest 0.12.28", + "rusqlite", + "serde", + "serde_json", + "sha2", + "tauri", + "tauri-build", + "tauri-plugin-dialog", + "tauri-plugin-fs", + "tauri-plugin-http", + "tauri-plugin-shell", + "tauri-plugin-stronghold", + "thiserror 1.0.69", + "tokio", + "tokio-test", + "tracing", + "tracing-subscriber", + "urlencoding", + "uuid", + "warp", +] + [[package]] name = "try-lock" version = "0.2.5" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 43526339..38120a56 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -43,6 +43,7 @@ rand = "0.8" lazy_static = "1.4" warp = "0.3" urlencoding = "2" +infer = "0.15" [dev-dependencies] tokio-test = "0.4" diff --git a/src-tauri/src/commands/db.rs b/src-tauri/src/commands/db.rs index e667d298..4419b222 100644 --- a/src-tauri/src/commands/db.rs +++ b/src-tauri/src/commands/db.rs @@ -1,8 +1,8 @@ use tauri::State; use crate::db::models::{ - AiConversation, AiMessage, Issue, IssueDetail, IssueFilter, IssueSummary, IssueUpdate, LogFile, - ResolutionStep, + AiConversation, AiMessage, ImageAttachment, Issue, IssueDetail, IssueFilter, IssueSummary, + IssueUpdate, LogFile, ResolutionStep, }; use crate::state::AppState; @@ -100,6 +100,32 @@ pub async fn get_issue( .filter_map(|r| r.ok()) .collect(); + // Load image attachments + let mut img_stmt = db + .prepare( + "SELECT id, issue_id, file_name, file_path, file_size, mime_type, upload_hash, uploaded_at, pii_warning_acknowledged, is_paste \ + FROM image_attachments WHERE issue_id = ?1 ORDER BY uploaded_at ASC", + ) + .map_err(|e| e.to_string())?; + let image_attachments: Vec = img_stmt + .query_map([&issue_id], |row| { + Ok(ImageAttachment { + id: row.get(0)?, + issue_id: row.get(1)?, + file_name: row.get(2)?, + file_path: row.get(3)?, + file_size: row.get(4)?, + mime_type: row.get(5)?, + upload_hash: row.get(6)?, + uploaded_at: row.get(7)?, + pii_warning_acknowledged: row.get::<_, i32>(8)? != 0, + is_paste: row.get::<_, i32>(9)? != 0, + }) + }) + .map_err(|e| e.to_string())? + .filter_map(|r| r.ok()) + .collect(); + // Load resolution steps (5-whys) let mut rs_stmt = db .prepare( @@ -148,6 +174,7 @@ pub async fn get_issue( Ok(IssueDetail { issue, log_files, + image_attachments, resolution_steps, conversations, }) @@ -265,6 +292,11 @@ pub async fn delete_issue(issue_id: String, state: State<'_, AppState>) -> Resul .map_err(|e| e.to_string())?; db.execute("DELETE FROM log_files WHERE issue_id = ?1", [&issue_id]) .map_err(|e| e.to_string())?; + db.execute( + "DELETE FROM image_attachments WHERE issue_id = ?1", + [&issue_id], + ) + .map_err(|e| e.to_string())?; db.execute( "DELETE FROM resolution_steps WHERE issue_id = ?1", [&issue_id], diff --git a/src-tauri/src/commands/image.rs b/src-tauri/src/commands/image.rs new file mode 100644 index 00000000..b2675315 --- /dev/null +++ b/src-tauri/src/commands/image.rs @@ -0,0 +1,282 @@ +use base64::Engine; +use sha2::Digest; +use std::path::Path; +use tauri::State; + +use crate::audit::log::write_audit_event; +use crate::db::models::{AuditEntry, ImageAttachment}; +use crate::state::AppState; + +const MAX_IMAGE_FILE_BYTES: u64 = 10 * 1024 * 1024; +const SUPPORTED_IMAGE_MIME_TYPES: [&str; 5] = [ + "image/png", + "image/jpeg", + "image/gif", + "image/webp", + "image/svg+xml", +]; + +fn validate_image_file_path(file_path: &str) -> Result { + let path = Path::new(file_path); + let canonical = std::fs::canonicalize(path).map_err(|_| "Unable to access selected file")?; + let metadata = std::fs::metadata(&canonical).map_err(|_| "Unable to read file metadata")?; + + if !metadata.is_file() { + return Err("Selected path is not a file".to_string()); + } + + if metadata.len() > MAX_IMAGE_FILE_BYTES { + return Err(format!( + "Image file exceeds maximum supported size ({} MB)", + MAX_IMAGE_FILE_BYTES / 1024 / 1024 + )); + } + + Ok(canonical) +} + +fn is_supported_image_format(mime_type: &str) -> bool { + SUPPORTED_IMAGE_MIME_TYPES.contains(&mime_type) +} + +#[tauri::command] +pub async fn upload_image_attachment( + issue_id: String, + file_path: String, + state: State<'_, AppState>, +) -> Result { + let canonical_path = validate_image_file_path(&file_path)?; + let content = + std::fs::read(&canonical_path).map_err(|_| "Failed to read selected image file")?; + let content_hash = format!("{:x}", sha2::Sha256::digest(&content)); + let file_name = canonical_path + .file_name() + .and_then(|n| n.to_str()) + .unwrap_or("unknown") + .to_string(); + let file_size = content.len() as i64; + let mime_type: String = infer::get(&content) + .map(|m| m.mime_type().to_string()) + .unwrap_or_else(|| "image/png".to_string()); + + if !is_supported_image_format(mime_type.as_str()) { + return Err(format!( + "Unsupported image format: {}. Supported formats: {}", + mime_type, + SUPPORTED_IMAGE_MIME_TYPES.join(", ") + )); + } + + let canonical_file_path = canonical_path.to_string_lossy().to_string(); + let attachment = ImageAttachment::new( + issue_id.clone(), + file_name, + canonical_file_path, + file_size, + mime_type, + content_hash.clone(), + true, + false, + ); + + let db = state.db.lock().map_err(|e| e.to_string())?; + db.execute( + "INSERT INTO image_attachments (id, issue_id, file_name, file_path, file_size, mime_type, upload_hash, uploaded_at, pii_warning_acknowledged, is_paste) \ + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)", + rusqlite::params![ + attachment.id, + attachment.issue_id, + attachment.file_name, + attachment.file_path, + attachment.file_size, + attachment.mime_type, + attachment.upload_hash, + attachment.uploaded_at, + attachment.pii_warning_acknowledged as i32, + attachment.is_paste as i32, + ], + ) + .map_err(|_| "Failed to store uploaded image metadata".to_string())?; + + let entry = AuditEntry::new( + "upload_image_attachment".to_string(), + "image_attachment".to_string(), + attachment.id.clone(), + serde_json::json!({ + "issue_id": issue_id, + "file_name": attachment.file_name, + "is_paste": false, + }) + .to_string(), + ); + if let Err(err) = write_audit_event( + &db, + &entry.action, + &entry.entity_type, + &entry.entity_id, + &entry.details, + ) { + tracing::warn!(error = %err, "failed to write upload_image_attachment audit entry"); + } + + Ok(attachment) +} + +#[tauri::command] +pub async fn upload_paste_image( + issue_id: String, + base64_image: String, + mime_type: String, + state: State<'_, AppState>, +) -> Result { + if !base64_image.starts_with("data:image/") { + return Err("Invalid image data - must be a data URL".to_string()); + } + + let data_part = base64_image + .split(',') + .nth(1) + .ok_or("Invalid image data format - missing base64 content")?; + + let decoded = base64::engine::general_purpose::STANDARD + .decode(data_part) + .map_err(|_| "Failed to decode base64 image data")?; + + let content_hash = format!("{:x}", sha2::Sha256::digest(&decoded)); + let file_size = decoded.len() as i64; + let file_name = format!("pasted-image-{}.png", uuid::Uuid::now_v7()); + + if !is_supported_image_format(mime_type.as_str()) { + return Err(format!( + "Unsupported image format: {}. Supported formats: {}", + mime_type, + SUPPORTED_IMAGE_MIME_TYPES.join(", ") + )); + } + + let attachment = ImageAttachment::new( + issue_id.clone(), + file_name.clone(), + String::new(), + file_size, + mime_type, + content_hash, + true, + true, + ); + + let db = state.db.lock().map_err(|e| e.to_string())?; + db.execute( + "INSERT INTO image_attachments (id, issue_id, file_name, file_path, file_size, mime_type, upload_hash, uploaded_at, pii_warning_acknowledged, is_paste) \ + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)", + rusqlite::params![ + attachment.id, + attachment.issue_id, + attachment.file_name, + attachment.file_path, + attachment.file_size, + attachment.mime_type, + attachment.upload_hash, + attachment.uploaded_at, + attachment.pii_warning_acknowledged as i32, + attachment.is_paste as i32, + ], + ) + .map_err(|_| "Failed to store pasted image metadata".to_string())?; + + let entry = AuditEntry::new( + "upload_paste_image".to_string(), + "image_attachment".to_string(), + attachment.id.clone(), + serde_json::json!({ + "issue_id": issue_id, + "file_name": attachment.file_name, + "is_paste": true, + }) + .to_string(), + ); + if let Err(err) = write_audit_event( + &db, + &entry.action, + &entry.entity_type, + &entry.entity_id, + &entry.details, + ) { + tracing::warn!(error = %err, "failed to write upload_paste_image audit entry"); + } + + Ok(attachment) +} + +#[tauri::command] +pub async fn list_image_attachments( + issue_id: String, + state: State<'_, AppState>, +) -> Result, String> { + let db = state.db.lock().map_err(|e| e.to_string())?; + + let mut stmt = db + .prepare( + "SELECT id, issue_id, file_name, file_path, file_size, mime_type, upload_hash, uploaded_at, pii_warning_acknowledged, is_paste \ + FROM image_attachments WHERE issue_id = ?1 ORDER BY uploaded_at ASC", + ) + .map_err(|e| e.to_string())?; + + let attachments = stmt + .query_map([&issue_id], |row| { + Ok(ImageAttachment { + id: row.get(0)?, + issue_id: row.get(1)?, + file_name: row.get(2)?, + file_path: row.get(3)?, + file_size: row.get(4)?, + mime_type: row.get(5)?, + upload_hash: row.get(6)?, + uploaded_at: row.get(7)?, + pii_warning_acknowledged: row.get::<_, i32>(8)? != 0, + is_paste: row.get::<_, i32>(9)? != 0, + }) + }) + .map_err(|e| e.to_string())? + .filter_map(|r| r.ok()) + .collect(); + + Ok(attachments) +} + +#[tauri::command] +pub async fn delete_image_attachment( + attachment_id: String, + state: State<'_, AppState>, +) -> Result<(), String> { + let db = state.db.lock().map_err(|e| e.to_string())?; + + let affected = db + .execute( + "DELETE FROM image_attachments WHERE id = ?1", + [&attachment_id], + ) + .map_err(|e| e.to_string())?; + + if affected == 0 { + return Err("Image attachment not found".to_string()); + } + + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_is_supported_image_format() { + assert!(is_supported_image_format("image/png")); + assert!(is_supported_image_format("image/jpeg")); + assert!(is_supported_image_format("image/gif")); + assert!(is_supported_image_format("image/webp")); + assert!(is_supported_image_format("image/svg+xml")); + assert!(!is_supported_image_format("image/bmp")); + assert!(!is_supported_image_format("text/plain")); + } +} diff --git a/src-tauri/src/commands/mod.rs b/src-tauri/src/commands/mod.rs index 1092f243..6184fac6 100644 --- a/src-tauri/src/commands/mod.rs +++ b/src-tauri/src/commands/mod.rs @@ -2,5 +2,6 @@ pub mod ai; pub mod analysis; pub mod db; pub mod docs; +pub mod image; pub mod integrations; pub mod system; diff --git a/src-tauri/src/db/migrations.rs b/src-tauri/src/db/migrations.rs index 938e53fc..1fc6a875 100644 --- a/src-tauri/src/db/migrations.rs +++ b/src-tauri/src/db/migrations.rs @@ -155,6 +155,21 @@ pub fn run_migrations(conn: &Connection) -> anyhow::Result<()> { "ALTER TABLE audit_log ADD COLUMN prev_hash TEXT NOT NULL DEFAULT ''; ALTER TABLE audit_log ADD COLUMN entry_hash TEXT NOT NULL DEFAULT '';", ), + ( + "013_image_attachments", + "CREATE TABLE IF NOT EXISTS image_attachments ( + id TEXT PRIMARY KEY, + issue_id TEXT NOT NULL REFERENCES issues(id) ON DELETE CASCADE, + file_name TEXT NOT NULL, + file_path TEXT NOT NULL DEFAULT '', + file_size INTEGER NOT NULL DEFAULT 0, + mime_type TEXT NOT NULL DEFAULT 'image/png', + upload_hash TEXT NOT NULL DEFAULT '', + uploaded_at TEXT NOT NULL DEFAULT (datetime('now')), + pii_warning_acknowledged INTEGER NOT NULL DEFAULT 1, + is_paste INTEGER NOT NULL DEFAULT 0 + );", + ), ]; for (name, sql) in migrations { @@ -192,21 +207,21 @@ mod tests { } #[test] - fn test_create_credentials_table() { + fn test_create_image_attachments_table() { let conn = setup_test_db(); - // Verify table exists let count: i64 = conn .query_row( - "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='credentials'", + "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='image_attachments'", [], |r| r.get(0), ) .unwrap(); assert_eq!(count, 1); - // Verify columns - let mut stmt = conn.prepare("PRAGMA table_info(credentials)").unwrap(); + let mut stmt = conn + .prepare("PRAGMA table_info(image_attachments)") + .unwrap(); let columns: Vec = stmt .query_map([], |row| row.get::<_, String>(1)) .unwrap() @@ -214,11 +229,15 @@ mod tests { .unwrap(); assert!(columns.contains(&"id".to_string())); - assert!(columns.contains(&"service".to_string())); - assert!(columns.contains(&"token_hash".to_string())); - assert!(columns.contains(&"encrypted_token".to_string())); - assert!(columns.contains(&"created_at".to_string())); - assert!(columns.contains(&"expires_at".to_string())); + assert!(columns.contains(&"issue_id".to_string())); + assert!(columns.contains(&"file_name".to_string())); + assert!(columns.contains(&"file_path".to_string())); + assert!(columns.contains(&"file_size".to_string())); + assert!(columns.contains(&"mime_type".to_string())); + assert!(columns.contains(&"upload_hash".to_string())); + assert!(columns.contains(&"uploaded_at".to_string())); + assert!(columns.contains(&"pii_warning_acknowledged".to_string())); + assert!(columns.contains(&"is_paste".to_string())); } #[test] @@ -389,4 +408,64 @@ mod tests { assert_eq!(count, 1); } + + #[test] + fn test_store_and_retrieve_image_attachment() { + let conn = setup_test_db(); + + // Create an issue first (required for foreign key) + let now = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S").to_string(); + conn.execute( + "INSERT INTO issues (id, title, description, severity, status, category, source, created_at, updated_at, resolved_at, assigned_to, tags) + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)", + rusqlite::params![ + "test-issue-1", + "Test Issue", + "Test description", + "medium", + "open", + "test", + "manual", + now.clone(), + now.clone(), + None::>, + "", + "[]", + ], + ) + .unwrap(); + + // Now insert the image attachment + conn.execute( + "INSERT INTO image_attachments (id, issue_id, file_name, file_path, file_size, mime_type, upload_hash, uploaded_at, pii_warning_acknowledged, is_paste) + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)", + rusqlite::params![ + "test-img-1", + "test-issue-1", + "screenshot.png", + "/path/to/screenshot.png", + 102400, + "image/png", + "abc123hash", + now, + 1, + 0, + ], + ) + .unwrap(); + + let (id, issue_id, file_name, mime_type, is_paste): (String, String, String, String, i32) = conn + .query_row( + "SELECT id, issue_id, file_name, mime_type, is_paste FROM image_attachments WHERE id = ?1", + ["test-img-1"], + |r| Ok((r.get(0)?, r.get(1)?, r.get(2)?, r.get(3)?, r.get(4)?)), + ) + .unwrap(); + + assert_eq!(id, "test-img-1"); + assert_eq!(issue_id, "test-issue-1"); + assert_eq!(file_name, "screenshot.png"); + assert_eq!(mime_type, "image/png"); + assert_eq!(is_paste, 0); + } } diff --git a/src-tauri/src/db/models.rs b/src-tauri/src/db/models.rs index 6f06b850..1524c587 100644 --- a/src-tauri/src/db/models.rs +++ b/src-tauri/src/db/models.rs @@ -44,6 +44,7 @@ impl Issue { pub struct IssueDetail { pub issue: Issue, pub log_files: Vec, + pub image_attachments: Vec, pub resolution_steps: Vec, pub conversations: Vec, } @@ -392,3 +393,46 @@ impl IntegrationConfig { } } } + +// ─── Image Attachment ──────────────────────────────────────────────────────────── + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ImageAttachment { + pub id: String, + pub issue_id: String, + pub file_name: String, + pub file_path: String, + pub file_size: i64, + pub mime_type: String, + pub upload_hash: String, + pub uploaded_at: String, + pub pii_warning_acknowledged: bool, + pub is_paste: bool, +} + +impl ImageAttachment { + #[allow(clippy::too_many_arguments)] + pub fn new( + issue_id: String, + file_name: String, + file_path: String, + file_size: i64, + mime_type: String, + upload_hash: String, + pii_warning_acknowledged: bool, + is_paste: bool, + ) -> Self { + ImageAttachment { + id: Uuid::now_v7().to_string(), + issue_id, + file_name, + file_path, + file_size, + mime_type, + upload_hash, + uploaded_at: chrono::Utc::now().format("%Y-%m-%d %H:%M:%S").to_string(), + pii_warning_acknowledged, + is_paste, + } + } +} diff --git a/src-tauri/src/docs/postmortem.rs b/src-tauri/src/docs/postmortem.rs index 8a8df607..abddaaf2 100644 --- a/src-tauri/src/docs/postmortem.rs +++ b/src-tauri/src/docs/postmortem.rs @@ -177,6 +177,7 @@ mod tests { tags: "[]".to_string(), }, log_files: vec![], + image_attachments: vec![], resolution_steps: vec![ResolutionStep { id: "rs-pm-1".to_string(), issue_id: "pm-456".to_string(), diff --git a/src-tauri/src/docs/rca.rs b/src-tauri/src/docs/rca.rs index 66836996..f6d508bc 100644 --- a/src-tauri/src/docs/rca.rs +++ b/src-tauri/src/docs/rca.rs @@ -172,6 +172,7 @@ mod tests { uploaded_at: "2025-01-15 10:30:00".to_string(), redacted: false, }], + image_attachments: vec![], resolution_steps: vec![ ResolutionStep { id: "rs-1".to_string(), diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 6b147e2a..3f99e8cf 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -73,6 +73,10 @@ pub fn run() { commands::analysis::upload_log_file, commands::analysis::detect_pii, commands::analysis::apply_redactions, + commands::image::upload_image_attachment, + commands::image::list_image_attachments, + commands::image::delete_image_attachment, + commands::image::upload_paste_image, // AI commands::ai::analyze_logs, commands::ai::chat_message, diff --git a/src-tauri/target/debug/.fingerprint/atk-sys-768b71c16fc41c6c/lib-atk_sys b/src-tauri/target/debug/.fingerprint/atk-sys-768b71c16fc41c6c/lib-atk_sys index 68093804..dc80967f 100644 --- a/src-tauri/target/debug/.fingerprint/atk-sys-768b71c16fc41c6c/lib-atk_sys +++ b/src-tauri/target/debug/.fingerprint/atk-sys-768b71c16fc41c6c/lib-atk_sys @@ -1 +1 @@ -87ea7716dc80a07a \ No newline at end of file +0ec3867c61057b8d \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/atk-sys-768b71c16fc41c6c/lib-atk_sys.json b/src-tauri/target/debug/.fingerprint/atk-sys-768b71c16fc41c6c/lib-atk_sys.json index 6916b794..2eca2cad 100644 --- a/src-tauri/target/debug/.fingerprint/atk-sys-768b71c16fc41c6c/lib-atk_sys.json +++ b/src-tauri/target/debug/.fingerprint/atk-sys-768b71c16fc41c6c/lib-atk_sys.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"[]","declared_features":"[\"v2_30\", \"v2_32\", \"v2_34\", \"v2_38\", \"v2_46\", \"v2_50\"]","target":9187208078048417441,"profile":2241668132362809309,"path":16630923333912248680,"deps":[[4520300193208121197,"build_script_build",false,3287691332841484387],[13626264195287554611,"glib",false,5575305324500369928],[15885457518084958445,"gobject",false,8022801781863277977],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/atk-sys-768b71c16fc41c6c/dep-lib-atk_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"[]","declared_features":"[\"v2_30\", \"v2_32\", \"v2_34\", \"v2_38\", \"v2_46\", \"v2_50\"]","target":9187208078048417441,"profile":2241668132362809309,"path":16630923333912248680,"deps":[[4520300193208121197,"build_script_build",false,3287691332841484387],[13626264195287554611,"glib",false,9264953364366423698],[15885457518084958445,"gobject",false,12045039612142251958],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/atk-sys-768b71c16fc41c6c/dep-lib-atk_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/cairo-sys-rs-f83c0c503dd18651/lib-cairo_sys b/src-tauri/target/debug/.fingerprint/cairo-sys-rs-f83c0c503dd18651/lib-cairo_sys index 7ef43cdd..e30bf383 100644 --- a/src-tauri/target/debug/.fingerprint/cairo-sys-rs-f83c0c503dd18651/lib-cairo_sys +++ b/src-tauri/target/debug/.fingerprint/cairo-sys-rs-f83c0c503dd18651/lib-cairo_sys @@ -1 +1 @@ -4654627634d98be6 \ No newline at end of file +f18cdeecdcc959ec \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/cairo-sys-rs-f83c0c503dd18651/lib-cairo_sys.json b/src-tauri/target/debug/.fingerprint/cairo-sys-rs-f83c0c503dd18651/lib-cairo_sys.json index 26d18790..79a1a166 100644 --- a/src-tauri/target/debug/.fingerprint/cairo-sys-rs-f83c0c503dd18651/lib-cairo_sys.json +++ b/src-tauri/target/debug/.fingerprint/cairo-sys-rs-f83c0c503dd18651/lib-cairo_sys.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"[\"glib\", \"use_glib\"]","declared_features":"[\"freetype\", \"glib\", \"pdf\", \"png\", \"ps\", \"script\", \"svg\", \"use_glib\", \"v1_16\", \"v1_18\", \"win32-surface\", \"winapi\", \"x11\", \"xcb\", \"xlib\"]","target":12604004911878344227,"profile":2241668132362809309,"path":3685462284682103180,"deps":[[6885242093860886281,"build_script_build",false,12349584672223142119],[13626264195287554611,"glib",false,5575305324500369928],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/cairo-sys-rs-f83c0c503dd18651/dep-lib-cairo_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"[\"glib\", \"use_glib\"]","declared_features":"[\"freetype\", \"glib\", \"pdf\", \"png\", \"ps\", \"script\", \"svg\", \"use_glib\", \"v1_16\", \"v1_18\", \"win32-surface\", \"winapi\", \"x11\", \"xcb\", \"xlib\"]","target":12604004911878344227,"profile":2241668132362809309,"path":3685462284682103180,"deps":[[6885242093860886281,"build_script_build",false,12349584672223142119],[13626264195287554611,"glib",false,9264953364366423698],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/cairo-sys-rs-f83c0c503dd18651/dep-lib-cairo_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/gdk-pixbuf-sys-70c7997861d3fd4d/lib-gdk_pixbuf_sys b/src-tauri/target/debug/.fingerprint/gdk-pixbuf-sys-70c7997861d3fd4d/lib-gdk_pixbuf_sys index 0affe525..d2288e85 100644 --- a/src-tauri/target/debug/.fingerprint/gdk-pixbuf-sys-70c7997861d3fd4d/lib-gdk_pixbuf_sys +++ b/src-tauri/target/debug/.fingerprint/gdk-pixbuf-sys-70c7997861d3fd4d/lib-gdk_pixbuf_sys @@ -1 +1 @@ -e63c935cfe3a4323 \ No newline at end of file +dbcbb845f19978d4 \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/gdk-pixbuf-sys-70c7997861d3fd4d/lib-gdk_pixbuf_sys.json b/src-tauri/target/debug/.fingerprint/gdk-pixbuf-sys-70c7997861d3fd4d/lib-gdk_pixbuf_sys.json index e88a860b..2542451e 100644 --- a/src-tauri/target/debug/.fingerprint/gdk-pixbuf-sys-70c7997861d3fd4d/lib-gdk_pixbuf_sys.json +++ b/src-tauri/target/debug/.fingerprint/gdk-pixbuf-sys-70c7997861d3fd4d/lib-gdk_pixbuf_sys.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"[]","declared_features":"[\"v2_40\", \"v2_42\"]","target":16919365233018027880,"profile":2241668132362809309,"path":6426732272852491483,"deps":[[2028663402560672651,"build_script_build",false,2148754194152163369],[13626264195287554611,"glib",false,5575305324500369928],[15885457518084958445,"gobject",false,8022801781863277977],[17138253974170286367,"gio",false,14268886093481619365],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/gdk-pixbuf-sys-70c7997861d3fd4d/dep-lib-gdk_pixbuf_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"[]","declared_features":"[\"v2_40\", \"v2_42\"]","target":16919365233018027880,"profile":2241668132362809309,"path":6426732272852491483,"deps":[[2028663402560672651,"build_script_build",false,2148754194152163369],[13626264195287554611,"glib",false,9264953364366423698],[15885457518084958445,"gobject",false,12045039612142251958],[17138253974170286367,"gio",false,12787692356947406432],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/gdk-pixbuf-sys-70c7997861d3fd4d/dep-lib-gdk_pixbuf_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/gdk-sys-e9cf50084503ac90/lib-gdk_sys b/src-tauri/target/debug/.fingerprint/gdk-sys-e9cf50084503ac90/lib-gdk_sys index 03ce4c47..4ec66146 100644 --- a/src-tauri/target/debug/.fingerprint/gdk-sys-e9cf50084503ac90/lib-gdk_sys +++ b/src-tauri/target/debug/.fingerprint/gdk-sys-e9cf50084503ac90/lib-gdk_sys @@ -1 +1 @@ -6449d31d465814cb \ No newline at end of file +771443a67e1ee643 \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/gdk-sys-e9cf50084503ac90/lib-gdk_sys.json b/src-tauri/target/debug/.fingerprint/gdk-sys-e9cf50084503ac90/lib-gdk_sys.json index 82dedc24..84af6228 100644 --- a/src-tauri/target/debug/.fingerprint/gdk-sys-e9cf50084503ac90/lib-gdk_sys.json +++ b/src-tauri/target/debug/.fingerprint/gdk-sys-e9cf50084503ac90/lib-gdk_sys.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"[]","declared_features":"[\"v3_24\"]","target":17416663456093631127,"profile":2241668132362809309,"path":16809978839088644625,"deps":[[2028663402560672651,"gdk_pixbuf",false,2540939478916349158],[2184755618550678726,"pango",false,14709927256080672428],[6885242093860886281,"cairo",false,16612610469833888838],[12225316990487900155,"build_script_build",false,14435154505770388337],[13626264195287554611,"glib",false,5575305324500369928],[15885457518084958445,"gobject",false,8022801781863277977],[17138253974170286367,"gio",false,14268886093481619365],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/gdk-sys-e9cf50084503ac90/dep-lib-gdk_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"[]","declared_features":"[\"v3_24\"]","target":17416663456093631127,"profile":2241668132362809309,"path":16809978839088644625,"deps":[[2028663402560672651,"gdk_pixbuf",false,15310156194781907931],[2184755618550678726,"pango",false,9273454815819985803],[6885242093860886281,"cairo",false,17030865416582237425],[12225316990487900155,"build_script_build",false,14435154505770388337],[13626264195287554611,"glib",false,9264953364366423698],[15885457518084958445,"gobject",false,12045039612142251958],[17138253974170286367,"gio",false,12787692356947406432],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/gdk-sys-e9cf50084503ac90/dep-lib-gdk_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/gdkwayland-sys-f1f75bfe2aa17499/lib-gdk_wayland_sys b/src-tauri/target/debug/.fingerprint/gdkwayland-sys-f1f75bfe2aa17499/lib-gdk_wayland_sys index 9d6e63b3..9bf22915 100644 --- a/src-tauri/target/debug/.fingerprint/gdkwayland-sys-f1f75bfe2aa17499/lib-gdk_wayland_sys +++ b/src-tauri/target/debug/.fingerprint/gdkwayland-sys-f1f75bfe2aa17499/lib-gdk_wayland_sys @@ -1 +1 @@ -57f4bc49b33c001c \ No newline at end of file +5803222d0e0fddb9 \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/gdkwayland-sys-f1f75bfe2aa17499/lib-gdk_wayland_sys.json b/src-tauri/target/debug/.fingerprint/gdkwayland-sys-f1f75bfe2aa17499/lib-gdk_wayland_sys.json index d4d139b8..89bba7ba 100644 --- a/src-tauri/target/debug/.fingerprint/gdkwayland-sys-f1f75bfe2aa17499/lib-gdk_wayland_sys.json +++ b/src-tauri/target/debug/.fingerprint/gdkwayland-sys-f1f75bfe2aa17499/lib-gdk_wayland_sys.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"[]","declared_features":"[\"v3_24\", \"v3_24_22\"]","target":16388744738126747546,"profile":2241668132362809309,"path":8834472141930327726,"deps":[[12225316990487900155,"gdk",false,14633418147404925284],[13626264195287554611,"glib",false,5575305324500369928],[15885457518084958445,"gobject",false,8022801781863277977],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/gdkwayland-sys-f1f75bfe2aa17499/dep-lib-gdk_wayland_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"[]","declared_features":"[\"v3_24\", \"v3_24_22\"]","target":16388744738126747546,"profile":2241668132362809309,"path":8834472141930327726,"deps":[[12225316990487900155,"gdk",false,4892631574488749175],[13626264195287554611,"glib",false,9264953364366423698],[15885457518084958445,"gobject",false,12045039612142251958],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/gdkwayland-sys-f1f75bfe2aa17499/dep-lib-gdk_wayland_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/gdkx11-sys-9068e96e66d6b24f/lib-gdk_x11_sys b/src-tauri/target/debug/.fingerprint/gdkx11-sys-9068e96e66d6b24f/lib-gdk_x11_sys index b5a7e632..6b668fad 100644 --- a/src-tauri/target/debug/.fingerprint/gdkx11-sys-9068e96e66d6b24f/lib-gdk_x11_sys +++ b/src-tauri/target/debug/.fingerprint/gdkx11-sys-9068e96e66d6b24f/lib-gdk_x11_sys @@ -1 +1 @@ -69504a124cbc9852 \ No newline at end of file +9f974a009171d4ef \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/gdkx11-sys-9068e96e66d6b24f/lib-gdk_x11_sys.json b/src-tauri/target/debug/.fingerprint/gdkx11-sys-9068e96e66d6b24f/lib-gdk_x11_sys.json index 874474a4..98d30ad6 100644 --- a/src-tauri/target/debug/.fingerprint/gdkx11-sys-9068e96e66d6b24f/lib-gdk_x11_sys.json +++ b/src-tauri/target/debug/.fingerprint/gdkx11-sys-9068e96e66d6b24f/lib-gdk_x11_sys.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"[]","declared_features":"[\"cairo\", \"v3_24\", \"v3_24_2\"]","target":3071379305588350754,"profile":2241668132362809309,"path":12095866328805076356,"deps":[[2875657597781529139,"x11",false,7752746684588018505],[12225316990487900155,"gdk",false,14633418147404925284],[13501336027759766565,"build_script_build",false,6264265318035135988],[13626264195287554611,"glib",false,5575305324500369928],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/gdkx11-sys-9068e96e66d6b24f/dep-lib-gdk_x11_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"[]","declared_features":"[\"cairo\", \"v3_24\", \"v3_24_2\"]","target":3071379305588350754,"profile":2241668132362809309,"path":12095866328805076356,"deps":[[2875657597781529139,"x11",false,7752746684588018505],[12225316990487900155,"gdk",false,4892631574488749175],[13501336027759766565,"build_script_build",false,6264265318035135988],[13626264195287554611,"glib",false,9264953364366423698],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/gdkx11-sys-9068e96e66d6b24f/dep-lib-gdk_x11_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/gio-sys-b3e6ea70af68d703/lib-gio_sys b/src-tauri/target/debug/.fingerprint/gio-sys-b3e6ea70af68d703/lib-gio_sys index bf11c740..096c86c3 100644 --- a/src-tauri/target/debug/.fingerprint/gio-sys-b3e6ea70af68d703/lib-gio_sys +++ b/src-tauri/target/debug/.fingerprint/gio-sys-b3e6ea70af68d703/lib-gio_sys @@ -1 +1 @@ -a5af7b5e4d4405c6 \ No newline at end of file +60eed350720277b1 \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/gio-sys-b3e6ea70af68d703/lib-gio_sys.json b/src-tauri/target/debug/.fingerprint/gio-sys-b3e6ea70af68d703/lib-gio_sys.json index 59620a37..046f8aff 100644 --- a/src-tauri/target/debug/.fingerprint/gio-sys-b3e6ea70af68d703/lib-gio_sys.json +++ b/src-tauri/target/debug/.fingerprint/gio-sys-b3e6ea70af68d703/lib-gio_sys.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"[\"v2_58\", \"v2_60\", \"v2_62\", \"v2_64\", \"v2_66\", \"v2_68\", \"v2_70\"]","declared_features":"[\"v2_58\", \"v2_60\", \"v2_62\", \"v2_64\", \"v2_66\", \"v2_68\", \"v2_70\", \"v2_72\", \"v2_74\", \"v2_76\", \"v2_78\"]","target":1236426455504356861,"profile":2241668132362809309,"path":9660104382480555911,"deps":[[13626264195287554611,"glib",false,5575305324500369928],[15885457518084958445,"gobject",false,8022801781863277977],[17138253974170286367,"build_script_build",false,9485537966158397706],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/gio-sys-b3e6ea70af68d703/dep-lib-gio_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"[\"v2_58\", \"v2_60\", \"v2_62\", \"v2_64\", \"v2_66\", \"v2_68\", \"v2_70\"]","declared_features":"[\"v2_58\", \"v2_60\", \"v2_62\", \"v2_64\", \"v2_66\", \"v2_68\", \"v2_70\", \"v2_72\", \"v2_74\", \"v2_76\", \"v2_78\"]","target":1236426455504356861,"profile":2241668132362809309,"path":9660104382480555911,"deps":[[13626264195287554611,"glib",false,9264953364366423698],[15885457518084958445,"gobject",false,12045039612142251958],[17138253974170286367,"build_script_build",false,9485537966158397706],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/gio-sys-b3e6ea70af68d703/dep-lib-gio_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/glib-sys-a08886eb2d4291e5/lib-glib_sys b/src-tauri/target/debug/.fingerprint/glib-sys-a08886eb2d4291e5/lib-glib_sys index b91a9154..54903ee1 100644 --- a/src-tauri/target/debug/.fingerprint/glib-sys-a08886eb2d4291e5/lib-glib_sys +++ b/src-tauri/target/debug/.fingerprint/glib-sys-a08886eb2d4291e5/lib-glib_sys @@ -1 +1 @@ -08423045a7765f4d \ No newline at end of file +92f69e3fffb99380 \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/glib-sys-a08886eb2d4291e5/lib-glib_sys.json b/src-tauri/target/debug/.fingerprint/glib-sys-a08886eb2d4291e5/lib-glib_sys.json index 49de95db..e6abc994 100644 --- a/src-tauri/target/debug/.fingerprint/glib-sys-a08886eb2d4291e5/lib-glib_sys.json +++ b/src-tauri/target/debug/.fingerprint/glib-sys-a08886eb2d4291e5/lib-glib_sys.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"[\"v2_58\", \"v2_60\", \"v2_62\", \"v2_64\", \"v2_66\", \"v2_68\", \"v2_70\"]","declared_features":"[\"v2_58\", \"v2_60\", \"v2_62\", \"v2_64\", \"v2_66\", \"v2_68\", \"v2_70\", \"v2_72\", \"v2_74\", \"v2_76\", \"v2_78\"]","target":9937524938355422997,"profile":2241668132362809309,"path":13065277488400788365,"deps":[[13626264195287554611,"build_script_build",false,6222553498416741123],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/glib-sys-a08886eb2d4291e5/dep-lib-glib_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"[\"v2_58\", \"v2_60\", \"v2_62\", \"v2_64\", \"v2_66\", \"v2_68\", \"v2_70\"]","declared_features":"[\"v2_58\", \"v2_60\", \"v2_62\", \"v2_64\", \"v2_66\", \"v2_68\", \"v2_70\", \"v2_72\", \"v2_74\", \"v2_76\", \"v2_78\"]","target":9937524938355422997,"profile":2241668132362809309,"path":13065277488400788365,"deps":[[13626264195287554611,"build_script_build",false,18138387534057493481],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/glib-sys-a08886eb2d4291e5/dep-lib-glib_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/glib-sys-f02d0a4c75864a6c/run-build-script-build-script-build b/src-tauri/target/debug/.fingerprint/glib-sys-f02d0a4c75864a6c/run-build-script-build-script-build index 43215f87..e934dd88 100644 --- a/src-tauri/target/debug/.fingerprint/glib-sys-f02d0a4c75864a6c/run-build-script-build-script-build +++ b/src-tauri/target/debug/.fingerprint/glib-sys-f02d0a4c75864a6c/run-build-script-build-script-build @@ -1 +1 @@ -037bfe3470f35a56 \ No newline at end of file +e9d3de655c7fb8fb \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/glib-sys-f02d0a4c75864a6c/run-build-script-build-script-build.json b/src-tauri/target/debug/.fingerprint/glib-sys-f02d0a4c75864a6c/run-build-script-build-script-build.json index f343b871..3824750b 100644 --- a/src-tauri/target/debug/.fingerprint/glib-sys-f02d0a4c75864a6c/run-build-script-build-script-build.json +++ b/src-tauri/target/debug/.fingerprint/glib-sys-f02d0a4c75864a6c/run-build-script-build-script-build.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"","declared_features":"","target":0,"profile":0,"path":0,"deps":[[13626264195287554611,"build_script_build",false,9828015301074265886]],"local":[{"RerunIfEnvChanged":{"var":"GLIB_2.0_NO_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"SYSROOT","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"GOBJECT_2.0_NO_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"SYSROOT","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_BUILD_INTERNAL","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_LINK","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_LIB","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_LIB_FRAMEWORK","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_SEARCH_NATIVE","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_SEARCH_FRAMEWORK","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_INCLUDE","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_NO_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_BUILD_INTERNAL","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_LINK","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_LIB","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_LIB_FRAMEWORK","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_SEARCH_NATIVE","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_SEARCH_FRAMEWORK","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_INCLUDE","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_NO_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_BUILD_INTERNAL","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_LINK","val":null}}],"rustflags":[],"config":0,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"","declared_features":"","target":0,"profile":0,"path":0,"deps":[[13626264195287554611,"build_script_build",false,9828015301074265886]],"local":[{"RerunIfEnvChanged":{"var":"GLIB_2.0_NO_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"SYSROOT","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"GOBJECT_2.0_NO_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"SYSROOT","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_PATH","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_LIBDIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64-unknown-linux-gnu","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR_aarch64_unknown_linux_gnu","val":null}},{"RerunIfEnvChanged":{"var":"HOST_PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"PKG_CONFIG_SYSROOT_DIR","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_BUILD_INTERNAL","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_LINK","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_LIB","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_LIB_FRAMEWORK","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_SEARCH_NATIVE","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_SEARCH_FRAMEWORK","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_INCLUDE","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_NO_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_BUILD_INTERNAL","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GOBJECT_2_0_LINK","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_LIB","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_LIB_FRAMEWORK","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_SEARCH_NATIVE","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_SEARCH_FRAMEWORK","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_INCLUDE","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_NO_PKG_CONFIG","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_BUILD_INTERNAL","val":null}},{"RerunIfEnvChanged":{"var":"SYSTEM_DEPS_GLIB_2_0_LINK","val":null}}],"rustflags":[],"config":0,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/gobject-sys-a51398dff084dc63/lib-gobject_sys b/src-tauri/target/debug/.fingerprint/gobject-sys-a51398dff084dc63/lib-gobject_sys index 85aadff1..eb1f7b66 100644 --- a/src-tauri/target/debug/.fingerprint/gobject-sys-a51398dff084dc63/lib-gobject_sys +++ b/src-tauri/target/debug/.fingerprint/gobject-sys-a51398dff084dc63/lib-gobject_sys @@ -1 +1 @@ -99e554c7b6b7566f \ No newline at end of file +b66f3fbbb59328a7 \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/gobject-sys-a51398dff084dc63/lib-gobject_sys.json b/src-tauri/target/debug/.fingerprint/gobject-sys-a51398dff084dc63/lib-gobject_sys.json index d5a5b952..c95f5e4c 100644 --- a/src-tauri/target/debug/.fingerprint/gobject-sys-a51398dff084dc63/lib-gobject_sys.json +++ b/src-tauri/target/debug/.fingerprint/gobject-sys-a51398dff084dc63/lib-gobject_sys.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"[\"v2_58\", \"v2_62\", \"v2_66\", \"v2_68\", \"v2_70\"]","declared_features":"[\"v2_58\", \"v2_62\", \"v2_66\", \"v2_68\", \"v2_70\", \"v2_72\", \"v2_74\", \"v2_76\", \"v2_78\"]","target":8496472197725967521,"profile":2241668132362809309,"path":5747273799920600823,"deps":[[13626264195287554611,"glib",false,5575305324500369928],[15885457518084958445,"build_script_build",false,8320609477498126585],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/gobject-sys-a51398dff084dc63/dep-lib-gobject_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"[\"v2_58\", \"v2_62\", \"v2_66\", \"v2_68\", \"v2_70\"]","declared_features":"[\"v2_58\", \"v2_62\", \"v2_66\", \"v2_68\", \"v2_70\", \"v2_72\", \"v2_74\", \"v2_76\", \"v2_78\"]","target":8496472197725967521,"profile":2241668132362809309,"path":5747273799920600823,"deps":[[13626264195287554611,"glib",false,9264953364366423698],[15885457518084958445,"build_script_build",false,8320609477498126585],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/gobject-sys-a51398dff084dc63/dep-lib-gobject_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/gtk-sys-ae9238fc13eedecb/lib-gtk_sys b/src-tauri/target/debug/.fingerprint/gtk-sys-ae9238fc13eedecb/lib-gtk_sys index eb1d0bfb..dbd086a0 100644 --- a/src-tauri/target/debug/.fingerprint/gtk-sys-ae9238fc13eedecb/lib-gtk_sys +++ b/src-tauri/target/debug/.fingerprint/gtk-sys-ae9238fc13eedecb/lib-gtk_sys @@ -1 +1 @@ -1b89f0fddc51bf06 \ No newline at end of file +1ccdb81f9803dbf3 \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/gtk-sys-ae9238fc13eedecb/lib-gtk_sys.json b/src-tauri/target/debug/.fingerprint/gtk-sys-ae9238fc13eedecb/lib-gtk_sys.json index ffd13bcb..f83f57d3 100644 --- a/src-tauri/target/debug/.fingerprint/gtk-sys-ae9238fc13eedecb/lib-gtk_sys.json +++ b/src-tauri/target/debug/.fingerprint/gtk-sys-ae9238fc13eedecb/lib-gtk_sys.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"[\"v3_24\"]","declared_features":"[\"v3_24\", \"v3_24_1\", \"v3_24_11\", \"v3_24_30\", \"v3_24_8\", \"v3_24_9\"]","target":4528965810399274372,"profile":2241668132362809309,"path":18001016390602429102,"deps":[[2028663402560672651,"gdk_pixbuf",false,2540939478916349158],[2184755618550678726,"pango",false,14709927256080672428],[4520300193208121197,"atk",false,8836204151659031175],[6885242093860886281,"cairo",false,16612610469833888838],[12225316990487900155,"gdk",false,14633418147404925284],[13244166758162771746,"build_script_build",false,3260786767325860862],[13626264195287554611,"glib",false,5575305324500369928],[15885457518084958445,"gobject",false,8022801781863277977],[17138253974170286367,"gio",false,14268886093481619365],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/gtk-sys-ae9238fc13eedecb/dep-lib-gtk_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"[\"v3_24\"]","declared_features":"[\"v3_24\", \"v3_24_1\", \"v3_24_11\", \"v3_24_30\", \"v3_24_8\", \"v3_24_9\"]","target":4528965810399274372,"profile":2241668132362809309,"path":18001016390602429102,"deps":[[2028663402560672651,"gdk_pixbuf",false,15310156194781907931],[2184755618550678726,"pango",false,9273454815819985803],[4520300193208121197,"atk",false,10194748097742422798],[6885242093860886281,"cairo",false,17030865416582237425],[12225316990487900155,"gdk",false,4892631574488749175],[13244166758162771746,"build_script_build",false,3260786767325860862],[13626264195287554611,"glib",false,9264953364366423698],[15885457518084958445,"gobject",false,12045039612142251958],[17138253974170286367,"gio",false,12787692356947406432],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/gtk-sys-ae9238fc13eedecb/dep-lib-gtk_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/javascriptcore-rs-sys-80bb3979b374ec9b/lib-javascriptcore_rs_sys b/src-tauri/target/debug/.fingerprint/javascriptcore-rs-sys-80bb3979b374ec9b/lib-javascriptcore_rs_sys index a80f05a5..a3d2c317 100644 --- a/src-tauri/target/debug/.fingerprint/javascriptcore-rs-sys-80bb3979b374ec9b/lib-javascriptcore_rs_sys +++ b/src-tauri/target/debug/.fingerprint/javascriptcore-rs-sys-80bb3979b374ec9b/lib-javascriptcore_rs_sys @@ -1 +1 @@ -24489362717cfd07 \ No newline at end of file +783fa28e59dbf287 \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/javascriptcore-rs-sys-80bb3979b374ec9b/lib-javascriptcore_rs_sys.json b/src-tauri/target/debug/.fingerprint/javascriptcore-rs-sys-80bb3979b374ec9b/lib-javascriptcore_rs_sys.json index e887dd37..57588854 100644 --- a/src-tauri/target/debug/.fingerprint/javascriptcore-rs-sys-80bb3979b374ec9b/lib-javascriptcore_rs_sys.json +++ b/src-tauri/target/debug/.fingerprint/javascriptcore-rs-sys-80bb3979b374ec9b/lib-javascriptcore_rs_sys.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"[\"v2_28\", \"v2_38\"]","declared_features":"[\"v2_28\", \"v2_38\"]","target":17217257543979948008,"profile":2241668132362809309,"path":17669955065355595971,"deps":[[12726616099386114179,"build_script_build",false,11029008866159647312],[13626264195287554611,"glib",false,5575305324500369928],[15885457518084958445,"gobject",false,8022801781863277977],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/javascriptcore-rs-sys-80bb3979b374ec9b/dep-lib-javascriptcore_rs_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"[\"v2_28\", \"v2_38\"]","declared_features":"[\"v2_28\", \"v2_38\"]","target":17217257543979948008,"profile":2241668132362809309,"path":17669955065355595971,"deps":[[12726616099386114179,"build_script_build",false,11029008866159647312],[13626264195287554611,"glib",false,9264953364366423698],[15885457518084958445,"gobject",false,12045039612142251958],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/javascriptcore-rs-sys-80bb3979b374ec9b/dep-lib-javascriptcore_rs_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/pango-sys-7fb2c6fcda294579/lib-pango_sys b/src-tauri/target/debug/.fingerprint/pango-sys-7fb2c6fcda294579/lib-pango_sys index 9de0a8f1..a30b3d79 100644 --- a/src-tauri/target/debug/.fingerprint/pango-sys-7fb2c6fcda294579/lib-pango_sys +++ b/src-tauri/target/debug/.fingerprint/pango-sys-7fb2c6fcda294579/lib-pango_sys @@ -1 +1 @@ -ac668622e72824cc \ No newline at end of file +8bf395a905eeb180 \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/pango-sys-7fb2c6fcda294579/lib-pango_sys.json b/src-tauri/target/debug/.fingerprint/pango-sys-7fb2c6fcda294579/lib-pango_sys.json index d421434c..bef15708 100644 --- a/src-tauri/target/debug/.fingerprint/pango-sys-7fb2c6fcda294579/lib-pango_sys.json +++ b/src-tauri/target/debug/.fingerprint/pango-sys-7fb2c6fcda294579/lib-pango_sys.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"[]","declared_features":"[\"v1_42\", \"v1_44\", \"v1_46\", \"v1_48\", \"v1_50\", \"v1_52\"]","target":5892295992406752241,"profile":2241668132362809309,"path":11681504582098819980,"deps":[[2184755618550678726,"build_script_build",false,11647657745266431528],[13626264195287554611,"glib",false,5575305324500369928],[15885457518084958445,"gobject",false,8022801781863277977],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/pango-sys-7fb2c6fcda294579/dep-lib-pango_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"[]","declared_features":"[\"v1_42\", \"v1_44\", \"v1_46\", \"v1_48\", \"v1_50\", \"v1_52\"]","target":5892295992406752241,"profile":2241668132362809309,"path":11681504582098819980,"deps":[[2184755618550678726,"build_script_build",false,11647657745266431528],[13626264195287554611,"glib",false,9264953364366423698],[15885457518084958445,"gobject",false,12045039612142251958],[17159683253194042242,"libc",false,9448623883530498034]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/pango-sys-7fb2c6fcda294579/dep-lib-pango_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/rfd-237efcd480f81110/lib-rfd b/src-tauri/target/debug/.fingerprint/rfd-237efcd480f81110/lib-rfd index 97a9b9be..9c4cb4e8 100644 --- a/src-tauri/target/debug/.fingerprint/rfd-237efcd480f81110/lib-rfd +++ b/src-tauri/target/debug/.fingerprint/rfd-237efcd480f81110/lib-rfd @@ -1 +1 @@ -12fb31ec9153a35c \ No newline at end of file +d2f18ca9005cef98 \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/rfd-237efcd480f81110/lib-rfd.json b/src-tauri/target/debug/.fingerprint/rfd-237efcd480f81110/lib-rfd.json index 9bc9bf1d..db803ae7 100644 --- a/src-tauri/target/debug/.fingerprint/rfd-237efcd480f81110/lib-rfd.json +++ b/src-tauri/target/debug/.fingerprint/rfd-237efcd480f81110/lib-rfd.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"[\"common-controls-v6\", \"glib-sys\", \"gobject-sys\", \"gtk-sys\", \"gtk3\"]","declared_features":"[\"ashpd\", \"async-std\", \"common-controls-v6\", \"default\", \"file-handle-inner\", \"glib-sys\", \"gobject-sys\", \"gtk-sys\", \"gtk3\", \"pollster\", \"tokio\", \"urlencoding\", \"wayland\", \"xdg-portal\"]","target":4644090373205775831,"profile":2241668132362809309,"path":16910467066997891197,"deps":[[4143744114649553716,"raw_window_handle",false,13356969486201052105],[10630857666389190470,"log",false,5933974529767802847],[13244166758162771746,"gtk_sys",false,486197294374357275],[13626264195287554611,"glib_sys",false,5575305324500369928],[15885457518084958445,"gobject_sys",false,8022801781863277977],[18096261089697941857,"build_script_build",false,7365468796528817961]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/rfd-237efcd480f81110/dep-lib-rfd","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"[\"common-controls-v6\", \"glib-sys\", \"gobject-sys\", \"gtk-sys\", \"gtk3\"]","declared_features":"[\"ashpd\", \"async-std\", \"common-controls-v6\", \"default\", \"file-handle-inner\", \"glib-sys\", \"gobject-sys\", \"gtk-sys\", \"gtk3\", \"pollster\", \"tokio\", \"urlencoding\", \"wayland\", \"xdg-portal\"]","target":4644090373205775831,"profile":2241668132362809309,"path":16910467066997891197,"deps":[[4143744114649553716,"raw_window_handle",false,13356969486201052105],[10630857666389190470,"log",false,5933974529767802847],[13244166758162771746,"gtk_sys",false,17571642323018239260],[13626264195287554611,"glib_sys",false,9264953364366423698],[15885457518084958445,"gobject_sys",false,12045039612142251958],[18096261089697941857,"build_script_build",false,7365468796528817961]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/rfd-237efcd480f81110/dep-lib-rfd","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/soup3-sys-759ec12a00a837af/lib-soup3_sys b/src-tauri/target/debug/.fingerprint/soup3-sys-759ec12a00a837af/lib-soup3_sys index 52fcf766..cd6c007b 100644 --- a/src-tauri/target/debug/.fingerprint/soup3-sys-759ec12a00a837af/lib-soup3_sys +++ b/src-tauri/target/debug/.fingerprint/soup3-sys-759ec12a00a837af/lib-soup3_sys @@ -1 +1 @@ -55aa6e20999fcd8c \ No newline at end of file +88b1680aca4836b8 \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/soup3-sys-759ec12a00a837af/lib-soup3_sys.json b/src-tauri/target/debug/.fingerprint/soup3-sys-759ec12a00a837af/lib-soup3_sys.json index a5949603..1d436f24 100644 --- a/src-tauri/target/debug/.fingerprint/soup3-sys-759ec12a00a837af/lib-soup3_sys.json +++ b/src-tauri/target/debug/.fingerprint/soup3-sys-759ec12a00a837af/lib-soup3_sys.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"[\"v3_0\"]","declared_features":"[\"v3_0\", \"v3_2\", \"v3_4\"]","target":4746024912976814357,"profile":2241668132362809309,"path":11899460850599487506,"deps":[[13626264195287554611,"glib",false,5575305324500369928],[15885457518084958445,"gobject",false,8022801781863277977],[17138253974170286367,"gio",false,14268886093481619365],[17159683253194042242,"libc",false,9448623883530498034],[17724869489793055652,"build_script_build",false,16284928507403598398]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/soup3-sys-759ec12a00a837af/dep-lib-soup3_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"[\"v3_0\"]","declared_features":"[\"v3_0\", \"v3_2\", \"v3_4\"]","target":4746024912976814357,"profile":2241668132362809309,"path":11899460850599487506,"deps":[[13626264195287554611,"glib",false,9264953364366423698],[15885457518084958445,"gobject",false,12045039612142251958],[17138253974170286367,"gio",false,12787692356947406432],[17159683253194042242,"libc",false,9448623883530498034],[17724869489793055652,"build_script_build",false,16284928507403598398]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/soup3-sys-759ec12a00a837af/dep-lib-soup3_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/webkit2gtk-sys-935418f782552fab/lib-webkit2gtk_sys b/src-tauri/target/debug/.fingerprint/webkit2gtk-sys-935418f782552fab/lib-webkit2gtk_sys index 73723b6d..84f8e06d 100644 --- a/src-tauri/target/debug/.fingerprint/webkit2gtk-sys-935418f782552fab/lib-webkit2gtk_sys +++ b/src-tauri/target/debug/.fingerprint/webkit2gtk-sys-935418f782552fab/lib-webkit2gtk_sys @@ -1 +1 @@ -14e35fb7bb7956a1 \ No newline at end of file +f39cae21ec772c7e \ No newline at end of file diff --git a/src-tauri/target/debug/.fingerprint/webkit2gtk-sys-935418f782552fab/lib-webkit2gtk_sys.json b/src-tauri/target/debug/.fingerprint/webkit2gtk-sys-935418f782552fab/lib-webkit2gtk_sys.json index b37931c5..a848e2cb 100644 --- a/src-tauri/target/debug/.fingerprint/webkit2gtk-sys-935418f782552fab/lib-webkit2gtk_sys.json +++ b/src-tauri/target/debug/.fingerprint/webkit2gtk-sys-935418f782552fab/lib-webkit2gtk_sys.json @@ -1 +1 @@ -{"rustc":9435880562281667341,"features":"[\"v2_10\", \"v2_12\", \"v2_14\", \"v2_16\", \"v2_18\", \"v2_20\", \"v2_22\", \"v2_24\", \"v2_26\", \"v2_28\", \"v2_30\", \"v2_32\", \"v2_34\", \"v2_36\", \"v2_38\", \"v2_40\", \"v2_6\", \"v2_8\"]","declared_features":"[\"v2_10\", \"v2_12\", \"v2_14\", \"v2_16\", \"v2_18\", \"v2_20\", \"v2_22\", \"v2_24\", \"v2_26\", \"v2_28\", \"v2_30\", \"v2_32\", \"v2_34\", \"v2_36\", \"v2_38\", \"v2_40\", \"v2_6\", \"v2_8\"]","target":423463711184852656,"profile":2241668132362809309,"path":10664168538057484594,"deps":[[6885242093860886281,"cairo",false,16612610469833888838],[10435729446543529114,"bitflags",false,10529288711119310154],[12216365939420334724,"build_script_build",false,17249160887632110307],[12225316990487900155,"gdk",false,14633418147404925284],[12726616099386114179,"java_script_core",false,575753153800259620],[13244166758162771746,"gtk",false,486197294374357275],[13626264195287554611,"glib",false,5575305324500369928],[15885457518084958445,"gobject",false,8022801781863277977],[17138253974170286367,"gio",false,14268886093481619365],[17159683253194042242,"libc",false,9448623883530498034],[17724869489793055652,"soup",false,10145941015558531669]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/webkit2gtk-sys-935418f782552fab/dep-lib-webkit2gtk_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file +{"rustc":9435880562281667341,"features":"[\"v2_10\", \"v2_12\", \"v2_14\", \"v2_16\", \"v2_18\", \"v2_20\", \"v2_22\", \"v2_24\", \"v2_26\", \"v2_28\", \"v2_30\", \"v2_32\", \"v2_34\", \"v2_36\", \"v2_38\", \"v2_40\", \"v2_6\", \"v2_8\"]","declared_features":"[\"v2_10\", \"v2_12\", \"v2_14\", \"v2_16\", \"v2_18\", \"v2_20\", \"v2_22\", \"v2_24\", \"v2_26\", \"v2_28\", \"v2_30\", \"v2_32\", \"v2_34\", \"v2_36\", \"v2_38\", \"v2_40\", \"v2_6\", \"v2_8\"]","target":423463711184852656,"profile":2241668132362809309,"path":10664168538057484594,"deps":[[6885242093860886281,"cairo",false,17030865416582237425],[10435729446543529114,"bitflags",false,10529288711119310154],[12216365939420334724,"build_script_build",false,17249160887632110307],[12225316990487900155,"gdk",false,4892631574488749175],[12726616099386114179,"java_script_core",false,9796133317175820152],[13244166758162771746,"gtk",false,17571642323018239260],[13626264195287554611,"glib",false,9264953364366423698],[15885457518084958445,"gobject",false,12045039612142251958],[17138253974170286367,"gio",false,12787692356947406432],[17159683253194042242,"libc",false,9448623883530498034],[17724869489793055652,"soup",false,13273876984316342664]],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/webkit2gtk-sys-935418f782552fab/dep-lib-webkit2gtk_sys","checksum":false}}],"rustflags":[],"config":8247474407144887393,"compile_kind":0} \ No newline at end of file diff --git a/src-tauri/target/debug/build/glib-sys-f02d0a4c75864a6c/output b/src-tauri/target/debug/build/glib-sys-f02d0a4c75864a6c/output index 47a212e1..6a331b91 100644 --- a/src-tauri/target/debug/build/glib-sys-f02d0a4c75864a6c/output +++ b/src-tauri/target/debug/build/glib-sys-f02d0a4c75864a6c/output @@ -74,14 +74,6 @@ cargo:rustc-link-lib=glib-2.0 cargo:include=/usr/include/glib-2.0:/usr/lib64/glib-2.0/include:/usr/include/sysprof-6:/usr/include:/usr/include:/usr/include/glib-2.0:/usr/lib64/glib-2.0/include:/usr/include/sysprof-6 cargo:rerun-if-env-changed=SYSTEM_DEPS_BUILD_INTERNAL cargo:rerun-if-env-changed=SYSTEM_DEPS_LINK -cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_LIB -cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_LIB_FRAMEWORK -cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_SEARCH_NATIVE -cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_SEARCH_FRAMEWORK -cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_INCLUDE -cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_NO_PKG_CONFIG -cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_BUILD_INTERNAL -cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_LINK cargo:rerun-if-env-changed=SYSTEM_DEPS_GOBJECT_2_0_LIB cargo:rerun-if-env-changed=SYSTEM_DEPS_GOBJECT_2_0_LIB_FRAMEWORK cargo:rerun-if-env-changed=SYSTEM_DEPS_GOBJECT_2_0_SEARCH_NATIVE @@ -90,6 +82,14 @@ cargo:rerun-if-env-changed=SYSTEM_DEPS_GOBJECT_2_0_INCLUDE cargo:rerun-if-env-changed=SYSTEM_DEPS_GOBJECT_2_0_NO_PKG_CONFIG cargo:rerun-if-env-changed=SYSTEM_DEPS_GOBJECT_2_0_BUILD_INTERNAL cargo:rerun-if-env-changed=SYSTEM_DEPS_GOBJECT_2_0_LINK +cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_LIB +cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_LIB_FRAMEWORK +cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_SEARCH_NATIVE +cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_SEARCH_FRAMEWORK +cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_INCLUDE +cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_NO_PKG_CONFIG +cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_BUILD_INTERNAL +cargo:rerun-if-env-changed=SYSTEM_DEPS_GLIB_2_0_LINK cargo:rustc-cfg=system_deps_have_glib_2_0 cargo:rustc-cfg=system_deps_have_gobject_2_0 diff --git a/src-tauri/target/debug/build/libsodium-sys-stable-fcf8b83ea1efb6f7/out/installed/lib/libsodium.a b/src-tauri/target/debug/build/libsodium-sys-stable-fcf8b83ea1efb6f7/out/installed/lib/libsodium.a index 01ffca9ebfcab5e8d893b9e6d63b3c2cea05fd79..2514624690f42b4d48a8b39acfc03059271a502d 100644 GIT binary patch delta 127 zcmWN=$qj-4006<@1s*6Mo_OHWfSO=pc|P_nHQ0k4(3VCgnfCJx+W)2q>)XA)T+a_A zkdAbvCw&=6D3J_hBx9LKEK`|DBB^9Dms}RIl$ESyBU>qCCwn=_QA#-pZ>rb#2hgk{ Ae*gdg delta 124 zcmWN=xe$%GnvamGRdWoQkJrkwQOW7JK0Mm2RX_~&Qi-ot{-l%Uk~wpBM|@q diff --git a/src-tauri/target/debug/build/ring-d2e7a6d6bd975252/out/libring_core_0_17_14_.a b/src-tauri/target/debug/build/ring-d2e7a6d6bd975252/out/libring_core_0_17_14_.a index 5f8949a9d710a105f1ae05c9cf14b3b203f99d56..4ae2b46c6f10f968d99e3f8056bff1b7304d6ff7 100644 GIT binary patch delta 466 zcmZ3rCt=l|gbkj8?51XxriKO<%>jb#0fLM`%(Oi~kU4c7Ok(;4c5d z_ZKc)U?(Wv9>14$d;DHDy=1uXhCB|h_InEK+wUoGoc4tYw*!T@Z^+{m^@E8_2a1Td zKild}FxXlB9(>#TJ^20B!iB-c z{{G6p{r6XaJP(*~JJ7Y;3+#lpmcm3P2LPS#yhR9zg@IUPyYm*&X&+&-+aD|y+o}iS zfrDWC<||^$>|jFM6NJTE1z^1CpupJ9tRl{*4i^F{5Z|uvE&h!kCIqxnY`asmcs>t` w$hma!>(WpWOR#UZA8r=ErU(<-zF?{NQC%1h;+E#i;>R>$LfZrWir-QI01exg-2eap delta 466 zcmZ3rCt=l|gbkj8?8c@h#wJE)%>jb#0fLM`%(Oi~kU4c7Ok(;4c5d z_ZKc)U?(Wv9>14$d;DHDy=1uXhCB|h_InEK+wUoGoc4tYw*!T@Z^+{m^@E8_2a1Td zKild}FxXlB9(>#TJ^20B!iB-c z{{G6p{r6XaJP(*~JJ7Y;3+#lpmO@3$CkFtX@4Q6_h=qYzWV`bg(P7c;a&a5KNrw$haDiGhU?=Aj~A0`B}Qf#|Zw0J%b wipaTi@$1qs5wLH!A8r=ErU(<-zF?{NQC%1h;+E#i;>R>$LfZrWir-QI0Ea4;L;wH) diff --git a/src-tauri/target/debug/build/ring-d2e7a6d6bd975252/out/libring_core_0_17_14__test.a b/src-tauri/target/debug/build/ring-d2e7a6d6bd975252/out/libring_core_0_17_14__test.a index 768997421f69dd2f5330192cbb3fd50d97ccd734..974021c0daf122e8d96623b43d2d3d7ae8886257 100644 GIT binary patch delta 26 hcmX@mz;>X4Z9_RDyQ!I_siA>oa~X4Z9_RDyRoT>v5Ap+a~6cU%q~?|8>X&BbmFQ>YrKDEq zWt8OR9Aso*5Ji$kl3`$AJjlral$T^+UX5Kw&510f)L;{zc^2F5E7 yKq3b@flQzzkOWEs1%Q%3C08D>gM_E)1ed-3z3PS)!O*()8 delta 183 zcmeA@qTYK%y`hD%g{g&k3(NQQ(}gy$$S^WZ*WbV*S#4LpV1Q diff --git a/src-tauri/target/debug/deps/libserde_spanned-0cf36ffdb7849374.rlib b/src-tauri/target/debug/deps/libserde_spanned-0cf36ffdb7849374.rlib index c551687a768ab79ef82f1e5fa50c546a406b9378..74843f5bfa0fbaafca61128eaca26b07c332014b 100644 GIT binary patch delta 33 mcmZ2>ifP#?rVaCgg%}tZPtIm!WMDkP4kUm~rp+6I%K`zx5DKvX delta 33 mcmZ2>ifP#?rVaCgg_sx^PtIm!U|>AL&Io2QZr%`F76<^rCkn9u diff --git a/src-tauri/target/debug/deps/libserde_spanned-0cf36ffdb7849374.rmeta b/src-tauri/target/debug/deps/libserde_spanned-0cf36ffdb7849374.rmeta index 27e13a3413cfdb6abfd367463c08695a0a2b182f..bf1d21c1cb232c92a0bf9af537c441a4c9fb7d42 100644 GIT binary patch delta 33 mcmaF(h4JAR#tnCTg%}tZPtIm!WMDkP4kUm~rp@nsi**3s%?rT* delta 33 mcmaF(h4JAR#tnCTg_sx^PtIm!U|>AL&Io2QZhq%mtOEewlwb29O|-wPgV_kU2vbD1Q$m z_#2`UBE!TWGpb z5{okw(n|A^OEUBG4gzJ2C-1vzI=S|{ybDn6?1jugL(eP(S$9_&DDZ3{Gmvap1QOn{ l2qX+t0u%u%0gBv}1_}U`07;+{pzw}n!5`ZNe=u4f006zCKL`K- delta 204 zcmX@}f$Pi%t_^d)am)~AU|_r_#58%;H)}U02FBk)U_K)Qwlx%d;>rFz8H{yQb>`l$^Z~Wcr4MAT#eu0|m}6WCoJ$i$KE57lDL3vm2s2F9ySdJV<{Sj-xGT*#dEEuc$!9KDFfvSL zy(sSj6r8<~8L0crLXf$4rGWy^7BU0LhD9LZ9g9H1KqWvCpc0_SU7+b8B|s9W1Sq^? J^URCyI{`c1GqwN# delta 202 zcmeC!&f2k^b%W{!?is=i42<`Lm>3w$C;Kfh_d3YL!1!ATEXK&dxPAdMkene56ubu# z1oDC8Z=iCZAW-JF5F>*SgFtafQE76Co?}UVu3kn-Zq7jl1_sf|`Rhd4K*rsbp8WTM z1ta5Rvy1XTdnV7ipzi_{p1lxc_J)NZ6Yoj`13Ll%Kghca}x8j<%lV1%AB9z%0pSwY#2j$nRcCP5U*AB{WLPp3) zdib3V(KTIqAd+_jzmzPv`Cv^rC97n+j_g)=`~vE+J9f^qyeFnv5JlS&en zSjtIw!MLe(@<(`&xx?#Kw;PuZkHiCBG;e#386UcxUwZZ#n(df+Ou{7I9Eu z3LS)&&uvxg>mpK6>}h7ZqxkMugDw#YceQ|~;Ep%`Bg$}w1)Q}T=%((4Cun$r!JmW> zo?!6L@P;$qa2{CF`fh^*5#ShL0LOt7zz8r3i~-|76gUZ-0%E`fFbSLnrhqe_b{o_8 Fg1>X<0tx^C delta 842 zcmYjOF-#Lt7=G^_7C|Z%v4RT0k}w!SX`C)>nz%R`7Y4lRUExA=*W6JO<3LTW6gRiG zSY6OC83z-aXiJY8$A$soNFXsWCdSdFM!)~HsSe-Ez5n~a@B82V+wH~e_F^&Qq4rK# zVIqFdF@3{-r0Y4y3?e2UhaxqiF&57l{<5b#ZYEc->`3OzV&)oSEZGxusinNJwh}~; z45Z+Z^}KW{(&Ud&T;g25DT_Nv$Pzu7WoI4N4k9k^mc;cw=%!_&rA=&f#1TjHN%48- zHhXh!{-jum;1Iv|`F-xce=?7M!uYYGtFm1Z6a9bGr6Q*`#pR1T5ebo?Tp7OEQ_dFT zlS6Ic21#400shJvvH#wr{t#M9d*pH4kkw6bCH<0aY}m4cjPIDXHD#FIx_SqKVbWCH z$Yo4Biec1AddK7jh5b|pc}U%u+z1vol8pVGueuxrSN58(6GMn&g;8BdFg07hE%P@U zVLk5#PUEih>vr7>{6v6K-}5wkj=QFAc-5L+yI(4~a@q4`$oypJ+jnHeu|t^{>f;7o zIEvP@trPq6W@@3Vm}X2N=*OI)zQuIj+U}Sn=xYbyILJZ)v1q-^%$7RUrum6~x^1AY zwdwTqvmP@qdZ`dB%B`h?@+BU6{Fy0;!edy(a);|Kr0dc<-Ll?QKiiaB+~rCfcV+0* zysC8bb~U(%_<~>wkptZgM;%%~T&xkFct-t>X=2I8b<+Nq30oroHp!09gS|sOa%Obo zi3MFGKIAryClCJv%tzN& delta 768 zcmYk3KWGzS7{R=)L@I#(Lr!=aM8iF+@CM)(Rf$x62V1-AmS!u z_!e`i6s40^5G>fFxt=)cQV%c9e0^S)ZZx8L$qk&wE$P>-x)=Bf330h~{nzQ%=bz;fE;KYK?aHd>%P1k$ z>d+(^s^6jW6(kJpG@tCVFI=ol?KIn*m%9@9Rd3ET7sJ4o;L=vX5b9-2g-P1%W*~g) zW;k$=JK=BriB3=;dvIUAfgUYMxjK3PWwnb`%&*6Y57BS^|3^n` z>lc0OSJQR4?H;GBykiLJzmBC$x9Cb3ZxY<;_8@s`<{d2inA-d>xx*JioG6;UxNp$j=R%|xN~)s^Kc z5x<`G3gT{tn0R87W<2Xh%$5X^T(Al|xhm2@7=-w)>*gIZmC6<@*LIS7xs;-}6JXy& z5jDmHiMts39~P1OevJL8BXR1-kh%0#vF59M5XL+jRfAD!Cs26PO*c{88%txXw20Y& z8j5fUf)w2&C5#qGA`MB1bu$Rt3AF*$LTUmUf-nwfvNywW-r&!1FT--d#AcKKt8C}8 zPO{*n_71o0;{z+Nmep(6Fc)>)LNV(mSFC(;*FD&;dM_-eN|@(IaMVVi|2dA425s@f zld@BOR(2Z7ysg|Aok70Rxz;eQkI%|jZ3LkoK?D-oTf^FT96T-dB_WF{#PFatB1qr_ zo2kdk3OTn%5&a9Mxnb=W?dm_TnbuMtA%W$^T^t9#jyr+kH`6)?Z~E;qxtUh497og% bPU=DeJwO=f1^R$~U;u~!gZFhY^nU&e8Xb-z delta 579 zcmXw0F-SsD6us~1>sx8sFC)jWDM9zYNaT=E6cJ4=AN^F2DgGa|86gz36cm4Ib_!ag zmPpH7T51X#++5P7NLoAZQNw+lf9^Tw-uK^i#kj5*2W3{~Wl!0AE+PR=C4FRI{NGW{wlp=DKrrV zgW&x=nGPW$K_e21ej2bFgMd-fDlIOZHa$#pwP`8K-xK5B7+8bE0% UA8HUagc?TqQGuHlA9*|d1#`oSssI20 diff --git a/src-tauri/target/debug/deps/libtoml-b011b516975af0e2.rmeta b/src-tauri/target/debug/deps/libtoml-b011b516975af0e2.rmeta index e384e1756f62b5b2b4f9fb8c6bed6ecdfb9a4eff..0f41faeacd7510031aa7cfd587a5a4eb97f26bd6 100644 GIT binary patch delta 494 zcmX9)u}%U(6x_GBCl-=B5HK+ma4{B=&>0&O3bZg0Z7ghwxnLn^@QATdOh`2G1Gc5I zqmx(>4ms#4Y%J&q5iHa|@9a_B-rJdZ^Jd>z#>X;Vtx=8Fv{#`g)`>B3a-2KtFh+yt zWzJ}Rz=+Y>sWcN}!{m(V*?hTh*#YPUNFF6b>>lE23fhK&Y8d5=H%;)ZJz#%rbKwQx z$%O&cT}Ad?g?j+dsuk-nh@`VD9kWgLzBt*o3 zConI711=E-xpL;DbNQ?Exl_DQubPDLNW(5w zis}85Q@&jgOb(JFT4=qi?A5Ny?x(ZWcC=ZLUVLm4!nNI1G5V`0-4#@5f_xHEQWi!Z zej5ALkqj)%urM1HEO4TmWX=+s^1%|ZT^eQlzE8pNF5V2|2*7CODe)-dW7vVeNQ@a} V)Xu`FX5M4Z68QADp0#9s{R6%eaOnU5 delta 538 zcmXX@ze_?<7`^v;U$02fURjHfN;D+s7)T(I4MGw{M61X{1An1UqNOB+f~KZB^(VL` zwTPNO=3E=xM9P*T_s+dGypMCgch33Fckftu#==vn(kiRkp19^+WQ6dO!}vj)60z>( z8`p%;!TmfVbQ&X+(6uw7?Int-d>c$7ZCQm}Vphn5TNeoNvv^|PyE7FoeiQSoc^e)N^HvEwqFOt z0L_k!)n5i|*+GX05F&ITLLIsxu#s;K0+ri9K1P@cHq=bS{e1J7={Sxeitx^fUA;g! we45CV&Gx?ms~gbC#~4Kb>IUvlT`Z>D^kmpkL|&<(&bK{3$EQ8_{B!<~KOVS!d;kCd diff --git a/src-tauri/target/debug/deps/libtoml_datetime-f43dbc998bc754b3.rlib b/src-tauri/target/debug/deps/libtoml_datetime-f43dbc998bc754b3.rlib index 18e7ecdcef405db8dfc52545280ed9ae4413a50f..14470149f0dd77d3268640feb76edcb37fc1286a 100644 GIT binary patch delta 344 zcmdmSnR~}&?hXE11Xx1+eSHoxFfe{z$;8CKpg5^Ssh$zc1CmXvfI=XWi9wM;z&|am zIJHEWx~ z&>Wx$&>Wx!pgACKgY``12kR*S839!Ah8IXo5a0rmKr?`9-#5SC+Wvkky0=k~@EtqUs4HBQq4HK7*GMwARswG07wAM0IK@Y{C;cu`>l-I-*06) GX$%0YIa@CP diff --git a/src-tauri/target/debug/deps/libtoml_datetime-f43dbc998bc754b3.rmeta b/src-tauri/target/debug/deps/libtoml_datetime-f43dbc998bc754b3.rmeta index 6dbc94c45287d346c7d324a21f3eefef77466910..c26deaf20f363d2fe932f8b455d68dfe07dbc3af 100644 GIT binary patch delta 342 zcmX@v!E&;LWy9ww0xTi^zCH&T7#KgVWMX1qP@KFZM5&$;%mtE7tAJu4l8Hf)LBKyP ztvIzr!6mUIRW~FvH}xP;lHVskIWY%GjFEwX3n2zH8ODX_5DId0Rxma;wp1uiO)kmI z&r>i08pJr2A4t661!~uw?9-r)|px0CS;M AH2?qr delta 318 zcmY+8Aq&D#6ou~{OM+|`K`fJH#r+54#G+sonIJe66sv*;0hAWxkw(Z?e>h{WR4$dB;UH+M%bduJ^AqC8 zR*71tGYm$5U-2wh d0XR@_Tr8xej|PAt01z~?Az&c&-iy^C`~X@?Q8EAk diff --git a/src-tauri/target/debug/deps/libtoml_edit-92eff86d0a979929.rlib b/src-tauri/target/debug/deps/libtoml_edit-92eff86d0a979929.rlib index d2fa5683dc7c120fa04d2549eae73d40b6a91611..ed5447dead7861bfdda99734603ab1bfb3855867 100644 GIT binary patch delta 1371 zcmYL|OKenC7{|{!rH|<#bGR@TX3EUaDX)rEp2e#oV0np%0-|7yshwF&>~zS?9f+&C zxCse~3m1A5BdN4lx@f|pPy%7Wgc!E$NQ6j?rimMNhEPM~_uWfvCcl$&zQ_OjpOZTe ze|T&j!Z*J5jo;)i@|*n@ztwN^V}83I_ZRyw`Ahu7Roj7Y_{DW(0es1J^SS)8|^*wUS#rSRL@lofsIZ7scJ^m^ivNmS?nT`e}=qva%y~cTDa-7v_H) z5Az*^$VsqOYLZA&H#05@=n!ijG5?%Jf*K@Q5#cVj<8EA(q@v?aTqDO@&p2XAltPD8 zBgL^v{gsS`ZWAxu_E!e$<>IgxK5pT~p~fjR@aH8l@I+Q~bY71jQd<4COfo!*2uALi z^8fS&2hl@Cms#+!LhY7MXhX0oV^_LZU0$vf>O;lcyo&*^R2gn?gZA3j!>)U#R4aKL zO^WOMcUAM`O(Yt@AFFKl2>r3jaBhFeJ5c{JtO{>G?&#THml^D6i6%vjk_+4EiK>lSC*>rj(qZP`8{%rog5595b*~XT%GmY% zC)%>MJ1*Lxvj(?1 V@G+c#PvBEH38$_na-SXk>N$&sLaYD) delta 1411 zcmYL{OH5Q(7{|{!JjUx-I1bXW49pB2C~d7&OY37QT9FFY+J{=Ib)g8eAUuXJml`)} z%xzrhuHKD-3T4W|gcy*fU3Fp;Hzrn>YSKj;lctHLi8Ya?!QXcWG0gAe@IC(D|D1F0 zUwmlp!x>L|#w+nky)v)d3wbL%$6M)zy;a^zUWHdVXE)av)$E^o5^lByqg1Jz9ULeq zWo8}ipRKWtr35pQZ}4x`*tTO@>BnO!3Z7b}^bg}H0@ubRFzXnl?~SKesnAlvGV2t} zh*Cx|6+ySrDq_qvU9KFNnamAmdJ0VRVuDlCN_x4rYejoViU>BTU4j}`iJ1|o`LvU})3W24y{-Zh@t;hDt z+{vMI`s+TPkGE4L{9E7?;ltF6bJ}l;+XhsXlO0NS^tqj*$E9lL(l=QrPem~Xl$wm_ z#i`&%^WvLs!eweEqQA?F=?6jb*SwV6DV9tv#YKba3qg)X_SDfsCwr=mY7znFRJ<^J zba2!S<5vIolg4ApUl+HDa)}m@!X{prycdxvTu)41=V#hv(y}8)6y=!u z&9ubFrp3Ye87Ax7(~|vL;=u)>g!34AlrSAu|3^fwXt^j9+<|{HVVyLBWDq2SAmRwJ zB8VX_z{JQP#ag_I;w9Y4pQ}t-SPc=Vf;CVLFGCd8!Yfb%F{p()h(iLBP!F#{3L2mh zUV|oh9o~R9VI8~$>!BImh7GV0-hmc)7v6(SuowgAj&r2@= diff --git a/src-tauri/target/debug/deps/libtoml_edit-92eff86d0a979929.rmeta b/src-tauri/target/debug/deps/libtoml_edit-92eff86d0a979929.rmeta index 57354d4b6423fe785e8a9c3e4c931cd66b3d216b..6c8081b98634b7f4a7b03f35aa1c698161c9adc7 100644 GIT binary patch delta 1079 zcmYLIO>0v@6rGu*$-Jh<_-b3R+N4QA=)#SH@YV%Cy6VQIQj;e}nne0u6jyceKrFcE zLIy+#O>5d>po@N?2pUAXY->|Qk-AVy{Q)9YM9-a}E#VG#?mhRMGnbdSiJ`fPp$7pE zL=XzXK}!$`qKnd7v&HX(;LH|ciHik`Gj>*eS(ANg`$f1l-oQQVmkJ{d!C0?~*TZSf z)u%O?zswjW8RJ1EBN!$H<13X63U8^vcPbf92pkKRf#C##YXov21dFh=y4fSs{Ul(K zQp&sIW^v=MCyDLJBuya4iJY;B+Fh5YQULtWfUi|_@LTWTNRgq;S&w?NAv@cc^!%LT zc>ZXEtNsmn0V?X&hU^(5InN!uu zwHhNPLUg^0anND6%Ql%JChZVtP~jS4-#aW3RmBgov&5`iDO)bMMc;#6E%)-o zqT}4ndwCyMaT2!wEpn_jghoT1-jsb~n72yB)Wy7iseD7D^ed-qzVn>6^1end*sjrs zfMGOS*u2f_y1Y{($oLFF04EJ(7%@s_ka~I?GX^c#8G@rxPwLK}m*gsbX!m-d>|=*4 zqk1=GGNP|s4K(qmc+`|Jb-O8(_14$ delta 1110 zcmX|9OH30{6us}YWo9U1or)NU1p`D^Y+M+-^0Uy$ip01SN;``t{SaoVVTFq^t|TGR z%*Ie@r9w0zhL4ejGSS2(ErE?JTxg8Og)z~E7=!1&sf6B}$35qsd+vL)I5WIBGkn_> zu5?3g*p0X?uC}7vo00~-^{3&%m@kRKPBEYJiR7{&yjPq0Ko~`f@qRB_*DsC=5Ua5>Lu~D6E#buxv;YyX8J)Fa$G@mW_ahDrg{sp}M6YQ_5A*LI%(5wa2ZrFUY%J z*9X$*sm`&|gE_D{3kCmm4$-F$sY&t@4gJ`ZC|7vxXE7l7iRTse{hLDnK31tfmXn?WNr6>{k>z2Wu$jB7arMy*eY~LH* zf1e)~Ddnu*|C3YA z_n=mLvXDq7Z)WjCcpnPke;=Pg7wqq^@Jsf1uj^V*oWDV%Sm?c+b*_}gn0g`j`0_j2 zi7C~>_dr!s?9Z!aZtFc$tgF23nkgLB;$96p6 zzzCEB6%4zx!1dV$9(->J14Uzj(QjN=w*w^zcLRqKyhiD-$#Q|yKuE2A>5JLi8lpfU z3KXIk08wO!!W4Fw-9R9R9Na>%|5okp(2kBU5Uq$Pq788f(T+Hbh#`(3%ojsD@f-F( DdOH@; diff --git a/src-tauri/target/debug/deps/liburl-6b85ad66c67c2522.rlib b/src-tauri/target/debug/deps/liburl-6b85ad66c67c2522.rlib index 51c72f8932fe944e19465c3b788ae9c3e1a517e2..18aae75cd4ede59e4c42aabdb06b67327727b083 100644 GIT binary patch delta 759 zcmXAm!D|yi6vp37Hi@xa8=JIZ6ENV#i^(ZHBo}i~5Cn~((%QW&-8Eg=?8@w}2QT#y zD0=cD<3SLl=+TSdK}Zt~MXHA$3dMu%QQAZO0|fD#$>AG@_rCXgZ{8f9whvF+Py4LT z`>BsccX^Q=*BMcMJ&qqmjan^oh2vI5G~z^4fgL~gqRIo$cSnr)GsM`Qh0~I)h+8td zV%*puqM0Zb$y!`p5`J|(?)j=XuStzY#}%IKdruUBjkD;LgRRkc7zI;ean_RK*F`lAasHcI<@#TCmRplhIAKH!$^FfX%6A;1wc?;;X(L zbgQB0)|B_f5MH)5G>K7q{zD6+;6_Da1H@D}Cb#b!%?p3D5opbXhfzOECHcnTrGg^8 z8YvQZFucCaWqsASY@nW`wQ5{44|Ez73|^M)zr5U1>zH1;d#lok?ZB~xqcHEjC=6g4 zgHgE4Mr21a!pn`&t zqKlh%2^K`0L>JM?v`<4saOe<+f@v2)x^xg6q>KN#4*%ue|D5xk^Um8nsO%n89<)VU zwiEBvwdFH3x^(%{)MBgF^lPCX6N&wjAR1}bTDOB}>T1xa$CAj?Tt=2&Gnjfs{zsu_4G-{ow9{P3HU95*etr6S-K+w3#zD$drh4`HQcuUSX=tb$J zu;IElR)c0N^}VV(sSwZWawc)=Jc(gR@;JzIuD4n@BX?%TpwEU8W)k1JwjlANYh#|B zO+L3hq35eAJ1L%Taja(%co`CZ%=2N)NyC!R8&#Fd_G8Wg#Z)3wP}|a9t15r`w+R6P zFL~l^nE}Y^ETHX>2Rg^!Fs)}p>5TC#uRbvgM8xuX!3M&nq70;hpFEeLmm!$Np+@f3^6wDVoL? zS)I8j4y%G_;CY(9N~}sH@nY8-kCU!JbUw7x*M3rd<_BI^kns*Zv0X#0ss4tjsXsIF zfgp7pq>{MYaNpWWrx-$k&6{w zA<;&U!|-?a?2NAZV9UzYV?Bfv&4*u5GfyS8@KTi2i7hjO@4Jiz9FC8VaPDEX)DXjY zj@+%18k>_h&h2Q^aYsF#lOvOKVfx9#@>FVvt{uB<{Pdk6Kxqi}VLtVfx*fn&cm0Sh zJ8Uuba!9zNR%|(<*58PWmst9zr;&k+DyjaGaeWcp&p(*?Q&;do{HlbQK(2#Q(bv`S`y7d;j16<=w&7^ugBjlQy@F zk7jvgj!rHw-kMno?RwQ#)rg3X%1m^kZif%OVCJ6ZyOBXu(U}%k@)47@DLk5I1yB3BI0;^Pt!-^^ZfWP(9 zO#HK##)Nx)Id?0tXM#{Qov?_oVdH{_< z=wxcAXi}09teQc1(YNcX#fDlfN&N4)A7nHprruu@Dy*Fa)J8J&W%=i``rig;Pl@5} z7YRTNYB^oI&$%g)zsE9Yu^9sv^wSm>Qm7gGNkc!f&2#BjU&RXoym|fMFXtbN_fsz| zgt!O}$@hY=(--;qKs=oV%xBVJ0x&##+fsUWT#DolG?IVB3V7%N56Y2jAA7|ZoA{)% zXb3>#4)i62?I+PUNI?b`GO+P7_O39N3%L{T2yCLHzUi1(0n+CkbM6fP8cIlaC~Y`# Shr%zqj)~vc=dP3JAN~hre7wg1 diff --git a/src/components/ImageGallery.tsx b/src/components/ImageGallery.tsx new file mode 100644 index 00000000..727773d6 --- /dev/null +++ b/src/components/ImageGallery.tsx @@ -0,0 +1,165 @@ +import React, { useState, useRef, useEffect } from "react"; +import { X, AlertTriangle, ExternalLink, Image as ImageIcon } from "lucide-react"; +import type { ImageAttachment } from "@/lib/tauriCommands"; + +interface ImageGalleryProps { + images: ImageAttachment[]; + onDelete?: (attachment: ImageAttachment) => void; + showWarning?: boolean; +} + +export function ImageGallery({ images, onDelete, showWarning = true }: ImageGalleryProps) { + const [selectedImage, setSelectedImage] = useState(null); + const [isModalOpen, setIsModalOpen] = useState(false); + const modalRef = useRef(null); + + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === "Escape" && isModalOpen) { + setIsModalOpen(false); + setSelectedImage(null); + } + }; + window.addEventListener("keydown", handleKeyDown); + return () => window.removeEventListener("keydown", handleKeyDown); + }, [isModalOpen]); + + if (images.length === 0) return null; + + const base64ToDataUrl = (base64: string, mimeType: string): string => { + if (base64.startsWith("data:image/")) { + return base64; + } + return `data:${mimeType};base64,${base64}`; + }; + + const getPreviewUrl = (attachment: ImageAttachment): string => { + if (attachment.file_path && attachment.file_path.length > 0) { + return `file://${attachment.file_path}`; + } + return base64ToDataUrl(attachment.upload_hash, attachment.mime_type); + }; + + const isWebSource = (image: ImageAttachment): boolean => { + return image.file_path.length > 0 && + (image.file_path.startsWith("http://") || + image.file_path.startsWith("https://")); + }; + + return ( +
+ {showWarning && ( +
+ + + ⚠️ PII cannot be automatically redacted from images. Use at your own risk. + +
+ )} + + {images.some(img => isWebSource(img)) && ( +
+ + + ⚠️ Some images appear to be from web sources. Ensure you have permission to share. + +
+ )} + +
+ {images.map((image, idx) => ( +
+ +
+

+ {image.file_name} +

+

+ {image.is_paste ? "Paste" : "Upload"} · {(image.file_size / 1024).toFixed(1)} KB +

+
+ {onDelete && ( + + )} +
+ ))} +
+ + {isModalOpen && selectedImage && ( +
{ + setIsModalOpen(false); + setSelectedImage(null); + }} + > +
e.stopPropagation()} + > +
+
+ +

{selectedImage.file_name}

+
+ +
+
+ {selectedImage.file_name} +
+
+
+
+ Type: {selectedImage.mime_type} +
+
+ Size: {(selectedImage.file_size / 1024).toFixed(2)} KB +
+
+ Source: {selectedImage.is_paste ? "Paste" : "File"} +
+
+
+
+
+ )} +
+ ); +} + +export default ImageGallery; diff --git a/src/lib/tauriCommands.ts b/src/lib/tauriCommands.ts index b1711134..3a16e5dc 100644 --- a/src/lib/tauriCommands.ts +++ b/src/lib/tauriCommands.ts @@ -100,6 +100,7 @@ export interface ResolutionStep { export interface IssueDetail { issue: Issue; log_files: LogFile[]; + image_attachments: ImageAttachment[]; resolution_steps: ResolutionStep[]; conversations: AiConversation[]; } @@ -145,6 +146,19 @@ export interface LogFile { redacted: boolean; } +export interface ImageAttachment { + id: string; + issue_id: string; + file_name: string; + file_path: string; + file_size: number; + mime_type: string; + upload_hash: string; + uploaded_at: string; + pii_warning_acknowledged: boolean; + is_paste: boolean; +} + export interface PiiSpan { id: string; pii_type: string; @@ -263,6 +277,18 @@ export const listProvidersCmd = () => invoke("list_providers"); export const uploadLogFileCmd = (issueId: string, filePath: string) => invoke("upload_log_file", { issueId, filePath }); +export const uploadImageAttachmentCmd = (issueId: string, filePath: string) => + invoke("upload_image_attachment", { issueId, filePath }); + +export const uploadPasteImageCmd = (issueId: string, base64Image: string, mimeType: string) => + invoke("upload_paste_image", { issueId, base64Image, mimeType }); + +export const listImageAttachmentsCmd = (issueId: string) => + invoke("list_image_attachments", { issueId }); + +export const deleteImageAttachmentCmd = (attachmentId: string) => + invoke("delete_image_attachment", { attachmentId }); + export const detectPiiCmd = (logFileId: string) => invoke("detect_pii", { logFileId }); diff --git a/src/pages/LogUpload/index.tsx b/src/pages/LogUpload/index.tsx index b680f623..65e0f0fb 100644 --- a/src/pages/LogUpload/index.tsx +++ b/src/pages/LogUpload/index.tsx @@ -1,16 +1,22 @@ -import React, { useState, useCallback } from "react"; +import React, { useState, useCallback, useRef, useEffect } from "react"; import { useNavigate, useParams } from "react-router-dom"; -import { Upload, File, Trash2, ShieldCheck } from "lucide-react"; +import { Upload, File, Trash2, ShieldCheck, AlertTriangle, Image as ImageIcon } from "lucide-react"; import { Button, Card, CardHeader, CardTitle, CardContent, Badge } from "@/components/ui"; import { PiiDiffViewer } from "@/components/PiiDiffViewer"; import { useSessionStore } from "@/stores/sessionStore"; import { uploadLogFileCmd, detectPiiCmd, + uploadImageAttachmentCmd, + uploadPasteImageCmd, + listImageAttachmentsCmd, + deleteImageAttachmentCmd, type LogFile, type PiiSpan, type PiiDetectionResult, + type ImageAttachment, } from "@/lib/tauriCommands"; +import ImageGallery from "@/components/ImageGallery"; export default function LogUpload() { const { id } = useParams<{ id: string }>(); @@ -18,11 +24,14 @@ export default function LogUpload() { const { piiSpans, approvedRedactions, setPiiSpans, setApprovedRedactions } = useSessionStore(); const [files, setFiles] = useState<{ file: File; uploaded?: LogFile }[]>([]); + const [images, setImages] = useState([]); const [piiResult, setPiiResult] = useState(null); const [isUploading, setIsUploading] = useState(false); const [isDetecting, setIsDetecting] = useState(false); const [error, setError] = useState(null); + const fileInputRef = useRef(null); + const handleDrop = useCallback( (e: React.DragEvent) => { e.preventDefault(); @@ -96,9 +105,136 @@ export default function LogUpload() { } }; + const handleImageDrop = useCallback( + (e: React.DragEvent) => { + e.preventDefault(); + const droppedFiles = Array.from(e.dataTransfer.files); + const imageFiles = droppedFiles.filter((f) => f.type.startsWith("image/")); + + if (imageFiles.length > 0) { + handleImagesUpload(imageFiles); + } + }, + [id] + ); + + const handleImageFileSelect = (e: React.ChangeEvent) => { + if (e.target.files) { + const selected = Array.from(e.target.files).filter((f) => f.type.startsWith("image/")); + if (selected.length > 0) { + handleImagesUpload(selected); + } + } + }; + + const handlePaste = useCallback( + async (e: React.ClipboardEvent) => { + const items = e.clipboardData?.items; + const imageItems = items ? Array.from(items).filter((item: DataTransferItem) => item.type.startsWith("image/")) : []; + + for (const item of imageItems) { + const file = item.getAsFile(); + if (file) { + const reader = new FileReader(); + reader.onload = async () => { + const base64Data = reader.result as string; + try { + const result = await uploadPasteImageCmd(id || "", base64Data, file.type); + setImages((prev) => [...prev, result]); + } catch (err) { + setError(String(err)); + } + }; + reader.readAsDataURL(file); + } + } + }, + [id] + ); + + const handleImagesUpload = async (imageFiles: File[]) => { + if (!id || imageFiles.length === 0) return; + + setIsUploading(true); + setError(null); + try { + const uploaded = await Promise.all( + imageFiles.map(async (file) => { + const result = await uploadImageAttachmentCmd(id, file.name); + return result; + }) + ); + setImages((prev) => [...prev, ...uploaded]); + } catch (err) { + setError(String(err)); + } finally { + setIsUploading(false); + } + }; + + const handleDeleteImage = async (image: ImageAttachment) => { + try { + await deleteImageAttachmentCmd(image.id); + setImages((prev) => prev.filter((img) => img.id !== image.id)); + } catch (err) { + setError(String(err)); + } + }; + + const fileToBase64 = (file: File): Promise => { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = () => resolve(reader.result as string); + reader.onerror = (err) => reject(err); + reader.readAsDataURL(file); + }); + }; + + const allUploaded = files.length > 0 && files.every((f) => f.uploaded); const piiReviewed = piiResult != null; + useEffect(() => { + const handleGlobalPaste = (e: ClipboardEvent) => { + if (document.activeElement?.tagName === "INPUT" || + document.activeElement?.tagName === "TEXTAREA" || + (document.activeElement as HTMLElement)?.isContentEditable || false) { + return; + } + + const items = e.clipboardData?.items; + const imageItems = items ? Array.from(items).filter((item: DataTransferItem) => item.type.startsWith("image/")) : []; + + for (const item of imageItems) { + const file = item.getAsFile(); + if (file) { + e.preventDefault(); + const reader = new FileReader(); + reader.onload = async () => { + const base64Data = reader.result as string; + try { + const result = await uploadPasteImageCmd(id || "", base64Data, file.type); + setImages((prev) => [...prev, result]); + } catch (err) { + setError(String(err)); + } + }; + reader.readAsDataURL(file); + break; + } + } + }; + + window.addEventListener("paste", handleGlobalPaste); + return () => window.removeEventListener("paste", handleGlobalPaste); + }, [id]); + + useEffect(() => { + if (id) { + listImageAttachmentsCmd(id).then(setImages).catch(setError); + } + }, [id]); + return (
@@ -165,6 +301,87 @@ export default function LogUpload() { )} + {/* Image Upload */} + {id && ( + <> +
+

+ + Image Attachments +

+

+ Upload or paste screenshots and images. +

+
+ + {/* Image drop zone */} +
e.preventDefault()} + onDrop={handleImageDrop} + className="border-2 border-dashed border-primary/30 rounded-lg p-8 text-center hover:border-primary transition-colors cursor-pointer bg-primary/5" + onClick={() => document.getElementById("image-input")?.click()} + > + +

+ Drag and drop images here, or click to browse +

+

+ Supported: PNG, JPEG, GIF, WebP, SVG +

+ +
+ + {/* Paste button */} +
+ + + Use Ctrl+V / Cmd+V or the button above to paste images + +
+ + {/* PII warning for images */} +
+ + + ⚠️ PII cannot be automatically redacted from images. Use at your own risk. + +
+ + {/* Image Gallery */} + {images.length > 0 && ( + + + + + Attached Images ({images.length}) + + + + + + + )} + + )} + {/* PII Detection */} {allUploaded && ( diff --git a/tests/unit/resolution.test.tsx b/tests/unit/resolution.test.tsx index 1b93f250..de13e933 100644 --- a/tests/unit/resolution.test.tsx +++ b/tests/unit/resolution.test.tsx @@ -21,6 +21,7 @@ const mockIssueDetail = { tags: "[]", }, log_files: [], + image_attachments: [], resolution_steps: [ { id: "step-1",