├── .editorconfig ├── .github └── workflows │ └── release.yml ├── .gitignore ├── .taurignore ├── LICENSE ├── README.md ├── package.json ├── pavo.png ├── pnpm-lock.yaml ├── postcss.config.js ├── public ├── tauri.svg └── yew.png ├── screenshot.PNG ├── src-tauri ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── build.rs ├── capabilities │ ├── desktop.json │ └── migrated.json ├── gen │ └── schemas │ │ ├── acl-manifests.json │ │ ├── capabilities.json │ │ ├── desktop-schema.json │ │ ├── macOS-schema.json │ │ └── windows-schema.json ├── icons │ ├── 128x128.png │ ├── 128x128@2x.png │ ├── 32x32.png │ ├── Square107x107Logo.png │ ├── Square142x142Logo.png │ ├── Square150x150Logo.png │ ├── Square284x284Logo.png │ ├── Square30x30Logo.png │ ├── Square310x310Logo.png │ ├── Square44x44Logo.png │ ├── Square71x71Logo.png │ ├── Square89x89Logo.png │ ├── StoreLogo.png │ ├── icon.icns │ ├── icon.ico │ ├── icon.png │ ├── tray.png │ └── win-icon.png ├── rustfmt.toml ├── src │ ├── background.rs │ ├── cmd.rs │ ├── config.rs │ ├── lib.rs │ ├── main.rs │ ├── plugins.rs │ ├── scheduler.rs │ ├── services │ │ ├── bing.rs │ │ └── mod.rs │ ├── shuffle_thread.rs │ ├── threads.rs │ └── tray.rs └── tauri.conf.json ├── src ├── app.css ├── app.html ├── lib │ ├── components │ │ ├── BingWallpaper.svelte │ │ ├── Skeleton.svelte │ │ └── Toolbar.svelte │ ├── index.ts │ └── updater.ts ├── pages │ ├── about.svelte │ ├── bing.svelte │ └── settings.svelte ├── routes │ ├── +layout.svelte │ ├── +layout.ts │ └── +page.svelte └── typing.d.ts ├── static └── icon.png ├── svelte.config.js ├── tailwind.config.js ├── tsconfig.json └── vite.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.md] 16 | # double whitespace at end of line 17 | # denotes a line break in Markdown 18 | trim_trailing_whitespace = false 19 | 20 | [*.yml] 21 | indent_size = 2 22 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: "publish" 2 | 3 | on: 4 | push: 5 | branches: 6 | - release 7 | env: 8 | TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} 9 | TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} 10 | 11 | # This is the example from the readme. 12 | # On each push to the `release` branch it will create or update a GitHub release, build your app, and upload the artifacts to the release. 13 | 14 | jobs: 15 | publish-tauri: 16 | permissions: 17 | contents: write 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | settings: 22 | - platform: "macos-latest" # for Arm based macs (M1 and above). 23 | args: "--target aarch64-apple-darwin" 24 | - platform: "macos-latest" # for Intel based macs. 25 | args: "--target x86_64-apple-darwin" 26 | - platform: "ubuntu-22.04" # for Tauri v1 you could replace this with ubuntu-20.04. 27 | args: "" 28 | - platform: "windows-latest" 29 | args: "" 30 | 31 | runs-on: ${{ matrix.settings.platform }} 32 | steps: 33 | - uses: actions/checkout@v4 34 | 35 | - name: setup node 36 | uses: actions/setup-node@v4 37 | with: 38 | node-version: lts/* 39 | 40 | - name: install Rust stable 41 | uses: dtolnay/rust-toolchain@stable 42 | with: 43 | # Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds. 44 | targets: ${{ matrix.settings.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }} 45 | 46 | - name: install dependencies (ubuntu only) 47 | if: matrix.settings.platform == 'ubuntu-22.04' # This must match the platform value defined above. 48 | run: | 49 | sudo apt-get update 50 | sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf 51 | # webkitgtk 4.0 is for Tauri v1 - webkitgtk 4.1 is for Tauri v2. 52 | # You can remove the one that doesn't apply to your app to speed up the workflow a bit. 53 | 54 | - uses: pnpm/action-setup@v3 55 | name: Install pnpm 56 | with: 57 | version: 8 58 | run_install: false 59 | 60 | - name: Get pnpm store directory 61 | shell: bash 62 | run: | 63 | echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV 64 | 65 | - uses: actions/cache@v4 66 | name: Setup pnpm cache 67 | with: 68 | path: ${{ env.STORE_PATH }} 69 | key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} 70 | restore-keys: | 71 | ${{ runner.os }}-pnpm-store- 72 | 73 | - name: Install dependencies 74 | run: pnpm install 75 | 76 | - uses: tauri-apps/tauri-action@v0 77 | env: 78 | GITHUB_TOKEN: ${{ secrets.PAVO_TOKEN }} 79 | with: 80 | tagName: v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version. 81 | releaseName: "v__VERSION__" 82 | releaseBody: "See the assets to download this version and install." 83 | releaseDraft: true 84 | prerelease: false 85 | args: ${{ matrix.settings.args }} 86 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /dist/ 2 | /target/ 3 | /Cargo.lock 4 | 5 | .idea 6 | .vscode 7 | .vs 8 | node_modules 9 | build 10 | .svelte-kit 11 | .svelte-kit/generated/server/internal.js 12 | -------------------------------------------------------------------------------- /.taurignore: -------------------------------------------------------------------------------- 1 | /src 2 | /public 3 | /Cargo.toml -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 zhanglun 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 |

Pavo

5 | 6 | Pavo is a lightweight desktop wallpaper app that lets you easily customize and change your desktop background. With Pavo, you can quickly switch between different wallpapers, set random wallpapers from your local directory, and even adjust the wallpaper's position and scaling. It's simple to use and perfect for anyone who wants to personalize their desktop with minimal effort. 7 | 8 | ## Screenshot 9 | 10 |

11 | 12 |

13 | 14 | ## Get Started 15 | 16 | ### Prerequisites 17 | 18 | * Install Node.js. I recommend you to use [NVM](https://github.com/nvm-sh/nvm). 19 | * Install pnpm. [Here](https://pnpm.io/installation) is the manual. 20 | * Install Rust. You can find way in [here](https://www.rust-lang.org/tools/install) 21 | * Follow the [Tauri setup guide](https://tauri.app/v1/guides/getting-started/prerequisites) 22 | * Run pnpm install 23 | 24 | ### Develop and Build 25 | 26 | It is easy to start developing 27 | 28 | ```bash 29 | pnpm tauri dev 30 | ``` 31 | 32 | And also easy to build. 33 | 34 | ```bash 35 | pnpm tauri build 36 | ``` 37 | 38 | You can get more details about building Tauri app in [here](https://tauri.app/v1/guides/distribution/publishing) 39 | 40 | ## Repo Activity 41 | 42 | ![Alt](https://repobeats.axiom.co/api/embed/ac6f91c5371bcea9fdb92dcc7da9479f50423d81.svg "Repobeats analytics image") 43 | 44 | ### More Projects 45 | 46 | * [Lettura: Another free and open-source feed reader for macOS and Window.. ](https://github.com/zhanglun/lettura) 47 | * [BookWise: book wise, read wiser](https://github.com/zhanglun/bookwise) 48 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pavo", 3 | "version": "0.0.10", 4 | "description": "bing daily wallpaper", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite dev", 8 | "build": "vite build", 9 | "preview": "vite preview", 10 | "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", 11 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", 12 | "tauri": "tauri" 13 | }, 14 | "license": "MIT", 15 | "dependencies": { 16 | "@tauri-apps/api": "^2", 17 | "@tauri-apps/plugin-dialog": "~2", 18 | "@tauri-apps/plugin-log": "~2", 19 | "@tauri-apps/plugin-positioner": "~2.2.0", 20 | "@tauri-apps/plugin-process": "~2", 21 | "@tauri-apps/plugin-shell": "^2", 22 | "@tauri-apps/plugin-updater": "~2" 23 | }, 24 | "devDependencies": { 25 | "@sveltejs/adapter-static": "^3.0.5", 26 | "@sveltejs/kit": "^2.7.0", 27 | "@sveltejs/vite-plugin-svelte": "^4.0.0", 28 | "@tailwindcss/typography": "^0.5.15", 29 | "@tauri-apps/cli": "^2.1.0", 30 | "autoprefixer": "^10.4.20", 31 | "flowbite": "^2.5.2", 32 | "flowbite-svelte": "^0.47.2", 33 | "flowbite-svelte-icons": "^2.0.2", 34 | "postcss": "^8.4.47", 35 | "svelte": "^5.0.0", 36 | "svelte-check": "^4.0.0", 37 | "tailwindcss": "^3.4.14", 38 | "tslib": "^2.8.0", 39 | "typescript": "^5.5.0", 40 | "vite": "^5.4.10" 41 | }, 42 | "pnpm": { 43 | "ignoredBuiltDependencies": [ 44 | "@sveltejs/kit", 45 | "esbuild" 46 | ], 47 | "onlyBuiltDependencies": [ 48 | "@sveltejs/kit", 49 | "esbuild" 50 | ] 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /pavo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/pavo.png -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@tauri-apps/api': 12 | specifier: ^2 13 | version: 2.1.1 14 | '@tauri-apps/plugin-dialog': 15 | specifier: ~2 16 | version: 2.2.0 17 | '@tauri-apps/plugin-log': 18 | specifier: ~2 19 | version: 2.2.0 20 | '@tauri-apps/plugin-positioner': 21 | specifier: ~2.2.0 22 | version: 2.2.0 23 | '@tauri-apps/plugin-process': 24 | specifier: ~2 25 | version: 2.2.0 26 | '@tauri-apps/plugin-shell': 27 | specifier: ^2 28 | version: 2.2.0 29 | '@tauri-apps/plugin-updater': 30 | specifier: ~2 31 | version: 2.3.0 32 | devDependencies: 33 | '@sveltejs/adapter-static': 34 | specifier: ^3.0.5 35 | version: 3.0.8(@sveltejs/kit@2.15.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.16.0)(vite@5.4.11))(svelte@5.16.0)(vite@5.4.11)) 36 | '@sveltejs/kit': 37 | specifier: ^2.7.0 38 | version: 2.15.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.16.0)(vite@5.4.11))(svelte@5.16.0)(vite@5.4.11) 39 | '@sveltejs/vite-plugin-svelte': 40 | specifier: ^4.0.0 41 | version: 4.0.4(svelte@5.16.0)(vite@5.4.11) 42 | '@tailwindcss/typography': 43 | specifier: ^0.5.15 44 | version: 0.5.15(tailwindcss@3.4.17) 45 | '@tauri-apps/cli': 46 | specifier: ^2.1.0 47 | version: 2.1.0 48 | autoprefixer: 49 | specifier: ^10.4.20 50 | version: 10.4.20(postcss@8.4.49) 51 | flowbite: 52 | specifier: ^2.5.2 53 | version: 2.5.2(rollup@4.29.1) 54 | flowbite-svelte: 55 | specifier: ^0.47.2 56 | version: 0.47.4(rollup@4.29.1)(svelte@5.16.0) 57 | flowbite-svelte-icons: 58 | specifier: ^2.0.2 59 | version: 2.0.2(svelte@5.16.0)(tailwind-merge@2.6.0)(tailwindcss@3.4.17) 60 | postcss: 61 | specifier: ^8.4.47 62 | version: 8.4.49 63 | svelte: 64 | specifier: ^5.0.0 65 | version: 5.16.0 66 | svelte-check: 67 | specifier: ^4.0.0 68 | version: 4.1.1(picomatch@4.0.2)(svelte@5.16.0)(typescript@5.7.2) 69 | tailwindcss: 70 | specifier: ^3.4.14 71 | version: 3.4.17 72 | tslib: 73 | specifier: ^2.8.0 74 | version: 2.8.1 75 | typescript: 76 | specifier: ^5.5.0 77 | version: 5.7.2 78 | vite: 79 | specifier: ^5.4.10 80 | version: 5.4.11 81 | 82 | packages: 83 | 84 | '@alloc/quick-lru@5.2.0': 85 | resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} 86 | engines: {node: '>=10'} 87 | 88 | '@ampproject/remapping@2.3.0': 89 | resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} 90 | engines: {node: '>=6.0.0'} 91 | 92 | '@esbuild/aix-ppc64@0.21.5': 93 | resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} 94 | engines: {node: '>=12'} 95 | cpu: [ppc64] 96 | os: [aix] 97 | 98 | '@esbuild/android-arm64@0.21.5': 99 | resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} 100 | engines: {node: '>=12'} 101 | cpu: [arm64] 102 | os: [android] 103 | 104 | '@esbuild/android-arm@0.21.5': 105 | resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} 106 | engines: {node: '>=12'} 107 | cpu: [arm] 108 | os: [android] 109 | 110 | '@esbuild/android-x64@0.21.5': 111 | resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} 112 | engines: {node: '>=12'} 113 | cpu: [x64] 114 | os: [android] 115 | 116 | '@esbuild/darwin-arm64@0.21.5': 117 | resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} 118 | engines: {node: '>=12'} 119 | cpu: [arm64] 120 | os: [darwin] 121 | 122 | '@esbuild/darwin-x64@0.21.5': 123 | resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} 124 | engines: {node: '>=12'} 125 | cpu: [x64] 126 | os: [darwin] 127 | 128 | '@esbuild/freebsd-arm64@0.21.5': 129 | resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} 130 | engines: {node: '>=12'} 131 | cpu: [arm64] 132 | os: [freebsd] 133 | 134 | '@esbuild/freebsd-x64@0.21.5': 135 | resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} 136 | engines: {node: '>=12'} 137 | cpu: [x64] 138 | os: [freebsd] 139 | 140 | '@esbuild/linux-arm64@0.21.5': 141 | resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} 142 | engines: {node: '>=12'} 143 | cpu: [arm64] 144 | os: [linux] 145 | 146 | '@esbuild/linux-arm@0.21.5': 147 | resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} 148 | engines: {node: '>=12'} 149 | cpu: [arm] 150 | os: [linux] 151 | 152 | '@esbuild/linux-ia32@0.21.5': 153 | resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} 154 | engines: {node: '>=12'} 155 | cpu: [ia32] 156 | os: [linux] 157 | 158 | '@esbuild/linux-loong64@0.21.5': 159 | resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} 160 | engines: {node: '>=12'} 161 | cpu: [loong64] 162 | os: [linux] 163 | 164 | '@esbuild/linux-mips64el@0.21.5': 165 | resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} 166 | engines: {node: '>=12'} 167 | cpu: [mips64el] 168 | os: [linux] 169 | 170 | '@esbuild/linux-ppc64@0.21.5': 171 | resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} 172 | engines: {node: '>=12'} 173 | cpu: [ppc64] 174 | os: [linux] 175 | 176 | '@esbuild/linux-riscv64@0.21.5': 177 | resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} 178 | engines: {node: '>=12'} 179 | cpu: [riscv64] 180 | os: [linux] 181 | 182 | '@esbuild/linux-s390x@0.21.5': 183 | resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} 184 | engines: {node: '>=12'} 185 | cpu: [s390x] 186 | os: [linux] 187 | 188 | '@esbuild/linux-x64@0.21.5': 189 | resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} 190 | engines: {node: '>=12'} 191 | cpu: [x64] 192 | os: [linux] 193 | 194 | '@esbuild/netbsd-x64@0.21.5': 195 | resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} 196 | engines: {node: '>=12'} 197 | cpu: [x64] 198 | os: [netbsd] 199 | 200 | '@esbuild/openbsd-x64@0.21.5': 201 | resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} 202 | engines: {node: '>=12'} 203 | cpu: [x64] 204 | os: [openbsd] 205 | 206 | '@esbuild/sunos-x64@0.21.5': 207 | resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} 208 | engines: {node: '>=12'} 209 | cpu: [x64] 210 | os: [sunos] 211 | 212 | '@esbuild/win32-arm64@0.21.5': 213 | resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} 214 | engines: {node: '>=12'} 215 | cpu: [arm64] 216 | os: [win32] 217 | 218 | '@esbuild/win32-ia32@0.21.5': 219 | resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} 220 | engines: {node: '>=12'} 221 | cpu: [ia32] 222 | os: [win32] 223 | 224 | '@esbuild/win32-x64@0.21.5': 225 | resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} 226 | engines: {node: '>=12'} 227 | cpu: [x64] 228 | os: [win32] 229 | 230 | '@floating-ui/core@1.6.8': 231 | resolution: {integrity: sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==} 232 | 233 | '@floating-ui/dom@1.6.12': 234 | resolution: {integrity: sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==} 235 | 236 | '@floating-ui/utils@0.2.8': 237 | resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==} 238 | 239 | '@isaacs/cliui@8.0.2': 240 | resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} 241 | engines: {node: '>=12'} 242 | 243 | '@jridgewell/gen-mapping@0.3.8': 244 | resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} 245 | engines: {node: '>=6.0.0'} 246 | 247 | '@jridgewell/resolve-uri@3.1.2': 248 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 249 | engines: {node: '>=6.0.0'} 250 | 251 | '@jridgewell/set-array@1.2.1': 252 | resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} 253 | engines: {node: '>=6.0.0'} 254 | 255 | '@jridgewell/sourcemap-codec@1.5.0': 256 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} 257 | 258 | '@jridgewell/trace-mapping@0.3.25': 259 | resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} 260 | 261 | '@nodelib/fs.scandir@2.1.5': 262 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 263 | engines: {node: '>= 8'} 264 | 265 | '@nodelib/fs.stat@2.0.5': 266 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 267 | engines: {node: '>= 8'} 268 | 269 | '@nodelib/fs.walk@1.2.8': 270 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 271 | engines: {node: '>= 8'} 272 | 273 | '@pkgjs/parseargs@0.11.0': 274 | resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} 275 | engines: {node: '>=14'} 276 | 277 | '@polka/url@1.0.0-next.28': 278 | resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} 279 | 280 | '@popperjs/core@2.11.8': 281 | resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} 282 | 283 | '@rollup/plugin-node-resolve@15.3.1': 284 | resolution: {integrity: sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==} 285 | engines: {node: '>=14.0.0'} 286 | peerDependencies: 287 | rollup: ^2.78.0||^3.0.0||^4.0.0 288 | peerDependenciesMeta: 289 | rollup: 290 | optional: true 291 | 292 | '@rollup/pluginutils@5.1.4': 293 | resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} 294 | engines: {node: '>=14.0.0'} 295 | peerDependencies: 296 | rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 297 | peerDependenciesMeta: 298 | rollup: 299 | optional: true 300 | 301 | '@rollup/rollup-android-arm-eabi@4.29.1': 302 | resolution: {integrity: sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==} 303 | cpu: [arm] 304 | os: [android] 305 | 306 | '@rollup/rollup-android-arm64@4.29.1': 307 | resolution: {integrity: sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==} 308 | cpu: [arm64] 309 | os: [android] 310 | 311 | '@rollup/rollup-darwin-arm64@4.29.1': 312 | resolution: {integrity: sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==} 313 | cpu: [arm64] 314 | os: [darwin] 315 | 316 | '@rollup/rollup-darwin-x64@4.29.1': 317 | resolution: {integrity: sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==} 318 | cpu: [x64] 319 | os: [darwin] 320 | 321 | '@rollup/rollup-freebsd-arm64@4.29.1': 322 | resolution: {integrity: sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==} 323 | cpu: [arm64] 324 | os: [freebsd] 325 | 326 | '@rollup/rollup-freebsd-x64@4.29.1': 327 | resolution: {integrity: sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==} 328 | cpu: [x64] 329 | os: [freebsd] 330 | 331 | '@rollup/rollup-linux-arm-gnueabihf@4.29.1': 332 | resolution: {integrity: sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==} 333 | cpu: [arm] 334 | os: [linux] 335 | libc: [glibc] 336 | 337 | '@rollup/rollup-linux-arm-musleabihf@4.29.1': 338 | resolution: {integrity: sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==} 339 | cpu: [arm] 340 | os: [linux] 341 | libc: [musl] 342 | 343 | '@rollup/rollup-linux-arm64-gnu@4.29.1': 344 | resolution: {integrity: sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==} 345 | cpu: [arm64] 346 | os: [linux] 347 | libc: [glibc] 348 | 349 | '@rollup/rollup-linux-arm64-musl@4.29.1': 350 | resolution: {integrity: sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==} 351 | cpu: [arm64] 352 | os: [linux] 353 | libc: [musl] 354 | 355 | '@rollup/rollup-linux-loongarch64-gnu@4.29.1': 356 | resolution: {integrity: sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==} 357 | cpu: [loong64] 358 | os: [linux] 359 | libc: [glibc] 360 | 361 | '@rollup/rollup-linux-powerpc64le-gnu@4.29.1': 362 | resolution: {integrity: sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==} 363 | cpu: [ppc64] 364 | os: [linux] 365 | libc: [glibc] 366 | 367 | '@rollup/rollup-linux-riscv64-gnu@4.29.1': 368 | resolution: {integrity: sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==} 369 | cpu: [riscv64] 370 | os: [linux] 371 | libc: [glibc] 372 | 373 | '@rollup/rollup-linux-s390x-gnu@4.29.1': 374 | resolution: {integrity: sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==} 375 | cpu: [s390x] 376 | os: [linux] 377 | libc: [glibc] 378 | 379 | '@rollup/rollup-linux-x64-gnu@4.29.1': 380 | resolution: {integrity: sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==} 381 | cpu: [x64] 382 | os: [linux] 383 | libc: [glibc] 384 | 385 | '@rollup/rollup-linux-x64-musl@4.29.1': 386 | resolution: {integrity: sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==} 387 | cpu: [x64] 388 | os: [linux] 389 | libc: [musl] 390 | 391 | '@rollup/rollup-win32-arm64-msvc@4.29.1': 392 | resolution: {integrity: sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==} 393 | cpu: [arm64] 394 | os: [win32] 395 | 396 | '@rollup/rollup-win32-ia32-msvc@4.29.1': 397 | resolution: {integrity: sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==} 398 | cpu: [ia32] 399 | os: [win32] 400 | 401 | '@rollup/rollup-win32-x64-msvc@4.29.1': 402 | resolution: {integrity: sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==} 403 | cpu: [x64] 404 | os: [win32] 405 | 406 | '@sveltejs/adapter-static@3.0.8': 407 | resolution: {integrity: sha512-YaDrquRpZwfcXbnlDsSrBQNCChVOT9MGuSg+dMAyfsAa1SmiAhrA5jUYUiIMC59G92kIbY/AaQOWcBdq+lh+zg==} 408 | peerDependencies: 409 | '@sveltejs/kit': ^2.0.0 410 | 411 | '@sveltejs/kit@2.15.0': 412 | resolution: {integrity: sha512-FI1bhfhFNGI2sKg+BhiRyM4eaOvX+KZqRYSQqL5PK3ZZREX2xufZ6MzZAw79N846OnIxYNqcz/3VOUq+FPDd3w==} 413 | engines: {node: '>=18.13'} 414 | hasBin: true 415 | peerDependencies: 416 | '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 417 | svelte: ^4.0.0 || ^5.0.0-next.0 418 | vite: ^5.0.3 || ^6.0.0 419 | 420 | '@sveltejs/vite-plugin-svelte-inspector@3.0.1': 421 | resolution: {integrity: sha512-2CKypmj1sM4GE7HjllT7UKmo4Q6L5xFRd7VMGEWhYnZ+wc6AUVU01IBd7yUi6WnFndEwWoMNOd6e8UjoN0nbvQ==} 422 | engines: {node: ^18.0.0 || ^20.0.0 || >=22} 423 | peerDependencies: 424 | '@sveltejs/vite-plugin-svelte': ^4.0.0-next.0||^4.0.0 425 | svelte: ^5.0.0-next.96 || ^5.0.0 426 | vite: ^5.0.0 427 | 428 | '@sveltejs/vite-plugin-svelte@4.0.4': 429 | resolution: {integrity: sha512-0ba1RQ/PHen5FGpdSrW7Y3fAMQjrXantECALeOiOdBdzR5+5vPP6HVZRLmZaQL+W8m++o+haIAKq5qT+MiZ7VA==} 430 | engines: {node: ^18.0.0 || ^20.0.0 || >=22} 431 | peerDependencies: 432 | svelte: ^5.0.0-next.96 || ^5.0.0 433 | vite: ^5.0.0 434 | 435 | '@tailwindcss/typography@0.5.15': 436 | resolution: {integrity: sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==} 437 | peerDependencies: 438 | tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20' 439 | 440 | '@tauri-apps/api@2.1.1': 441 | resolution: {integrity: sha512-fzUfFFKo4lknXGJq8qrCidkUcKcH2UHhfaaCNt4GzgzGaW2iS26uFOg4tS3H4P8D6ZEeUxtiD5z0nwFF0UN30A==} 442 | 443 | '@tauri-apps/cli-darwin-arm64@2.1.0': 444 | resolution: {integrity: sha512-ESc6J6CE8hl1yKH2vJ+ALF+thq4Be+DM1mvmTyUCQObvezNCNhzfS6abIUd3ou4x5RGH51ouiANeT3wekU6dCw==} 445 | engines: {node: '>= 10'} 446 | cpu: [arm64] 447 | os: [darwin] 448 | 449 | '@tauri-apps/cli-darwin-x64@2.1.0': 450 | resolution: {integrity: sha512-TasHS442DFs8cSH2eUQzuDBXUST4ECjCd0yyP+zZzvAruiB0Bg+c8A+I/EnqCvBQ2G2yvWLYG8q/LI7c87A5UA==} 451 | engines: {node: '>= 10'} 452 | cpu: [x64] 453 | os: [darwin] 454 | 455 | '@tauri-apps/cli-linux-arm-gnueabihf@2.1.0': 456 | resolution: {integrity: sha512-aP7ZBGNL4ny07Cbb6kKpUOSrmhcIK2KhjviTzYlh+pPhAptxnC78xQGD3zKQkTi2WliJLPmBYbOHWWQa57lQ9w==} 457 | engines: {node: '>= 10'} 458 | cpu: [arm] 459 | os: [linux] 460 | 461 | '@tauri-apps/cli-linux-arm64-gnu@2.1.0': 462 | resolution: {integrity: sha512-ZTdgD5gLeMCzndMT2f358EkoYkZ5T+Qy6zPzU+l5vv5M7dHVN9ZmblNAYYXmoOuw7y+BY4X/rZvHV9pcGrcanQ==} 463 | engines: {node: '>= 10'} 464 | cpu: [arm64] 465 | os: [linux] 466 | libc: [glibc] 467 | 468 | '@tauri-apps/cli-linux-arm64-musl@2.1.0': 469 | resolution: {integrity: sha512-NzwqjUCilhnhJzusz3d/0i0F1GFrwCQbkwR6yAHUxItESbsGYkZRJk0yMEWkg3PzFnyK4cWTlQJMEU52TjhEzA==} 470 | engines: {node: '>= 10'} 471 | cpu: [arm64] 472 | os: [linux] 473 | libc: [musl] 474 | 475 | '@tauri-apps/cli-linux-x64-gnu@2.1.0': 476 | resolution: {integrity: sha512-TyiIpMEtZxNOQmuFyfJwaaYbg3movSthpBJLIdPlKxSAB2BW0VWLY3/ZfIxm/G2YGHyREkjJvimzYE0i37PnMA==} 477 | engines: {node: '>= 10'} 478 | cpu: [x64] 479 | os: [linux] 480 | libc: [glibc] 481 | 482 | '@tauri-apps/cli-linux-x64-musl@2.1.0': 483 | resolution: {integrity: sha512-/dQd0TlaxBdJACrR72DhynWftzHDaX32eBtS5WBrNJ+nnNb+znM3gON6nJ9tSE9jgDa6n1v2BkI/oIDtypfUXw==} 484 | engines: {node: '>= 10'} 485 | cpu: [x64] 486 | os: [linux] 487 | libc: [musl] 488 | 489 | '@tauri-apps/cli-win32-arm64-msvc@2.1.0': 490 | resolution: {integrity: sha512-NdQJO7SmdYqOcE+JPU7bwg7+odfZMWO6g8xF9SXYCMdUzvM2Gv/AQfikNXz5yS7ralRhNFuW32i5dcHlxh4pDg==} 491 | engines: {node: '>= 10'} 492 | cpu: [arm64] 493 | os: [win32] 494 | 495 | '@tauri-apps/cli-win32-ia32-msvc@2.1.0': 496 | resolution: {integrity: sha512-f5h8gKT/cB8s1ticFRUpNmHqkmaLutT62oFDB7N//2YTXnxst7EpMIn1w+QimxTvTk2gcx6EcW6bEk/y2hZGzg==} 497 | engines: {node: '>= 10'} 498 | cpu: [ia32] 499 | os: [win32] 500 | 501 | '@tauri-apps/cli-win32-x64-msvc@2.1.0': 502 | resolution: {integrity: sha512-P/+LrdSSb5Xbho1LRP4haBjFHdyPdjWvGgeopL96OVtrFpYnfC+RctB45z2V2XxqFk3HweDDxk266btjttfjGw==} 503 | engines: {node: '>= 10'} 504 | cpu: [x64] 505 | os: [win32] 506 | 507 | '@tauri-apps/cli@2.1.0': 508 | resolution: {integrity: sha512-K2VhcKqBhAeS5pNOVdnR/xQRU6jwpgmkSL2ejHXcl0m+kaTggT0WRDQnFtPq6NljA7aE03cvwsbCAoFG7vtkJw==} 509 | engines: {node: '>= 10'} 510 | hasBin: true 511 | 512 | '@tauri-apps/plugin-dialog@2.2.0': 513 | resolution: {integrity: sha512-6bLkYK68zyK31418AK5fNccCdVuRnNpbxquCl8IqgFByOgWFivbiIlvb79wpSXi0O+8k8RCSsIpOquebusRVSg==} 514 | 515 | '@tauri-apps/plugin-log@2.2.0': 516 | resolution: {integrity: sha512-g6CsQAR1lsm5ABSZZxpM/iCn86GrMDTTlhj7GPkZkYBRSm3+WczfOAl7SV7HDn77tOKCzhZffwI5uHfRoHutrw==} 517 | 518 | '@tauri-apps/plugin-positioner@2.2.0': 519 | resolution: {integrity: sha512-3JIWqV4U1US4nmM4PGmAHODq0ltkJ91MyANR033elKSSpX3AqKnVQnLz76xThBFHjChJrZwsXASpc2Inpu+cTg==} 520 | 521 | '@tauri-apps/plugin-process@2.2.0': 522 | resolution: {integrity: sha512-uypN2Crmyop9z+KRJr3zl71OyVFgTuvHFjsJ0UxxQ/J5212jVa5w4nPEYjIewcn8bUEXacRebwE6F7owgrbhSw==} 523 | 524 | '@tauri-apps/plugin-shell@2.2.0': 525 | resolution: {integrity: sha512-iC3Ic1hLmasoboG7BO+7p+AriSoqAwKrIk+Hpk+S/bjTQdXqbl2GbdclghI4gM32X0bls7xHzIFqhRdrlvJeaA==} 526 | 527 | '@tauri-apps/plugin-updater@2.3.0': 528 | resolution: {integrity: sha512-qdzyZEUN69FZQ/nRx51fBub10tT6wffJl3DLVo9q922Gvw8Wk++rZhoD9eethPlZYbog/7RGgT8JkrfLh5BKAg==} 529 | 530 | '@types/cookie@0.6.0': 531 | resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} 532 | 533 | '@types/estree@1.0.6': 534 | resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} 535 | 536 | '@types/resolve@1.20.2': 537 | resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} 538 | 539 | '@yr/monotone-cubic-spline@1.0.3': 540 | resolution: {integrity: sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==} 541 | 542 | acorn-typescript@1.4.13: 543 | resolution: {integrity: sha512-xsc9Xv0xlVfwp2o7sQ+GCQ1PgbkdcpWdTzrwXxO3xDMTAywVS3oXVOcOHuRjAPkS4P9b+yc/qNF15460v+jp4Q==} 544 | peerDependencies: 545 | acorn: '>=8.9.0' 546 | 547 | acorn@8.14.0: 548 | resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} 549 | engines: {node: '>=0.4.0'} 550 | hasBin: true 551 | 552 | ansi-regex@5.0.1: 553 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 554 | engines: {node: '>=8'} 555 | 556 | ansi-regex@6.1.0: 557 | resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} 558 | engines: {node: '>=12'} 559 | 560 | ansi-styles@4.3.0: 561 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 562 | engines: {node: '>=8'} 563 | 564 | ansi-styles@6.2.1: 565 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} 566 | engines: {node: '>=12'} 567 | 568 | any-promise@1.3.0: 569 | resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} 570 | 571 | anymatch@3.1.3: 572 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 573 | engines: {node: '>= 8'} 574 | 575 | apexcharts@3.54.1: 576 | resolution: {integrity: sha512-E4et0h/J1U3r3EwS/WlqJCQIbepKbp6wGUmaAwJOMjHUP4Ci0gxanLa7FR3okx6p9coi4st6J853/Cb1NP0vpA==} 577 | 578 | arg@5.0.2: 579 | resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} 580 | 581 | aria-query@5.3.2: 582 | resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} 583 | engines: {node: '>= 0.4'} 584 | 585 | autoprefixer@10.4.20: 586 | resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} 587 | engines: {node: ^10 || ^12 || >=14} 588 | hasBin: true 589 | peerDependencies: 590 | postcss: ^8.1.0 591 | 592 | axobject-query@4.1.0: 593 | resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} 594 | engines: {node: '>= 0.4'} 595 | 596 | balanced-match@1.0.2: 597 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 598 | 599 | binary-extensions@2.3.0: 600 | resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} 601 | engines: {node: '>=8'} 602 | 603 | brace-expansion@2.0.1: 604 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} 605 | 606 | braces@3.0.3: 607 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 608 | engines: {node: '>=8'} 609 | 610 | browserslist@4.24.3: 611 | resolution: {integrity: sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==} 612 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 613 | hasBin: true 614 | 615 | camelcase-css@2.0.1: 616 | resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} 617 | engines: {node: '>= 6'} 618 | 619 | caniuse-lite@1.0.30001690: 620 | resolution: {integrity: sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==} 621 | 622 | chokidar@3.6.0: 623 | resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} 624 | engines: {node: '>= 8.10.0'} 625 | 626 | chokidar@4.0.3: 627 | resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} 628 | engines: {node: '>= 14.16.0'} 629 | 630 | clsx@2.1.1: 631 | resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} 632 | engines: {node: '>=6'} 633 | 634 | color-convert@2.0.1: 635 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 636 | engines: {node: '>=7.0.0'} 637 | 638 | color-name@1.1.4: 639 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 640 | 641 | commander@4.1.1: 642 | resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} 643 | engines: {node: '>= 6'} 644 | 645 | cookie@0.6.0: 646 | resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} 647 | engines: {node: '>= 0.6'} 648 | 649 | cross-spawn@7.0.6: 650 | resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} 651 | engines: {node: '>= 8'} 652 | 653 | cssesc@3.0.0: 654 | resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} 655 | engines: {node: '>=4'} 656 | hasBin: true 657 | 658 | debug@4.4.0: 659 | resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} 660 | engines: {node: '>=6.0'} 661 | peerDependencies: 662 | supports-color: '*' 663 | peerDependenciesMeta: 664 | supports-color: 665 | optional: true 666 | 667 | deepmerge@4.3.1: 668 | resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} 669 | engines: {node: '>=0.10.0'} 670 | 671 | devalue@5.1.1: 672 | resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} 673 | 674 | didyoumean@1.2.2: 675 | resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} 676 | 677 | dlv@1.1.3: 678 | resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} 679 | 680 | eastasianwidth@0.2.0: 681 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} 682 | 683 | electron-to-chromium@1.5.76: 684 | resolution: {integrity: sha512-CjVQyG7n7Sr+eBXE86HIulnL5N8xZY1sgmOPGuq/F0Rr0FJq63lg0kEtOIDfZBk44FnDLf6FUJ+dsJcuiUDdDQ==} 685 | 686 | emoji-regex@8.0.0: 687 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 688 | 689 | emoji-regex@9.2.2: 690 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 691 | 692 | esbuild@0.21.5: 693 | resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} 694 | engines: {node: '>=12'} 695 | hasBin: true 696 | 697 | escalade@3.2.0: 698 | resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} 699 | engines: {node: '>=6'} 700 | 701 | esm-env@1.2.1: 702 | resolution: {integrity: sha512-U9JedYYjCnadUlXk7e1Kr+aENQhtUaoaV9+gZm1T8LC/YBAPJx3NSPIAurFOC0U5vrdSevnUJS2/wUVxGwPhng==} 703 | 704 | esrap@1.3.2: 705 | resolution: {integrity: sha512-C4PXusxYhFT98GjLSmb20k9PREuUdporer50dhzGuJu9IJXktbMddVCMLAERl5dAHyAi73GWWCE4FVHGP1794g==} 706 | 707 | estree-walker@2.0.2: 708 | resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} 709 | 710 | fast-glob@3.3.2: 711 | resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} 712 | engines: {node: '>=8.6.0'} 713 | 714 | fastq@1.18.0: 715 | resolution: {integrity: sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==} 716 | 717 | fdir@6.4.2: 718 | resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} 719 | peerDependencies: 720 | picomatch: ^3 || ^4 721 | peerDependenciesMeta: 722 | picomatch: 723 | optional: true 724 | 725 | fill-range@7.1.1: 726 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 727 | engines: {node: '>=8'} 728 | 729 | flowbite-datepicker@1.3.1: 730 | resolution: {integrity: sha512-FM8EZE0Vc/nhEr+FcvJQldkIeS3hGhDQY5hoTWvqSrnlAqNd1JJhSj9bNiq6xpIXLqewWiTONiRVMUcUcSSiQA==} 731 | 732 | flowbite-svelte-icons@2.0.2: 733 | resolution: {integrity: sha512-Vkmduy2867Rk8R7TziPirsWkixJnToFBEXRaN4ouJabOx62NQjiBbHFe+HTaMOQmdp4FNMI2Nhtk2I2CQ8r3RQ==} 734 | engines: {node: '>=18.0.0', npm: '>=7.0.0'} 735 | peerDependencies: 736 | svelte: ^5.0.0 737 | tailwind-merge: ^2.3.0 738 | tailwindcss: ^3.4.3 739 | 740 | flowbite-svelte@0.47.4: 741 | resolution: {integrity: sha512-8oiY/oeWA7fgkDF91MZKEBo5VmjL8El3wuqTDWAFO1j7p45BHIL6G1VGnnidgCEYlbADDQN9BIGCvyPq4J3g+w==} 742 | peerDependencies: 743 | svelte: ^3.55.1 || ^4.0.0 || ^5.0.0 744 | 745 | flowbite@2.5.2: 746 | resolution: {integrity: sha512-kwFD3n8/YW4EG8GlY3Od9IoKND97kitO+/ejISHSqpn3vw2i5K/+ZI8Jm2V+KC4fGdnfi0XZ+TzYqQb4Q1LshA==} 747 | 748 | foreground-child@3.3.0: 749 | resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} 750 | engines: {node: '>=14'} 751 | 752 | fraction.js@4.3.7: 753 | resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} 754 | 755 | fsevents@2.3.3: 756 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 757 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 758 | os: [darwin] 759 | 760 | function-bind@1.1.2: 761 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} 762 | 763 | glob-parent@5.1.2: 764 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 765 | engines: {node: '>= 6'} 766 | 767 | glob-parent@6.0.2: 768 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} 769 | engines: {node: '>=10.13.0'} 770 | 771 | glob@10.4.5: 772 | resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} 773 | hasBin: true 774 | 775 | globalyzer@0.1.0: 776 | resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==} 777 | 778 | globrex@0.1.2: 779 | resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} 780 | 781 | hasown@2.0.2: 782 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} 783 | engines: {node: '>= 0.4'} 784 | 785 | import-meta-resolve@4.1.0: 786 | resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} 787 | 788 | is-binary-path@2.1.0: 789 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 790 | engines: {node: '>=8'} 791 | 792 | is-core-module@2.16.1: 793 | resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} 794 | engines: {node: '>= 0.4'} 795 | 796 | is-extglob@2.1.1: 797 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 798 | engines: {node: '>=0.10.0'} 799 | 800 | is-fullwidth-code-point@3.0.0: 801 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 802 | engines: {node: '>=8'} 803 | 804 | is-glob@4.0.3: 805 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 806 | engines: {node: '>=0.10.0'} 807 | 808 | is-module@1.0.0: 809 | resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} 810 | 811 | is-number@7.0.0: 812 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 813 | engines: {node: '>=0.12.0'} 814 | 815 | is-reference@3.0.3: 816 | resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} 817 | 818 | isexe@2.0.0: 819 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 820 | 821 | jackspeak@3.4.3: 822 | resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} 823 | 824 | jiti@1.21.7: 825 | resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} 826 | hasBin: true 827 | 828 | kleur@4.1.5: 829 | resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} 830 | engines: {node: '>=6'} 831 | 832 | lilconfig@3.1.3: 833 | resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} 834 | engines: {node: '>=14'} 835 | 836 | lines-and-columns@1.2.4: 837 | resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} 838 | 839 | locate-character@3.0.0: 840 | resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} 841 | 842 | lodash.castarray@4.4.0: 843 | resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} 844 | 845 | lodash.isplainobject@4.0.6: 846 | resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} 847 | 848 | lodash.merge@4.6.2: 849 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} 850 | 851 | lru-cache@10.4.3: 852 | resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} 853 | 854 | magic-string@0.30.17: 855 | resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} 856 | 857 | merge2@1.4.1: 858 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 859 | engines: {node: '>= 8'} 860 | 861 | micromatch@4.0.8: 862 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 863 | engines: {node: '>=8.6'} 864 | 865 | mini-svg-data-uri@1.4.4: 866 | resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} 867 | hasBin: true 868 | 869 | minimatch@9.0.5: 870 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} 871 | engines: {node: '>=16 || 14 >=14.17'} 872 | 873 | minipass@7.1.2: 874 | resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} 875 | engines: {node: '>=16 || 14 >=14.17'} 876 | 877 | mri@1.2.0: 878 | resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} 879 | engines: {node: '>=4'} 880 | 881 | mrmime@2.0.0: 882 | resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} 883 | engines: {node: '>=10'} 884 | 885 | ms@2.1.3: 886 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 887 | 888 | mz@2.7.0: 889 | resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} 890 | 891 | nanoid@3.3.8: 892 | resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} 893 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 894 | hasBin: true 895 | 896 | node-releases@2.0.19: 897 | resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} 898 | 899 | normalize-path@3.0.0: 900 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 901 | engines: {node: '>=0.10.0'} 902 | 903 | normalize-range@0.1.2: 904 | resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} 905 | engines: {node: '>=0.10.0'} 906 | 907 | object-assign@4.1.1: 908 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} 909 | engines: {node: '>=0.10.0'} 910 | 911 | object-hash@3.0.0: 912 | resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} 913 | engines: {node: '>= 6'} 914 | 915 | package-json-from-dist@1.0.1: 916 | resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} 917 | 918 | path-key@3.1.1: 919 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 920 | engines: {node: '>=8'} 921 | 922 | path-parse@1.0.7: 923 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 924 | 925 | path-scurry@1.11.1: 926 | resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} 927 | engines: {node: '>=16 || 14 >=14.18'} 928 | 929 | picocolors@1.1.1: 930 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 931 | 932 | picomatch@2.3.1: 933 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 934 | engines: {node: '>=8.6'} 935 | 936 | picomatch@4.0.2: 937 | resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} 938 | engines: {node: '>=12'} 939 | 940 | pify@2.3.0: 941 | resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} 942 | engines: {node: '>=0.10.0'} 943 | 944 | pirates@4.0.6: 945 | resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} 946 | engines: {node: '>= 6'} 947 | 948 | postcss-import@15.1.0: 949 | resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} 950 | engines: {node: '>=14.0.0'} 951 | peerDependencies: 952 | postcss: ^8.0.0 953 | 954 | postcss-js@4.0.1: 955 | resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} 956 | engines: {node: ^12 || ^14 || >= 16} 957 | peerDependencies: 958 | postcss: ^8.4.21 959 | 960 | postcss-load-config@4.0.2: 961 | resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} 962 | engines: {node: '>= 14'} 963 | peerDependencies: 964 | postcss: '>=8.0.9' 965 | ts-node: '>=9.0.0' 966 | peerDependenciesMeta: 967 | postcss: 968 | optional: true 969 | ts-node: 970 | optional: true 971 | 972 | postcss-nested@6.2.0: 973 | resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} 974 | engines: {node: '>=12.0'} 975 | peerDependencies: 976 | postcss: ^8.2.14 977 | 978 | postcss-selector-parser@6.0.10: 979 | resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} 980 | engines: {node: '>=4'} 981 | 982 | postcss-selector-parser@6.1.2: 983 | resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} 984 | engines: {node: '>=4'} 985 | 986 | postcss-value-parser@4.2.0: 987 | resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} 988 | 989 | postcss@8.4.49: 990 | resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} 991 | engines: {node: ^10 || ^12 || >=14} 992 | 993 | queue-microtask@1.2.3: 994 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 995 | 996 | read-cache@1.0.0: 997 | resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} 998 | 999 | readdirp@3.6.0: 1000 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 1001 | engines: {node: '>=8.10.0'} 1002 | 1003 | readdirp@4.0.2: 1004 | resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} 1005 | engines: {node: '>= 14.16.0'} 1006 | 1007 | resolve@1.22.10: 1008 | resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} 1009 | engines: {node: '>= 0.4'} 1010 | hasBin: true 1011 | 1012 | reusify@1.0.4: 1013 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 1014 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 1015 | 1016 | rollup@4.29.1: 1017 | resolution: {integrity: sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==} 1018 | engines: {node: '>=18.0.0', npm: '>=8.0.0'} 1019 | hasBin: true 1020 | 1021 | run-parallel@1.2.0: 1022 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 1023 | 1024 | sade@1.8.1: 1025 | resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} 1026 | engines: {node: '>=6'} 1027 | 1028 | set-cookie-parser@2.7.1: 1029 | resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} 1030 | 1031 | shebang-command@2.0.0: 1032 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 1033 | engines: {node: '>=8'} 1034 | 1035 | shebang-regex@3.0.0: 1036 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 1037 | engines: {node: '>=8'} 1038 | 1039 | signal-exit@4.1.0: 1040 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 1041 | engines: {node: '>=14'} 1042 | 1043 | sirv@3.0.0: 1044 | resolution: {integrity: sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==} 1045 | engines: {node: '>=18'} 1046 | 1047 | source-map-js@1.2.1: 1048 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 1049 | engines: {node: '>=0.10.0'} 1050 | 1051 | string-width@4.2.3: 1052 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 1053 | engines: {node: '>=8'} 1054 | 1055 | string-width@5.1.2: 1056 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} 1057 | engines: {node: '>=12'} 1058 | 1059 | strip-ansi@6.0.1: 1060 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 1061 | engines: {node: '>=8'} 1062 | 1063 | strip-ansi@7.1.0: 1064 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} 1065 | engines: {node: '>=12'} 1066 | 1067 | sucrase@3.35.0: 1068 | resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} 1069 | engines: {node: '>=16 || 14 >=14.17'} 1070 | hasBin: true 1071 | 1072 | supports-preserve-symlinks-flag@1.0.0: 1073 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 1074 | engines: {node: '>= 0.4'} 1075 | 1076 | svelte-check@4.1.1: 1077 | resolution: {integrity: sha512-NfaX+6Qtc8W/CyVGS/F7/XdiSSyXz+WGYA9ZWV3z8tso14V2vzjfXviKaTFEzB7g8TqfgO2FOzP6XT4ApSTUTw==} 1078 | engines: {node: '>= 18.0.0'} 1079 | hasBin: true 1080 | peerDependencies: 1081 | svelte: ^4.0.0 || ^5.0.0-next.0 1082 | typescript: '>=5.0.0' 1083 | 1084 | svelte@5.16.0: 1085 | resolution: {integrity: sha512-Ygqsiac6UogVED2ruKclU+pOeMThxWtp9LG+li7BXeDKC2paVIsRTMkNmcON4Zejerd1s5sZHWx6ZtU85xklVg==} 1086 | engines: {node: '>=18'} 1087 | 1088 | svg.draggable.js@2.2.2: 1089 | resolution: {integrity: sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==} 1090 | engines: {node: '>= 0.8.0'} 1091 | 1092 | svg.easing.js@2.0.0: 1093 | resolution: {integrity: sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==} 1094 | engines: {node: '>= 0.8.0'} 1095 | 1096 | svg.filter.js@2.0.2: 1097 | resolution: {integrity: sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==} 1098 | engines: {node: '>= 0.8.0'} 1099 | 1100 | svg.js@2.7.1: 1101 | resolution: {integrity: sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==} 1102 | 1103 | svg.pathmorphing.js@0.1.3: 1104 | resolution: {integrity: sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==} 1105 | engines: {node: '>= 0.8.0'} 1106 | 1107 | svg.resize.js@1.4.3: 1108 | resolution: {integrity: sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==} 1109 | engines: {node: '>= 0.8.0'} 1110 | 1111 | svg.select.js@2.1.2: 1112 | resolution: {integrity: sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==} 1113 | engines: {node: '>= 0.8.0'} 1114 | 1115 | svg.select.js@3.0.1: 1116 | resolution: {integrity: sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==} 1117 | engines: {node: '>= 0.8.0'} 1118 | 1119 | tailwind-merge@2.6.0: 1120 | resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} 1121 | 1122 | tailwindcss@3.4.17: 1123 | resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} 1124 | engines: {node: '>=14.0.0'} 1125 | hasBin: true 1126 | 1127 | thenify-all@1.6.0: 1128 | resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} 1129 | engines: {node: '>=0.8'} 1130 | 1131 | thenify@3.3.1: 1132 | resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} 1133 | 1134 | tiny-glob@0.2.9: 1135 | resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} 1136 | 1137 | to-regex-range@5.0.1: 1138 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1139 | engines: {node: '>=8.0'} 1140 | 1141 | totalist@3.0.1: 1142 | resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} 1143 | engines: {node: '>=6'} 1144 | 1145 | ts-interface-checker@0.1.13: 1146 | resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} 1147 | 1148 | tslib@2.8.1: 1149 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 1150 | 1151 | typescript@5.7.2: 1152 | resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} 1153 | engines: {node: '>=14.17'} 1154 | hasBin: true 1155 | 1156 | update-browserslist-db@1.1.1: 1157 | resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} 1158 | hasBin: true 1159 | peerDependencies: 1160 | browserslist: '>= 4.21.0' 1161 | 1162 | util-deprecate@1.0.2: 1163 | resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 1164 | 1165 | vite@5.4.11: 1166 | resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} 1167 | engines: {node: ^18.0.0 || >=20.0.0} 1168 | hasBin: true 1169 | peerDependencies: 1170 | '@types/node': ^18.0.0 || >=20.0.0 1171 | less: '*' 1172 | lightningcss: ^1.21.0 1173 | sass: '*' 1174 | sass-embedded: '*' 1175 | stylus: '*' 1176 | sugarss: '*' 1177 | terser: ^5.4.0 1178 | peerDependenciesMeta: 1179 | '@types/node': 1180 | optional: true 1181 | less: 1182 | optional: true 1183 | lightningcss: 1184 | optional: true 1185 | sass: 1186 | optional: true 1187 | sass-embedded: 1188 | optional: true 1189 | stylus: 1190 | optional: true 1191 | sugarss: 1192 | optional: true 1193 | terser: 1194 | optional: true 1195 | 1196 | vitefu@1.0.4: 1197 | resolution: {integrity: sha512-y6zEE3PQf6uu/Mt6DTJ9ih+kyJLr4XcSgHR2zUkM8SWDhuixEJxfJ6CZGMHh1Ec3vPLoEA0IHU5oWzVqw8ulow==} 1198 | peerDependencies: 1199 | vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 1200 | peerDependenciesMeta: 1201 | vite: 1202 | optional: true 1203 | 1204 | which@2.0.2: 1205 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 1206 | engines: {node: '>= 8'} 1207 | hasBin: true 1208 | 1209 | wrap-ansi@7.0.0: 1210 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 1211 | engines: {node: '>=10'} 1212 | 1213 | wrap-ansi@8.1.0: 1214 | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} 1215 | engines: {node: '>=12'} 1216 | 1217 | yaml@2.6.1: 1218 | resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==} 1219 | engines: {node: '>= 14'} 1220 | hasBin: true 1221 | 1222 | zimmerframe@1.1.2: 1223 | resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==} 1224 | 1225 | snapshots: 1226 | 1227 | '@alloc/quick-lru@5.2.0': {} 1228 | 1229 | '@ampproject/remapping@2.3.0': 1230 | dependencies: 1231 | '@jridgewell/gen-mapping': 0.3.8 1232 | '@jridgewell/trace-mapping': 0.3.25 1233 | 1234 | '@esbuild/aix-ppc64@0.21.5': 1235 | optional: true 1236 | 1237 | '@esbuild/android-arm64@0.21.5': 1238 | optional: true 1239 | 1240 | '@esbuild/android-arm@0.21.5': 1241 | optional: true 1242 | 1243 | '@esbuild/android-x64@0.21.5': 1244 | optional: true 1245 | 1246 | '@esbuild/darwin-arm64@0.21.5': 1247 | optional: true 1248 | 1249 | '@esbuild/darwin-x64@0.21.5': 1250 | optional: true 1251 | 1252 | '@esbuild/freebsd-arm64@0.21.5': 1253 | optional: true 1254 | 1255 | '@esbuild/freebsd-x64@0.21.5': 1256 | optional: true 1257 | 1258 | '@esbuild/linux-arm64@0.21.5': 1259 | optional: true 1260 | 1261 | '@esbuild/linux-arm@0.21.5': 1262 | optional: true 1263 | 1264 | '@esbuild/linux-ia32@0.21.5': 1265 | optional: true 1266 | 1267 | '@esbuild/linux-loong64@0.21.5': 1268 | optional: true 1269 | 1270 | '@esbuild/linux-mips64el@0.21.5': 1271 | optional: true 1272 | 1273 | '@esbuild/linux-ppc64@0.21.5': 1274 | optional: true 1275 | 1276 | '@esbuild/linux-riscv64@0.21.5': 1277 | optional: true 1278 | 1279 | '@esbuild/linux-s390x@0.21.5': 1280 | optional: true 1281 | 1282 | '@esbuild/linux-x64@0.21.5': 1283 | optional: true 1284 | 1285 | '@esbuild/netbsd-x64@0.21.5': 1286 | optional: true 1287 | 1288 | '@esbuild/openbsd-x64@0.21.5': 1289 | optional: true 1290 | 1291 | '@esbuild/sunos-x64@0.21.5': 1292 | optional: true 1293 | 1294 | '@esbuild/win32-arm64@0.21.5': 1295 | optional: true 1296 | 1297 | '@esbuild/win32-ia32@0.21.5': 1298 | optional: true 1299 | 1300 | '@esbuild/win32-x64@0.21.5': 1301 | optional: true 1302 | 1303 | '@floating-ui/core@1.6.8': 1304 | dependencies: 1305 | '@floating-ui/utils': 0.2.8 1306 | 1307 | '@floating-ui/dom@1.6.12': 1308 | dependencies: 1309 | '@floating-ui/core': 1.6.8 1310 | '@floating-ui/utils': 0.2.8 1311 | 1312 | '@floating-ui/utils@0.2.8': {} 1313 | 1314 | '@isaacs/cliui@8.0.2': 1315 | dependencies: 1316 | string-width: 5.1.2 1317 | string-width-cjs: string-width@4.2.3 1318 | strip-ansi: 7.1.0 1319 | strip-ansi-cjs: strip-ansi@6.0.1 1320 | wrap-ansi: 8.1.0 1321 | wrap-ansi-cjs: wrap-ansi@7.0.0 1322 | 1323 | '@jridgewell/gen-mapping@0.3.8': 1324 | dependencies: 1325 | '@jridgewell/set-array': 1.2.1 1326 | '@jridgewell/sourcemap-codec': 1.5.0 1327 | '@jridgewell/trace-mapping': 0.3.25 1328 | 1329 | '@jridgewell/resolve-uri@3.1.2': {} 1330 | 1331 | '@jridgewell/set-array@1.2.1': {} 1332 | 1333 | '@jridgewell/sourcemap-codec@1.5.0': {} 1334 | 1335 | '@jridgewell/trace-mapping@0.3.25': 1336 | dependencies: 1337 | '@jridgewell/resolve-uri': 3.1.2 1338 | '@jridgewell/sourcemap-codec': 1.5.0 1339 | 1340 | '@nodelib/fs.scandir@2.1.5': 1341 | dependencies: 1342 | '@nodelib/fs.stat': 2.0.5 1343 | run-parallel: 1.2.0 1344 | 1345 | '@nodelib/fs.stat@2.0.5': {} 1346 | 1347 | '@nodelib/fs.walk@1.2.8': 1348 | dependencies: 1349 | '@nodelib/fs.scandir': 2.1.5 1350 | fastq: 1.18.0 1351 | 1352 | '@pkgjs/parseargs@0.11.0': 1353 | optional: true 1354 | 1355 | '@polka/url@1.0.0-next.28': {} 1356 | 1357 | '@popperjs/core@2.11.8': {} 1358 | 1359 | '@rollup/plugin-node-resolve@15.3.1(rollup@4.29.1)': 1360 | dependencies: 1361 | '@rollup/pluginutils': 5.1.4(rollup@4.29.1) 1362 | '@types/resolve': 1.20.2 1363 | deepmerge: 4.3.1 1364 | is-module: 1.0.0 1365 | resolve: 1.22.10 1366 | optionalDependencies: 1367 | rollup: 4.29.1 1368 | 1369 | '@rollup/pluginutils@5.1.4(rollup@4.29.1)': 1370 | dependencies: 1371 | '@types/estree': 1.0.6 1372 | estree-walker: 2.0.2 1373 | picomatch: 4.0.2 1374 | optionalDependencies: 1375 | rollup: 4.29.1 1376 | 1377 | '@rollup/rollup-android-arm-eabi@4.29.1': 1378 | optional: true 1379 | 1380 | '@rollup/rollup-android-arm64@4.29.1': 1381 | optional: true 1382 | 1383 | '@rollup/rollup-darwin-arm64@4.29.1': 1384 | optional: true 1385 | 1386 | '@rollup/rollup-darwin-x64@4.29.1': 1387 | optional: true 1388 | 1389 | '@rollup/rollup-freebsd-arm64@4.29.1': 1390 | optional: true 1391 | 1392 | '@rollup/rollup-freebsd-x64@4.29.1': 1393 | optional: true 1394 | 1395 | '@rollup/rollup-linux-arm-gnueabihf@4.29.1': 1396 | optional: true 1397 | 1398 | '@rollup/rollup-linux-arm-musleabihf@4.29.1': 1399 | optional: true 1400 | 1401 | '@rollup/rollup-linux-arm64-gnu@4.29.1': 1402 | optional: true 1403 | 1404 | '@rollup/rollup-linux-arm64-musl@4.29.1': 1405 | optional: true 1406 | 1407 | '@rollup/rollup-linux-loongarch64-gnu@4.29.1': 1408 | optional: true 1409 | 1410 | '@rollup/rollup-linux-powerpc64le-gnu@4.29.1': 1411 | optional: true 1412 | 1413 | '@rollup/rollup-linux-riscv64-gnu@4.29.1': 1414 | optional: true 1415 | 1416 | '@rollup/rollup-linux-s390x-gnu@4.29.1': 1417 | optional: true 1418 | 1419 | '@rollup/rollup-linux-x64-gnu@4.29.1': 1420 | optional: true 1421 | 1422 | '@rollup/rollup-linux-x64-musl@4.29.1': 1423 | optional: true 1424 | 1425 | '@rollup/rollup-win32-arm64-msvc@4.29.1': 1426 | optional: true 1427 | 1428 | '@rollup/rollup-win32-ia32-msvc@4.29.1': 1429 | optional: true 1430 | 1431 | '@rollup/rollup-win32-x64-msvc@4.29.1': 1432 | optional: true 1433 | 1434 | '@sveltejs/adapter-static@3.0.8(@sveltejs/kit@2.15.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.16.0)(vite@5.4.11))(svelte@5.16.0)(vite@5.4.11))': 1435 | dependencies: 1436 | '@sveltejs/kit': 2.15.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.16.0)(vite@5.4.11))(svelte@5.16.0)(vite@5.4.11) 1437 | 1438 | '@sveltejs/kit@2.15.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.16.0)(vite@5.4.11))(svelte@5.16.0)(vite@5.4.11)': 1439 | dependencies: 1440 | '@sveltejs/vite-plugin-svelte': 4.0.4(svelte@5.16.0)(vite@5.4.11) 1441 | '@types/cookie': 0.6.0 1442 | cookie: 0.6.0 1443 | devalue: 5.1.1 1444 | esm-env: 1.2.1 1445 | import-meta-resolve: 4.1.0 1446 | kleur: 4.1.5 1447 | magic-string: 0.30.17 1448 | mrmime: 2.0.0 1449 | sade: 1.8.1 1450 | set-cookie-parser: 2.7.1 1451 | sirv: 3.0.0 1452 | svelte: 5.16.0 1453 | tiny-glob: 0.2.9 1454 | vite: 5.4.11 1455 | 1456 | '@sveltejs/vite-plugin-svelte-inspector@3.0.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.16.0)(vite@5.4.11))(svelte@5.16.0)(vite@5.4.11)': 1457 | dependencies: 1458 | '@sveltejs/vite-plugin-svelte': 4.0.4(svelte@5.16.0)(vite@5.4.11) 1459 | debug: 4.4.0 1460 | svelte: 5.16.0 1461 | vite: 5.4.11 1462 | transitivePeerDependencies: 1463 | - supports-color 1464 | 1465 | '@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.16.0)(vite@5.4.11)': 1466 | dependencies: 1467 | '@sveltejs/vite-plugin-svelte-inspector': 3.0.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.16.0)(vite@5.4.11))(svelte@5.16.0)(vite@5.4.11) 1468 | debug: 4.4.0 1469 | deepmerge: 4.3.1 1470 | kleur: 4.1.5 1471 | magic-string: 0.30.17 1472 | svelte: 5.16.0 1473 | vite: 5.4.11 1474 | vitefu: 1.0.4(vite@5.4.11) 1475 | transitivePeerDependencies: 1476 | - supports-color 1477 | 1478 | '@tailwindcss/typography@0.5.15(tailwindcss@3.4.17)': 1479 | dependencies: 1480 | lodash.castarray: 4.4.0 1481 | lodash.isplainobject: 4.0.6 1482 | lodash.merge: 4.6.2 1483 | postcss-selector-parser: 6.0.10 1484 | tailwindcss: 3.4.17 1485 | 1486 | '@tauri-apps/api@2.1.1': {} 1487 | 1488 | '@tauri-apps/cli-darwin-arm64@2.1.0': 1489 | optional: true 1490 | 1491 | '@tauri-apps/cli-darwin-x64@2.1.0': 1492 | optional: true 1493 | 1494 | '@tauri-apps/cli-linux-arm-gnueabihf@2.1.0': 1495 | optional: true 1496 | 1497 | '@tauri-apps/cli-linux-arm64-gnu@2.1.0': 1498 | optional: true 1499 | 1500 | '@tauri-apps/cli-linux-arm64-musl@2.1.0': 1501 | optional: true 1502 | 1503 | '@tauri-apps/cli-linux-x64-gnu@2.1.0': 1504 | optional: true 1505 | 1506 | '@tauri-apps/cli-linux-x64-musl@2.1.0': 1507 | optional: true 1508 | 1509 | '@tauri-apps/cli-win32-arm64-msvc@2.1.0': 1510 | optional: true 1511 | 1512 | '@tauri-apps/cli-win32-ia32-msvc@2.1.0': 1513 | optional: true 1514 | 1515 | '@tauri-apps/cli-win32-x64-msvc@2.1.0': 1516 | optional: true 1517 | 1518 | '@tauri-apps/cli@2.1.0': 1519 | optionalDependencies: 1520 | '@tauri-apps/cli-darwin-arm64': 2.1.0 1521 | '@tauri-apps/cli-darwin-x64': 2.1.0 1522 | '@tauri-apps/cli-linux-arm-gnueabihf': 2.1.0 1523 | '@tauri-apps/cli-linux-arm64-gnu': 2.1.0 1524 | '@tauri-apps/cli-linux-arm64-musl': 2.1.0 1525 | '@tauri-apps/cli-linux-x64-gnu': 2.1.0 1526 | '@tauri-apps/cli-linux-x64-musl': 2.1.0 1527 | '@tauri-apps/cli-win32-arm64-msvc': 2.1.0 1528 | '@tauri-apps/cli-win32-ia32-msvc': 2.1.0 1529 | '@tauri-apps/cli-win32-x64-msvc': 2.1.0 1530 | 1531 | '@tauri-apps/plugin-dialog@2.2.0': 1532 | dependencies: 1533 | '@tauri-apps/api': 2.1.1 1534 | 1535 | '@tauri-apps/plugin-log@2.2.0': 1536 | dependencies: 1537 | '@tauri-apps/api': 2.1.1 1538 | 1539 | '@tauri-apps/plugin-positioner@2.2.0': 1540 | dependencies: 1541 | '@tauri-apps/api': 2.1.1 1542 | 1543 | '@tauri-apps/plugin-process@2.2.0': 1544 | dependencies: 1545 | '@tauri-apps/api': 2.1.1 1546 | 1547 | '@tauri-apps/plugin-shell@2.2.0': 1548 | dependencies: 1549 | '@tauri-apps/api': 2.1.1 1550 | 1551 | '@tauri-apps/plugin-updater@2.3.0': 1552 | dependencies: 1553 | '@tauri-apps/api': 2.1.1 1554 | 1555 | '@types/cookie@0.6.0': {} 1556 | 1557 | '@types/estree@1.0.6': {} 1558 | 1559 | '@types/resolve@1.20.2': {} 1560 | 1561 | '@yr/monotone-cubic-spline@1.0.3': {} 1562 | 1563 | acorn-typescript@1.4.13(acorn@8.14.0): 1564 | dependencies: 1565 | acorn: 8.14.0 1566 | 1567 | acorn@8.14.0: {} 1568 | 1569 | ansi-regex@5.0.1: {} 1570 | 1571 | ansi-regex@6.1.0: {} 1572 | 1573 | ansi-styles@4.3.0: 1574 | dependencies: 1575 | color-convert: 2.0.1 1576 | 1577 | ansi-styles@6.2.1: {} 1578 | 1579 | any-promise@1.3.0: {} 1580 | 1581 | anymatch@3.1.3: 1582 | dependencies: 1583 | normalize-path: 3.0.0 1584 | picomatch: 2.3.1 1585 | 1586 | apexcharts@3.54.1: 1587 | dependencies: 1588 | '@yr/monotone-cubic-spline': 1.0.3 1589 | svg.draggable.js: 2.2.2 1590 | svg.easing.js: 2.0.0 1591 | svg.filter.js: 2.0.2 1592 | svg.pathmorphing.js: 0.1.3 1593 | svg.resize.js: 1.4.3 1594 | svg.select.js: 3.0.1 1595 | 1596 | arg@5.0.2: {} 1597 | 1598 | aria-query@5.3.2: {} 1599 | 1600 | autoprefixer@10.4.20(postcss@8.4.49): 1601 | dependencies: 1602 | browserslist: 4.24.3 1603 | caniuse-lite: 1.0.30001690 1604 | fraction.js: 4.3.7 1605 | normalize-range: 0.1.2 1606 | picocolors: 1.1.1 1607 | postcss: 8.4.49 1608 | postcss-value-parser: 4.2.0 1609 | 1610 | axobject-query@4.1.0: {} 1611 | 1612 | balanced-match@1.0.2: {} 1613 | 1614 | binary-extensions@2.3.0: {} 1615 | 1616 | brace-expansion@2.0.1: 1617 | dependencies: 1618 | balanced-match: 1.0.2 1619 | 1620 | braces@3.0.3: 1621 | dependencies: 1622 | fill-range: 7.1.1 1623 | 1624 | browserslist@4.24.3: 1625 | dependencies: 1626 | caniuse-lite: 1.0.30001690 1627 | electron-to-chromium: 1.5.76 1628 | node-releases: 2.0.19 1629 | update-browserslist-db: 1.1.1(browserslist@4.24.3) 1630 | 1631 | camelcase-css@2.0.1: {} 1632 | 1633 | caniuse-lite@1.0.30001690: {} 1634 | 1635 | chokidar@3.6.0: 1636 | dependencies: 1637 | anymatch: 3.1.3 1638 | braces: 3.0.3 1639 | glob-parent: 5.1.2 1640 | is-binary-path: 2.1.0 1641 | is-glob: 4.0.3 1642 | normalize-path: 3.0.0 1643 | readdirp: 3.6.0 1644 | optionalDependencies: 1645 | fsevents: 2.3.3 1646 | 1647 | chokidar@4.0.3: 1648 | dependencies: 1649 | readdirp: 4.0.2 1650 | 1651 | clsx@2.1.1: {} 1652 | 1653 | color-convert@2.0.1: 1654 | dependencies: 1655 | color-name: 1.1.4 1656 | 1657 | color-name@1.1.4: {} 1658 | 1659 | commander@4.1.1: {} 1660 | 1661 | cookie@0.6.0: {} 1662 | 1663 | cross-spawn@7.0.6: 1664 | dependencies: 1665 | path-key: 3.1.1 1666 | shebang-command: 2.0.0 1667 | which: 2.0.2 1668 | 1669 | cssesc@3.0.0: {} 1670 | 1671 | debug@4.4.0: 1672 | dependencies: 1673 | ms: 2.1.3 1674 | 1675 | deepmerge@4.3.1: {} 1676 | 1677 | devalue@5.1.1: {} 1678 | 1679 | didyoumean@1.2.2: {} 1680 | 1681 | dlv@1.1.3: {} 1682 | 1683 | eastasianwidth@0.2.0: {} 1684 | 1685 | electron-to-chromium@1.5.76: {} 1686 | 1687 | emoji-regex@8.0.0: {} 1688 | 1689 | emoji-regex@9.2.2: {} 1690 | 1691 | esbuild@0.21.5: 1692 | optionalDependencies: 1693 | '@esbuild/aix-ppc64': 0.21.5 1694 | '@esbuild/android-arm': 0.21.5 1695 | '@esbuild/android-arm64': 0.21.5 1696 | '@esbuild/android-x64': 0.21.5 1697 | '@esbuild/darwin-arm64': 0.21.5 1698 | '@esbuild/darwin-x64': 0.21.5 1699 | '@esbuild/freebsd-arm64': 0.21.5 1700 | '@esbuild/freebsd-x64': 0.21.5 1701 | '@esbuild/linux-arm': 0.21.5 1702 | '@esbuild/linux-arm64': 0.21.5 1703 | '@esbuild/linux-ia32': 0.21.5 1704 | '@esbuild/linux-loong64': 0.21.5 1705 | '@esbuild/linux-mips64el': 0.21.5 1706 | '@esbuild/linux-ppc64': 0.21.5 1707 | '@esbuild/linux-riscv64': 0.21.5 1708 | '@esbuild/linux-s390x': 0.21.5 1709 | '@esbuild/linux-x64': 0.21.5 1710 | '@esbuild/netbsd-x64': 0.21.5 1711 | '@esbuild/openbsd-x64': 0.21.5 1712 | '@esbuild/sunos-x64': 0.21.5 1713 | '@esbuild/win32-arm64': 0.21.5 1714 | '@esbuild/win32-ia32': 0.21.5 1715 | '@esbuild/win32-x64': 0.21.5 1716 | 1717 | escalade@3.2.0: {} 1718 | 1719 | esm-env@1.2.1: {} 1720 | 1721 | esrap@1.3.2: 1722 | dependencies: 1723 | '@jridgewell/sourcemap-codec': 1.5.0 1724 | 1725 | estree-walker@2.0.2: {} 1726 | 1727 | fast-glob@3.3.2: 1728 | dependencies: 1729 | '@nodelib/fs.stat': 2.0.5 1730 | '@nodelib/fs.walk': 1.2.8 1731 | glob-parent: 5.1.2 1732 | merge2: 1.4.1 1733 | micromatch: 4.0.8 1734 | 1735 | fastq@1.18.0: 1736 | dependencies: 1737 | reusify: 1.0.4 1738 | 1739 | fdir@6.4.2(picomatch@4.0.2): 1740 | optionalDependencies: 1741 | picomatch: 4.0.2 1742 | 1743 | fill-range@7.1.1: 1744 | dependencies: 1745 | to-regex-range: 5.0.1 1746 | 1747 | flowbite-datepicker@1.3.1(rollup@4.29.1): 1748 | dependencies: 1749 | '@rollup/plugin-node-resolve': 15.3.1(rollup@4.29.1) 1750 | flowbite: 2.5.2(rollup@4.29.1) 1751 | transitivePeerDependencies: 1752 | - rollup 1753 | 1754 | flowbite-svelte-icons@2.0.2(svelte@5.16.0)(tailwind-merge@2.6.0)(tailwindcss@3.4.17): 1755 | dependencies: 1756 | svelte: 5.16.0 1757 | tailwind-merge: 2.6.0 1758 | tailwindcss: 3.4.17 1759 | 1760 | flowbite-svelte@0.47.4(rollup@4.29.1)(svelte@5.16.0): 1761 | dependencies: 1762 | '@floating-ui/dom': 1.6.12 1763 | apexcharts: 3.54.1 1764 | flowbite: 2.5.2(rollup@4.29.1) 1765 | svelte: 5.16.0 1766 | tailwind-merge: 2.6.0 1767 | transitivePeerDependencies: 1768 | - rollup 1769 | 1770 | flowbite@2.5.2(rollup@4.29.1): 1771 | dependencies: 1772 | '@popperjs/core': 2.11.8 1773 | flowbite-datepicker: 1.3.1(rollup@4.29.1) 1774 | mini-svg-data-uri: 1.4.4 1775 | transitivePeerDependencies: 1776 | - rollup 1777 | 1778 | foreground-child@3.3.0: 1779 | dependencies: 1780 | cross-spawn: 7.0.6 1781 | signal-exit: 4.1.0 1782 | 1783 | fraction.js@4.3.7: {} 1784 | 1785 | fsevents@2.3.3: 1786 | optional: true 1787 | 1788 | function-bind@1.1.2: {} 1789 | 1790 | glob-parent@5.1.2: 1791 | dependencies: 1792 | is-glob: 4.0.3 1793 | 1794 | glob-parent@6.0.2: 1795 | dependencies: 1796 | is-glob: 4.0.3 1797 | 1798 | glob@10.4.5: 1799 | dependencies: 1800 | foreground-child: 3.3.0 1801 | jackspeak: 3.4.3 1802 | minimatch: 9.0.5 1803 | minipass: 7.1.2 1804 | package-json-from-dist: 1.0.1 1805 | path-scurry: 1.11.1 1806 | 1807 | globalyzer@0.1.0: {} 1808 | 1809 | globrex@0.1.2: {} 1810 | 1811 | hasown@2.0.2: 1812 | dependencies: 1813 | function-bind: 1.1.2 1814 | 1815 | import-meta-resolve@4.1.0: {} 1816 | 1817 | is-binary-path@2.1.0: 1818 | dependencies: 1819 | binary-extensions: 2.3.0 1820 | 1821 | is-core-module@2.16.1: 1822 | dependencies: 1823 | hasown: 2.0.2 1824 | 1825 | is-extglob@2.1.1: {} 1826 | 1827 | is-fullwidth-code-point@3.0.0: {} 1828 | 1829 | is-glob@4.0.3: 1830 | dependencies: 1831 | is-extglob: 2.1.1 1832 | 1833 | is-module@1.0.0: {} 1834 | 1835 | is-number@7.0.0: {} 1836 | 1837 | is-reference@3.0.3: 1838 | dependencies: 1839 | '@types/estree': 1.0.6 1840 | 1841 | isexe@2.0.0: {} 1842 | 1843 | jackspeak@3.4.3: 1844 | dependencies: 1845 | '@isaacs/cliui': 8.0.2 1846 | optionalDependencies: 1847 | '@pkgjs/parseargs': 0.11.0 1848 | 1849 | jiti@1.21.7: {} 1850 | 1851 | kleur@4.1.5: {} 1852 | 1853 | lilconfig@3.1.3: {} 1854 | 1855 | lines-and-columns@1.2.4: {} 1856 | 1857 | locate-character@3.0.0: {} 1858 | 1859 | lodash.castarray@4.4.0: {} 1860 | 1861 | lodash.isplainobject@4.0.6: {} 1862 | 1863 | lodash.merge@4.6.2: {} 1864 | 1865 | lru-cache@10.4.3: {} 1866 | 1867 | magic-string@0.30.17: 1868 | dependencies: 1869 | '@jridgewell/sourcemap-codec': 1.5.0 1870 | 1871 | merge2@1.4.1: {} 1872 | 1873 | micromatch@4.0.8: 1874 | dependencies: 1875 | braces: 3.0.3 1876 | picomatch: 2.3.1 1877 | 1878 | mini-svg-data-uri@1.4.4: {} 1879 | 1880 | minimatch@9.0.5: 1881 | dependencies: 1882 | brace-expansion: 2.0.1 1883 | 1884 | minipass@7.1.2: {} 1885 | 1886 | mri@1.2.0: {} 1887 | 1888 | mrmime@2.0.0: {} 1889 | 1890 | ms@2.1.3: {} 1891 | 1892 | mz@2.7.0: 1893 | dependencies: 1894 | any-promise: 1.3.0 1895 | object-assign: 4.1.1 1896 | thenify-all: 1.6.0 1897 | 1898 | nanoid@3.3.8: {} 1899 | 1900 | node-releases@2.0.19: {} 1901 | 1902 | normalize-path@3.0.0: {} 1903 | 1904 | normalize-range@0.1.2: {} 1905 | 1906 | object-assign@4.1.1: {} 1907 | 1908 | object-hash@3.0.0: {} 1909 | 1910 | package-json-from-dist@1.0.1: {} 1911 | 1912 | path-key@3.1.1: {} 1913 | 1914 | path-parse@1.0.7: {} 1915 | 1916 | path-scurry@1.11.1: 1917 | dependencies: 1918 | lru-cache: 10.4.3 1919 | minipass: 7.1.2 1920 | 1921 | picocolors@1.1.1: {} 1922 | 1923 | picomatch@2.3.1: {} 1924 | 1925 | picomatch@4.0.2: {} 1926 | 1927 | pify@2.3.0: {} 1928 | 1929 | pirates@4.0.6: {} 1930 | 1931 | postcss-import@15.1.0(postcss@8.4.49): 1932 | dependencies: 1933 | postcss: 8.4.49 1934 | postcss-value-parser: 4.2.0 1935 | read-cache: 1.0.0 1936 | resolve: 1.22.10 1937 | 1938 | postcss-js@4.0.1(postcss@8.4.49): 1939 | dependencies: 1940 | camelcase-css: 2.0.1 1941 | postcss: 8.4.49 1942 | 1943 | postcss-load-config@4.0.2(postcss@8.4.49): 1944 | dependencies: 1945 | lilconfig: 3.1.3 1946 | yaml: 2.6.1 1947 | optionalDependencies: 1948 | postcss: 8.4.49 1949 | 1950 | postcss-nested@6.2.0(postcss@8.4.49): 1951 | dependencies: 1952 | postcss: 8.4.49 1953 | postcss-selector-parser: 6.1.2 1954 | 1955 | postcss-selector-parser@6.0.10: 1956 | dependencies: 1957 | cssesc: 3.0.0 1958 | util-deprecate: 1.0.2 1959 | 1960 | postcss-selector-parser@6.1.2: 1961 | dependencies: 1962 | cssesc: 3.0.0 1963 | util-deprecate: 1.0.2 1964 | 1965 | postcss-value-parser@4.2.0: {} 1966 | 1967 | postcss@8.4.49: 1968 | dependencies: 1969 | nanoid: 3.3.8 1970 | picocolors: 1.1.1 1971 | source-map-js: 1.2.1 1972 | 1973 | queue-microtask@1.2.3: {} 1974 | 1975 | read-cache@1.0.0: 1976 | dependencies: 1977 | pify: 2.3.0 1978 | 1979 | readdirp@3.6.0: 1980 | dependencies: 1981 | picomatch: 2.3.1 1982 | 1983 | readdirp@4.0.2: {} 1984 | 1985 | resolve@1.22.10: 1986 | dependencies: 1987 | is-core-module: 2.16.1 1988 | path-parse: 1.0.7 1989 | supports-preserve-symlinks-flag: 1.0.0 1990 | 1991 | reusify@1.0.4: {} 1992 | 1993 | rollup@4.29.1: 1994 | dependencies: 1995 | '@types/estree': 1.0.6 1996 | optionalDependencies: 1997 | '@rollup/rollup-android-arm-eabi': 4.29.1 1998 | '@rollup/rollup-android-arm64': 4.29.1 1999 | '@rollup/rollup-darwin-arm64': 4.29.1 2000 | '@rollup/rollup-darwin-x64': 4.29.1 2001 | '@rollup/rollup-freebsd-arm64': 4.29.1 2002 | '@rollup/rollup-freebsd-x64': 4.29.1 2003 | '@rollup/rollup-linux-arm-gnueabihf': 4.29.1 2004 | '@rollup/rollup-linux-arm-musleabihf': 4.29.1 2005 | '@rollup/rollup-linux-arm64-gnu': 4.29.1 2006 | '@rollup/rollup-linux-arm64-musl': 4.29.1 2007 | '@rollup/rollup-linux-loongarch64-gnu': 4.29.1 2008 | '@rollup/rollup-linux-powerpc64le-gnu': 4.29.1 2009 | '@rollup/rollup-linux-riscv64-gnu': 4.29.1 2010 | '@rollup/rollup-linux-s390x-gnu': 4.29.1 2011 | '@rollup/rollup-linux-x64-gnu': 4.29.1 2012 | '@rollup/rollup-linux-x64-musl': 4.29.1 2013 | '@rollup/rollup-win32-arm64-msvc': 4.29.1 2014 | '@rollup/rollup-win32-ia32-msvc': 4.29.1 2015 | '@rollup/rollup-win32-x64-msvc': 4.29.1 2016 | fsevents: 2.3.3 2017 | 2018 | run-parallel@1.2.0: 2019 | dependencies: 2020 | queue-microtask: 1.2.3 2021 | 2022 | sade@1.8.1: 2023 | dependencies: 2024 | mri: 1.2.0 2025 | 2026 | set-cookie-parser@2.7.1: {} 2027 | 2028 | shebang-command@2.0.0: 2029 | dependencies: 2030 | shebang-regex: 3.0.0 2031 | 2032 | shebang-regex@3.0.0: {} 2033 | 2034 | signal-exit@4.1.0: {} 2035 | 2036 | sirv@3.0.0: 2037 | dependencies: 2038 | '@polka/url': 1.0.0-next.28 2039 | mrmime: 2.0.0 2040 | totalist: 3.0.1 2041 | 2042 | source-map-js@1.2.1: {} 2043 | 2044 | string-width@4.2.3: 2045 | dependencies: 2046 | emoji-regex: 8.0.0 2047 | is-fullwidth-code-point: 3.0.0 2048 | strip-ansi: 6.0.1 2049 | 2050 | string-width@5.1.2: 2051 | dependencies: 2052 | eastasianwidth: 0.2.0 2053 | emoji-regex: 9.2.2 2054 | strip-ansi: 7.1.0 2055 | 2056 | strip-ansi@6.0.1: 2057 | dependencies: 2058 | ansi-regex: 5.0.1 2059 | 2060 | strip-ansi@7.1.0: 2061 | dependencies: 2062 | ansi-regex: 6.1.0 2063 | 2064 | sucrase@3.35.0: 2065 | dependencies: 2066 | '@jridgewell/gen-mapping': 0.3.8 2067 | commander: 4.1.1 2068 | glob: 10.4.5 2069 | lines-and-columns: 1.2.4 2070 | mz: 2.7.0 2071 | pirates: 4.0.6 2072 | ts-interface-checker: 0.1.13 2073 | 2074 | supports-preserve-symlinks-flag@1.0.0: {} 2075 | 2076 | svelte-check@4.1.1(picomatch@4.0.2)(svelte@5.16.0)(typescript@5.7.2): 2077 | dependencies: 2078 | '@jridgewell/trace-mapping': 0.3.25 2079 | chokidar: 4.0.3 2080 | fdir: 6.4.2(picomatch@4.0.2) 2081 | picocolors: 1.1.1 2082 | sade: 1.8.1 2083 | svelte: 5.16.0 2084 | typescript: 5.7.2 2085 | transitivePeerDependencies: 2086 | - picomatch 2087 | 2088 | svelte@5.16.0: 2089 | dependencies: 2090 | '@ampproject/remapping': 2.3.0 2091 | '@jridgewell/sourcemap-codec': 1.5.0 2092 | '@types/estree': 1.0.6 2093 | acorn: 8.14.0 2094 | acorn-typescript: 1.4.13(acorn@8.14.0) 2095 | aria-query: 5.3.2 2096 | axobject-query: 4.1.0 2097 | clsx: 2.1.1 2098 | esm-env: 1.2.1 2099 | esrap: 1.3.2 2100 | is-reference: 3.0.3 2101 | locate-character: 3.0.0 2102 | magic-string: 0.30.17 2103 | zimmerframe: 1.1.2 2104 | 2105 | svg.draggable.js@2.2.2: 2106 | dependencies: 2107 | svg.js: 2.7.1 2108 | 2109 | svg.easing.js@2.0.0: 2110 | dependencies: 2111 | svg.js: 2.7.1 2112 | 2113 | svg.filter.js@2.0.2: 2114 | dependencies: 2115 | svg.js: 2.7.1 2116 | 2117 | svg.js@2.7.1: {} 2118 | 2119 | svg.pathmorphing.js@0.1.3: 2120 | dependencies: 2121 | svg.js: 2.7.1 2122 | 2123 | svg.resize.js@1.4.3: 2124 | dependencies: 2125 | svg.js: 2.7.1 2126 | svg.select.js: 2.1.2 2127 | 2128 | svg.select.js@2.1.2: 2129 | dependencies: 2130 | svg.js: 2.7.1 2131 | 2132 | svg.select.js@3.0.1: 2133 | dependencies: 2134 | svg.js: 2.7.1 2135 | 2136 | tailwind-merge@2.6.0: {} 2137 | 2138 | tailwindcss@3.4.17: 2139 | dependencies: 2140 | '@alloc/quick-lru': 5.2.0 2141 | arg: 5.0.2 2142 | chokidar: 3.6.0 2143 | didyoumean: 1.2.2 2144 | dlv: 1.1.3 2145 | fast-glob: 3.3.2 2146 | glob-parent: 6.0.2 2147 | is-glob: 4.0.3 2148 | jiti: 1.21.7 2149 | lilconfig: 3.1.3 2150 | micromatch: 4.0.8 2151 | normalize-path: 3.0.0 2152 | object-hash: 3.0.0 2153 | picocolors: 1.1.1 2154 | postcss: 8.4.49 2155 | postcss-import: 15.1.0(postcss@8.4.49) 2156 | postcss-js: 4.0.1(postcss@8.4.49) 2157 | postcss-load-config: 4.0.2(postcss@8.4.49) 2158 | postcss-nested: 6.2.0(postcss@8.4.49) 2159 | postcss-selector-parser: 6.1.2 2160 | resolve: 1.22.10 2161 | sucrase: 3.35.0 2162 | transitivePeerDependencies: 2163 | - ts-node 2164 | 2165 | thenify-all@1.6.0: 2166 | dependencies: 2167 | thenify: 3.3.1 2168 | 2169 | thenify@3.3.1: 2170 | dependencies: 2171 | any-promise: 1.3.0 2172 | 2173 | tiny-glob@0.2.9: 2174 | dependencies: 2175 | globalyzer: 0.1.0 2176 | globrex: 0.1.2 2177 | 2178 | to-regex-range@5.0.1: 2179 | dependencies: 2180 | is-number: 7.0.0 2181 | 2182 | totalist@3.0.1: {} 2183 | 2184 | ts-interface-checker@0.1.13: {} 2185 | 2186 | tslib@2.8.1: {} 2187 | 2188 | typescript@5.7.2: {} 2189 | 2190 | update-browserslist-db@1.1.1(browserslist@4.24.3): 2191 | dependencies: 2192 | browserslist: 4.24.3 2193 | escalade: 3.2.0 2194 | picocolors: 1.1.1 2195 | 2196 | util-deprecate@1.0.2: {} 2197 | 2198 | vite@5.4.11: 2199 | dependencies: 2200 | esbuild: 0.21.5 2201 | postcss: 8.4.49 2202 | rollup: 4.29.1 2203 | optionalDependencies: 2204 | fsevents: 2.3.3 2205 | 2206 | vitefu@1.0.4(vite@5.4.11): 2207 | optionalDependencies: 2208 | vite: 5.4.11 2209 | 2210 | which@2.0.2: 2211 | dependencies: 2212 | isexe: 2.0.0 2213 | 2214 | wrap-ansi@7.0.0: 2215 | dependencies: 2216 | ansi-styles: 4.3.0 2217 | string-width: 4.2.3 2218 | strip-ansi: 6.0.1 2219 | 2220 | wrap-ansi@8.1.0: 2221 | dependencies: 2222 | ansi-styles: 6.2.1 2223 | string-width: 5.1.2 2224 | strip-ansi: 7.1.0 2225 | 2226 | yaml@2.6.1: {} 2227 | 2228 | zimmerframe@1.1.2: {} 2229 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {} 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /public/tauri.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/yew.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/public/yew.png -------------------------------------------------------------------------------- /screenshot.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/screenshot.PNG -------------------------------------------------------------------------------- /src-tauri/.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | -------------------------------------------------------------------------------- /src-tauri/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pavo" 3 | version = "0.0.10" 4 | description = "wallpaper" 5 | authors = ["you"] 6 | license = "" 7 | repository = "" 8 | edition = "2021" 9 | rust-version = "1.57" 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [build-dependencies] 14 | tauri-build = { version = "2", features = [] } 15 | 16 | [dependencies] 17 | serde_json = "1.0" 18 | serde = { version = "1.0", features = ["derive"] } 19 | serde-wasm-bindgen = "0.4" 20 | tauri = { version = "2.1.1", features = [ "image-ico", "image-png", "tray-icon"] } 21 | reqwest = { version = "0.11", features = ["json", "socks", "stream"] } 22 | tokio = { version = "1.25.0", features = ["full", "time"] } 23 | toml = "0.7.1" 24 | indicatif = "0.17.3" 25 | futures-util = "0.3.25" 26 | wallpaper = { version = "3.2.0", features = ["from_url"] } 27 | chrono = { version = "0.4.23"} 28 | rand = { version = "*"} 29 | once_cell = "1.17.0" 30 | dirs = "5.0.1" 31 | log = "0.4" 32 | tauri-plugin-process = "2" 33 | tauri-plugin-dialog = "2" 34 | tauri-plugin-log = "2" 35 | tauri-plugin-shell = "2" 36 | tauri-plugin-fs = "2" 37 | showfile = "0.1.1" 38 | 39 | [features] 40 | # by default Tauri runs in production mode 41 | # when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL 42 | default = ["custom-protocol"] 43 | # this feature is used used for production builds where `devPath` points to the filesystem 44 | # DO NOT remove this 45 | custom-protocol = ["tauri/custom-protocol"] 46 | 47 | [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] 48 | tauri-plugin-single-instance = "2" 49 | tauri-plugin-updater = "2" 50 | -------------------------------------------------------------------------------- /src-tauri/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | tauri_build::build() 3 | } 4 | -------------------------------------------------------------------------------- /src-tauri/capabilities/desktop.json: -------------------------------------------------------------------------------- 1 | { 2 | "identifier": "desktop-capability", 3 | "platforms": [ 4 | "macOS", 5 | "windows", 6 | "linux" 7 | ], 8 | "permissions": [ 9 | "updater:default", 10 | "updater:default", 11 | "process:default", 12 | "updater:allow-install", 13 | "updater:allow-check", 14 | "updater:allow-download", 15 | "updater:allow-download-and-install", 16 | "dialog:default" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /src-tauri/capabilities/migrated.json: -------------------------------------------------------------------------------- 1 | { 2 | "identifier": "migrated", 3 | "description": "permissions that were migrated from v1", 4 | "local": true, 5 | "windows": [ 6 | "main" 7 | ], 8 | "permissions": [ 9 | "core:default", 10 | "fs:allow-read-file", 11 | "shell:allow-open", 12 | "shell:default", 13 | "fs:default", 14 | "process:default", 15 | "updater:allow-install", 16 | "updater:allow-check", 17 | "updater:allow-download", 18 | "updater:allow-download-and-install", 19 | "dialog:default" 20 | ] 21 | } -------------------------------------------------------------------------------- /src-tauri/gen/schemas/capabilities.json: -------------------------------------------------------------------------------- 1 | {"desktop-capability":{"identifier":"desktop-capability","description":"","local":true,"permissions":["updater:default","updater:default","process:default","updater:allow-install","updater:allow-check","updater:allow-download","updater:allow-download-and-install","dialog:default"],"platforms":["macOS","windows","linux"]},"migrated":{"identifier":"migrated","description":"permissions that were migrated from v1","local":true,"windows":["main"],"permissions":["core:default","fs:allow-read-file","shell:allow-open","shell:default","fs:default","process:default","updater:allow-install","updater:allow-check","updater:allow-download","updater:allow-download-and-install","dialog:default"]}} -------------------------------------------------------------------------------- /src-tauri/icons/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/128x128.png -------------------------------------------------------------------------------- /src-tauri/icons/128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/128x128@2x.png -------------------------------------------------------------------------------- /src-tauri/icons/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/32x32.png -------------------------------------------------------------------------------- /src-tauri/icons/Square107x107Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/Square107x107Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square142x142Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/Square142x142Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square150x150Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/Square150x150Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square284x284Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/Square284x284Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square30x30Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/Square30x30Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square310x310Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/Square310x310Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square44x44Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/Square44x44Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square71x71Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/Square71x71Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/Square89x89Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/Square89x89Logo.png -------------------------------------------------------------------------------- /src-tauri/icons/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/StoreLogo.png -------------------------------------------------------------------------------- /src-tauri/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/icon.icns -------------------------------------------------------------------------------- /src-tauri/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/icon.ico -------------------------------------------------------------------------------- /src-tauri/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/icon.png -------------------------------------------------------------------------------- /src-tauri/icons/tray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/tray.png -------------------------------------------------------------------------------- /src-tauri/icons/win-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/src-tauri/icons/win-icon.png -------------------------------------------------------------------------------- /src-tauri/rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width = 100 2 | hard_tabs = false 3 | tab_spaces = 2 4 | newline_style = "Auto" 5 | use_small_heuristics = "Default" 6 | reorder_imports = true 7 | reorder_modules = true 8 | remove_nested_parens = true 9 | edition = "2018" 10 | merge_derives = true 11 | use_try_shorthand = false 12 | use_field_init_shorthand = false 13 | force_explicit_abi = true 14 | imports_granularity = "Crate" 15 | -------------------------------------------------------------------------------- /src-tauri/src/background.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | use tokio::{ 3 | sync::{mpsc, Mutex}, 4 | time, 5 | }; 6 | 7 | use crate::{config, scheduler, services::AsyncProcessMessage, shuffle_thread}; 8 | 9 | const BING_EXPIRE_TIME: u64 = 60 * 60 * 12; 10 | 11 | pub struct Background {} 12 | 13 | impl Background { 14 | pub async fn new(receiver: Arc>>) -> Self { 15 | let mut scheduler = scheduler::Scheduler::new(); 16 | scheduler.setup_list().await; 17 | let mut shuffle_thread = shuffle_thread::ShuffleThread::new(); 18 | let mut scheduler_clone = scheduler.clone(); 19 | 20 | let cfg = config::PavoConfig::get_config(); 21 | 22 | if cfg.auto_shuffle { 23 | shuffle_thread 24 | .start_shuffle(Arc::new(Mutex::new(scheduler.clone()))) 25 | .await; 26 | } 27 | 28 | tauri::async_runtime::spawn(async move { 29 | loop { 30 | let message = receiver.lock().await.recv().await; 31 | 32 | if let Some(message) = message { 33 | println!("output: {:?}", message); 34 | 35 | match message { 36 | AsyncProcessMessage::StartShuffle => { 37 | println!("init output start 2 {:?}", message); 38 | shuffle_thread 39 | .start_shuffle(Arc::new(Mutex::new(scheduler.clone()))) 40 | .await; 41 | } 42 | AsyncProcessMessage::StopShuffle => { 43 | println!("init output stop 2 {:?}", message); 44 | shuffle_thread.stop_shuffle(); 45 | } 46 | AsyncProcessMessage::PreviousPhoto => { 47 | println!("PreviousPhoto {:?}", message); 48 | scheduler.previous_photo().await; 49 | } 50 | AsyncProcessMessage::NextPhoto => { 51 | println!("NextPhoto {:?}", message); 52 | scheduler.next_photo().await; 53 | } 54 | }; 55 | }; 56 | } 57 | }); 58 | 59 | let mut interval = time::interval(time::Duration::from_secs(BING_EXPIRE_TIME)); 60 | 61 | tauri::async_runtime::spawn(async move { 62 | loop { 63 | interval.tick().await; 64 | scheduler_clone.setup_list().await; 65 | log::info!("A Bright New Day!"); 66 | } 67 | }); 68 | 69 | Self {} 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src-tauri/src/cmd.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | 3 | use crate::scheduler; 4 | use crate::services::{bing, AsyncProcessMessage, PhotoService}; 5 | use crate::{config, services}; 6 | 7 | use tokio::sync::{mpsc, Mutex}; 8 | use showfile; 9 | 10 | pub struct AsyncProcInputTx { 11 | pub sender: Mutex>, 12 | } 13 | 14 | #[tauri::command] 15 | pub async fn set_as_desktop(url: &str, service: PhotoService) -> Result { 16 | println!("set as {:?}", url); 17 | 18 | match service { 19 | PhotoService::Bing => Ok(bing::Wallpaper::set_wallpaper(url).await.unwrap()), 20 | } 21 | } 22 | 23 | #[tauri::command] 24 | pub async fn download(url: &str, service: PhotoService) -> Result { 25 | match service { 26 | PhotoService::Bing => Ok(bing::Wallpaper::save_wallpaper(url, None).await.unwrap()), 27 | } 28 | } 29 | 30 | #[tauri::command] 31 | pub async fn get_bing_wallpaper_list() -> Vec { 32 | let mut scheduler = scheduler::SCHEDULER.lock().await; 33 | let res = scheduler.batch_fetch().await.unwrap(); 34 | 35 | res 36 | } 37 | 38 | #[tauri::command] 39 | pub async fn get_config() -> serde_json::Value { 40 | let pavo_config = config::PavoConfig::get_config(); 41 | 42 | serde_json::to_value(pavo_config).unwrap() 43 | } 44 | 45 | #[tauri::command] 46 | #[allow(unused)] 47 | pub async fn set_auto_shuffle( 48 | shuffle: bool, 49 | state: tauri::State<'_, AsyncProcInputTx>, 50 | ) -> Result<(), ()> { 51 | let pavo_config = config::PavoConfig::get_config(); 52 | 53 | pavo_config.set_auto_shuffle(shuffle); 54 | 55 | let async_proc_input_tx = state.sender.lock().await; 56 | 57 | if shuffle { 58 | async_proc_input_tx 59 | .send(AsyncProcessMessage::StartShuffle) 60 | .await 61 | .map_err(|e| e.to_string()); 62 | } else { 63 | async_proc_input_tx 64 | .send(AsyncProcessMessage::StopShuffle) 65 | .await 66 | .map_err(|e| e.to_string()); 67 | } 68 | 69 | Ok(()) 70 | } 71 | 72 | #[tauri::command] 73 | pub async fn set_interval(interval: u64) { 74 | let pavo_config = config::PavoConfig::get_config(); 75 | 76 | println!("{:?}", interval); 77 | 78 | pavo_config.set_interval(interval); 79 | } 80 | 81 | #[tauri::command] 82 | pub async fn reveal_log_file() { 83 | let folder_dir = config::PavoConfig::get_app_folder().unwrap(); 84 | let file_path = Path::new(&folder_dir).join("logs/Pavo.log"); 85 | 86 | showfile::show_path_in_file_manager(file_path.to_path_buf()); 87 | } 88 | 89 | #[tauri::command] 90 | pub async fn set_randomly(randomly: bool) { 91 | let pavo_config = config::PavoConfig::get_config(); 92 | 93 | pavo_config.set_randomly(randomly); 94 | } 95 | 96 | #[tauri::command] 97 | pub async fn set_auto_save(auto_save: bool) { 98 | let pavo_config = config::PavoConfig::get_config(); 99 | 100 | pavo_config.set_auto_save(auto_save); 101 | } 102 | 103 | #[tauri::command] 104 | pub async fn view_photo(handle: tauri::AppHandle, href: String) { 105 | services::view_photo(handle, href); 106 | } 107 | -------------------------------------------------------------------------------- /src-tauri/src/config.rs: -------------------------------------------------------------------------------- 1 | use dirs; 2 | use serde::{Deserialize, Serialize}; 3 | use std::fs; 4 | use std::io::{Error, ErrorKind}; 5 | use std::path::Path; 6 | 7 | #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] 8 | pub struct PavoConfig { 9 | pub auto_shuffle: bool, 10 | pub shuffle_source: Vec, 11 | pub randomly: bool, 12 | pub interval: u64, 13 | pub auto_save: bool, 14 | } 15 | 16 | impl PavoConfig { 17 | pub fn new() -> Self { 18 | Self { 19 | auto_shuffle: false, 20 | shuffle_source: vec![], 21 | randomly: false, 22 | interval: 30, 23 | auto_save: false, 24 | } 25 | } 26 | 27 | pub fn create_app_folder() -> Result { 28 | let home_dir = dirs::home_dir(); 29 | 30 | match home_dir { 31 | Some(home_dir) => { 32 | let app_config_dir = Path::new(&home_dir).join(".pavo"); 33 | 34 | match fs::create_dir_all(app_config_dir.clone()) { 35 | Ok(_) => Ok(app_config_dir.clone().to_str().unwrap().to_string()), 36 | Err(e) => Err(e), 37 | } 38 | } 39 | None => Err(Error::new(ErrorKind::NotFound, "home dir is not fount")), 40 | } 41 | } 42 | 43 | pub fn get_app_folder() -> Result { 44 | let home_dir = dirs::home_dir(); 45 | 46 | match home_dir { 47 | Some(home_dir) => { 48 | let app_config_dir = Path::new(&home_dir).join(".pavo"); 49 | 50 | if app_config_dir.exists() { 51 | Ok(app_config_dir.clone().to_str().unwrap().to_string()) 52 | } else { 53 | Ok(Self::create_app_folder().unwrap()) 54 | } 55 | } 56 | None => Err((2, "no home dir".to_string())), 57 | } 58 | } 59 | 60 | pub fn write_config(data: PavoConfig) { 61 | let folder_dir = Self::get_app_folder().unwrap(); 62 | let file_path = Path::new(&folder_dir).join("pavo.toml"); 63 | 64 | if !file_path.exists() { 65 | fs::File::create(&file_path).expect("create config failed"); 66 | } 67 | 68 | let content = toml::to_string(&data).unwrap(); 69 | 70 | fs::write(file_path, content).expect("write file error"); 71 | } 72 | 73 | pub fn get_config() -> Self { 74 | let folder_dir = Self::get_app_folder().unwrap(); 75 | let file_path = Path::new(&folder_dir).join("pavo.toml"); 76 | 77 | if !file_path.exists() { 78 | fs::File::create(&file_path).expect("create config failed"); 79 | } 80 | 81 | let content = fs::read_to_string(&file_path).unwrap_or_default(); 82 | let data: PavoConfig = match toml::from_str(&content) { 83 | Ok(data) => PavoConfig { ..data }, 84 | Err(_) => PavoConfig::new(), 85 | }; 86 | 87 | data 88 | } 89 | 90 | pub fn set_auto_shuffle(&self, auto_shuffle: bool) -> Self { 91 | let mut data = Self::get_config(); 92 | 93 | data.auto_shuffle = auto_shuffle; 94 | 95 | Self::write_config(data.clone()); 96 | 97 | data 98 | } 99 | 100 | pub fn set_interval(&self, interval: u64) -> Self { 101 | let mut data = Self::get_config(); 102 | 103 | data.interval = interval; 104 | 105 | println!("data; {:?}", data); 106 | 107 | Self::write_config(data.clone()); 108 | 109 | data 110 | } 111 | 112 | pub fn get_interval() -> u64 { 113 | let data = Self::get_config(); 114 | println!("data: {:?}", data); 115 | 116 | data.interval.clone() 117 | } 118 | 119 | pub fn set_randomly(&self, randomly: bool) -> Self { 120 | let mut data = Self::get_config(); 121 | 122 | data.randomly = randomly; 123 | 124 | Self::write_config(data.clone()); 125 | 126 | data 127 | } 128 | 129 | pub fn set_auto_save(&self, status: bool) -> Self { 130 | let mut data = Self::get_config(); 131 | 132 | data.auto_save = status; 133 | 134 | Self::write_config(data.clone()); 135 | 136 | data 137 | } 138 | } 139 | 140 | -------------------------------------------------------------------------------- /src-tauri/src/lib.rs: -------------------------------------------------------------------------------- 1 | use tauri_plugin_updater::UpdaterExt; 2 | 3 | pub async fn update(app: tauri::AppHandle) -> tauri_plugin_updater::Result<()> { 4 | if let Some(update) = app.updater()?.check().await? { 5 | let mut downloaded = 0; 6 | 7 | // alternatively we could also call update.download() and update.install() separately 8 | update 9 | .download_and_install( 10 | |chunk_length, content_length| { 11 | downloaded += chunk_length; 12 | println!("downloaded {downloaded} from {content_length:?}"); 13 | }, 14 | || { 15 | println!("download finished"); 16 | }, 17 | ) 18 | .await?; 19 | 20 | println!("update installed"); 21 | app.restart(); 22 | } 23 | 24 | Ok(()) 25 | } 26 | -------------------------------------------------------------------------------- /src-tauri/src/main.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr( 2 | all(not(debug_assertions), target_os = "windows"), 3 | windows_subsystem = "windows" 4 | )] 5 | 6 | mod background; 7 | mod cmd; 8 | mod config; 9 | mod scheduler; 10 | mod plugins; 11 | mod services; 12 | mod shuffle_thread; 13 | mod tray; 14 | 15 | use cmd::AsyncProcInputTx; 16 | use plugins::register_plugins; 17 | use services::AsyncProcessMessage; 18 | use std::sync::Arc; 19 | use tokio::sync::{mpsc, Mutex}; 20 | 21 | fn handle_window_event(window: &tauri::Window, event: &tauri::WindowEvent) { 22 | match event { 23 | tauri::WindowEvent::CloseRequested { api, .. } => { 24 | let window = window.clone(); 25 | api.prevent_close(); 26 | window.hide().unwrap(); 27 | } 28 | _ => {} 29 | } 30 | } 31 | 32 | #[tokio::main] 33 | async fn main() { 34 | config::PavoConfig::create_app_folder().expect("create app folder failed!"); 35 | 36 | let (async_process_input_tx, async_process_input_rx) = mpsc::channel::(32); 37 | let tx = async_process_input_tx.clone(); 38 | 39 | let builder = tauri::Builder::default(); 40 | let builder = register_plugins(builder); 41 | 42 | builder.manage(AsyncProcInputTx { 43 | sender: Mutex::new(async_process_input_tx), 44 | }) 45 | .setup(move |app| { 46 | #[cfg(target_os = "macos")] 47 | app.set_activation_policy(tauri::ActivationPolicy::Accessory); 48 | 49 | let sender = tx.clone(); 50 | let _ = tray::create_tray(app, sender); 51 | 52 | use pavo::update; 53 | 54 | let handle = app.handle().clone(); 55 | 56 | tauri::async_runtime::spawn(async move { 57 | println!("background start"); 58 | background::Background::new(Arc::new(Mutex::new(async_process_input_rx))).await; 59 | 60 | update(handle).await.unwrap(); 61 | }); 62 | 63 | Ok(()) 64 | }) 65 | .invoke_handler(tauri::generate_handler![ 66 | cmd::set_as_desktop, 67 | cmd::download, 68 | cmd::view_photo, 69 | cmd::get_bing_wallpaper_list, 70 | cmd::get_config, 71 | cmd::set_auto_shuffle, 72 | cmd::set_interval, 73 | cmd::set_randomly, 74 | cmd::set_auto_save, 75 | cmd::reveal_log_file, 76 | ]) 77 | .on_window_event(handle_window_event) 78 | .run(tauri::generate_context!()) 79 | .expect("error while running Pavo"); 80 | } 81 | -------------------------------------------------------------------------------- /src-tauri/src/plugins.rs: -------------------------------------------------------------------------------- 1 | use crate::config; 2 | use tauri::{Builder, Manager, Runtime}; 3 | 4 | pub fn register_plugins(builder: Builder) -> Builder { 5 | builder 6 | .plugin(tauri_plugin_dialog::init()) 7 | .plugin(tauri_plugin_process::init()) 8 | .plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| { 9 | let _ = app 10 | .get_webview_window("main") 11 | .expect("no main window") 12 | .set_focus(); 13 | })) 14 | .plugin( 15 | tauri_plugin_log::Builder::new() 16 | .target(tauri_plugin_log::Target::new( 17 | tauri_plugin_log::TargetKind::Folder { 18 | path: std::path::PathBuf::from(config::PavoConfig::get_app_folder().unwrap() + "/logs"), 19 | file_name: None, 20 | }, 21 | )) 22 | .level(log::LevelFilter::Info) 23 | .build(), 24 | ) 25 | .plugin(tauri_plugin_updater::Builder::new().build()) 26 | .plugin(tauri_plugin_fs::init()) 27 | .plugin(tauri_plugin_shell::init()) 28 | .plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| { 29 | let _ = app 30 | .get_webview_window("main") 31 | .expect("no main window") 32 | .set_focus(); 33 | })) 34 | } 35 | -------------------------------------------------------------------------------- /src-tauri/src/scheduler.rs: -------------------------------------------------------------------------------- 1 | use chrono::offset::Utc; 2 | use chrono::Local; 3 | use once_cell::sync::Lazy; 4 | use reqwest::Client; 5 | use serde::{Deserialize, Serialize}; 6 | use std::path::Path; 7 | use tokio::{self, sync::Mutex}; 8 | 9 | use crate::config; 10 | use crate::services::bing; 11 | use crate::services::download_file; 12 | 13 | #[allow(dead_code)] 14 | fn now() -> String { 15 | Local::now().format("%F %T").to_string() 16 | } 17 | 18 | const BING_EXPIRE_TIME: i64 = 60 * 60 * 12; 19 | 20 | #[derive(Debug, Clone, Serialize, Deserialize)] 21 | pub struct SchedulerPhoto { 22 | filename: String, 23 | regions: Vec, 24 | urls: Vec, 25 | titles: Vec, 26 | startdates: Vec, 27 | copyrights: Vec, 28 | copyrightlinks: Vec, 29 | } 30 | 31 | #[derive(Debug, Clone)] 32 | pub struct Scheduler { 33 | pub last_load_time: i64, 34 | pub cache_list: Vec, 35 | pub current_lang: String, 36 | pub current_idx: usize, 37 | } 38 | 39 | impl Scheduler { 40 | pub fn new() -> Self { 41 | Self { 42 | last_load_time: Utc::now().timestamp(), 43 | cache_list: vec![], 44 | current_lang: String::from("zh-cn"), 45 | current_idx: 0, 46 | } 47 | } 48 | 49 | pub fn should_refresh(&mut self) -> bool { 50 | let now = Utc::now().timestamp(); 51 | 52 | if now - self.last_load_time < BING_EXPIRE_TIME { 53 | return false; 54 | } else { 55 | self.last_load_time = now; 56 | return true; 57 | } 58 | } 59 | 60 | pub async fn batch_fetch(&mut self) -> Result, Box> { 61 | if !self.should_refresh() && !self.cache_list.is_empty() { 62 | return Ok(self.cache_list.clone()); 63 | } 64 | 65 | let region_codes = [ 66 | "zh-CN", "en-US", "fr-FR", "de-DE", "ja-JP", "en-CA", "en-GB", "en-IN", "it-IT", 67 | ]; 68 | 69 | let mut handles = vec![]; 70 | 71 | for region_code in region_codes { 72 | let region = region_code.to_string(); 73 | let mut scheduler = self.clone(); 74 | let handle = tokio::spawn(async move { 75 | scheduler.fetch_list_with_region(region).await 76 | }); 77 | handles.push(handle); 78 | } 79 | 80 | let mut res: Vec = vec![]; 81 | for handle in handles { 82 | if let Ok(Ok(mut photos)) = handle.await { 83 | res.append(&mut photos); 84 | } 85 | } 86 | 87 | let mut formatted_list = vec![]; 88 | 89 | for i in res { 90 | let unique_name = i.filename.clone().split("_").collect::>()[0].to_string(); 91 | 92 | let idx = formatted_list.iter().position(|x: &SchedulerPhoto| x.filename.clone().split("_").collect::>()[0] == unique_name); 93 | 94 | match idx { 95 | Some(idx) => { 96 | let item = &mut formatted_list[idx]; 97 | 98 | item.regions.append(&mut i.clone().regions); 99 | item.urls.append(&mut i.clone().urls); 100 | item.titles.append(&mut i.clone().titles); 101 | item.startdates.append(&mut i.clone().startdates); 102 | item.copyrights.append(&mut i.clone().copyrights); 103 | item.copyrightlinks.append(&mut i.clone().copyrightlinks); 104 | } 105 | None => { 106 | let item = i.clone(); 107 | formatted_list.push(item); 108 | } 109 | } 110 | } 111 | 112 | self.cache_list = formatted_list.clone(); 113 | 114 | Ok(formatted_list) 115 | } 116 | 117 | pub async fn fetch_list_with_region(&mut self, region: String) -> Result, Box> { 118 | let res1 = bing::Wallpaper::new(0, 8, Some(region.clone())) 119 | .await 120 | .unwrap(); 121 | let res2 = bing::Wallpaper::new(7, 8, Some(region.clone())).await.unwrap(); 122 | 123 | let images1 = res1.json.images; 124 | let images2 = res2.json.images; 125 | 126 | let mut res: Vec = images1 127 | .into_iter() 128 | .chain(images2.into_iter()) 129 | .into_iter() 130 | .map(|i| SchedulerPhoto { 131 | filename: bing::Images::get_filename(&i.url).to_string(), 132 | urls: vec![["https://www.bing.com", &i.url].concat()], 133 | regions: vec![region.clone()], 134 | titles: vec![i.clone().title], 135 | startdates: vec![i.clone().startdate], 136 | copyrights: vec![i.clone().copyright], 137 | copyrightlinks: vec![i.clone().copyrightlink], 138 | }) 139 | .collect(); 140 | 141 | res.dedup_by(|a, b| a.filename == b.filename); 142 | 143 | Ok(res) 144 | } 145 | 146 | pub async fn setup_list(&mut self) -> Vec { 147 | let list = self.batch_fetch().await.unwrap(); 148 | 149 | list 150 | } 151 | 152 | pub async fn save_wallpaper(url: &str, filename: &str) -> Result { 153 | let app_folder = config::PavoConfig::get_app_folder().unwrap(); 154 | let path = Path::new(&app_folder).join(&*filename); 155 | let res = download_file(&Client::new(), &url, path.clone().to_str().unwrap()) 156 | .await 157 | .unwrap(); 158 | 159 | println!("{:?}", res); 160 | 161 | Ok(res) 162 | } 163 | 164 | pub async fn set_wallpaper_from_local(a: String) -> String { 165 | wallpaper::set_from_path(a.as_str()).unwrap(); 166 | 167 | if cfg!(not(target_os = "macos")) { 168 | wallpaper::set_mode(wallpaper::Mode::Crop).unwrap(); 169 | } 170 | 171 | a 172 | } 173 | 174 | pub async fn set_wallpaper(url: &str, filename: &str) -> Result { 175 | let a = Self::save_wallpaper(url, filename).await; 176 | 177 | match a { 178 | Ok(a) => { 179 | Self::set_wallpaper_from_local(a).await; 180 | 181 | Ok(String::from("OK")) 182 | } 183 | Err(e) => Err(e.to_string().into()), 184 | } 185 | } 186 | 187 | pub async fn previous_photo(&mut self) { 188 | let list = self.cache_list.clone(); 189 | 190 | if self.current_idx <= 0 { 191 | self.current_idx = list.len() - 1; 192 | } else { 193 | self.current_idx -= 1; 194 | } 195 | 196 | let item = list[self.current_idx].clone(); 197 | 198 | Self::set_wallpaper(&item.urls[0], &item.filename) 199 | .await 200 | .unwrap(); 201 | } 202 | 203 | pub async fn next_photo(&mut self) { 204 | let list = self.cache_list.clone(); 205 | 206 | if self.current_idx >= list.len() - 1 { 207 | self.current_idx = 0; 208 | } else { 209 | self.current_idx += 1; 210 | } 211 | 212 | let item = list[self.current_idx].clone(); 213 | 214 | Self::set_wallpaper(&item.urls[0], &item.filename) 215 | .await 216 | .unwrap(); 217 | } 218 | } 219 | 220 | pub static SCHEDULER: Lazy> = Lazy::new(|| Mutex::new(Scheduler::new())); 221 | -------------------------------------------------------------------------------- /src-tauri/src/services/bing.rs: -------------------------------------------------------------------------------- 1 | use reqwest::Client; 2 | use serde::{Deserialize, Serialize}; 3 | use std::path::Path; 4 | 5 | use super::download_file; 6 | use crate::config; 7 | 8 | pub type Result = std::result::Result>; 9 | 10 | #[derive(Debug, Clone, Serialize, Deserialize)] 11 | pub struct UrlParams { 12 | pub index: u8, 13 | pub number: u8, 14 | pub mkt: Option, 15 | pub hdr: Option, 16 | } 17 | 18 | #[derive(Debug, Clone, Serialize, Deserialize)] 19 | pub struct Tooltips { 20 | pub loading: String, 21 | pub next: String, 22 | pub previous: String, 23 | pub walle: String, 24 | pub walls: String, 25 | } 26 | 27 | #[derive(Default, Debug, Clone, Serialize, Deserialize)] 28 | pub struct Images { 29 | pub bot: usize, 30 | pub copyright: String, 31 | pub copyrightlink: String, 32 | pub drk: usize, 33 | pub enddate: String, 34 | pub fullstartdate: String, 35 | pub hs: Vec, 36 | pub hsh: String, 37 | pub quiz: String, 38 | pub startdate: String, 39 | pub title: String, 40 | pub top: usize, 41 | pub url: String, 42 | pub urlbase: String, 43 | pub wp: bool, 44 | } 45 | 46 | impl Images { 47 | pub fn get_filename(url: &str) -> &str { 48 | let s = url.find("OHR.").ok_or(0).unwrap(); 49 | let e = url.find("&rf=").ok_or(0).unwrap(); 50 | 51 | &url[s..e] 52 | } 53 | } 54 | 55 | #[derive(Debug, Clone, Serialize, Deserialize)] 56 | pub struct WallpaperRes { 57 | pub images: Vec, 58 | pub tooltips: Tooltips, 59 | } 60 | 61 | impl WallpaperRes { 62 | pub async fn new(index: u8, number: u8, mkt: Option) -> Result { 63 | Ok( 64 | reqwest::get(get_url(index, number, mkt).as_str()) 65 | .await? 66 | .json::() 67 | .await?, 68 | ) 69 | } 70 | } 71 | 72 | const BING_URL: &str = 73 | "https://www.bing.com/HPImageArchive.aspx?&format=js&uhd=1&uhdwidth=3840&uhdheight=2160"; 74 | 75 | #[derive(Debug, Serialize, Deserialize)] 76 | pub struct Wallpaper { 77 | index: u8, 78 | number: u8, 79 | files: Vec, 80 | pub json: WallpaperRes, 81 | } 82 | 83 | impl Wallpaper { 84 | pub async fn new(index: u8, number: u8, mkt: Option) -> Result { 85 | let json = WallpaperRes::new(index, number, mkt).await?; 86 | Ok(Wallpaper { 87 | index, 88 | number, 89 | files: vec![], 90 | json, 91 | }) 92 | } 93 | 94 | pub async fn save_wallpaper(url: &str, filename: Option<&str>) -> Result { 95 | let filename = match filename { 96 | Some(filename) => filename, 97 | None => Images::get_filename(url), 98 | }; 99 | let app_folder = config::PavoConfig::get_app_folder().unwrap(); 100 | let path = Path::new(&app_folder).join(&*filename); 101 | let res = download_file(&Client::new(), &url, path.clone().to_str().unwrap()) 102 | .await 103 | .unwrap(); 104 | 105 | println!("{:?}", res); 106 | 107 | Ok(res) 108 | } 109 | 110 | /// set wallpaper from local file 111 | pub async fn set_wallpaper_from_local(a: String) -> String { 112 | wallpaper::set_from_path(a.as_str()).unwrap(); 113 | 114 | if cfg!(not(target_os = "macos")) { 115 | wallpaper::set_mode(wallpaper::Mode::Crop).unwrap(); 116 | } 117 | 118 | a 119 | } 120 | 121 | pub async fn set_wallpaper(url: &str) -> Result { 122 | let a = Wallpaper::save_wallpaper(url, None).await; 123 | match a { 124 | Ok(a) => { 125 | Self::set_wallpaper_from_local(a).await; 126 | 127 | Ok(String::from("OK")) 128 | } 129 | Err(e) => Err(e.to_string().into()), 130 | } 131 | } 132 | } 133 | 134 | fn get_url(index: u8, number: u8, mkt: Option) -> String { 135 | let num = number.to_string(); 136 | let idx = index.to_string(); 137 | let mut url = format!("{}&idx={}&n={}", BING_URL, &idx, &num); 138 | 139 | if let Some(mkt_val) = mkt.clone() { 140 | let v = mkt_val.clone(); 141 | url.push_str("&mkt="); 142 | url.push_str(v.clone().as_str()); 143 | } 144 | 145 | println!("url: {:?}", url); 146 | 147 | url 148 | } 149 | -------------------------------------------------------------------------------- /src-tauri/src/services/mod.rs: -------------------------------------------------------------------------------- 1 | use futures_util::StreamExt; 2 | use reqwest::Client; 3 | use serde::{Deserialize, Serialize}; 4 | use std::cmp::min; 5 | use std::fs::File; 6 | use std::io::{Seek, Write}; 7 | 8 | pub mod bing; 9 | #[derive(Debug, Serialize, Deserialize)] 10 | pub enum PhotoService { 11 | Bing, 12 | } 13 | 14 | #[derive(Debug, Serialize, Deserialize)] 15 | pub enum AsyncProcessMessage { 16 | StartShuffle, 17 | StopShuffle, 18 | PreviousPhoto, 19 | NextPhoto, 20 | } 21 | 22 | pub async fn download_file(client: &Client, url: &str, path: &str) -> Result { 23 | let res = client 24 | .get(url) 25 | .send() 26 | .await 27 | .or(Err(format!("Failed to GET from '{}'", &url)))?; 28 | let total_size = res 29 | .content_length() 30 | .ok_or(format!("Failed to get content length from '{}'", &url))?; 31 | 32 | // let pb = ProgressBar::new(total_size); 33 | // pb.set_style(ProgressStyle::default_bar() 34 | // .template("{msg}\n{spinner:.green} [{elapsed_precise}] [{wide_bar:.white/blue}] {bytes}/{total_bytes} ({bytes_per_sec}, {eta})") 35 | // .progress_chars("█ ")); 36 | // pb.set_message(&format!("Downloading {}", url)); 37 | 38 | let mut file; 39 | let mut downloaded: u64 = 0; 40 | let mut stream = res.bytes_stream(); 41 | 42 | println!("Seeking in file."); 43 | 44 | if std::path::Path::new(path).exists() { 45 | println!("File exists. Resuming."); 46 | 47 | file = std::fs::OpenOptions::new() 48 | .read(true) 49 | .append(true) 50 | .open(path) 51 | .unwrap(); 52 | 53 | let file_size = std::fs::metadata(path).unwrap().len(); 54 | 55 | file.seek(std::io::SeekFrom::Start(file_size)).unwrap(); 56 | downloaded = file_size; 57 | } else { 58 | println!("Fresh file.."); 59 | 60 | file = File::create(path).or(Err(format!("Failed to create file '{}'", path)))?; 61 | } 62 | 63 | println!("Commencing transfer"); 64 | 65 | while let Some(item) = stream.next().await { 66 | let chunk = item.or(Err(format!("Error while downloading file")))?; 67 | 68 | file 69 | .write(&chunk) 70 | .or(Err(format!("Error while writing to file")))?; 71 | let new = min(downloaded + (chunk.len() as u64), total_size); 72 | downloaded = new; 73 | // pb.set_position(new); 74 | } 75 | 76 | // pb.finish_with_message(&format!("Downloaded {} to {}", url, path)); 77 | println!("Downloaded ==> {:?} to {:?}", url, path); 78 | return Ok(path.to_string()); 79 | } 80 | 81 | pub fn view_photo(handle: tauri::AppHandle, href: String) { 82 | let _label = href.clone(); 83 | let label = "view_photo"; 84 | 85 | println!("{:?}", label); 86 | 87 | let _view_window = tauri::webview::WebviewWindowBuilder::new( 88 | &handle, 89 | label, 90 | tauri::WebviewUrl::External(href.parse().unwrap()), 91 | ) 92 | .build() 93 | .unwrap(); 94 | 95 | println!("{:?} ", href); 96 | } 97 | -------------------------------------------------------------------------------- /src-tauri/src/shuffle_thread.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | use tokio::sync::Mutex; 3 | use tokio::time; 4 | use crate::scheduler::Scheduler; 5 | 6 | use crate::config; 7 | 8 | pub struct ShuffleThread { 9 | thread: Option>, 10 | } 11 | 12 | impl ShuffleThread { 13 | pub fn new () -> Self { 14 | 15 | Self { 16 | thread: None, 17 | } 18 | } 19 | 20 | pub async fn start_shuffle(&mut self, scheduler: Arc>) { 21 | if let Some(thread) = self.thread.take() { 22 | println!("shuffle thread abort, restart now"); 23 | thread.abort(); 24 | } 25 | 26 | let shuffle_interval = config::PavoConfig::get_interval(); 27 | let mut interval = time::interval(time::Duration::from_secs(shuffle_interval * 60)); 28 | 29 | let thread = tauri::async_runtime::spawn(async move { 30 | loop { 31 | log::info!( 32 | "WAITTING! Wallpaper will switch in {:?} mins \n", 33 | shuffle_interval 34 | ); 35 | 36 | interval.tick().await; 37 | 38 | let mut scheduler = scheduler.lock().await; 39 | 40 | scheduler.next_photo().await; 41 | } 42 | }); 43 | 44 | log::info!("shuffle thread started thread id: {:?}", thread.inner().id()); 45 | 46 | self.thread = Some(thread); 47 | } 48 | 49 | pub fn stop_shuffle(&mut self) { 50 | if let Some(thread) = self.thread.take() { 51 | println!("shuffle thread abort, thread id: {:?} ", thread.inner().id()); 52 | thread.abort(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src-tauri/src/threads.rs: -------------------------------------------------------------------------------- 1 | use std::sync::{mpsc, Arc, Mutex}; 2 | use std::thread; 3 | 4 | type Job = Box; 5 | 6 | struct Worker { 7 | id: usize, 8 | thread: Option>, 9 | } 10 | 11 | impl Worker { 12 | pub fn new(id: usize, receiver: Arc>>) -> Self { 13 | let thread = thread::spawn(move || { 14 | let message = receiver.lock().unwrap().recv(); 15 | 16 | println!("Worker {id} got a job; executing."); 17 | 18 | match message { 19 | Ok(job) => { 20 | println!("Worker {id} got a job; executing."); 21 | 22 | job(); 23 | } 24 | Err(_) => { 25 | println!("Worker {id} disconnected; shutting down."); 26 | } 27 | }; 28 | }); 29 | 30 | Self { 31 | id, 32 | thread: Some(thread), 33 | } 34 | } 35 | } 36 | 37 | pub struct ThreadPool { 38 | workers: Vec, 39 | sender: Option>, 40 | } 41 | 42 | impl ThreadPool { 43 | pub fn new(size: usize) -> ThreadPool { 44 | let (sender, receiver) = mpsc::channel(); 45 | let receiver = Arc::new(Mutex::new(receiver)); 46 | let mut workers = Vec::with_capacity(size); 47 | 48 | for id in 0..size { 49 | workers.push(Worker::new(id, Arc::clone(&receiver))); 50 | } 51 | 52 | ThreadPool { 53 | workers, 54 | sender: Some(sender), 55 | } 56 | } 57 | 58 | pub fn execute(&self, f: F) 59 | where 60 | F: FnOnce() + Send + 'static, 61 | { 62 | let job = Box::new(f); 63 | 64 | self.sender.as_ref().unwrap().send(job).unwrap(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src-tauri/src/tray.rs: -------------------------------------------------------------------------------- 1 | use tauri::image::Image; 2 | use tauri::{ 3 | menu::{MenuBuilder, MenuItemBuilder}, 4 | tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent}, 5 | App, Emitter, Manager, 6 | }; 7 | 8 | use crate::services::AsyncProcessMessage; 9 | use tokio::sync::mpsc; 10 | 11 | pub fn create_tray( 12 | app: &mut App, 13 | sender: mpsc::Sender, 14 | ) -> Result<(), tauri::Error> { 15 | let quit = MenuItemBuilder::new("Quit").id("quit").build(app).unwrap(); 16 | let show = MenuItemBuilder::new("Show").id("show").build(app).unwrap(); 17 | let hide = MenuItemBuilder::new("Hide").id("hide").build(app).unwrap(); 18 | // we could opt handle an error case better than calling unwrap 19 | 20 | let previous_photo = MenuItemBuilder::new("Previous photo") 21 | .id("previous_photo") 22 | .build(app) 23 | .unwrap(); 24 | let next_photo = MenuItemBuilder::new("Next photo") 25 | .id("next_photo") 26 | .build(app) 27 | .unwrap(); 28 | 29 | let about = MenuItemBuilder::new("About Pavo") 30 | .id("about") 31 | .build(app) 32 | .unwrap(); 33 | let check_for_update = MenuItemBuilder::new("Check for Updates") 34 | .id("check_for_updates") 35 | .build(app) 36 | .unwrap(); 37 | let settings = MenuItemBuilder::new("Settings...") 38 | .id("settings") 39 | .build(app) 40 | .unwrap(); 41 | 42 | let menu = MenuBuilder::new(app) 43 | .items(&[&previous_photo, &next_photo]) 44 | .separator() 45 | .items(&[&show, &hide]) 46 | .separator() 47 | .items(&[&about, &check_for_update, &settings]) 48 | .separator() 49 | .items(&[&quit]) 50 | .build() 51 | .unwrap(); 52 | 53 | let icon_path = app 54 | .path() 55 | .resolve("icons/tray.png", tauri::path::BaseDirectory::Resource)?; 56 | 57 | let _ = TrayIconBuilder::new() 58 | .menu(&menu) 59 | .icon_as_template(true) 60 | .icon(Image::from_path(icon_path).unwrap()) 61 | .on_tray_icon_event(|tray, event| { 62 | let app = tray.app_handle(); 63 | 64 | match event { 65 | TrayIconEvent::Click { 66 | button: MouseButton::Left, 67 | button_state: MouseButtonState::Up, 68 | .. 69 | } => { 70 | if let Some(window) = app.get_webview_window("main") { 71 | if window.is_minimized().unwrap() { 72 | let _ = window.unminimize().unwrap(); 73 | let _ = window.show(); 74 | let _ = window.set_focus(); 75 | } else if window.is_visible().unwrap() { 76 | let _ = window.hide(); 77 | } else { 78 | let _ = window.show(); 79 | let _ = window.set_focus(); 80 | } 81 | } 82 | } 83 | _ => { 84 | log::trace!("unhandled event {event:?}"); 85 | } 86 | } 87 | }) 88 | .menu_on_left_click(false) 89 | .on_menu_event(move |app, event| match event.id.as_ref() { 90 | "show" => { 91 | let app = app.app_handle(); 92 | 93 | if let Some(window) = app.get_webview_window("main") { 94 | let _ = window.show(); 95 | let _ = window.set_focus(); 96 | } 97 | } 98 | "hide" => { 99 | let app = app.app_handle(); 100 | 101 | if let Some(window) = app.get_webview_window("main") { 102 | let _ = window.hide(); 103 | } 104 | } 105 | "previous_photo" => { 106 | let tx = sender.clone(); 107 | tokio::spawn(async move { 108 | tx.send(AsyncProcessMessage::PreviousPhoto).await.unwrap(); 109 | }); 110 | } 111 | "next_photo" => { 112 | let tx = sender.clone(); 113 | tokio::spawn(async move { 114 | tx.send(AsyncProcessMessage::NextPhoto).await.unwrap(); 115 | println!("send"); 116 | }); 117 | } 118 | "about" => { 119 | let app = app.app_handle(); 120 | 121 | if let Some(window) = app.get_webview_window("main") { 122 | let _ = app.emit("go-to-about", ()); 123 | let _ = window.show(); 124 | let _ = window.set_focus(); 125 | } 126 | } 127 | "settings" => { 128 | let app = app.app_handle(); 129 | 130 | if let Some(window) = app.get_webview_window("main") { 131 | let _ = app.emit("go-to-settings", ()); 132 | let _ = window.show(); 133 | let _ = window.set_focus(); 134 | } 135 | } 136 | "check_for_updates" => { 137 | let _ = app.emit("check-for-updates", ()); 138 | } 139 | "quit" => { 140 | println!("quit menu item was clicked"); 141 | app.exit(0); 142 | } 143 | "toggle" => { 144 | println!("toggle clicked"); 145 | } 146 | _ => { 147 | println!("menu item {:?} not handled", event.id); 148 | } 149 | }) 150 | .build(app); 151 | Ok(()) 152 | } 153 | -------------------------------------------------------------------------------- /src-tauri/tauri.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "beforeDevCommand": "pnpm dev", 4 | "devUrl": "http://localhost:1420", 5 | "beforeBuildCommand": "pnpm build", 6 | "frontendDist": "../build" 7 | }, 8 | "bundle": { 9 | "active": true, 10 | "category": "DeveloperTool", 11 | "copyright": "", 12 | "targets": "all", 13 | "externalBin": [], 14 | "icon": [ 15 | "icons/32x32.png", 16 | "icons/128x128.png", 17 | "icons/128x128@2x.png", 18 | "icons/icon.icns", 19 | "icons/icon.ico" 20 | ], 21 | "windows": { 22 | "certificateThumbprint": null, 23 | "digestAlgorithm": "sha256", 24 | "timestampUrl": "" 25 | }, 26 | "longDescription": "", 27 | "macOS": { 28 | "entitlements": null, 29 | "exceptionDomain": "", 30 | "frameworks": [], 31 | "providerShortName": null, 32 | "signingIdentity": null 33 | }, 34 | "resources": [ 35 | "icons/**/*" 36 | ], 37 | "shortDescription": "", 38 | "linux": { 39 | "deb": { 40 | "depends": [] 41 | } 42 | }, 43 | "createUpdaterArtifacts": true 44 | }, 45 | "productName": "Pavo", 46 | "mainBinaryName": "Pavo", 47 | "version": "0.0.10", 48 | "identifier": "com.pavo.dev", 49 | "plugins": { 50 | "updater": { 51 | "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDRCMDVFRTJENTUxRjVBRTQKUldUa1doOVZMZTRGUzI0L2o1Z09PWHdadU1admFkSTRuQk1EUkNZa1l0eHNvWWp5RDMvd3lPVFEK", 52 | "endpoints": [ 53 | "https://github.com/zhanglun/pavo/releases/latest/download/latest.json" 54 | ] 55 | } 56 | }, 57 | "app": { 58 | "windows": [ 59 | { 60 | "fullscreen": false, 61 | "height": 800, 62 | "resizable": false, 63 | "title": "Pavo", 64 | "width": 340, 65 | "visible": false 66 | } 67 | ], 68 | "withGlobalTauri": true, 69 | "security": { 70 | "csp": null 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/app.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss/base"; 2 | @import "tailwindcss/components"; 3 | @import "tailwindcss/utilities"; 4 | 5 | #app { 6 | height: 100vh; 7 | background-color: white; 8 | border-radius: 12px; 9 | } 10 | 11 | @layer components { 12 | .scrollbar-stable { 13 | scrollbar-gutter: stable; 14 | } 15 | .scrollbar-stable::-webkit-scrollbar { 16 | width: 8px; 17 | } 18 | .scrollbar-stable::-webkit-scrollbar-thumb { 19 | background-color: rgba(0, 0, 0, 0.6); 20 | border-radius: 8px; 21 | /* box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); */ 22 | } 23 | .scrollbar-stable::-webkit-scrollbar-track { 24 | background-color: transparent; 25 | } 26 | } 27 | 28 | body { 29 | overflow: hidden; 30 | } 31 | -------------------------------------------------------------------------------- /src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %sveltekit.head% 8 | 9 | 10 |
%sveltekit.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /src/lib/components/BingWallpaper.svelte: -------------------------------------------------------------------------------- 1 | 65 | 66 |
67 | 86 |
95 |
96 |
97 |
{title}
98 | 99 |
100 |
101 | {`${startdate.slice(0, 4)}-${startdate.slice(4, 6)}-${startdate.slice(6, 8)}`} 104 | {copyright} 105 |
106 | 111 |
112 |
113 |
114 | -------------------------------------------------------------------------------- /src/lib/components/Skeleton.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/lib/components/Toolbar.svelte: -------------------------------------------------------------------------------- 1 | 2 | 26 | 27 |
28 |
29 | 47 | 65 | 66 | 82 |
83 |
84 | -------------------------------------------------------------------------------- /src/lib/index.ts: -------------------------------------------------------------------------------- 1 | // place files you want to import through the `$lib` alias in this folder. 2 | -------------------------------------------------------------------------------- /src/lib/updater.ts: -------------------------------------------------------------------------------- 1 | import { check } from "@tauri-apps/plugin-updater"; 2 | import { message } from "@tauri-apps/plugin-dialog"; 3 | import { relaunch } from "@tauri-apps/plugin-process"; 4 | 5 | export async function checkUpdate() { 6 | try { 7 | const update = await check(); 8 | console.log("🚀 ~ file: updater.ts:6 ~ checkUpdate ~ update:", update); 9 | 10 | if (update) { 11 | console.log( 12 | `found update ${update.version} from ${update.date} with notes ${update.body}` 13 | ); 14 | let downloaded = 0; 15 | let contentLength = 0; 16 | // alternatively we could also call update.download() and update.install() separately 17 | await update.downloadAndInstall((event) => { 18 | switch (event.event) { 19 | case "Started": 20 | contentLength = event.data.contentLength || 0; 21 | console.log( 22 | `started downloading ${event.data.contentLength} bytes` 23 | ); 24 | break; 25 | case "Progress": 26 | downloaded += event.data.chunkLength; 27 | console.log(`downloaded ${downloaded} from ${contentLength}`); 28 | break; 29 | case "Finished": 30 | console.log("download finished"); 31 | break; 32 | } 33 | }); 34 | 35 | console.log("update installed"); 36 | await relaunch(); 37 | } else { 38 | await message("File not found", { title: "Tauri", kind: "error" }); 39 | } 40 | } catch (err) { 41 | await message("Error"); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/pages/about.svelte: -------------------------------------------------------------------------------- 1 | 21 | 22 |
23 |
24 | {name} 25 |
26 |
{name}
27 |
28 | version {version} 31 |
32 |
33 | Github Repo 36 | 37 | Report Issue 40 |
41 | 44 |
45 | -------------------------------------------------------------------------------- /src/pages/bing.svelte: -------------------------------------------------------------------------------- 1 | 2 | 77 | 78 |
79 |
80 | {#if loading} 81 | {#each images as image} 82 | 83 |
84 | 85 | 86 | {/each} 87 | {:else} 88 | {#each images as image} 89 | 90 |
91 | 92 | 93 | {/each} 94 | {/if} 95 |
96 |
97 | -------------------------------------------------------------------------------- /src/pages/settings.svelte: -------------------------------------------------------------------------------- 1 | 70 | 71 |
72 |
73 | { 77 | if (e.target) { 78 | const checked = (e.target as HTMLInputElement).checked; 79 | updateConfigShuffle("shuffle", checked); 80 | } 81 | }}>Shuffle 83 |
84 |
85 | 86 | 102 |
103 |
104 | 105 | 106 |
107 |
108 | -------------------------------------------------------------------------------- /src/routes/+layout.svelte: -------------------------------------------------------------------------------- 1 | 7 | 8 | {@render children()} 9 | -------------------------------------------------------------------------------- /src/routes/+layout.ts: -------------------------------------------------------------------------------- 1 | export const prerender = true; 2 | export const ssr = false; 3 | -------------------------------------------------------------------------------- /src/routes/+page.svelte: -------------------------------------------------------------------------------- 1 | 29 | 30 |
31 | 32 | { 37 | current = "Bing"; 38 | }} 39 | > 40 | 41 | 42 | { 47 | current = "Settings"; 48 | }} 49 | > 50 | 51 | 52 | { 57 | current = "About"; 58 | }} 59 | > 60 | 61 | 62 | 63 |
64 | -------------------------------------------------------------------------------- /src/typing.d.ts: -------------------------------------------------------------------------------- 1 | // See https://svelte.dev/docs/kit/types#app.d.ts 2 | // for information about these interfaces 3 | declare global { 4 | namespace App { 5 | // interface Error {} 6 | // interface Locals {} 7 | // interface PageData {} 8 | // interface PageState {} 9 | // interface Platform {} 10 | interface UserConfig { 11 | auto_shuffle: boolean; 12 | interval: number; 13 | } 14 | } 15 | type BingImage = { 16 | copyrights: string[]; 17 | copyrightlinks: string[]; 18 | startdates: string[]; 19 | titles: string[]; 20 | urls: string[]; 21 | }; 22 | } 23 | 24 | export {}; 25 | -------------------------------------------------------------------------------- /static/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhanglun/pavo/bb66403e668e0eae3aed83d41027354d62b37638/static/icon.png -------------------------------------------------------------------------------- /svelte.config.js: -------------------------------------------------------------------------------- 1 | // Tauri doesn't have a Node.js server to do proper SSR 2 | // so we will use adapter-static to prerender the app (SSG) 3 | // See: https://v2.tauri.app/start/frontend/sveltekit/ for more info 4 | import adapter from "@sveltejs/adapter-static"; 5 | import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"; 6 | 7 | /** @type {import('@sveltejs/kit').Config} */ 8 | const config = { 9 | preprocess: vitePreprocess(), 10 | onwarn: (warning, handler) => { 11 | // suppress warnings on `vite dev` and `vite build`; but even without this, things still work 12 | if (warning.code.indexOf("a11y_") === 0) return; 13 | handler(warning); 14 | }, 15 | kit: { 16 | adapter: adapter(), 17 | }, 18 | }; 19 | 20 | export default config; 21 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | darkMode: "selector", 3 | content: [ 4 | "./src/**/*.{html,js,svelte,ts}", 5 | "./node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}", 6 | "./node_modules/flowbite-svelte-icons/**/*.{html,js,svelte,ts}", 7 | ], 8 | theme: { 9 | colors: ({ colors }) => { 10 | return { 11 | ...colors, 12 | medirian: { 13 | 1: "#283c86", 14 | 2: "#45a247", 15 | }, 16 | bayOfMany: { 17 | 50: "#f0f5fe", 18 | 100: "#dee9fb", 19 | 200: "#c4daf9", 20 | 300: "#9bc1f5", 21 | 400: "#6ca0ee", 22 | 500: "#4a7fe7", 23 | 600: "#3561db", 24 | 700: "#2c4ec9", 25 | 800: "#2a40a3", 26 | 900: "#283c86", 27 | }, 28 | apple: { 29 | 50: "#f3faf3", 30 | 100: "#e3f5e3", 31 | 200: "#c8eac8", 32 | 300: "#9dd89e", 33 | 400: "#6abe6c", 34 | 500: "#45a247", 35 | 600: "#348536", 36 | 700: "#2c692e", 37 | 800: "#275428", 38 | 900: "#224524", 39 | }, 40 | }; 41 | }, 42 | extend: { 43 | backgroundImage: (theme) => ({ 44 | "button-gradient": `linear-gradient(to right, ${theme( 45 | "colors.bayOfMany.900" 46 | )} 0%, ${theme("colors.apple.500")} 51%, ${theme( 47 | "colors.bayOfMany.900" 48 | )} 100%)`, 49 | }), 50 | zIndex: { 51 | 100: "100", 52 | }, 53 | colors: { 54 | // flowbite-svelte 55 | primary: { 56 | 50: "#FFF5F2", 57 | 100: "#FFF1EE", 58 | 200: "#FFE4DE", 59 | 300: "#FFD5CC", 60 | 400: "#FFBCAD", 61 | 500: "#FE795D", 62 | 600: "#EF562F", 63 | 700: "#EB4F27", 64 | 800: "#CC4522", 65 | 900: "#A5371B", 66 | }, 67 | // pink 68 | // primary: {"50":"#fdf2f8","100":"#fce7f3","200":"#fbcfe8","300":"#f9a8d4","400":"#f472b6","500":"#ec4899","600":"#db2777","700":"#be185d","800":"#9d174d","900":"#831843"} 69 | 70 | // fuchsia 71 | // primary: {"50":"#fdf4ff","100":"#fae8ff","200":"#f5d0fe","300":"#f0abfc","400":"#e879f9","500":"#d946ef","600":"#c026d3","700":"#a21caf","800":"#86198f","900":"#701a75"} 72 | 73 | // purple 74 | // primary: {"50":"#faf5ff","100":"#f3e8ff","200":"#e9d5ff","300":"#d8b4fe","400":"#c084fc","500":"#a855f7","600":"#9333ea","700":"#7e22ce","800":"#6b21a8","900":"#581c87"} 75 | 76 | // violet 77 | // primary: {"50":"#f5f3ff","100":"#ede9fe","200":"#ddd6fe","300":"#c4b5fd","400":"#a78bfa","500":"#8b5cf6","600":"#7c3aed","700":"#6d28d9","800":"#5b21b6","900":"#4c1d95"} 78 | 79 | // indigo 80 | // primary: {"50":"#eef2ff","100":"#e0e7ff","200":"#c7d2fe","300":"#a5b4fc","400":"#818cf8","500":"#6366f1","600":"#4f46e5","700":"#4338ca","800":"#3730a3","900":"#312e81"} 81 | 82 | // blue 83 | // primary: {"50":"#eff6ff","100":"#dbeafe","200":"#bfdbfe","300":"#93c5fd","400":"#60a5fa","500":"#3b82f6","600":"#2563eb","700":"#1d4ed8","800":"#1e40af","900":"#1e3a8a"} 84 | 85 | // sky 86 | // primary: {"50":"#f0f9ff","100":"#e0f2fe","200":"#bae6fd","300":"#7dd3fc","400":"#38bdf8","500":"#0ea5e9","600":"#0284c7","700":"#0369a1","800":"#075985","900":"#0c4a6e"} 87 | 88 | // cyan 89 | // primary: {"50":"#ecfeff","100":"#cffafe","200":"#a5f3fc","300":"#67e8f9","400":"#22d3ee","500":"#06b6d4","600":"#0891b2","700":"#0e7490","800":"#155e75","900":"#164e63"} 90 | 91 | // teal 92 | // primary: {"50":"#f0fdfa","100":"#ccfbf1","200":"#99f6e4","300":"#5eead4","400":"#2dd4bf","500":"#14b8a6","600":"#0d9488","700":"#0f766e","800":"#115e59","900":"#134e4a"} 93 | 94 | // emerald 95 | // primary: {"50":"#ecfdf5","100":"#d1fae5","200":"#a7f3d0","300":"#6ee7b7","400":"#34d399","500":"#10b981","600":"#059669","700":"#047857","800":"#065f46","900":"#064e3b"} 96 | 97 | // green 98 | // primary: {"50":"#f0fdf4","100":"#dcfce7","200":"#bbf7d0","300":"#86efac","400":"#4ade80","500":"#22c55e","600":"#16a34a","700":"#15803d","800":"#166534","900":"#14532d"} 99 | 100 | // lime 101 | // primary: {"50":"#f7fee7","100":"#ecfccb","200":"#d9f99d","300":"#bef264","400":"#a3e635","500":"#84cc16","600":"#65a30d","700":"#4d7c0f","800":"#3f6212","900":"#365314"} 102 | 103 | // yellow 104 | // primary: {"50":"#fefce8","100":"#fef9c3","200":"#fef08a","300":"#fde047","400":"#facc15","500":"#eab308","600":"#ca8a04","700":"#a16207","800":"#854d0e","900":"#713f12"} 105 | 106 | // amber 107 | // primary: {"50":"#fffbeb","100":"#fef3c7","200":"#fde68a","300":"#fcd34d","400":"#fbbf24","500":"#f59e0b","600":"#d97706","700":"#b45309","800":"#92400e","900":"#78350f"} 108 | 109 | // orange 110 | // primary: {"50":"#fff7ed","100":"#ffedd5","200":"#fed7aa","300":"#fdba74","400":"#fb923c","500":"#f97316","600":"#ea580c","700":"#c2410c","800":"#9a3412","900":"#7c2d12"} 111 | 112 | // red 113 | // primary: {"50":"#fef2f2","100":"#fee2e2","200":"#fecaca","300":"#fca5a5","400":"#f87171","500":"#ef4444","600":"#dc2626","700":"#b91c1c","800":"#991b1b","900":"#7f1d1d"} 114 | 115 | // stone 116 | // primary: {"50":"#fafaf9","100":"#f5f5f4","200":"#e7e5e4","300":"#d6d3d1","400":"#a8a29e","500":"#78716c","600":"#57534e","700":"#44403c","800":"#292524","900":"#1c1917"} 117 | 118 | // neutral 119 | // primary: {"50":"#fafafa","100":"#f5f5f5","200":"#e5e5e5","300":"#d4d4d4","400":"#a3a3a3","500":"#737373","600":"#525252","700":"#404040","800":"#262626","900":"#171717"} 120 | 121 | // zinc 122 | // primary: {"50":"#fafafa","100":"#f4f4f5","200":"#e4e4e7","300":"#d4d4d8","400":"#a1a1aa","500":"#71717a","600":"#52525b","700":"#3f3f46","800":"#27272a","900":"#18181b"} 123 | 124 | // gray 125 | // primary: {"50":"#f9fafb","100":"#f3f4f6","200":"#e5e7eb","300":"#d1d5db","400":"#9ca3af","500":"#6b7280","600":"#4b5563","700":"#374151","800":"#1f2937","900":"#111827"} 126 | 127 | // slate 128 | // primary: {"50":"#f8fafc","100":"#f1f5f9","200":"#e2e8f0","300":"#cbd5e1","400":"#94a3b8","500":"#64748b","600":"#475569","700":"#334155","800":"#1e293b","900":"#0f172a"} 129 | }, 130 | }, 131 | }, 132 | plugins: [require("flowbite/plugin")], 133 | }; 134 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json", 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "checkJs": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "resolveJsonModule": true, 9 | "skipLibCheck": true, 10 | "sourceMap": true, 11 | "strict": true, 12 | "moduleResolution": "bundler", 13 | "types": ["./node_modules", "./src/typing.d.ts"] 14 | }, 15 | "include": ["src"] 16 | 17 | // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias 18 | // except $lib which is handled by https://kit.svelte.dev/docs/configuration#files 19 | // 20 | // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes 21 | // from the referenced tsconfig.json - TypeScript does not merge them in 22 | } 23 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import { sveltekit } from "@sveltejs/kit/vite"; 3 | 4 | // @ts-expect-error process is a nodejs global 5 | const host = process.env.TAURI_DEV_HOST; 6 | 7 | // https://vitejs.dev/config/ 8 | export default defineConfig(async () => ({ 9 | plugins: [sveltekit()], 10 | 11 | // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build` 12 | // 13 | // 1. prevent vite from obscuring rust errors 14 | clearScreen: false, 15 | // 2. tauri expects a fixed port, fail if that port is not available 16 | server: { 17 | port: 1420, 18 | strictPort: true, 19 | host: host || false, 20 | hmr: host 21 | ? { 22 | protocol: "ws", 23 | host, 24 | port: 1421, 25 | } 26 | : undefined, 27 | watch: { 28 | // 3. tell vite to ignore watching `src-tauri` 29 | ignored: ["**/src-tauri/**"], 30 | }, 31 | }, 32 | })); 33 | --------------------------------------------------------------------------------