From 07a91a238165341e96e8f772c3a88c0da4786bf6 Mon Sep 17 00:00:00 2001 From: Jamie Pine Date: Wed, 28 Jan 2026 00:00:18 -0800 Subject: [PATCH] Update app version to 0.1.4 and integrate @tanstack/react-router for improved routing functionality - Bumped version for @voicebox/app, @voicebox/landing, @voicebox/tauri, and @voicebox/web to 0.1.4. - Added @tanstack/react-router dependency for enhanced routing capabilities. - Refactored App component to utilize RouterProvider for routing management. - Created a new router configuration in router.tsx to define application routes and layout. - Updated Sidebar component to use Link from @tanstack/react-router for navigation. --- app/package.json | 1 + app/src/App.tsx | 70 +----------------- app/src/components/Sidebar.tsx | 29 ++++---- app/src/router.tsx | 125 +++++++++++++++++++++++++++++++++ bun.lock | 31 ++++++-- tauri/src-tauri/Cargo.lock | 2 +- tauri/src-tauri/gen/Assets.car | Bin 3847048 -> 3847048 bytes 7 files changed, 173 insertions(+), 85 deletions(-) create mode 100644 app/src/router.tsx diff --git a/app/package.json b/app/package.json index fbf7f775..fc19a740 100644 --- a/app/package.json +++ b/app/package.json @@ -30,6 +30,7 @@ "@radix-ui/react-toast": "^1.2.1", "@tanstack/react-query": "^5.0.0", "@tanstack/react-query-devtools": "^5.0.0", + "@tanstack/react-router": "^1.157.16", "@tauri-apps/api": "^2.0.0", "@tauri-apps/plugin-dialog": "^2.0.0", "@tauri-apps/plugin-fs": "^2.0.0", diff --git a/app/src/App.tsx b/app/src/App.tsx index a832aa48..84d8fc8d 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -1,27 +1,17 @@ import { useEffect, useState } from 'react'; +import { RouterProvider } from '@tanstack/react-router'; import voiceboxLogo from '@/assets/voicebox-logo.png'; -import { AppFrame } from '@/components/AppFrame/AppFrame'; -import { AudioTab } from '@/components/AudioTab/AudioTab'; -import { MainEditor } from '@/components/MainEditor/MainEditor'; -import { ModelsTab } from '@/components/ModelsTab/ModelsTab'; -import { ServerTab } from '@/components/ServerTab/ServerTab'; -// import { GenerationForm } from '@/components/Generation/GenerationForm'; import ShinyText from '@/components/ShinyText'; -import { Sidebar } from '@/components/Sidebar'; import { TitleBarDragRegion } from '@/components/TitleBarDragRegion'; -import { Toaster } from '@/components/ui/toaster'; -import { VoicesTab } from '@/components/VoicesTab/VoicesTab'; import { TOP_SAFE_AREA_PADDING } from '@/lib/constants/ui'; -import { useModelDownloadToast } from '@/lib/hooks/useModelDownloadToast'; -import { MODEL_DISPLAY_NAMES, useRestoreActiveTasks } from '@/lib/hooks/useRestoreActiveTasks'; import { - isMacOS, isTauri, setKeepServerRunning, setupWindowCloseHandler, startServer, } from '@/lib/tauri'; import { cn } from '@/lib/utils/cn'; +import { router } from '@/router'; import { useServerStore } from '@/stores/serverStore'; // Track if server is starting to prevent duplicate starts @@ -51,13 +41,9 @@ const LOADING_MESSAGES = [ ]; function App() { - const [activeTab, setActiveTab] = useState('main'); const [serverReady, setServerReady] = useState(false); const [loadingMessageIndex, setLoadingMessageIndex] = useState(0); - // Monitor active downloads/generations and show toasts for them - const activeDownloads = useRestoreActiveTasks(); - // Sync stored setting to Rust on startup useEffect(() => { if (isTauri()) { @@ -172,57 +158,7 @@ function App() { ); } - return ( - -
- - -
-
- {activeTab === 'main' && } - {activeTab === 'voices' && } - {activeTab === 'audio' && } - {activeTab === 'server' && } - {activeTab === 'models' && } -
-
-
- - {/* Show download toasts for any active downloads (from anywhere) */} - {activeDownloads.map((download) => { - const displayName = MODEL_DISPLAY_NAMES[download.model_name] || download.model_name; - return ( - - ); - })} - - -
- ); -} - -/** - * Component that restores a download toast for a specific model. - */ -function DownloadToastRestorer({ - modelName, - displayName, -}: { - modelName: string; - displayName: string; -}) { - // Use the download toast hook to restore the toast - useModelDownloadToast({ - modelName, - displayName, - enabled: true, - }); - - return null; + return ; } export default App; diff --git a/app/src/components/Sidebar.tsx b/app/src/components/Sidebar.tsx index 6ec5c4a4..5fdc16a6 100644 --- a/app/src/components/Sidebar.tsx +++ b/app/src/components/Sidebar.tsx @@ -1,3 +1,4 @@ +import { Link, useMatchRoute } from '@tanstack/react-router'; import { Box, Loader2, Mic, Server, Speaker, Volume2 } from 'lucide-react'; import voiceboxLogo from '@/assets/voicebox-logo.png'; import { cn } from '@/lib/utils/cn'; @@ -5,23 +6,22 @@ import { useGenerationStore } from '@/stores/generationStore'; import { usePlayerStore } from '@/stores/playerStore'; interface SidebarProps { - activeTab: string; - onTabChange: (tab: string) => void; isMacOS?: boolean; } const tabs = [ - { id: 'main', icon: Volume2, label: 'Generate' }, - { id: 'voices', icon: Mic, label: 'Voices' }, - { id: 'audio', icon: Speaker, label: 'Audio' }, - { id: 'models', icon: Box, label: 'Models' }, - { id: 'server', icon: Server, label: 'Server' }, + { id: 'main', path: '/', icon: Volume2, label: 'Generate' }, + { id: 'voices', path: '/voices', icon: Mic, label: 'Voices' }, + { id: 'audio', path: '/audio', icon: Speaker, label: 'Audio' }, + { id: 'models', path: '/models', icon: Box, label: 'Models' }, + { id: 'server', path: '/server', icon: Server, label: 'Server' }, ]; -export function Sidebar({ activeTab, onTabChange, isMacOS }: SidebarProps) { +export function Sidebar({ isMacOS }: SidebarProps) { const isGenerating = useGenerationStore((state) => state.isGenerating); const audioUrl = usePlayerStore((state) => state.audioUrl); const isPlayerVisible = !!audioUrl; + const matchRoute = useMatchRoute(); return (
{tabs.map((tab) => { const Icon = tab.icon; - const isActive = activeTab === tab.id; + // For index route, use exact match; for others, use default matching + const isActive = + tab.path === '/' + ? matchRoute({ to: '/', exact: true }) + : matchRoute({ to: tab.path }); return ( - + ); })}
diff --git a/app/src/router.tsx b/app/src/router.tsx new file mode 100644 index 00000000..b9ce6a6e --- /dev/null +++ b/app/src/router.tsx @@ -0,0 +1,125 @@ +import { createRootRoute, createRoute, createRouter, Outlet } from '@tanstack/react-router'; +import { AppFrame } from '@/components/AppFrame/AppFrame'; +import { AudioTab } from '@/components/AudioTab/AudioTab'; +import { MainEditor } from '@/components/MainEditor/MainEditor'; +import { ModelsTab } from '@/components/ModelsTab/ModelsTab'; +import { ServerTab } from '@/components/ServerTab/ServerTab'; +import { Sidebar } from '@/components/Sidebar'; +import { Toaster } from '@/components/ui/toaster'; +import { VoicesTab } from '@/components/VoicesTab/VoicesTab'; +import { useModelDownloadToast } from '@/lib/hooks/useModelDownloadToast'; +import { MODEL_DISPLAY_NAMES, useRestoreActiveTasks } from '@/lib/hooks/useRestoreActiveTasks'; +import { isMacOS } from '@/lib/tauri'; + +// Root layout component +function RootLayout() { + // Monitor active downloads/generations and show toasts for them + const activeDownloads = useRestoreActiveTasks(); + + return ( + +
+ + +
+
+ +
+
+
+ + {/* Show download toasts for any active downloads (from anywhere) */} + {activeDownloads.map((download) => { + const displayName = MODEL_DISPLAY_NAMES[download.model_name] || download.model_name; + return ( + + ); + })} + + +
+ ); +} + +/** + * Component that restores a download toast for a specific model. + */ +function DownloadToastRestorer({ + modelName, + displayName, +}: { + modelName: string; + displayName: string; +}) { + // Use the download toast hook to restore the toast + useModelDownloadToast({ + modelName, + displayName, + enabled: true, + }); + + return null; +} + +// Root route with layout +const rootRoute = createRootRoute({ + component: RootLayout, +}); + +// Index route (main/generate) +const indexRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/', + component: MainEditor, +}); + +// Voices route +const voicesRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/voices', + component: VoicesTab, +}); + +// Audio route +const audioRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/audio', + component: AudioTab, +}); + +// Models route +const modelsRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/models', + component: ModelsTab, +}); + +// Server route +const serverRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/server', + component: ServerTab, +}); + +// Route tree +const routeTree = rootRoute.addChildren([ + indexRoute, + voicesRoute, + audioRoute, + modelsRoute, + serverRoute, +]); + +// Create router +export const router = createRouter({ routeTree }); + +// Register router for type safety +declare module '@tanstack/react-router' { + interface Register { + router: typeof router; + } +} diff --git a/bun.lock b/bun.lock index ab6ce78b..ee866528 100644 --- a/bun.lock +++ b/bun.lock @@ -13,7 +13,7 @@ }, "app": { "name": "@voicebox/app", - "version": "0.1.0", + "version": "0.1.4", "dependencies": { "@hookform/resolvers": "^3.9.0", "@radix-ui/react-alert-dialog": "^1.1.1", @@ -32,6 +32,7 @@ "@radix-ui/react-toast": "^1.2.1", "@tanstack/react-query": "^5.0.0", "@tanstack/react-query-devtools": "^5.0.0", + "@tanstack/react-router": "^1.157.16", "@tauri-apps/api": "^2.0.0", "@tauri-apps/plugin-dialog": "^2.0.0", "@tauri-apps/plugin-fs": "^2.0.0", @@ -63,7 +64,7 @@ }, "landing": { "name": "@voicebox/landing", - "version": "0.1.0", + "version": "0.1.4", "dependencies": { "@radix-ui/react-separator": "^1.1.8", "@radix-ui/react-slot": "^1.2.4", @@ -88,7 +89,7 @@ }, "tauri": { "name": "@voicebox/tauri", - "version": "0.1.0", + "version": "0.1.4", "dependencies": { "@tauri-apps/api": "^2.0.0", "@tauri-apps/plugin-shell": "^2.0.0", @@ -107,7 +108,7 @@ }, "web": { "name": "@voicebox/web", - "version": "0.1.0", + "version": "0.1.4", "dependencies": { "@tanstack/react-query": "^5.0.0", "react": "^18.3.0", @@ -512,6 +513,8 @@ "@tailwindcss/vite": ["@tailwindcss/vite@4.1.18", "", { "dependencies": { "@tailwindcss/node": "4.1.18", "@tailwindcss/oxide": "4.1.18", "tailwindcss": "4.1.18" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA=="], + "@tanstack/history": ["@tanstack/history@1.154.14", "", {}, "sha512-xyIfof8eHBuub1CkBnbKNKQXeRZC4dClhmzePHVOEel4G7lk/dW+TQ16da7CFdeNLv6u6Owf5VoBQxoo6DFTSA=="], + "@tanstack/query-core": ["@tanstack/query-core@5.90.20", "", {}, "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg=="], "@tanstack/query-devtools": ["@tanstack/query-devtools@5.92.0", "", {}, "sha512-N8D27KH1vEpVacvZgJL27xC6yPFUy0Zkezn5gnB3L3gRCxlDeSuiya7fKge8Y91uMTnC8aSxBQhcK6ocY7alpQ=="], @@ -520,6 +523,14 @@ "@tanstack/react-query-devtools": ["@tanstack/react-query-devtools@5.91.2", "", { "dependencies": { "@tanstack/query-devtools": "5.92.0" }, "peerDependencies": { "@tanstack/react-query": "^5.90.14", "react": "^18 || ^19" } }, "sha512-ZJ1503ay5fFeEYFUdo7LMNFzZryi6B0Cacrgr2h1JRkvikK1khgIq6Nq2EcblqEdIlgB/r7XDW8f8DQ89RuUgg=="], + "@tanstack/react-router": ["@tanstack/react-router@1.157.16", "", { "dependencies": { "@tanstack/history": "1.154.14", "@tanstack/react-store": "^0.8.0", "@tanstack/router-core": "1.157.16", "isbot": "^5.1.22", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-xwFQa7S7dhBhm3aJYwU79cITEYgAKSrcL6wokaROIvl2JyIeazn8jueWqUPJzFjv+QF6Q8euKRlKUEyb5q2ymg=="], + + "@tanstack/react-store": ["@tanstack/react-store@0.8.0", "", { "dependencies": { "@tanstack/store": "0.8.0", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow=="], + + "@tanstack/router-core": ["@tanstack/router-core@1.157.16", "", { "dependencies": { "@tanstack/history": "1.154.14", "@tanstack/store": "^0.8.0", "cookie-es": "^2.0.0", "seroval": "^1.4.2", "seroval-plugins": "^1.4.2", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" } }, "sha512-eJuVgM7KZYTTr4uPorbUzUflmljMVcaX2g6VvhITLnHmg9SBx9RAgtQ1HmT+72mzyIbRSlQ1q0fY/m+of/fosA=="], + + "@tanstack/store": ["@tanstack/store@0.8.0", "", {}, "sha512-Om+BO0YfMZe//X2z0uLF2j+75nQga6TpTJgLJQBiq85aOyZNIhkCgleNcud2KQg4k4v9Y9l+Uhru3qWMPGTOzQ=="], + "@tauri-apps/api": ["@tauri-apps/api@2.9.1", "", {}, "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw=="], "@tauri-apps/cli": ["@tauri-apps/cli@2.9.6", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.9.6", "@tauri-apps/cli-darwin-x64": "2.9.6", "@tauri-apps/cli-linux-arm-gnueabihf": "2.9.6", "@tauri-apps/cli-linux-arm64-gnu": "2.9.6", "@tauri-apps/cli-linux-arm64-musl": "2.9.6", "@tauri-apps/cli-linux-riscv64-gnu": "2.9.6", "@tauri-apps/cli-linux-x64-gnu": "2.9.6", "@tauri-apps/cli-linux-x64-musl": "2.9.6", "@tauri-apps/cli-win32-arm64-msvc": "2.9.6", "@tauri-apps/cli-win32-ia32-msvc": "2.9.6", "@tauri-apps/cli-win32-x64-msvc": "2.9.6" }, "bin": { "tauri": "tauri.js" } }, "sha512-3xDdXL5omQ3sPfBfdC8fCtDKcnyV7OqyzQgfyT5P3+zY6lcPqIYKQBvUasNvppi21RSdfhy44ttvJmftb0PCDw=="], @@ -664,6 +675,8 @@ "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], + "cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="], + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], @@ -792,6 +805,8 @@ "is-path-inside": ["is-path-inside@3.0.3", "", {}, "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ=="], + "isbot": ["isbot@5.1.34", "", {}, "sha512-aCMIBSKd/XPRYdiCQTLC8QHH4YT8B3JUADu+7COgYIZPvkeoMcUHMRjZLM9/7V8fCj+l7FSREc1lOPNjzogo/A=="], + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], @@ -966,6 +981,10 @@ "semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "seroval": ["seroval@1.5.0", "", {}, "sha512-OE4cvmJ1uSPrKorFIH9/w/Qwuvi/IMcGbv5RKgcJ/zjA/IohDLU6SVaxFN9FwajbP7nsX0dQqMDes1whk3y+yw=="], + + "seroval-plugins": ["seroval-plugins@1.5.0", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-EAHqADIQondwRZIdeW2I636zgsODzoBDwb3PT/+7TLDWyw1Dy/Xv7iGUIEXXav7usHDE9HVhOU61irI3EnyyHA=="], + "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], @@ -1002,6 +1021,10 @@ "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], + "tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="], + + "tiny-warning": ["tiny-warning@1.0.3", "", {}, "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="], + "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], diff --git a/tauri/src-tauri/Cargo.lock b/tauri/src-tauri/Cargo.lock index 5bba547c..2f73203a 100644 --- a/tauri/src-tauri/Cargo.lock +++ b/tauri/src-tauri/Cargo.lock @@ -4840,7 +4840,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "voicebox" -version = "0.1.3" +version = "0.1.4" dependencies = [ "base64 0.22.1", "core-foundation-sys", diff --git a/tauri/src-tauri/gen/Assets.car b/tauri/src-tauri/gen/Assets.car index 3cdfc5c1adf56530777f9e9010aa6517007b2de8..ebcc4552b48421e17714874fd428312fa6035eee 100644 GIT binary patch delta 832 zcmZwGJx^3Y6b9g3)|CYmL|Ftx0d@U8?0kRFTxRaQ6G}?{ft|6murRUMZE<64v?rl4 zp}3U(0250a3p+Q)7`37GMbKuQ!+$evM_SWL|2{$k@CfCAc8Rg{DF)9k^$bc}3i4 zVTk=%l1CY%W!|kne)Mp6ZRz>Y_lCX>W6*#z(1f!vUJZS#Y-W-(CRi%S7S53}Wl2#5 zM=^PCxVDA~K6;LKp;Ra5ELZ)k^|Fx(!}G*bARCLEP-H<)NKQ8C;Jo5O{x2vp=F7i9 zPx4l~o^ghj%YeSTnju}D%ILL0{;bcRCA z4JpN?%r&}{Vk9V!m~uF&XrZ^W)q)9_gef=&=V2OV-~!CTMYsfW(1v-q496LZumo3N z8Lq-LSbOvvvRIC@Z`VR+@r*6u2)TJcWdJ5v6xIQ`{HD zXj8b%WKXBF)Z5#900isM1qK`hNKl}wy-ibn&r%X)X%i#vSR^H5NnY?oR!N&uk}NVi yGDVCzm*(^#_71xi9Qf+6yU}<$J6Ege&-e*r*nePOc=djNW2HV{ecRu7J^mZitK|Ct delta 833 zcmZwGJx>%t90u?^PUHaPL;(R&K*jgrW_D(0{zJ3OYbYuC26o2M!otMjXvxLcXiq|8 zLa}@Z6YXs6yclE9#L)T>LgTr~Z)cNDo|$K6clX=(<}Q5rvNqdkG#XPd4sDo(iNjxO zpE`Sdw0~Uk{80kM!}t34NaZ9&Q)JD^7Lh5kcuJI5RLM|5rRS0} zsbwJ;KfTK2g?8Cw9oC;ed%Cx}_HV!wLq}Qk|~u7 zMw%S+Mn>%nPdeD)d1446oz1gU?^f+Mt%?FSL{>7VIf9blj9lRuaVpE;C*%KT9r>^R1A?ti&m)S zu{KnrK#2#=Bl+QKfkzRFv!MCj&Q=@7VFD)M5?qEU=)e`2hO2N5W?&ZP;5wXUEWje% zfF-yIw_q7oU=?n|9k>f?a1ZXo19%9J>Yc5}Cnpsd^cOiYUkH!g!OaJh3WjsVWvOHo zL%ZWu88e-gTI}s_J^=>n&;j8Wo3yeA2V|zDMk`!Tu@;Z z-u-*7o_itO`GiMZ(>v-C*!rlu(Rw*O-)NLy@hgmAJjOWp_T$0Ea&xBsaj@}j>@RN2 B=idMT