From 528a1ba2f2b1a4d48d7dae40b4d5b63f9d7e10c4 Mon Sep 17 00:00:00 2001 From: Louis Beaumont Date: Thu, 18 Jul 2024 09:33:48 +0200 Subject: [PATCH 1/6] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 656422af6..b439756a9 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,11 @@ # Extend your human memory with LLM. Open source, runs locally, developer friendly. -Library for devs to build AI apps on top of all your life data. Alternative to Rewind.ai +Library for devs to build AI apps on top of all your life data. Alternative to Rewind.ai. Record your screens & audio 24/7. You own your data. Rust. We are shipping daily, make suggestions, post bugs, [give feedback](https://cal.com/louis030195/screenpipe)! -Chat with an AI that knows everything about you. Record your screens & audio 24/7. You own your data. Rust. +![image](https://github.com/user-attachments/assets/b89a867f-aa09-4aa0-bf58-d808df688c16) + ## Getting started From 0c09457196d62f7b5e6dc365fc3aca196f9336b1 Mon Sep 17 00:00:00 2001 From: Louis Beaumont Date: Thu, 18 Jul 2024 09:35:15 +0200 Subject: [PATCH 2/6] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b439756a9..c6583cff1 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ ![Demo](./public/demo.gif) -# Extend your human memory with LLM. Open source, runs locally, developer friendly. +# Give AI the full context. Runs locally. Low code/no code. Library for devs to build AI apps on top of all your life data. Alternative to Rewind.ai. Record your screens & audio 24/7. You own your data. Rust. We are shipping daily, make suggestions, post bugs, [give feedback](https://cal.com/louis030195/screenpipe)! From c61759ecd277c50bb33b0d2cb6dba26ab9a222b2 Mon Sep 17 00:00:00 2001 From: Louis Beaumont Date: Thu, 18 Jul 2024 10:24:04 +0200 Subject: [PATCH 3/6] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c6583cff1..b15112a69 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ ![Demo](./public/demo.gif) -# Give AI the full context. Runs locally. Low code/no code. +# Build AI apps that have the full context Library for devs to build AI apps on top of all your life data. Alternative to Rewind.ai. Record your screens & audio 24/7. You own your data. Rust. We are shipping daily, make suggestions, post bugs, [give feedback](https://cal.com/louis030195/screenpipe)! From ff0cfe16237a04a396408faaaf793e11886dfdf4 Mon Sep 17 00:00:00 2001 From: Louis Beaumont Date: Thu, 18 Jul 2024 10:53:10 +0200 Subject: [PATCH 4/6] update tauri example --- .github/workflows/release-app.yml | 10 +- .github/workflows/release.yml | 81 - Cargo.toml | 2 + examples/apps/screen-pipe-app/README.md | 36 +- examples/apps/screen-pipe-app/package.json | 11 +- examples/apps/screen-pipe-app/pnpm-lock.yaml | 111 +- .../apps/screen-pipe-app/src-tauri/Cargo.toml | 42 +- .../apps/screen-pipe-app/src-tauri/build.rs | 2 +- .../src-tauri/capabilities/main.json | 40 + .../src-tauri/gen/schemas/acl-manifests.json | 1 + .../src-tauri/gen/schemas/capabilities.json | 1 + .../src-tauri/gen/schemas/desktop-schema.json | 2748 +++++++++++++++++ .../src-tauri/gen/schemas/macOS-schema.json | 2748 +++++++++++++++++ .../screen-pipe-app/src-tauri/null/db.sqlite | Bin 0 -> 4096 bytes .../src-tauri/null/db.sqlite-shm | Bin 0 -> 32768 bytes .../src-tauri/null/db.sqlite-wal | Bin 0 -> 107152 bytes .../screen-pipe-app/src-tauri/src/main.rs | 466 ++- .../screen-pipe-app/src-tauri/tauri.conf.json | 101 +- 18 files changed, 5926 insertions(+), 474 deletions(-) delete mode 100644 .github/workflows/release.yml create mode 100644 examples/apps/screen-pipe-app/src-tauri/capabilities/main.json create mode 100644 examples/apps/screen-pipe-app/src-tauri/gen/schemas/acl-manifests.json create mode 100644 examples/apps/screen-pipe-app/src-tauri/gen/schemas/capabilities.json create mode 100644 examples/apps/screen-pipe-app/src-tauri/gen/schemas/desktop-schema.json create mode 100644 examples/apps/screen-pipe-app/src-tauri/gen/schemas/macOS-schema.json create mode 100644 examples/apps/screen-pipe-app/src-tauri/null/db.sqlite create mode 100644 examples/apps/screen-pipe-app/src-tauri/null/db.sqlite-shm create mode 100644 examples/apps/screen-pipe-app/src-tauri/null/db.sqlite-wal diff --git a/.github/workflows/release-app.yml b/.github/workflows/release-app.yml index d461d3cda..50e5a06b3 100644 --- a/.github/workflows/release-app.yml +++ b/.github/workflows/release-app.yml @@ -1,5 +1,11 @@ # # Run for macOS -# act -W .github/workflows/release-app.yml --container-architecture linux/amd64 -j release -P macos-latest=-self-hosted + +# act -W .github/workflows/release-app.yml --container-architecture linux/amd64 -j release -P macos-latest=-self-hosted + +# # Run for Linux +# act -W .github/workflows/release-app.yml --container-architecture linux/amd64 -j release -P ubuntu-22.04=-self-hosted + + name: "Release app" @@ -37,7 +43,7 @@ jobs: - name: install frontend dependencies working-directory: examples/apps/screen-pipe-app/ - run: pnpm i + run: npm i - uses: tauri-apps/tauri-action@v0 env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 1b0e37a5e..000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,81 +0,0 @@ -name: Release - -on: - push: - tags: - - "v*.*.*" - -jobs: - build-ubuntu: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y libavformat-dev libavfilter-dev libavdevice-dev ffmpeg libasound2-dev - - - name: Set up Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - profile: minimal - override: true - - - name: Build with RPATH - run: | - export PKG_CONFIG_PATH="/usr/lib/x86_64-linux-gnu/pkgconfig:$PKG_CONFIG_PATH" - export RUSTFLAGS="-C link-arg=-Wl,-rpath,\$ORIGIN/lib" - cargo build --release - - - name: Copy FFmpeg libraries - run: | - mkdir -p target/release/lib - cp /usr/lib/x86_64-linux-gnu/libavcodec.so* target/release/lib/ - cp /usr/lib/x86_64-linux-gnu/libavformat.so* target/release/lib/ - cp /usr/lib/x86_64-linux-gnu/libavutil.so* target/release/lib/ - cp /usr/lib/x86_64-linux-gnu/libswresample.so* target/release/lib/ - cp /usr/lib/x86_64-linux-gnu/libswscale.so* target/release/lib/ - cp /usr/lib/x86_64-linux-gnu/libavfilter.so* target/release/lib/ - cp /usr/lib/x86_64-linux-gnu/libavdevice.so* target/release/lib/ - - - name: Create deployment package - run: | - mkdir -p screenpipe-linux - cp target/release/screenpipe screenpipe-linux/screenpipe - cp -r target/release/lib screenpipe-linux/ - chmod +x screenpipe-linux/screenpipe - tar -czvf screenpipe-linux.tar.gz screenpipe-linux - - - name: Upload Artifact - uses: actions/upload-artifact@v2 - with: - name: screenpipe-linux - path: screenpipe-linux.tar.gz - - release: - runs-on: ubuntu-latest - needs: [build-ubuntu] - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Download Artifacts - uses: actions/download-artifact@v2 - with: - name: screenpipe-linux - - - name: Set Version - shell: bash - run: | - echo "VERSION=${GITHUB_REF_NAME#v}" >> $GITHUB_ENV - echo "RELEASE_VERSION=$(echo ${GITHUB_REF_NAME} | cut -f1 -d-)" >> $GITHUB_ENV - - - name: Create or update Release - env: - GH_TOKEN: ${{ secrets.PAT }} - run: | - gh release create ${{ env.RELEASE_VERSION }} --title ${{ env.RELEASE_VERSION }} --generate-notes - gh release upload ${{ env.RELEASE_VERSION }} screenpipe-linux.tar.gz diff --git a/Cargo.toml b/Cargo.toml index e4c18fc9c..5e0532dd0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ members = ["screenpipe-server", "screenpipe-vision", "screenpipe-audio", "exampl exclude = [] resolver = "2" + [workspace.package] version = "0.1.0" authors = ["louis030195 "] @@ -25,3 +26,4 @@ criterion = { version = "0.5.1", features = ["async_tokio"] } + diff --git a/examples/apps/screen-pipe-app/README.md b/examples/apps/screen-pipe-app/README.md index c4033664f..a5e7cc722 100644 --- a/examples/apps/screen-pipe-app/README.md +++ b/examples/apps/screen-pipe-app/README.md @@ -1,36 +1,18 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). +README TODO -## Getting Started -First, run the development server: -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -# or -bun dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. - -This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. -## Learn More +releasing app: -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. +``` +export TAURI_SIGNING_PRIVATE_KEY="$HOME/.tauri/myapp.key" +export TAURI_SIGNING_PRIVATE_KEY_PASSWORD="" +pnpm tauri build +# todo rest +``` -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! +ask @louis030195 for key/pw -## Deploy on Vercel -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/examples/apps/screen-pipe-app/package.json b/examples/apps/screen-pipe-app/package.json index 06bc0240c..c9d19d92b 100644 --- a/examples/apps/screen-pipe-app/package.json +++ b/examples/apps/screen-pipe-app/package.json @@ -9,13 +9,16 @@ "lint": "next lint" }, "dependencies": { + "@tauri-apps/plugin-cli": "2.0.0-beta.7", + "@tauri-apps/plugin-shell": "2.0.0-beta.8", + "@tauri-apps/plugin-store": "2.0.0-beta.7", + "@tauri-apps/plugin-updater": "2.0.0-beta.7", "next": "14.2.4", "react": "^18", - "react-dom": "^18", - "tauri-plugin-autostart-api": "github:tauri-apps/tauri-plugin-autostart#v1" + "react-dom": "^18" }, "devDependencies": { - "@tauri-apps/cli": "^1.6.0", + "@tauri-apps/cli": "2.0.0-beta.22", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", @@ -25,4 +28,4 @@ "tailwindcss": "^3.4.1", "typescript": "^5" } -} +} \ No newline at end of file diff --git a/examples/apps/screen-pipe-app/pnpm-lock.yaml b/examples/apps/screen-pipe-app/pnpm-lock.yaml index cc5fa0145..ad37be54c 100644 --- a/examples/apps/screen-pipe-app/pnpm-lock.yaml +++ b/examples/apps/screen-pipe-app/pnpm-lock.yaml @@ -5,6 +5,18 @@ settings: excludeLinksFromLockfile: false dependencies: + '@tauri-apps/plugin-cli': + specifier: 2.0.0-beta.7 + version: 2.0.0-beta.7 + '@tauri-apps/plugin-shell': + specifier: 2.0.0-beta.8 + version: 2.0.0-beta.8 + '@tauri-apps/plugin-store': + specifier: 2.0.0-beta.7 + version: 2.0.0-beta.7 + '@tauri-apps/plugin-updater': + specifier: 2.0.0-beta.7 + version: 2.0.0-beta.7 next: specifier: 14.2.4 version: 14.2.4(react-dom@18.3.1)(react@18.3.1) @@ -20,8 +32,8 @@ dependencies: devDependencies: '@tauri-apps/cli': - specifier: ^1.6.0 - version: 1.6.0 + specifier: 2.0.0-beta.22 + version: 2.0.0-beta.22 '@types/node': specifier: ^20 version: 20.14.9 @@ -294,8 +306,13 @@ packages: engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'} dev: false - /@tauri-apps/cli-darwin-arm64@1.6.0: - resolution: {integrity: sha512-SNRwUD9nqGxY47mbY1CGTt/jqyQOU7Ps7Mx/mpgahL0FVUDiCEY/5L9QfEPPhEgccgcelEVn7i6aQHIkHyUtCA==} + /@tauri-apps/api@2.0.0-beta.15: + resolution: {integrity: sha512-H9w6iISmR+NvH4XuyCZB4zDN10tf9RFt6i/9JHEjaRhAowdAaJ+oiXq/3kedizNClHMtbTQ5j0oqDVPkZDAI8g==} + engines: {node: '>= 18.18', npm: '>= 6.6.0', yarn: '>= 1.19.1'} + dev: false + + /@tauri-apps/cli-darwin-arm64@2.0.0-beta.22: + resolution: {integrity: sha512-Ofhythvg1Ks2IM87WUYNtgFzm21aU1Zn+8QP81lJy9Y7ZGMxP8FYfqeHz6GIWKI+CYf6I77HA8LHkT9pyE5PYg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -303,8 +320,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-darwin-x64@1.6.0: - resolution: {integrity: sha512-g2/uDR/eeH2arvuawA4WwaEOqv/7jDO/ZLNI3JlBjP5Pk8GGb3Kdy0ro1xQzF94mtk2mOnOXa4dMgAet4sUJ1A==} + /@tauri-apps/cli-darwin-x64@2.0.0-beta.22: + resolution: {integrity: sha512-/lWIixo7WgmMUqcxlPT7Ojlkl6qbVlNDwUZ+9DtTpoWnaaBxv/YpSe1k62vDWEC7l0apFY+Fz7cRONN2wglFyQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -312,8 +329,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-linux-arm-gnueabihf@1.6.0: - resolution: {integrity: sha512-EVwf4oRkQyG8BpSrk0gqO7oA0sDM2MdNDtJpMfleYFEgCxLIOGZKNqaOW3M7U+0Y4qikmG3TtRK+ngc8Ymtrjg==} + /@tauri-apps/cli-linux-arm-gnueabihf@2.0.0-beta.22: + resolution: {integrity: sha512-9nJCSStoxu4BKaKVJhu/uBJ8IsIofwAdsX0TWFxqo0obaZbeQSEpPhVsCy+uk3u/28dF+qyUtMCYawO2Uljnag==} engines: {node: '>= 10'} cpu: [arm] os: [linux] @@ -321,8 +338,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-linux-arm64-gnu@1.6.0: - resolution: {integrity: sha512-YdpY17cAySrhK9dX4BUVEmhAxE2o+6skIEFg8iN/xrDwRxhaNPI9I80YXPatUTX54Kx55T5++25VJG9+3iw83A==} + /@tauri-apps/cli-linux-arm64-gnu@2.0.0-beta.22: + resolution: {integrity: sha512-TF9q9zHFBx9LaG2fJJC+BcpIokOmX1UIniBapndvx3dJmdDiK4F6w2QYKDkrBQVzDzcIducmdo2zNBv17O9tFQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -330,8 +347,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-linux-arm64-musl@1.6.0: - resolution: {integrity: sha512-4U628tuf2U8pMr4tIBJhEkrFwt+46dwhXrDlpdyWSZtnop5RJAVKHODm0KbWns4xGKfTW1F3r6sSv+2ZxLcISA==} + /@tauri-apps/cli-linux-arm64-musl@2.0.0-beta.22: + resolution: {integrity: sha512-ak/RdmaV7sATQmNOxlpHVlbKlrdquH7WH8nOv82X+iK+1HgAOGGqLqBUMzzhkGqo9SHQ9zJ6A2yOo7Z6TJXMmQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -339,8 +356,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-linux-x64-gnu@1.6.0: - resolution: {integrity: sha512-AKRzp76fVUaJyXj5KRJT9bJyhwZyUnRQU0RqIRqOtZCT5yr6qGP8rjtQ7YhCIzWrseBlOllc3Qvbgw3Yl0VQcA==} + /@tauri-apps/cli-linux-x64-gnu@2.0.0-beta.22: + resolution: {integrity: sha512-9t+jQeMqBdXz51ikTh1PQFG/gs9PBzXmtMcIzUxE0juvH/ynjw0Vf+yZbNmwqVS9g7cj8XiBXoc6/N41SZE2cA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -348,8 +365,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-linux-x64-musl@1.6.0: - resolution: {integrity: sha512-0edIdq6aMBTaRMIXddHfyAFL361JqulLLd2Wi2aoOie7DkQ2MYh6gv3hA7NB9gqFwNIGE+xtJ4BkXIP2tSGPlg==} + /@tauri-apps/cli-linux-x64-musl@2.0.0-beta.22: + resolution: {integrity: sha512-PemcztfHG3HAuuo7HcnhfDrtN9NT7kueyNg8ipxJNPMa+s4K7kfieViyEiMW5pTr2F5WG/UuBSNcuwY+DVCcPA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -357,8 +374,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-win32-arm64-msvc@1.6.0: - resolution: {integrity: sha512-QwWpWk4ubcwJ1rljsRAmINgB2AwkyzZhpYbalA+MmzyYMREcdXWGkyixWbRZgqc6fEWEBmq5UG73qz5eBJiIKg==} + /@tauri-apps/cli-win32-arm64-msvc@2.0.0-beta.22: + resolution: {integrity: sha512-EgKoG/jGEtTzhOp7ISjMdQsfd8IOG/5yZhO9Z4L/u7oB9mprKAJohYs24+ZxJtq2bOz4f/ZIysZ19nbkpxUzrg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -366,8 +383,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-win32-ia32-msvc@1.6.0: - resolution: {integrity: sha512-Vtw0yxO9+aEFuhuxQ57ALG43tjECopRimRuKGbtZYDCriB/ty5TrT3QWMdy0dxBkpDTu3Rqsz30sbDzw6tlP3Q==} + /@tauri-apps/cli-win32-ia32-msvc@2.0.0-beta.22: + resolution: {integrity: sha512-67OrM2m4FB3KujPbjd/i+9lqcLDO3/ixqL1GMc3BoHhcjF+7QY08OxqWeitdsP/8ihnMIIdir2xEjNUKc6Zelw==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] @@ -375,8 +392,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-win32-x64-msvc@1.6.0: - resolution: {integrity: sha512-h54FHOvGi7+LIfRchzgZYSCHB1HDlP599vWXQQJ/XnwJY+6Rwr2E5bOe/EhqoG8rbGkfK0xX3KPAvXPbUlmggg==} + /@tauri-apps/cli-win32-x64-msvc@2.0.0-beta.22: + resolution: {integrity: sha512-BsO5xMUxliTZTImXnOC73sKT2U9VUeqR8AtklSObBcAg5LaZKpYOdF2pZzU6rIMAZwzROTAT1hYsr4r/nx2UZg==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -384,22 +401,46 @@ packages: dev: true optional: true - /@tauri-apps/cli@1.6.0: - resolution: {integrity: sha512-DBBpBl6GhTzm8ImMbKkfaZ4fDTykWrC7Q5OXP4XqD91recmDEn2LExuvuiiS3HYe7uP8Eb5B9NPHhqJb+Zo7qQ==} + /@tauri-apps/cli@2.0.0-beta.22: + resolution: {integrity: sha512-OAuiDdSRKxNmr/dseQKKMoZZxIhQ6aAxmXJctGYJxCnkd62tQ8xeq87roVXGNS5Qkuv7WpySAyR0ntiMjvNLUA==} engines: {node: '>= 10'} hasBin: true optionalDependencies: - '@tauri-apps/cli-darwin-arm64': 1.6.0 - '@tauri-apps/cli-darwin-x64': 1.6.0 - '@tauri-apps/cli-linux-arm-gnueabihf': 1.6.0 - '@tauri-apps/cli-linux-arm64-gnu': 1.6.0 - '@tauri-apps/cli-linux-arm64-musl': 1.6.0 - '@tauri-apps/cli-linux-x64-gnu': 1.6.0 - '@tauri-apps/cli-linux-x64-musl': 1.6.0 - '@tauri-apps/cli-win32-arm64-msvc': 1.6.0 - '@tauri-apps/cli-win32-ia32-msvc': 1.6.0 - '@tauri-apps/cli-win32-x64-msvc': 1.6.0 - dev: true + '@tauri-apps/cli-darwin-arm64': 2.0.0-beta.22 + '@tauri-apps/cli-darwin-x64': 2.0.0-beta.22 + '@tauri-apps/cli-linux-arm-gnueabihf': 2.0.0-beta.22 + '@tauri-apps/cli-linux-arm64-gnu': 2.0.0-beta.22 + '@tauri-apps/cli-linux-arm64-musl': 2.0.0-beta.22 + '@tauri-apps/cli-linux-x64-gnu': 2.0.0-beta.22 + '@tauri-apps/cli-linux-x64-musl': 2.0.0-beta.22 + '@tauri-apps/cli-win32-arm64-msvc': 2.0.0-beta.22 + '@tauri-apps/cli-win32-ia32-msvc': 2.0.0-beta.22 + '@tauri-apps/cli-win32-x64-msvc': 2.0.0-beta.22 + dev: true + + /@tauri-apps/plugin-cli@2.0.0-beta.7: + resolution: {integrity: sha512-AOKtMrPmBumfOLdD2jv3ct5Sbm4LQJ+iTY5v+cQN2siW4wGZXWSLHH6ZwhbEyEclIOepHvPlaRv91gS1PQE76g==} + dependencies: + '@tauri-apps/api': 2.0.0-beta.15 + dev: false + + /@tauri-apps/plugin-shell@2.0.0-beta.8: + resolution: {integrity: sha512-rFXI6MvsCdSGbuKbDu/NaOePREb9YTVTdeugHdvvljnKWW3dvmThBb2h/8Hxj+Z7Cd8MUoRxPeJWUZbPbJ2Imw==} + dependencies: + '@tauri-apps/api': 2.0.0-beta.15 + dev: false + + /@tauri-apps/plugin-store@2.0.0-beta.7: + resolution: {integrity: sha512-OgeicsLfN7/u/vfxhzJfsZsNfVJWrhmwhEn2oK4OJ1kvkrGbkfK0/ZORSkmqbpByI6hXWYZrbeyXDuVIefVWAQ==} + dependencies: + '@tauri-apps/api': 2.0.0-beta.15 + dev: false + + /@tauri-apps/plugin-updater@2.0.0-beta.7: + resolution: {integrity: sha512-wnIVPPMuD33Wf8Q1CyvAQLAT2sVH0sefTNrYF5ITqzUxzeH54MaiVIu+e8/zBaRFcuBpJv7exljLlrcNW47ybQ==} + dependencies: + '@tauri-apps/api': 2.0.0-beta.15 + dev: false /@types/json5@0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} diff --git a/examples/apps/screen-pipe-app/src-tauri/Cargo.toml b/examples/apps/screen-pipe-app/src-tauri/Cargo.toml index 072fd3679..65d78b033 100644 --- a/examples/apps/screen-pipe-app/src-tauri/Cargo.toml +++ b/examples/apps/screen-pipe-app/src-tauri/Cargo.toml @@ -12,18 +12,15 @@ rust-version = "1.60" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [build-dependencies] -tauri-build = { version = "1.5.3", features = [] } +tauri-build = { version = "=2.0.0-beta.19", features = [] } [dependencies] serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } -tauri = { version = "^1.7.0", features = [ "system-tray", "cli", "shell-open-api"] } -# tauri = { version = "2.0.0-beta", features = [ "cli", "unstable", "devtools"] } +tauri = { version = "2.0.0-beta.24", features = ["tray-icon", "devtools"] } -# https://github.com/louis030195/screen-pipe -screenpipe-server = { git = "https://github.com/louis030195/screen-pipe", branch = "main" } -screenpipe-audio = { git = "https://github.com/louis030195/screen-pipe", branch = "main" } screenpipe-vision = { git = "https://github.com/louis030195/screen-pipe", branch = "main" } + axum = "0.7.5" # Logging @@ -46,19 +43,36 @@ uuid = { version = "1.10.0", features = ["v4"] } sentry = "0.34.0" # Autostart -tauri-plugin-autostart = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" } +tauri-plugin-autostart = "2.0.0-beta.9" # Chrono chrono = "0.4.3" +tauri-plugin-shell = "2.0.0-alpha.2" +tauri-plugin-store = "2.0.0-beta" -[features] -# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled. -# If you use cargo directly instead of tauri's cli you can use this feature flag to switch between tauri's `dev` and `build` modes. -# DO NOT REMOVE!! -custom-protocol = [ "tauri/custom-protocol" ] # M series MacOS -metal = ["screenpipe-server/metal", "screenpipe-audio/metal"] -# Nvidia +[target.'cfg(target_os = "macos")'.dependencies] +screenpipe-server = { path = "../../../../screenpipe-server", features = ["metal"] } +screenpipe-audio = { path = "../../../../screenpipe-audio", features = ["metal"] } + +# Linux +[target.'cfg(target_os = "linux")'.dependencies] +screenpipe-server = { path = "../../../../screenpipe-server", features = [] } +screenpipe-audio = { path = "../../../../screenpipe-audio", features = [] } + +# Windows +[target.'cfg(target_os = "windows")'.dependencies] +screenpipe-server = { path = "../../../../screenpipe-server", features = [] } +screenpipe-audio = { path = "../../../../screenpipe-audio", features = [] } + +[target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies] +tauri-plugin-cli = "2.0.0-alpha.2" +tauri-plugin-updater = "2.0.0-alpha.2" + +[features] cuda = ["screenpipe-server/cuda", "screenpipe-audio/cuda"] +metal = ["screenpipe-server/metal", "screenpipe-audio/metal"] +# DO NOT REMOVE!! +custom-protocol = [ "tauri/custom-protocol" ] diff --git a/examples/apps/screen-pipe-app/src-tauri/build.rs b/examples/apps/screen-pipe-app/src-tauri/build.rs index 795b9b7c8..d860e1e6a 100644 --- a/examples/apps/screen-pipe-app/src-tauri/build.rs +++ b/examples/apps/screen-pipe-app/src-tauri/build.rs @@ -1,3 +1,3 @@ fn main() { - tauri_build::build() + tauri_build::build() } diff --git a/examples/apps/screen-pipe-app/src-tauri/capabilities/main.json b/examples/apps/screen-pipe-app/src-tauri/capabilities/main.json new file mode 100644 index 000000000..ae1432223 --- /dev/null +++ b/examples/apps/screen-pipe-app/src-tauri/capabilities/main.json @@ -0,0 +1,40 @@ +{ + "identifier": "migrated", + "description": "permissions that were migrated from v1", + "local": true, + "windows": [ + "main" + ], + "permissions": [ + "path:default", + "event:default", + "window:default", + "app:default", + "resources:default", + "menu:default", + "tray:default", + "shell:default", + "store:allow-get", + "store:allow-set", + "store:allow-save", + "store:allow-load", + { + "identifier": "shell:allow-execute", + "allow": [ + { + "name": "exec-sh", + "cmd": "sh", + "args": [ + "-c", + { + "validator": "\\S+" + } + ], + "sidecar": false + } + ] + }, + "cli:default", + "updater:default" + ] +} \ No newline at end of file diff --git a/examples/apps/screen-pipe-app/src-tauri/gen/schemas/acl-manifests.json b/examples/apps/screen-pipe-app/src-tauri/gen/schemas/acl-manifests.json new file mode 100644 index 000000000..e2b2d758d --- /dev/null +++ b/examples/apps/screen-pipe-app/src-tauri/gen/schemas/acl-manifests.json @@ -0,0 +1 @@ +{"app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"autostart":{"default_permission":{"identifier":"default","description":"This permission set configures if your\napplication can enable or disable auto\nstarting the application on boot.\n\n#### Granted Permissions\n\nIt allows all to check, enable and\ndisable the automatic start on boot.\n\n","permissions":["allow-enable","allow-disable","allow-is-enabled"]},"permissions":{"allow-disable":{"identifier":"allow-disable","description":"Enables the disable command without any pre-configured scope.","commands":{"allow":["disable"],"deny":[]}},"allow-enable":{"identifier":"allow-enable","description":"Enables the enable command without any pre-configured scope.","commands":{"allow":["enable"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"deny-disable":{"identifier":"deny-disable","description":"Denies the disable command without any pre-configured scope.","commands":{"allow":[],"deny":["disable"]}},"deny-enable":{"identifier":"deny-enable","description":"Denies the enable command without any pre-configured scope.","commands":{"allow":[],"deny":["enable"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}}},"permission_sets":{},"global_scope_schema":null},"cli":{"default_permission":{"identifier":"default","description":"Allows reading the CLI matches","permissions":["allow-cli-matches"]},"permissions":{"allow-cli-matches":{"identifier":"allow-cli-matches","description":"Enables the cli_matches command without any pre-configured scope.","commands":{"allow":["cli_matches"],"deny":[]}},"deny-cli-matches":{"identifier":"deny-cli-matches","description":"Denies the cli_matches command without any pre-configured scope.","commands":{"allow":[],"deny":["cli_matches"]}}},"permission_sets":{},"global_scope_schema":null},"event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"shell":{"default_permission":{"identifier":"default","description":"This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n","permissions":["allow-open"]},"permissions":{"allow-execute":{"identifier":"allow-execute","description":"Enables the execute command without any pre-configured scope.","commands":{"allow":["execute"],"deny":[]}},"allow-kill":{"identifier":"allow-kill","description":"Enables the kill command without any pre-configured scope.","commands":{"allow":["kill"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-spawn":{"identifier":"allow-spawn","description":"Enables the spawn command without any pre-configured scope.","commands":{"allow":["spawn"],"deny":[]}},"allow-stdin-write":{"identifier":"allow-stdin-write","description":"Enables the stdin_write command without any pre-configured scope.","commands":{"allow":["stdin_write"],"deny":[]}},"deny-execute":{"identifier":"deny-execute","description":"Denies the execute command without any pre-configured scope.","commands":{"allow":[],"deny":["execute"]}},"deny-kill":{"identifier":"deny-kill","description":"Denies the kill command without any pre-configured scope.","commands":{"allow":[],"deny":["kill"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-spawn":{"identifier":"deny-spawn","description":"Denies the spawn command without any pre-configured scope.","commands":{"allow":[],"deny":["spawn"]}},"deny-stdin-write":{"identifier":"deny-stdin-write","description":"Denies the stdin_write command without any pre-configured scope.","commands":{"allow":[],"deny":["stdin_write"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","definitions":{"ShellAllowedArg":{"anyOf":[{"description":"A non-configurable argument that is passed to the command in the order it was specified.","type":"string"},{"additionalProperties":false,"description":"A variable that is set while calling the command from the webview API.","properties":{"validator":{"description":"[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\n[regex]: https://docs.rs/regex/latest/regex/#syntax","type":"string"}},"required":["validator"],"type":"object"}],"description":"A command argument allowed to be executed by the webview API."},"ShellAllowedArgs":{"anyOf":[{"description":"Use a simple boolean to allow all or disable all arguments to this command configuration.","type":"boolean"},{"description":"A specific set of [`ShellAllowedArg`] that are valid to call for the command configuration.","items":{"$ref":"#/definitions/ShellAllowedArg"},"type":"array"}],"description":"A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration."}},"description":"A command allowed to be executed by the webview API.","properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellAllowedArgs"}],"description":"The allowed arguments for the command execution."},"cmd":{"description":"The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"},"sidecar":{"description":"If this command is a sidecar command.","type":"boolean"}},"required":["args","cmd","name","sidecar"],"title":"Entry","type":"object"}},"store":{"default_permission":{"identifier":"default","description":"This permission set configures what kind of\noperations are available from the store plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n","permissions":["allow-clear","allow-delete","allow-entries","allow-get","allow-has","allow-keys","allow-length","allow-load","allow-reset","allow-save","allow-set","allow-values"]},"permissions":{"allow-clear":{"identifier":"allow-clear","description":"Enables the clear command without any pre-configured scope.","commands":{"allow":["clear"],"deny":[]}},"allow-delete":{"identifier":"allow-delete","description":"Enables the delete command without any pre-configured scope.","commands":{"allow":["delete"],"deny":[]}},"allow-entries":{"identifier":"allow-entries","description":"Enables the entries command without any pre-configured scope.","commands":{"allow":["entries"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-has":{"identifier":"allow-has","description":"Enables the has command without any pre-configured scope.","commands":{"allow":["has"],"deny":[]}},"allow-keys":{"identifier":"allow-keys","description":"Enables the keys command without any pre-configured scope.","commands":{"allow":["keys"],"deny":[]}},"allow-length":{"identifier":"allow-length","description":"Enables the length command without any pre-configured scope.","commands":{"allow":["length"],"deny":[]}},"allow-load":{"identifier":"allow-load","description":"Enables the load command without any pre-configured scope.","commands":{"allow":["load"],"deny":[]}},"allow-reset":{"identifier":"allow-reset","description":"Enables the reset command without any pre-configured scope.","commands":{"allow":["reset"],"deny":[]}},"allow-save":{"identifier":"allow-save","description":"Enables the save command without any pre-configured scope.","commands":{"allow":["save"],"deny":[]}},"allow-set":{"identifier":"allow-set","description":"Enables the set command without any pre-configured scope.","commands":{"allow":["set"],"deny":[]}},"allow-values":{"identifier":"allow-values","description":"Enables the values command without any pre-configured scope.","commands":{"allow":["values"],"deny":[]}},"deny-clear":{"identifier":"deny-clear","description":"Denies the clear command without any pre-configured scope.","commands":{"allow":[],"deny":["clear"]}},"deny-delete":{"identifier":"deny-delete","description":"Denies the delete command without any pre-configured scope.","commands":{"allow":[],"deny":["delete"]}},"deny-entries":{"identifier":"deny-entries","description":"Denies the entries command without any pre-configured scope.","commands":{"allow":[],"deny":["entries"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-has":{"identifier":"deny-has","description":"Denies the has command without any pre-configured scope.","commands":{"allow":[],"deny":["has"]}},"deny-keys":{"identifier":"deny-keys","description":"Denies the keys command without any pre-configured scope.","commands":{"allow":[],"deny":["keys"]}},"deny-length":{"identifier":"deny-length","description":"Denies the length command without any pre-configured scope.","commands":{"allow":[],"deny":["length"]}},"deny-load":{"identifier":"deny-load","description":"Denies the load command without any pre-configured scope.","commands":{"allow":[],"deny":["load"]}},"deny-reset":{"identifier":"deny-reset","description":"Denies the reset command without any pre-configured scope.","commands":{"allow":[],"deny":["reset"]}},"deny-save":{"identifier":"deny-save","description":"Denies the save command without any pre-configured scope.","commands":{"allow":[],"deny":["save"]}},"deny-set":{"identifier":"deny-set","description":"Denies the set command without any pre-configured scope.","commands":{"allow":[],"deny":["set"]}},"deny-values":{"identifier":"deny-values","description":"Denies the values command without any pre-configured scope.","commands":{"allow":[],"deny":["values"]}}},"permission_sets":{},"global_scope_schema":null},"tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"updater":{"default_permission":{"identifier":"default","description":"This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n","permissions":["allow-check","allow-download","allow-install","allow-download-and-install"]},"permissions":{"allow-check":{"identifier":"allow-check","description":"Enables the check command without any pre-configured scope.","commands":{"allow":["check"],"deny":[]}},"allow-download":{"identifier":"allow-download","description":"Enables the download command without any pre-configured scope.","commands":{"allow":["download"],"deny":[]}},"allow-download-and-install":{"identifier":"allow-download-and-install","description":"Enables the download_and_install command without any pre-configured scope.","commands":{"allow":["download_and_install"],"deny":[]}},"allow-install":{"identifier":"allow-install","description":"Enables the install command without any pre-configured scope.","commands":{"allow":["install"],"deny":[]}},"deny-check":{"identifier":"deny-check","description":"Denies the check command without any pre-configured scope.","commands":{"allow":[],"deny":["check"]}},"deny-download":{"identifier":"deny-download","description":"Denies the download command without any pre-configured scope.","commands":{"allow":[],"deny":["download"]}},"deny-download-and-install":{"identifier":"deny-download-and-install","description":"Denies the download_and_install command without any pre-configured scope.","commands":{"allow":[],"deny":["download_and_install"]}},"deny-install":{"identifier":"deny-install","description":"Denies the install command without any pre-configured scope.","commands":{"allow":[],"deny":["install"]}}},"permission_sets":{},"global_scope_schema":null},"webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-internal-toggle-maximize"]},"permissions":{"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null}} \ No newline at end of file diff --git a/examples/apps/screen-pipe-app/src-tauri/gen/schemas/capabilities.json b/examples/apps/screen-pipe-app/src-tauri/gen/schemas/capabilities.json new file mode 100644 index 000000000..38bd88597 --- /dev/null +++ b/examples/apps/screen-pipe-app/src-tauri/gen/schemas/capabilities.json @@ -0,0 +1 @@ +{"migrated":{"identifier":"migrated","description":"permissions that were migrated from v1","local":true,"windows":["main"],"permissions":["path:default","event:default","window:default","app:default","resources:default","menu:default","tray:default","shell:default","store:allow-get","store:allow-set","store:allow-save","store:allow-load",{"identifier":"shell:allow-execute","allow":[{"args":["-c",{"validator":"\\S+"}],"cmd":"sh","name":"exec-sh","sidecar":false}]},"cli:default","updater:default"]}} \ No newline at end of file diff --git a/examples/apps/screen-pipe-app/src-tauri/gen/schemas/desktop-schema.json b/examples/apps/screen-pipe-app/src-tauri/gen/schemas/desktop-schema.json new file mode 100644 index 000000000..19205eb6e --- /dev/null +++ b/examples/apps/screen-pipe-app/src-tauri/gen/schemas/desktop-schema.json @@ -0,0 +1,2748 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CapabilityFile", + "description": "Capability formats accepted in a capability file.", + "anyOf": [ + { + "description": "A single capability.", + "allOf": [ + { + "$ref": "#/definitions/Capability" + } + ] + }, + { + "description": "A list of capabilities.", + "type": "array", + "items": { + "$ref": "#/definitions/Capability" + } + }, + { + "description": "A list of capabilities.", + "type": "object", + "required": [ + "capabilities" + ], + "properties": { + "capabilities": { + "description": "The list of capabilities.", + "type": "array", + "items": { + "$ref": "#/definitions/Capability" + } + } + } + } + ], + "definitions": { + "Capability": { + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"path:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, \"platforms\": [\"macOS\",\"windows\"] } ```", + "type": "object", + "required": [ + "identifier", + "permissions" + ], + "properties": { + "identifier": { + "description": "Identifier of the capability.\n\n## Example\n\n`main-user-files-write`", + "type": "string" + }, + "description": { + "description": "Description of what the capability is intended to allow on associated windows.\n\nIt should contain a description of what the grouped permissions should allow.\n\n## Example\n\nThis capability allows the `main` window access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.", + "default": "", + "type": "string" + }, + "remote": { + "description": "Configure remote URLs that can use the capability permissions.\n\nThis setting is optional and defaults to not being set, as our default use case is that the content is served from our local application.\n\n:::caution Make sure you understand the security implications of providing remote sources with local system access. :::\n\n## Example\n\n```json { \"urls\": [\"https://*.mydomain.dev\"] } ```", + "anyOf": [ + { + "$ref": "#/definitions/CapabilityRemote" + }, + { + "type": "null" + } + ] + }, + "local": { + "description": "Whether this capability is enabled for local app URLs or not. Defaults to `true`.", + "default": true, + "type": "boolean" + }, + "windows": { + "description": "List of windows that are affected by this capability. Can be a glob pattern.\n\nOn multiwebview windows, prefer [`Self::webviews`] for a fine grained access control.\n\n## Example\n\n`[\"main\"]`", + "type": "array", + "items": { + "type": "string" + } + }, + "webviews": { + "description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\nThis is only required when using on multiwebview contexts, by default all child webviews of a window that matches [`Self::windows`] are linked.\n\n## Example\n\n`[\"sub-webview-one\", \"sub-webview-two\"]`", + "type": "array", + "items": { + "type": "string" + } + }, + "permissions": { + "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"path:default\", \"event:default\", \"window:default\", \"app:default\", \"image:default\", \"resources:default\", \"menu:default\", \"tray:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ```", + "type": "array", + "items": { + "$ref": "#/definitions/PermissionEntry" + }, + "uniqueItems": true + }, + "platforms": { + "description": "Limit which target platforms this capability applies to.\n\nBy default all platforms are targeted.\n\n## Example\n\n`[\"macOS\",\"windows\"]`", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/Target" + } + } + } + }, + "CapabilityRemote": { + "description": "Configuration for remote URLs that are associated with the capability.", + "type": "object", + "required": [ + "urls" + ], + "properties": { + "urls": { + "description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).\n\n## Examples\n\n- \"https://*.mydomain.dev\": allows subdomains of mydomain.dev - \"https://mydomain.dev/api/*\": allows any subpath of mydomain.dev/api", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "PermissionEntry": { + "description": "An entry for a permission value in a [`Capability`] can be either a raw permission [`Identifier`] or an object that references a permission and extends its scope.", + "anyOf": [ + { + "description": "Reference a permission or permission set by identifier.", + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ] + }, + { + "description": "Reference a permission or permission set by identifier and extends its scope.", + "type": "object", + "oneOf": [ + { + "type": "object", + "required": [ + "identifier" + ], + "properties": { + "identifier": { + "oneOf": [ + { + "description": "shell:default -> This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", + "type": "string", + "enum": [ + "shell:default" + ] + }, + { + "description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-execute" + ] + }, + { + "description": "shell:allow-kill -> Enables the kill command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-kill" + ] + }, + { + "description": "shell:allow-open -> Enables the open command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-open" + ] + }, + { + "description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-spawn" + ] + }, + { + "description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-stdin-write" + ] + }, + { + "description": "shell:deny-execute -> Denies the execute command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-execute" + ] + }, + { + "description": "shell:deny-kill -> Denies the kill command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-kill" + ] + }, + { + "description": "shell:deny-open -> Denies the open command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-open" + ] + }, + { + "description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-spawn" + ] + }, + { + "description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-stdin-write" + ] + } + ] + }, + "allow": { + "items": { + "title": "Entry", + "description": "A command allowed to be executed by the webview API.", + "type": "object", + "required": [ + "args", + "cmd", + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + } + } + }, + "deny": { + "items": { + "title": "Entry", + "description": "A command allowed to be executed by the webview API.", + "type": "object", + "required": [ + "args", + "cmd", + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + } + } + } + } + } + ] + } + ] + }, + "Identifier": { + "oneOf": [ + { + "description": "app:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "app:default" + ] + }, + { + "description": "app:allow-app-hide -> Enables the app_hide command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:allow-app-hide" + ] + }, + { + "description": "app:allow-app-show -> Enables the app_show command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:allow-app-show" + ] + }, + { + "description": "app:allow-default-window-icon -> Enables the default_window_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:allow-default-window-icon" + ] + }, + { + "description": "app:allow-name -> Enables the name command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:allow-name" + ] + }, + { + "description": "app:allow-tauri-version -> Enables the tauri_version command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:allow-tauri-version" + ] + }, + { + "description": "app:allow-version -> Enables the version command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:allow-version" + ] + }, + { + "description": "app:deny-app-hide -> Denies the app_hide command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:deny-app-hide" + ] + }, + { + "description": "app:deny-app-show -> Denies the app_show command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:deny-app-show" + ] + }, + { + "description": "app:deny-default-window-icon -> Denies the default_window_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:deny-default-window-icon" + ] + }, + { + "description": "app:deny-name -> Denies the name command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:deny-name" + ] + }, + { + "description": "app:deny-tauri-version -> Denies the tauri_version command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:deny-tauri-version" + ] + }, + { + "description": "app:deny-version -> Denies the version command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:deny-version" + ] + }, + { + "description": "autostart:default -> This permission set configures if your\napplication can enable or disable auto\nstarting the application on boot.\n\n#### Granted Permissions\n\nIt allows all to check, enable and\ndisable the automatic start on boot.\n\n", + "type": "string", + "enum": [ + "autostart:default" + ] + }, + { + "description": "autostart:allow-disable -> Enables the disable command without any pre-configured scope.", + "type": "string", + "enum": [ + "autostart:allow-disable" + ] + }, + { + "description": "autostart:allow-enable -> Enables the enable command without any pre-configured scope.", + "type": "string", + "enum": [ + "autostart:allow-enable" + ] + }, + { + "description": "autostart:allow-is-enabled -> Enables the is_enabled command without any pre-configured scope.", + "type": "string", + "enum": [ + "autostart:allow-is-enabled" + ] + }, + { + "description": "autostart:deny-disable -> Denies the disable command without any pre-configured scope.", + "type": "string", + "enum": [ + "autostart:deny-disable" + ] + }, + { + "description": "autostart:deny-enable -> Denies the enable command without any pre-configured scope.", + "type": "string", + "enum": [ + "autostart:deny-enable" + ] + }, + { + "description": "autostart:deny-is-enabled -> Denies the is_enabled command without any pre-configured scope.", + "type": "string", + "enum": [ + "autostart:deny-is-enabled" + ] + }, + { + "description": "cli:default -> Allows reading the CLI matches", + "type": "string", + "enum": [ + "cli:default" + ] + }, + { + "description": "cli:allow-cli-matches -> Enables the cli_matches command without any pre-configured scope.", + "type": "string", + "enum": [ + "cli:allow-cli-matches" + ] + }, + { + "description": "cli:deny-cli-matches -> Denies the cli_matches command without any pre-configured scope.", + "type": "string", + "enum": [ + "cli:deny-cli-matches" + ] + }, + { + "description": "event:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "event:default" + ] + }, + { + "description": "event:allow-emit -> Enables the emit command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:allow-emit" + ] + }, + { + "description": "event:allow-emit-to -> Enables the emit_to command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:allow-emit-to" + ] + }, + { + "description": "event:allow-listen -> Enables the listen command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:allow-listen" + ] + }, + { + "description": "event:allow-unlisten -> Enables the unlisten command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:allow-unlisten" + ] + }, + { + "description": "event:deny-emit -> Denies the emit command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:deny-emit" + ] + }, + { + "description": "event:deny-emit-to -> Denies the emit_to command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:deny-emit-to" + ] + }, + { + "description": "event:deny-listen -> Denies the listen command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:deny-listen" + ] + }, + { + "description": "event:deny-unlisten -> Denies the unlisten command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:deny-unlisten" + ] + }, + { + "description": "image:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "image:default" + ] + }, + { + "description": "image:allow-from-bytes -> Enables the from_bytes command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:allow-from-bytes" + ] + }, + { + "description": "image:allow-from-path -> Enables the from_path command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:allow-from-path" + ] + }, + { + "description": "image:allow-new -> Enables the new command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:allow-new" + ] + }, + { + "description": "image:allow-rgba -> Enables the rgba command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:allow-rgba" + ] + }, + { + "description": "image:allow-size -> Enables the size command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:allow-size" + ] + }, + { + "description": "image:deny-from-bytes -> Denies the from_bytes command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:deny-from-bytes" + ] + }, + { + "description": "image:deny-from-path -> Denies the from_path command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:deny-from-path" + ] + }, + { + "description": "image:deny-new -> Denies the new command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:deny-new" + ] + }, + { + "description": "image:deny-rgba -> Denies the rgba command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:deny-rgba" + ] + }, + { + "description": "image:deny-size -> Denies the size command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:deny-size" + ] + }, + { + "description": "menu:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "menu:default" + ] + }, + { + "description": "menu:allow-append -> Enables the append command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-append" + ] + }, + { + "description": "menu:allow-create-default -> Enables the create_default command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-create-default" + ] + }, + { + "description": "menu:allow-get -> Enables the get command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-get" + ] + }, + { + "description": "menu:allow-insert -> Enables the insert command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-insert" + ] + }, + { + "description": "menu:allow-is-checked -> Enables the is_checked command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-is-checked" + ] + }, + { + "description": "menu:allow-is-enabled -> Enables the is_enabled command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-is-enabled" + ] + }, + { + "description": "menu:allow-items -> Enables the items command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-items" + ] + }, + { + "description": "menu:allow-new -> Enables the new command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-new" + ] + }, + { + "description": "menu:allow-popup -> Enables the popup command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-popup" + ] + }, + { + "description": "menu:allow-prepend -> Enables the prepend command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-prepend" + ] + }, + { + "description": "menu:allow-remove -> Enables the remove command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-remove" + ] + }, + { + "description": "menu:allow-remove-at -> Enables the remove_at command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-remove-at" + ] + }, + { + "description": "menu:allow-set-accelerator -> Enables the set_accelerator command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-accelerator" + ] + }, + { + "description": "menu:allow-set-as-app-menu -> Enables the set_as_app_menu command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-as-app-menu" + ] + }, + { + "description": "menu:allow-set-as-help-menu-for-nsapp -> Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-as-help-menu-for-nsapp" + ] + }, + { + "description": "menu:allow-set-as-window-menu -> Enables the set_as_window_menu command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-as-window-menu" + ] + }, + { + "description": "menu:allow-set-as-windows-menu-for-nsapp -> Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-as-windows-menu-for-nsapp" + ] + }, + { + "description": "menu:allow-set-checked -> Enables the set_checked command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-checked" + ] + }, + { + "description": "menu:allow-set-enabled -> Enables the set_enabled command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-enabled" + ] + }, + { + "description": "menu:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-icon" + ] + }, + { + "description": "menu:allow-set-text -> Enables the set_text command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-text" + ] + }, + { + "description": "menu:allow-text -> Enables the text command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-text" + ] + }, + { + "description": "menu:deny-append -> Denies the append command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-append" + ] + }, + { + "description": "menu:deny-create-default -> Denies the create_default command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-create-default" + ] + }, + { + "description": "menu:deny-get -> Denies the get command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-get" + ] + }, + { + "description": "menu:deny-insert -> Denies the insert command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-insert" + ] + }, + { + "description": "menu:deny-is-checked -> Denies the is_checked command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-is-checked" + ] + }, + { + "description": "menu:deny-is-enabled -> Denies the is_enabled command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-is-enabled" + ] + }, + { + "description": "menu:deny-items -> Denies the items command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-items" + ] + }, + { + "description": "menu:deny-new -> Denies the new command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-new" + ] + }, + { + "description": "menu:deny-popup -> Denies the popup command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-popup" + ] + }, + { + "description": "menu:deny-prepend -> Denies the prepend command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-prepend" + ] + }, + { + "description": "menu:deny-remove -> Denies the remove command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-remove" + ] + }, + { + "description": "menu:deny-remove-at -> Denies the remove_at command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-remove-at" + ] + }, + { + "description": "menu:deny-set-accelerator -> Denies the set_accelerator command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-accelerator" + ] + }, + { + "description": "menu:deny-set-as-app-menu -> Denies the set_as_app_menu command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-as-app-menu" + ] + }, + { + "description": "menu:deny-set-as-help-menu-for-nsapp -> Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-as-help-menu-for-nsapp" + ] + }, + { + "description": "menu:deny-set-as-window-menu -> Denies the set_as_window_menu command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-as-window-menu" + ] + }, + { + "description": "menu:deny-set-as-windows-menu-for-nsapp -> Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-as-windows-menu-for-nsapp" + ] + }, + { + "description": "menu:deny-set-checked -> Denies the set_checked command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-checked" + ] + }, + { + "description": "menu:deny-set-enabled -> Denies the set_enabled command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-enabled" + ] + }, + { + "description": "menu:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-icon" + ] + }, + { + "description": "menu:deny-set-text -> Denies the set_text command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-text" + ] + }, + { + "description": "menu:deny-text -> Denies the text command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-text" + ] + }, + { + "description": "path:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "path:default" + ] + }, + { + "description": "path:allow-basename -> Enables the basename command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-basename" + ] + }, + { + "description": "path:allow-dirname -> Enables the dirname command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-dirname" + ] + }, + { + "description": "path:allow-extname -> Enables the extname command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-extname" + ] + }, + { + "description": "path:allow-is-absolute -> Enables the is_absolute command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-is-absolute" + ] + }, + { + "description": "path:allow-join -> Enables the join command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-join" + ] + }, + { + "description": "path:allow-normalize -> Enables the normalize command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-normalize" + ] + }, + { + "description": "path:allow-resolve -> Enables the resolve command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-resolve" + ] + }, + { + "description": "path:allow-resolve-directory -> Enables the resolve_directory command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-resolve-directory" + ] + }, + { + "description": "path:deny-basename -> Denies the basename command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-basename" + ] + }, + { + "description": "path:deny-dirname -> Denies the dirname command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-dirname" + ] + }, + { + "description": "path:deny-extname -> Denies the extname command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-extname" + ] + }, + { + "description": "path:deny-is-absolute -> Denies the is_absolute command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-is-absolute" + ] + }, + { + "description": "path:deny-join -> Denies the join command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-join" + ] + }, + { + "description": "path:deny-normalize -> Denies the normalize command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-normalize" + ] + }, + { + "description": "path:deny-resolve -> Denies the resolve command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-resolve" + ] + }, + { + "description": "path:deny-resolve-directory -> Denies the resolve_directory command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-resolve-directory" + ] + }, + { + "description": "resources:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "resources:default" + ] + }, + { + "description": "resources:allow-close -> Enables the close command without any pre-configured scope.", + "type": "string", + "enum": [ + "resources:allow-close" + ] + }, + { + "description": "resources:deny-close -> Denies the close command without any pre-configured scope.", + "type": "string", + "enum": [ + "resources:deny-close" + ] + }, + { + "description": "shell:default -> This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", + "type": "string", + "enum": [ + "shell:default" + ] + }, + { + "description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-execute" + ] + }, + { + "description": "shell:allow-kill -> Enables the kill command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-kill" + ] + }, + { + "description": "shell:allow-open -> Enables the open command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-open" + ] + }, + { + "description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-spawn" + ] + }, + { + "description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-stdin-write" + ] + }, + { + "description": "shell:deny-execute -> Denies the execute command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-execute" + ] + }, + { + "description": "shell:deny-kill -> Denies the kill command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-kill" + ] + }, + { + "description": "shell:deny-open -> Denies the open command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-open" + ] + }, + { + "description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-spawn" + ] + }, + { + "description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-stdin-write" + ] + }, + { + "description": "store:default -> This permission set configures what kind of\noperations are available from the store plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n", + "type": "string", + "enum": [ + "store:default" + ] + }, + { + "description": "store:allow-clear -> Enables the clear command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-clear" + ] + }, + { + "description": "store:allow-delete -> Enables the delete command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-delete" + ] + }, + { + "description": "store:allow-entries -> Enables the entries command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-entries" + ] + }, + { + "description": "store:allow-get -> Enables the get command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-get" + ] + }, + { + "description": "store:allow-has -> Enables the has command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-has" + ] + }, + { + "description": "store:allow-keys -> Enables the keys command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-keys" + ] + }, + { + "description": "store:allow-length -> Enables the length command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-length" + ] + }, + { + "description": "store:allow-load -> Enables the load command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-load" + ] + }, + { + "description": "store:allow-reset -> Enables the reset command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-reset" + ] + }, + { + "description": "store:allow-save -> Enables the save command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-save" + ] + }, + { + "description": "store:allow-set -> Enables the set command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-set" + ] + }, + { + "description": "store:allow-values -> Enables the values command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-values" + ] + }, + { + "description": "store:deny-clear -> Denies the clear command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-clear" + ] + }, + { + "description": "store:deny-delete -> Denies the delete command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-delete" + ] + }, + { + "description": "store:deny-entries -> Denies the entries command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-entries" + ] + }, + { + "description": "store:deny-get -> Denies the get command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-get" + ] + }, + { + "description": "store:deny-has -> Denies the has command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-has" + ] + }, + { + "description": "store:deny-keys -> Denies the keys command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-keys" + ] + }, + { + "description": "store:deny-length -> Denies the length command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-length" + ] + }, + { + "description": "store:deny-load -> Denies the load command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-load" + ] + }, + { + "description": "store:deny-reset -> Denies the reset command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-reset" + ] + }, + { + "description": "store:deny-save -> Denies the save command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-save" + ] + }, + { + "description": "store:deny-set -> Denies the set command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-set" + ] + }, + { + "description": "store:deny-values -> Denies the values command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-values" + ] + }, + { + "description": "tray:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "tray:default" + ] + }, + { + "description": "tray:allow-get-by-id -> Enables the get_by_id command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-get-by-id" + ] + }, + { + "description": "tray:allow-new -> Enables the new command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-new" + ] + }, + { + "description": "tray:allow-remove-by-id -> Enables the remove_by_id command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-remove-by-id" + ] + }, + { + "description": "tray:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-icon" + ] + }, + { + "description": "tray:allow-set-icon-as-template -> Enables the set_icon_as_template command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-icon-as-template" + ] + }, + { + "description": "tray:allow-set-menu -> Enables the set_menu command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-menu" + ] + }, + { + "description": "tray:allow-set-show-menu-on-left-click -> Enables the set_show_menu_on_left_click command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-show-menu-on-left-click" + ] + }, + { + "description": "tray:allow-set-temp-dir-path -> Enables the set_temp_dir_path command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-temp-dir-path" + ] + }, + { + "description": "tray:allow-set-title -> Enables the set_title command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-title" + ] + }, + { + "description": "tray:allow-set-tooltip -> Enables the set_tooltip command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-tooltip" + ] + }, + { + "description": "tray:allow-set-visible -> Enables the set_visible command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-visible" + ] + }, + { + "description": "tray:deny-get-by-id -> Denies the get_by_id command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-get-by-id" + ] + }, + { + "description": "tray:deny-new -> Denies the new command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-new" + ] + }, + { + "description": "tray:deny-remove-by-id -> Denies the remove_by_id command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-remove-by-id" + ] + }, + { + "description": "tray:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-icon" + ] + }, + { + "description": "tray:deny-set-icon-as-template -> Denies the set_icon_as_template command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-icon-as-template" + ] + }, + { + "description": "tray:deny-set-menu -> Denies the set_menu command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-menu" + ] + }, + { + "description": "tray:deny-set-show-menu-on-left-click -> Denies the set_show_menu_on_left_click command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-show-menu-on-left-click" + ] + }, + { + "description": "tray:deny-set-temp-dir-path -> Denies the set_temp_dir_path command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-temp-dir-path" + ] + }, + { + "description": "tray:deny-set-title -> Denies the set_title command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-title" + ] + }, + { + "description": "tray:deny-set-tooltip -> Denies the set_tooltip command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-tooltip" + ] + }, + { + "description": "tray:deny-set-visible -> Denies the set_visible command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-visible" + ] + }, + { + "description": "updater:default -> This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n", + "type": "string", + "enum": [ + "updater:default" + ] + }, + { + "description": "updater:allow-check -> Enables the check command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:allow-check" + ] + }, + { + "description": "updater:allow-download -> Enables the download command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:allow-download" + ] + }, + { + "description": "updater:allow-download-and-install -> Enables the download_and_install command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:allow-download-and-install" + ] + }, + { + "description": "updater:allow-install -> Enables the install command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:allow-install" + ] + }, + { + "description": "updater:deny-check -> Denies the check command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:deny-check" + ] + }, + { + "description": "updater:deny-download -> Denies the download command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:deny-download" + ] + }, + { + "description": "updater:deny-download-and-install -> Denies the download_and_install command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:deny-download-and-install" + ] + }, + { + "description": "updater:deny-install -> Denies the install command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:deny-install" + ] + }, + { + "description": "webview:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "webview:default" + ] + }, + { + "description": "webview:allow-create-webview -> Enables the create_webview command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-create-webview" + ] + }, + { + "description": "webview:allow-create-webview-window -> Enables the create_webview_window command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-create-webview-window" + ] + }, + { + "description": "webview:allow-internal-toggle-devtools -> Enables the internal_toggle_devtools command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-internal-toggle-devtools" + ] + }, + { + "description": "webview:allow-print -> Enables the print command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-print" + ] + }, + { + "description": "webview:allow-reparent -> Enables the reparent command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-reparent" + ] + }, + { + "description": "webview:allow-set-webview-focus -> Enables the set_webview_focus command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-set-webview-focus" + ] + }, + { + "description": "webview:allow-set-webview-position -> Enables the set_webview_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-set-webview-position" + ] + }, + { + "description": "webview:allow-set-webview-size -> Enables the set_webview_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-set-webview-size" + ] + }, + { + "description": "webview:allow-set-webview-zoom -> Enables the set_webview_zoom command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-set-webview-zoom" + ] + }, + { + "description": "webview:allow-webview-close -> Enables the webview_close command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-webview-close" + ] + }, + { + "description": "webview:allow-webview-position -> Enables the webview_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-webview-position" + ] + }, + { + "description": "webview:allow-webview-size -> Enables the webview_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-webview-size" + ] + }, + { + "description": "webview:deny-create-webview -> Denies the create_webview command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-create-webview" + ] + }, + { + "description": "webview:deny-create-webview-window -> Denies the create_webview_window command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-create-webview-window" + ] + }, + { + "description": "webview:deny-internal-toggle-devtools -> Denies the internal_toggle_devtools command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-internal-toggle-devtools" + ] + }, + { + "description": "webview:deny-print -> Denies the print command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-print" + ] + }, + { + "description": "webview:deny-reparent -> Denies the reparent command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-reparent" + ] + }, + { + "description": "webview:deny-set-webview-focus -> Denies the set_webview_focus command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-set-webview-focus" + ] + }, + { + "description": "webview:deny-set-webview-position -> Denies the set_webview_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-set-webview-position" + ] + }, + { + "description": "webview:deny-set-webview-size -> Denies the set_webview_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-set-webview-size" + ] + }, + { + "description": "webview:deny-set-webview-zoom -> Denies the set_webview_zoom command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-set-webview-zoom" + ] + }, + { + "description": "webview:deny-webview-close -> Denies the webview_close command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-webview-close" + ] + }, + { + "description": "webview:deny-webview-position -> Denies the webview_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-webview-position" + ] + }, + { + "description": "webview:deny-webview-size -> Denies the webview_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-webview-size" + ] + }, + { + "description": "window:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "window:default" + ] + }, + { + "description": "window:allow-available-monitors -> Enables the available_monitors command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-available-monitors" + ] + }, + { + "description": "window:allow-center -> Enables the center command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-center" + ] + }, + { + "description": "window:allow-close -> Enables the close command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-close" + ] + }, + { + "description": "window:allow-create -> Enables the create command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-create" + ] + }, + { + "description": "window:allow-current-monitor -> Enables the current_monitor command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-current-monitor" + ] + }, + { + "description": "window:allow-cursor-position -> Enables the cursor_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-cursor-position" + ] + }, + { + "description": "window:allow-destroy -> Enables the destroy command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-destroy" + ] + }, + { + "description": "window:allow-hide -> Enables the hide command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-hide" + ] + }, + { + "description": "window:allow-inner-position -> Enables the inner_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-inner-position" + ] + }, + { + "description": "window:allow-inner-size -> Enables the inner_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-inner-size" + ] + }, + { + "description": "window:allow-internal-toggle-maximize -> Enables the internal_toggle_maximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-internal-toggle-maximize" + ] + }, + { + "description": "window:allow-is-closable -> Enables the is_closable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-closable" + ] + }, + { + "description": "window:allow-is-decorated -> Enables the is_decorated command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-decorated" + ] + }, + { + "description": "window:allow-is-focused -> Enables the is_focused command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-focused" + ] + }, + { + "description": "window:allow-is-fullscreen -> Enables the is_fullscreen command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-fullscreen" + ] + }, + { + "description": "window:allow-is-maximizable -> Enables the is_maximizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-maximizable" + ] + }, + { + "description": "window:allow-is-maximized -> Enables the is_maximized command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-maximized" + ] + }, + { + "description": "window:allow-is-minimizable -> Enables the is_minimizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-minimizable" + ] + }, + { + "description": "window:allow-is-minimized -> Enables the is_minimized command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-minimized" + ] + }, + { + "description": "window:allow-is-resizable -> Enables the is_resizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-resizable" + ] + }, + { + "description": "window:allow-is-visible -> Enables the is_visible command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-visible" + ] + }, + { + "description": "window:allow-maximize -> Enables the maximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-maximize" + ] + }, + { + "description": "window:allow-minimize -> Enables the minimize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-minimize" + ] + }, + { + "description": "window:allow-monitor-from-point -> Enables the monitor_from_point command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-monitor-from-point" + ] + }, + { + "description": "window:allow-outer-position -> Enables the outer_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-outer-position" + ] + }, + { + "description": "window:allow-outer-size -> Enables the outer_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-outer-size" + ] + }, + { + "description": "window:allow-primary-monitor -> Enables the primary_monitor command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-primary-monitor" + ] + }, + { + "description": "window:allow-request-user-attention -> Enables the request_user_attention command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-request-user-attention" + ] + }, + { + "description": "window:allow-scale-factor -> Enables the scale_factor command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-scale-factor" + ] + }, + { + "description": "window:allow-set-always-on-bottom -> Enables the set_always_on_bottom command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-always-on-bottom" + ] + }, + { + "description": "window:allow-set-always-on-top -> Enables the set_always_on_top command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-always-on-top" + ] + }, + { + "description": "window:allow-set-closable -> Enables the set_closable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-closable" + ] + }, + { + "description": "window:allow-set-content-protected -> Enables the set_content_protected command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-content-protected" + ] + }, + { + "description": "window:allow-set-cursor-grab -> Enables the set_cursor_grab command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-cursor-grab" + ] + }, + { + "description": "window:allow-set-cursor-icon -> Enables the set_cursor_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-cursor-icon" + ] + }, + { + "description": "window:allow-set-cursor-position -> Enables the set_cursor_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-cursor-position" + ] + }, + { + "description": "window:allow-set-cursor-visible -> Enables the set_cursor_visible command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-cursor-visible" + ] + }, + { + "description": "window:allow-set-decorations -> Enables the set_decorations command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-decorations" + ] + }, + { + "description": "window:allow-set-effects -> Enables the set_effects command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-effects" + ] + }, + { + "description": "window:allow-set-focus -> Enables the set_focus command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-focus" + ] + }, + { + "description": "window:allow-set-fullscreen -> Enables the set_fullscreen command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-fullscreen" + ] + }, + { + "description": "window:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-icon" + ] + }, + { + "description": "window:allow-set-ignore-cursor-events -> Enables the set_ignore_cursor_events command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-ignore-cursor-events" + ] + }, + { + "description": "window:allow-set-max-size -> Enables the set_max_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-max-size" + ] + }, + { + "description": "window:allow-set-maximizable -> Enables the set_maximizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-maximizable" + ] + }, + { + "description": "window:allow-set-min-size -> Enables the set_min_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-min-size" + ] + }, + { + "description": "window:allow-set-minimizable -> Enables the set_minimizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-minimizable" + ] + }, + { + "description": "window:allow-set-position -> Enables the set_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-position" + ] + }, + { + "description": "window:allow-set-progress-bar -> Enables the set_progress_bar command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-progress-bar" + ] + }, + { + "description": "window:allow-set-resizable -> Enables the set_resizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-resizable" + ] + }, + { + "description": "window:allow-set-shadow -> Enables the set_shadow command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-shadow" + ] + }, + { + "description": "window:allow-set-size -> Enables the set_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-size" + ] + }, + { + "description": "window:allow-set-skip-taskbar -> Enables the set_skip_taskbar command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-skip-taskbar" + ] + }, + { + "description": "window:allow-set-title -> Enables the set_title command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-title" + ] + }, + { + "description": "window:allow-set-title-bar-style -> Enables the set_title_bar_style command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-title-bar-style" + ] + }, + { + "description": "window:allow-set-visible-on-all-workspaces -> Enables the set_visible_on_all_workspaces command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-visible-on-all-workspaces" + ] + }, + { + "description": "window:allow-show -> Enables the show command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-show" + ] + }, + { + "description": "window:allow-start-dragging -> Enables the start_dragging command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-start-dragging" + ] + }, + { + "description": "window:allow-start-resize-dragging -> Enables the start_resize_dragging command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-start-resize-dragging" + ] + }, + { + "description": "window:allow-theme -> Enables the theme command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-theme" + ] + }, + { + "description": "window:allow-title -> Enables the title command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-title" + ] + }, + { + "description": "window:allow-toggle-maximize -> Enables the toggle_maximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-toggle-maximize" + ] + }, + { + "description": "window:allow-unmaximize -> Enables the unmaximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-unmaximize" + ] + }, + { + "description": "window:allow-unminimize -> Enables the unminimize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-unminimize" + ] + }, + { + "description": "window:deny-available-monitors -> Denies the available_monitors command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-available-monitors" + ] + }, + { + "description": "window:deny-center -> Denies the center command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-center" + ] + }, + { + "description": "window:deny-close -> Denies the close command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-close" + ] + }, + { + "description": "window:deny-create -> Denies the create command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-create" + ] + }, + { + "description": "window:deny-current-monitor -> Denies the current_monitor command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-current-monitor" + ] + }, + { + "description": "window:deny-cursor-position -> Denies the cursor_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-cursor-position" + ] + }, + { + "description": "window:deny-destroy -> Denies the destroy command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-destroy" + ] + }, + { + "description": "window:deny-hide -> Denies the hide command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-hide" + ] + }, + { + "description": "window:deny-inner-position -> Denies the inner_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-inner-position" + ] + }, + { + "description": "window:deny-inner-size -> Denies the inner_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-inner-size" + ] + }, + { + "description": "window:deny-internal-toggle-maximize -> Denies the internal_toggle_maximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-internal-toggle-maximize" + ] + }, + { + "description": "window:deny-is-closable -> Denies the is_closable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-closable" + ] + }, + { + "description": "window:deny-is-decorated -> Denies the is_decorated command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-decorated" + ] + }, + { + "description": "window:deny-is-focused -> Denies the is_focused command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-focused" + ] + }, + { + "description": "window:deny-is-fullscreen -> Denies the is_fullscreen command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-fullscreen" + ] + }, + { + "description": "window:deny-is-maximizable -> Denies the is_maximizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-maximizable" + ] + }, + { + "description": "window:deny-is-maximized -> Denies the is_maximized command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-maximized" + ] + }, + { + "description": "window:deny-is-minimizable -> Denies the is_minimizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-minimizable" + ] + }, + { + "description": "window:deny-is-minimized -> Denies the is_minimized command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-minimized" + ] + }, + { + "description": "window:deny-is-resizable -> Denies the is_resizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-resizable" + ] + }, + { + "description": "window:deny-is-visible -> Denies the is_visible command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-visible" + ] + }, + { + "description": "window:deny-maximize -> Denies the maximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-maximize" + ] + }, + { + "description": "window:deny-minimize -> Denies the minimize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-minimize" + ] + }, + { + "description": "window:deny-monitor-from-point -> Denies the monitor_from_point command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-monitor-from-point" + ] + }, + { + "description": "window:deny-outer-position -> Denies the outer_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-outer-position" + ] + }, + { + "description": "window:deny-outer-size -> Denies the outer_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-outer-size" + ] + }, + { + "description": "window:deny-primary-monitor -> Denies the primary_monitor command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-primary-monitor" + ] + }, + { + "description": "window:deny-request-user-attention -> Denies the request_user_attention command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-request-user-attention" + ] + }, + { + "description": "window:deny-scale-factor -> Denies the scale_factor command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-scale-factor" + ] + }, + { + "description": "window:deny-set-always-on-bottom -> Denies the set_always_on_bottom command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-always-on-bottom" + ] + }, + { + "description": "window:deny-set-always-on-top -> Denies the set_always_on_top command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-always-on-top" + ] + }, + { + "description": "window:deny-set-closable -> Denies the set_closable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-closable" + ] + }, + { + "description": "window:deny-set-content-protected -> Denies the set_content_protected command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-content-protected" + ] + }, + { + "description": "window:deny-set-cursor-grab -> Denies the set_cursor_grab command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-cursor-grab" + ] + }, + { + "description": "window:deny-set-cursor-icon -> Denies the set_cursor_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-cursor-icon" + ] + }, + { + "description": "window:deny-set-cursor-position -> Denies the set_cursor_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-cursor-position" + ] + }, + { + "description": "window:deny-set-cursor-visible -> Denies the set_cursor_visible command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-cursor-visible" + ] + }, + { + "description": "window:deny-set-decorations -> Denies the set_decorations command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-decorations" + ] + }, + { + "description": "window:deny-set-effects -> Denies the set_effects command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-effects" + ] + }, + { + "description": "window:deny-set-focus -> Denies the set_focus command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-focus" + ] + }, + { + "description": "window:deny-set-fullscreen -> Denies the set_fullscreen command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-fullscreen" + ] + }, + { + "description": "window:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-icon" + ] + }, + { + "description": "window:deny-set-ignore-cursor-events -> Denies the set_ignore_cursor_events command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-ignore-cursor-events" + ] + }, + { + "description": "window:deny-set-max-size -> Denies the set_max_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-max-size" + ] + }, + { + "description": "window:deny-set-maximizable -> Denies the set_maximizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-maximizable" + ] + }, + { + "description": "window:deny-set-min-size -> Denies the set_min_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-min-size" + ] + }, + { + "description": "window:deny-set-minimizable -> Denies the set_minimizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-minimizable" + ] + }, + { + "description": "window:deny-set-position -> Denies the set_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-position" + ] + }, + { + "description": "window:deny-set-progress-bar -> Denies the set_progress_bar command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-progress-bar" + ] + }, + { + "description": "window:deny-set-resizable -> Denies the set_resizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-resizable" + ] + }, + { + "description": "window:deny-set-shadow -> Denies the set_shadow command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-shadow" + ] + }, + { + "description": "window:deny-set-size -> Denies the set_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-size" + ] + }, + { + "description": "window:deny-set-skip-taskbar -> Denies the set_skip_taskbar command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-skip-taskbar" + ] + }, + { + "description": "window:deny-set-title -> Denies the set_title command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-title" + ] + }, + { + "description": "window:deny-set-title-bar-style -> Denies the set_title_bar_style command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-title-bar-style" + ] + }, + { + "description": "window:deny-set-visible-on-all-workspaces -> Denies the set_visible_on_all_workspaces command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-visible-on-all-workspaces" + ] + }, + { + "description": "window:deny-show -> Denies the show command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-show" + ] + }, + { + "description": "window:deny-start-dragging -> Denies the start_dragging command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-start-dragging" + ] + }, + { + "description": "window:deny-start-resize-dragging -> Denies the start_resize_dragging command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-start-resize-dragging" + ] + }, + { + "description": "window:deny-theme -> Denies the theme command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-theme" + ] + }, + { + "description": "window:deny-title -> Denies the title command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-title" + ] + }, + { + "description": "window:deny-toggle-maximize -> Denies the toggle_maximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-toggle-maximize" + ] + }, + { + "description": "window:deny-unmaximize -> Denies the unmaximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-unmaximize" + ] + }, + { + "description": "window:deny-unminimize -> Denies the unminimize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-unminimize" + ] + } + ] + }, + "Value": { + "description": "All supported ACL values.", + "anyOf": [ + { + "description": "Represents a null JSON value.", + "type": "null" + }, + { + "description": "Represents a [`bool`].", + "type": "boolean" + }, + { + "description": "Represents a valid ACL [`Number`].", + "allOf": [ + { + "$ref": "#/definitions/Number" + } + ] + }, + { + "description": "Represents a [`String`].", + "type": "string" + }, + { + "description": "Represents a list of other [`Value`]s.", + "type": "array", + "items": { + "$ref": "#/definitions/Value" + } + }, + { + "description": "Represents a map of [`String`] keys to [`Value`]s.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/Value" + } + } + ] + }, + "Number": { + "description": "A valid ACL number.", + "anyOf": [ + { + "description": "Represents an [`i64`].", + "type": "integer", + "format": "int64" + }, + { + "description": "Represents a [`f64`].", + "type": "number", + "format": "double" + } + ] + }, + "Target": { + "description": "Platform target.", + "oneOf": [ + { + "description": "MacOS.", + "type": "string", + "enum": [ + "macOS" + ] + }, + { + "description": "Windows.", + "type": "string", + "enum": [ + "windows" + ] + }, + { + "description": "Linux.", + "type": "string", + "enum": [ + "linux" + ] + }, + { + "description": "Android.", + "type": "string", + "enum": [ + "android" + ] + }, + { + "description": "iOS.", + "type": "string", + "enum": [ + "iOS" + ] + } + ] + }, + "ShellAllowedArg": { + "description": "A command argument allowed to be executed by the webview API.", + "anyOf": [ + { + "description": "A non-configurable argument that is passed to the command in the order it was specified.", + "type": "string" + }, + { + "description": "A variable that is set while calling the command from the webview API.", + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\n[regex]: https://docs.rs/regex/latest/regex/#syntax", + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "ShellAllowedArgs": { + "description": "A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration.", + "anyOf": [ + { + "description": "Use a simple boolean to allow all or disable all arguments to this command configuration.", + "type": "boolean" + }, + { + "description": "A specific set of [`ShellAllowedArg`] that are valid to call for the command configuration.", + "type": "array", + "items": { + "$ref": "#/definitions/ShellAllowedArg" + } + } + ] + } + } +} \ No newline at end of file diff --git a/examples/apps/screen-pipe-app/src-tauri/gen/schemas/macOS-schema.json b/examples/apps/screen-pipe-app/src-tauri/gen/schemas/macOS-schema.json new file mode 100644 index 000000000..19205eb6e --- /dev/null +++ b/examples/apps/screen-pipe-app/src-tauri/gen/schemas/macOS-schema.json @@ -0,0 +1,2748 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CapabilityFile", + "description": "Capability formats accepted in a capability file.", + "anyOf": [ + { + "description": "A single capability.", + "allOf": [ + { + "$ref": "#/definitions/Capability" + } + ] + }, + { + "description": "A list of capabilities.", + "type": "array", + "items": { + "$ref": "#/definitions/Capability" + } + }, + { + "description": "A list of capabilities.", + "type": "object", + "required": [ + "capabilities" + ], + "properties": { + "capabilities": { + "description": "The list of capabilities.", + "type": "array", + "items": { + "$ref": "#/definitions/Capability" + } + } + } + } + ], + "definitions": { + "Capability": { + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"path:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, \"platforms\": [\"macOS\",\"windows\"] } ```", + "type": "object", + "required": [ + "identifier", + "permissions" + ], + "properties": { + "identifier": { + "description": "Identifier of the capability.\n\n## Example\n\n`main-user-files-write`", + "type": "string" + }, + "description": { + "description": "Description of what the capability is intended to allow on associated windows.\n\nIt should contain a description of what the grouped permissions should allow.\n\n## Example\n\nThis capability allows the `main` window access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.", + "default": "", + "type": "string" + }, + "remote": { + "description": "Configure remote URLs that can use the capability permissions.\n\nThis setting is optional and defaults to not being set, as our default use case is that the content is served from our local application.\n\n:::caution Make sure you understand the security implications of providing remote sources with local system access. :::\n\n## Example\n\n```json { \"urls\": [\"https://*.mydomain.dev\"] } ```", + "anyOf": [ + { + "$ref": "#/definitions/CapabilityRemote" + }, + { + "type": "null" + } + ] + }, + "local": { + "description": "Whether this capability is enabled for local app URLs or not. Defaults to `true`.", + "default": true, + "type": "boolean" + }, + "windows": { + "description": "List of windows that are affected by this capability. Can be a glob pattern.\n\nOn multiwebview windows, prefer [`Self::webviews`] for a fine grained access control.\n\n## Example\n\n`[\"main\"]`", + "type": "array", + "items": { + "type": "string" + } + }, + "webviews": { + "description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\nThis is only required when using on multiwebview contexts, by default all child webviews of a window that matches [`Self::windows`] are linked.\n\n## Example\n\n`[\"sub-webview-one\", \"sub-webview-two\"]`", + "type": "array", + "items": { + "type": "string" + } + }, + "permissions": { + "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"path:default\", \"event:default\", \"window:default\", \"app:default\", \"image:default\", \"resources:default\", \"menu:default\", \"tray:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ```", + "type": "array", + "items": { + "$ref": "#/definitions/PermissionEntry" + }, + "uniqueItems": true + }, + "platforms": { + "description": "Limit which target platforms this capability applies to.\n\nBy default all platforms are targeted.\n\n## Example\n\n`[\"macOS\",\"windows\"]`", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/Target" + } + } + } + }, + "CapabilityRemote": { + "description": "Configuration for remote URLs that are associated with the capability.", + "type": "object", + "required": [ + "urls" + ], + "properties": { + "urls": { + "description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).\n\n## Examples\n\n- \"https://*.mydomain.dev\": allows subdomains of mydomain.dev - \"https://mydomain.dev/api/*\": allows any subpath of mydomain.dev/api", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "PermissionEntry": { + "description": "An entry for a permission value in a [`Capability`] can be either a raw permission [`Identifier`] or an object that references a permission and extends its scope.", + "anyOf": [ + { + "description": "Reference a permission or permission set by identifier.", + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ] + }, + { + "description": "Reference a permission or permission set by identifier and extends its scope.", + "type": "object", + "oneOf": [ + { + "type": "object", + "required": [ + "identifier" + ], + "properties": { + "identifier": { + "oneOf": [ + { + "description": "shell:default -> This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", + "type": "string", + "enum": [ + "shell:default" + ] + }, + { + "description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-execute" + ] + }, + { + "description": "shell:allow-kill -> Enables the kill command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-kill" + ] + }, + { + "description": "shell:allow-open -> Enables the open command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-open" + ] + }, + { + "description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-spawn" + ] + }, + { + "description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-stdin-write" + ] + }, + { + "description": "shell:deny-execute -> Denies the execute command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-execute" + ] + }, + { + "description": "shell:deny-kill -> Denies the kill command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-kill" + ] + }, + { + "description": "shell:deny-open -> Denies the open command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-open" + ] + }, + { + "description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-spawn" + ] + }, + { + "description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-stdin-write" + ] + } + ] + }, + "allow": { + "items": { + "title": "Entry", + "description": "A command allowed to be executed by the webview API.", + "type": "object", + "required": [ + "args", + "cmd", + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + } + } + }, + "deny": { + "items": { + "title": "Entry", + "description": "A command allowed to be executed by the webview API.", + "type": "object", + "required": [ + "args", + "cmd", + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + } + } + } + } + } + ] + } + ] + }, + "Identifier": { + "oneOf": [ + { + "description": "app:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "app:default" + ] + }, + { + "description": "app:allow-app-hide -> Enables the app_hide command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:allow-app-hide" + ] + }, + { + "description": "app:allow-app-show -> Enables the app_show command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:allow-app-show" + ] + }, + { + "description": "app:allow-default-window-icon -> Enables the default_window_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:allow-default-window-icon" + ] + }, + { + "description": "app:allow-name -> Enables the name command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:allow-name" + ] + }, + { + "description": "app:allow-tauri-version -> Enables the tauri_version command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:allow-tauri-version" + ] + }, + { + "description": "app:allow-version -> Enables the version command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:allow-version" + ] + }, + { + "description": "app:deny-app-hide -> Denies the app_hide command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:deny-app-hide" + ] + }, + { + "description": "app:deny-app-show -> Denies the app_show command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:deny-app-show" + ] + }, + { + "description": "app:deny-default-window-icon -> Denies the default_window_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:deny-default-window-icon" + ] + }, + { + "description": "app:deny-name -> Denies the name command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:deny-name" + ] + }, + { + "description": "app:deny-tauri-version -> Denies the tauri_version command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:deny-tauri-version" + ] + }, + { + "description": "app:deny-version -> Denies the version command without any pre-configured scope.", + "type": "string", + "enum": [ + "app:deny-version" + ] + }, + { + "description": "autostart:default -> This permission set configures if your\napplication can enable or disable auto\nstarting the application on boot.\n\n#### Granted Permissions\n\nIt allows all to check, enable and\ndisable the automatic start on boot.\n\n", + "type": "string", + "enum": [ + "autostart:default" + ] + }, + { + "description": "autostart:allow-disable -> Enables the disable command without any pre-configured scope.", + "type": "string", + "enum": [ + "autostart:allow-disable" + ] + }, + { + "description": "autostart:allow-enable -> Enables the enable command without any pre-configured scope.", + "type": "string", + "enum": [ + "autostart:allow-enable" + ] + }, + { + "description": "autostart:allow-is-enabled -> Enables the is_enabled command without any pre-configured scope.", + "type": "string", + "enum": [ + "autostart:allow-is-enabled" + ] + }, + { + "description": "autostart:deny-disable -> Denies the disable command without any pre-configured scope.", + "type": "string", + "enum": [ + "autostart:deny-disable" + ] + }, + { + "description": "autostart:deny-enable -> Denies the enable command without any pre-configured scope.", + "type": "string", + "enum": [ + "autostart:deny-enable" + ] + }, + { + "description": "autostart:deny-is-enabled -> Denies the is_enabled command without any pre-configured scope.", + "type": "string", + "enum": [ + "autostart:deny-is-enabled" + ] + }, + { + "description": "cli:default -> Allows reading the CLI matches", + "type": "string", + "enum": [ + "cli:default" + ] + }, + { + "description": "cli:allow-cli-matches -> Enables the cli_matches command without any pre-configured scope.", + "type": "string", + "enum": [ + "cli:allow-cli-matches" + ] + }, + { + "description": "cli:deny-cli-matches -> Denies the cli_matches command without any pre-configured scope.", + "type": "string", + "enum": [ + "cli:deny-cli-matches" + ] + }, + { + "description": "event:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "event:default" + ] + }, + { + "description": "event:allow-emit -> Enables the emit command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:allow-emit" + ] + }, + { + "description": "event:allow-emit-to -> Enables the emit_to command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:allow-emit-to" + ] + }, + { + "description": "event:allow-listen -> Enables the listen command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:allow-listen" + ] + }, + { + "description": "event:allow-unlisten -> Enables the unlisten command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:allow-unlisten" + ] + }, + { + "description": "event:deny-emit -> Denies the emit command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:deny-emit" + ] + }, + { + "description": "event:deny-emit-to -> Denies the emit_to command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:deny-emit-to" + ] + }, + { + "description": "event:deny-listen -> Denies the listen command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:deny-listen" + ] + }, + { + "description": "event:deny-unlisten -> Denies the unlisten command without any pre-configured scope.", + "type": "string", + "enum": [ + "event:deny-unlisten" + ] + }, + { + "description": "image:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "image:default" + ] + }, + { + "description": "image:allow-from-bytes -> Enables the from_bytes command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:allow-from-bytes" + ] + }, + { + "description": "image:allow-from-path -> Enables the from_path command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:allow-from-path" + ] + }, + { + "description": "image:allow-new -> Enables the new command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:allow-new" + ] + }, + { + "description": "image:allow-rgba -> Enables the rgba command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:allow-rgba" + ] + }, + { + "description": "image:allow-size -> Enables the size command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:allow-size" + ] + }, + { + "description": "image:deny-from-bytes -> Denies the from_bytes command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:deny-from-bytes" + ] + }, + { + "description": "image:deny-from-path -> Denies the from_path command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:deny-from-path" + ] + }, + { + "description": "image:deny-new -> Denies the new command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:deny-new" + ] + }, + { + "description": "image:deny-rgba -> Denies the rgba command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:deny-rgba" + ] + }, + { + "description": "image:deny-size -> Denies the size command without any pre-configured scope.", + "type": "string", + "enum": [ + "image:deny-size" + ] + }, + { + "description": "menu:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "menu:default" + ] + }, + { + "description": "menu:allow-append -> Enables the append command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-append" + ] + }, + { + "description": "menu:allow-create-default -> Enables the create_default command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-create-default" + ] + }, + { + "description": "menu:allow-get -> Enables the get command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-get" + ] + }, + { + "description": "menu:allow-insert -> Enables the insert command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-insert" + ] + }, + { + "description": "menu:allow-is-checked -> Enables the is_checked command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-is-checked" + ] + }, + { + "description": "menu:allow-is-enabled -> Enables the is_enabled command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-is-enabled" + ] + }, + { + "description": "menu:allow-items -> Enables the items command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-items" + ] + }, + { + "description": "menu:allow-new -> Enables the new command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-new" + ] + }, + { + "description": "menu:allow-popup -> Enables the popup command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-popup" + ] + }, + { + "description": "menu:allow-prepend -> Enables the prepend command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-prepend" + ] + }, + { + "description": "menu:allow-remove -> Enables the remove command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-remove" + ] + }, + { + "description": "menu:allow-remove-at -> Enables the remove_at command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-remove-at" + ] + }, + { + "description": "menu:allow-set-accelerator -> Enables the set_accelerator command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-accelerator" + ] + }, + { + "description": "menu:allow-set-as-app-menu -> Enables the set_as_app_menu command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-as-app-menu" + ] + }, + { + "description": "menu:allow-set-as-help-menu-for-nsapp -> Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-as-help-menu-for-nsapp" + ] + }, + { + "description": "menu:allow-set-as-window-menu -> Enables the set_as_window_menu command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-as-window-menu" + ] + }, + { + "description": "menu:allow-set-as-windows-menu-for-nsapp -> Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-as-windows-menu-for-nsapp" + ] + }, + { + "description": "menu:allow-set-checked -> Enables the set_checked command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-checked" + ] + }, + { + "description": "menu:allow-set-enabled -> Enables the set_enabled command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-enabled" + ] + }, + { + "description": "menu:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-icon" + ] + }, + { + "description": "menu:allow-set-text -> Enables the set_text command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-set-text" + ] + }, + { + "description": "menu:allow-text -> Enables the text command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:allow-text" + ] + }, + { + "description": "menu:deny-append -> Denies the append command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-append" + ] + }, + { + "description": "menu:deny-create-default -> Denies the create_default command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-create-default" + ] + }, + { + "description": "menu:deny-get -> Denies the get command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-get" + ] + }, + { + "description": "menu:deny-insert -> Denies the insert command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-insert" + ] + }, + { + "description": "menu:deny-is-checked -> Denies the is_checked command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-is-checked" + ] + }, + { + "description": "menu:deny-is-enabled -> Denies the is_enabled command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-is-enabled" + ] + }, + { + "description": "menu:deny-items -> Denies the items command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-items" + ] + }, + { + "description": "menu:deny-new -> Denies the new command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-new" + ] + }, + { + "description": "menu:deny-popup -> Denies the popup command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-popup" + ] + }, + { + "description": "menu:deny-prepend -> Denies the prepend command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-prepend" + ] + }, + { + "description": "menu:deny-remove -> Denies the remove command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-remove" + ] + }, + { + "description": "menu:deny-remove-at -> Denies the remove_at command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-remove-at" + ] + }, + { + "description": "menu:deny-set-accelerator -> Denies the set_accelerator command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-accelerator" + ] + }, + { + "description": "menu:deny-set-as-app-menu -> Denies the set_as_app_menu command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-as-app-menu" + ] + }, + { + "description": "menu:deny-set-as-help-menu-for-nsapp -> Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-as-help-menu-for-nsapp" + ] + }, + { + "description": "menu:deny-set-as-window-menu -> Denies the set_as_window_menu command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-as-window-menu" + ] + }, + { + "description": "menu:deny-set-as-windows-menu-for-nsapp -> Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-as-windows-menu-for-nsapp" + ] + }, + { + "description": "menu:deny-set-checked -> Denies the set_checked command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-checked" + ] + }, + { + "description": "menu:deny-set-enabled -> Denies the set_enabled command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-enabled" + ] + }, + { + "description": "menu:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-icon" + ] + }, + { + "description": "menu:deny-set-text -> Denies the set_text command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-set-text" + ] + }, + { + "description": "menu:deny-text -> Denies the text command without any pre-configured scope.", + "type": "string", + "enum": [ + "menu:deny-text" + ] + }, + { + "description": "path:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "path:default" + ] + }, + { + "description": "path:allow-basename -> Enables the basename command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-basename" + ] + }, + { + "description": "path:allow-dirname -> Enables the dirname command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-dirname" + ] + }, + { + "description": "path:allow-extname -> Enables the extname command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-extname" + ] + }, + { + "description": "path:allow-is-absolute -> Enables the is_absolute command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-is-absolute" + ] + }, + { + "description": "path:allow-join -> Enables the join command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-join" + ] + }, + { + "description": "path:allow-normalize -> Enables the normalize command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-normalize" + ] + }, + { + "description": "path:allow-resolve -> Enables the resolve command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-resolve" + ] + }, + { + "description": "path:allow-resolve-directory -> Enables the resolve_directory command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:allow-resolve-directory" + ] + }, + { + "description": "path:deny-basename -> Denies the basename command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-basename" + ] + }, + { + "description": "path:deny-dirname -> Denies the dirname command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-dirname" + ] + }, + { + "description": "path:deny-extname -> Denies the extname command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-extname" + ] + }, + { + "description": "path:deny-is-absolute -> Denies the is_absolute command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-is-absolute" + ] + }, + { + "description": "path:deny-join -> Denies the join command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-join" + ] + }, + { + "description": "path:deny-normalize -> Denies the normalize command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-normalize" + ] + }, + { + "description": "path:deny-resolve -> Denies the resolve command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-resolve" + ] + }, + { + "description": "path:deny-resolve-directory -> Denies the resolve_directory command without any pre-configured scope.", + "type": "string", + "enum": [ + "path:deny-resolve-directory" + ] + }, + { + "description": "resources:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "resources:default" + ] + }, + { + "description": "resources:allow-close -> Enables the close command without any pre-configured scope.", + "type": "string", + "enum": [ + "resources:allow-close" + ] + }, + { + "description": "resources:deny-close -> Denies the close command without any pre-configured scope.", + "type": "string", + "enum": [ + "resources:deny-close" + ] + }, + { + "description": "shell:default -> This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality without any specific\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n", + "type": "string", + "enum": [ + "shell:default" + ] + }, + { + "description": "shell:allow-execute -> Enables the execute command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-execute" + ] + }, + { + "description": "shell:allow-kill -> Enables the kill command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-kill" + ] + }, + { + "description": "shell:allow-open -> Enables the open command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-open" + ] + }, + { + "description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-spawn" + ] + }, + { + "description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-stdin-write" + ] + }, + { + "description": "shell:deny-execute -> Denies the execute command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-execute" + ] + }, + { + "description": "shell:deny-kill -> Denies the kill command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-kill" + ] + }, + { + "description": "shell:deny-open -> Denies the open command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-open" + ] + }, + { + "description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-spawn" + ] + }, + { + "description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-stdin-write" + ] + }, + { + "description": "store:default -> This permission set configures what kind of\noperations are available from the store plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n", + "type": "string", + "enum": [ + "store:default" + ] + }, + { + "description": "store:allow-clear -> Enables the clear command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-clear" + ] + }, + { + "description": "store:allow-delete -> Enables the delete command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-delete" + ] + }, + { + "description": "store:allow-entries -> Enables the entries command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-entries" + ] + }, + { + "description": "store:allow-get -> Enables the get command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-get" + ] + }, + { + "description": "store:allow-has -> Enables the has command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-has" + ] + }, + { + "description": "store:allow-keys -> Enables the keys command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-keys" + ] + }, + { + "description": "store:allow-length -> Enables the length command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-length" + ] + }, + { + "description": "store:allow-load -> Enables the load command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-load" + ] + }, + { + "description": "store:allow-reset -> Enables the reset command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-reset" + ] + }, + { + "description": "store:allow-save -> Enables the save command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-save" + ] + }, + { + "description": "store:allow-set -> Enables the set command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-set" + ] + }, + { + "description": "store:allow-values -> Enables the values command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:allow-values" + ] + }, + { + "description": "store:deny-clear -> Denies the clear command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-clear" + ] + }, + { + "description": "store:deny-delete -> Denies the delete command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-delete" + ] + }, + { + "description": "store:deny-entries -> Denies the entries command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-entries" + ] + }, + { + "description": "store:deny-get -> Denies the get command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-get" + ] + }, + { + "description": "store:deny-has -> Denies the has command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-has" + ] + }, + { + "description": "store:deny-keys -> Denies the keys command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-keys" + ] + }, + { + "description": "store:deny-length -> Denies the length command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-length" + ] + }, + { + "description": "store:deny-load -> Denies the load command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-load" + ] + }, + { + "description": "store:deny-reset -> Denies the reset command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-reset" + ] + }, + { + "description": "store:deny-save -> Denies the save command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-save" + ] + }, + { + "description": "store:deny-set -> Denies the set command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-set" + ] + }, + { + "description": "store:deny-values -> Denies the values command without any pre-configured scope.", + "type": "string", + "enum": [ + "store:deny-values" + ] + }, + { + "description": "tray:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "tray:default" + ] + }, + { + "description": "tray:allow-get-by-id -> Enables the get_by_id command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-get-by-id" + ] + }, + { + "description": "tray:allow-new -> Enables the new command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-new" + ] + }, + { + "description": "tray:allow-remove-by-id -> Enables the remove_by_id command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-remove-by-id" + ] + }, + { + "description": "tray:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-icon" + ] + }, + { + "description": "tray:allow-set-icon-as-template -> Enables the set_icon_as_template command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-icon-as-template" + ] + }, + { + "description": "tray:allow-set-menu -> Enables the set_menu command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-menu" + ] + }, + { + "description": "tray:allow-set-show-menu-on-left-click -> Enables the set_show_menu_on_left_click command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-show-menu-on-left-click" + ] + }, + { + "description": "tray:allow-set-temp-dir-path -> Enables the set_temp_dir_path command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-temp-dir-path" + ] + }, + { + "description": "tray:allow-set-title -> Enables the set_title command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-title" + ] + }, + { + "description": "tray:allow-set-tooltip -> Enables the set_tooltip command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-tooltip" + ] + }, + { + "description": "tray:allow-set-visible -> Enables the set_visible command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:allow-set-visible" + ] + }, + { + "description": "tray:deny-get-by-id -> Denies the get_by_id command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-get-by-id" + ] + }, + { + "description": "tray:deny-new -> Denies the new command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-new" + ] + }, + { + "description": "tray:deny-remove-by-id -> Denies the remove_by_id command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-remove-by-id" + ] + }, + { + "description": "tray:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-icon" + ] + }, + { + "description": "tray:deny-set-icon-as-template -> Denies the set_icon_as_template command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-icon-as-template" + ] + }, + { + "description": "tray:deny-set-menu -> Denies the set_menu command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-menu" + ] + }, + { + "description": "tray:deny-set-show-menu-on-left-click -> Denies the set_show_menu_on_left_click command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-show-menu-on-left-click" + ] + }, + { + "description": "tray:deny-set-temp-dir-path -> Denies the set_temp_dir_path command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-temp-dir-path" + ] + }, + { + "description": "tray:deny-set-title -> Denies the set_title command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-title" + ] + }, + { + "description": "tray:deny-set-tooltip -> Denies the set_tooltip command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-tooltip" + ] + }, + { + "description": "tray:deny-set-visible -> Denies the set_visible command without any pre-configured scope.", + "type": "string", + "enum": [ + "tray:deny-set-visible" + ] + }, + { + "description": "updater:default -> This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n", + "type": "string", + "enum": [ + "updater:default" + ] + }, + { + "description": "updater:allow-check -> Enables the check command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:allow-check" + ] + }, + { + "description": "updater:allow-download -> Enables the download command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:allow-download" + ] + }, + { + "description": "updater:allow-download-and-install -> Enables the download_and_install command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:allow-download-and-install" + ] + }, + { + "description": "updater:allow-install -> Enables the install command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:allow-install" + ] + }, + { + "description": "updater:deny-check -> Denies the check command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:deny-check" + ] + }, + { + "description": "updater:deny-download -> Denies the download command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:deny-download" + ] + }, + { + "description": "updater:deny-download-and-install -> Denies the download_and_install command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:deny-download-and-install" + ] + }, + { + "description": "updater:deny-install -> Denies the install command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:deny-install" + ] + }, + { + "description": "webview:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "webview:default" + ] + }, + { + "description": "webview:allow-create-webview -> Enables the create_webview command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-create-webview" + ] + }, + { + "description": "webview:allow-create-webview-window -> Enables the create_webview_window command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-create-webview-window" + ] + }, + { + "description": "webview:allow-internal-toggle-devtools -> Enables the internal_toggle_devtools command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-internal-toggle-devtools" + ] + }, + { + "description": "webview:allow-print -> Enables the print command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-print" + ] + }, + { + "description": "webview:allow-reparent -> Enables the reparent command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-reparent" + ] + }, + { + "description": "webview:allow-set-webview-focus -> Enables the set_webview_focus command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-set-webview-focus" + ] + }, + { + "description": "webview:allow-set-webview-position -> Enables the set_webview_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-set-webview-position" + ] + }, + { + "description": "webview:allow-set-webview-size -> Enables the set_webview_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-set-webview-size" + ] + }, + { + "description": "webview:allow-set-webview-zoom -> Enables the set_webview_zoom command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-set-webview-zoom" + ] + }, + { + "description": "webview:allow-webview-close -> Enables the webview_close command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-webview-close" + ] + }, + { + "description": "webview:allow-webview-position -> Enables the webview_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-webview-position" + ] + }, + { + "description": "webview:allow-webview-size -> Enables the webview_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:allow-webview-size" + ] + }, + { + "description": "webview:deny-create-webview -> Denies the create_webview command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-create-webview" + ] + }, + { + "description": "webview:deny-create-webview-window -> Denies the create_webview_window command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-create-webview-window" + ] + }, + { + "description": "webview:deny-internal-toggle-devtools -> Denies the internal_toggle_devtools command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-internal-toggle-devtools" + ] + }, + { + "description": "webview:deny-print -> Denies the print command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-print" + ] + }, + { + "description": "webview:deny-reparent -> Denies the reparent command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-reparent" + ] + }, + { + "description": "webview:deny-set-webview-focus -> Denies the set_webview_focus command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-set-webview-focus" + ] + }, + { + "description": "webview:deny-set-webview-position -> Denies the set_webview_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-set-webview-position" + ] + }, + { + "description": "webview:deny-set-webview-size -> Denies the set_webview_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-set-webview-size" + ] + }, + { + "description": "webview:deny-set-webview-zoom -> Denies the set_webview_zoom command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-set-webview-zoom" + ] + }, + { + "description": "webview:deny-webview-close -> Denies the webview_close command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-webview-close" + ] + }, + { + "description": "webview:deny-webview-position -> Denies the webview_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-webview-position" + ] + }, + { + "description": "webview:deny-webview-size -> Denies the webview_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "webview:deny-webview-size" + ] + }, + { + "description": "window:default -> Default permissions for the plugin.", + "type": "string", + "enum": [ + "window:default" + ] + }, + { + "description": "window:allow-available-monitors -> Enables the available_monitors command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-available-monitors" + ] + }, + { + "description": "window:allow-center -> Enables the center command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-center" + ] + }, + { + "description": "window:allow-close -> Enables the close command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-close" + ] + }, + { + "description": "window:allow-create -> Enables the create command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-create" + ] + }, + { + "description": "window:allow-current-monitor -> Enables the current_monitor command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-current-monitor" + ] + }, + { + "description": "window:allow-cursor-position -> Enables the cursor_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-cursor-position" + ] + }, + { + "description": "window:allow-destroy -> Enables the destroy command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-destroy" + ] + }, + { + "description": "window:allow-hide -> Enables the hide command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-hide" + ] + }, + { + "description": "window:allow-inner-position -> Enables the inner_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-inner-position" + ] + }, + { + "description": "window:allow-inner-size -> Enables the inner_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-inner-size" + ] + }, + { + "description": "window:allow-internal-toggle-maximize -> Enables the internal_toggle_maximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-internal-toggle-maximize" + ] + }, + { + "description": "window:allow-is-closable -> Enables the is_closable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-closable" + ] + }, + { + "description": "window:allow-is-decorated -> Enables the is_decorated command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-decorated" + ] + }, + { + "description": "window:allow-is-focused -> Enables the is_focused command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-focused" + ] + }, + { + "description": "window:allow-is-fullscreen -> Enables the is_fullscreen command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-fullscreen" + ] + }, + { + "description": "window:allow-is-maximizable -> Enables the is_maximizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-maximizable" + ] + }, + { + "description": "window:allow-is-maximized -> Enables the is_maximized command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-maximized" + ] + }, + { + "description": "window:allow-is-minimizable -> Enables the is_minimizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-minimizable" + ] + }, + { + "description": "window:allow-is-minimized -> Enables the is_minimized command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-minimized" + ] + }, + { + "description": "window:allow-is-resizable -> Enables the is_resizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-resizable" + ] + }, + { + "description": "window:allow-is-visible -> Enables the is_visible command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-is-visible" + ] + }, + { + "description": "window:allow-maximize -> Enables the maximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-maximize" + ] + }, + { + "description": "window:allow-minimize -> Enables the minimize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-minimize" + ] + }, + { + "description": "window:allow-monitor-from-point -> Enables the monitor_from_point command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-monitor-from-point" + ] + }, + { + "description": "window:allow-outer-position -> Enables the outer_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-outer-position" + ] + }, + { + "description": "window:allow-outer-size -> Enables the outer_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-outer-size" + ] + }, + { + "description": "window:allow-primary-monitor -> Enables the primary_monitor command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-primary-monitor" + ] + }, + { + "description": "window:allow-request-user-attention -> Enables the request_user_attention command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-request-user-attention" + ] + }, + { + "description": "window:allow-scale-factor -> Enables the scale_factor command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-scale-factor" + ] + }, + { + "description": "window:allow-set-always-on-bottom -> Enables the set_always_on_bottom command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-always-on-bottom" + ] + }, + { + "description": "window:allow-set-always-on-top -> Enables the set_always_on_top command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-always-on-top" + ] + }, + { + "description": "window:allow-set-closable -> Enables the set_closable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-closable" + ] + }, + { + "description": "window:allow-set-content-protected -> Enables the set_content_protected command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-content-protected" + ] + }, + { + "description": "window:allow-set-cursor-grab -> Enables the set_cursor_grab command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-cursor-grab" + ] + }, + { + "description": "window:allow-set-cursor-icon -> Enables the set_cursor_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-cursor-icon" + ] + }, + { + "description": "window:allow-set-cursor-position -> Enables the set_cursor_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-cursor-position" + ] + }, + { + "description": "window:allow-set-cursor-visible -> Enables the set_cursor_visible command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-cursor-visible" + ] + }, + { + "description": "window:allow-set-decorations -> Enables the set_decorations command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-decorations" + ] + }, + { + "description": "window:allow-set-effects -> Enables the set_effects command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-effects" + ] + }, + { + "description": "window:allow-set-focus -> Enables the set_focus command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-focus" + ] + }, + { + "description": "window:allow-set-fullscreen -> Enables the set_fullscreen command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-fullscreen" + ] + }, + { + "description": "window:allow-set-icon -> Enables the set_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-icon" + ] + }, + { + "description": "window:allow-set-ignore-cursor-events -> Enables the set_ignore_cursor_events command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-ignore-cursor-events" + ] + }, + { + "description": "window:allow-set-max-size -> Enables the set_max_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-max-size" + ] + }, + { + "description": "window:allow-set-maximizable -> Enables the set_maximizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-maximizable" + ] + }, + { + "description": "window:allow-set-min-size -> Enables the set_min_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-min-size" + ] + }, + { + "description": "window:allow-set-minimizable -> Enables the set_minimizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-minimizable" + ] + }, + { + "description": "window:allow-set-position -> Enables the set_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-position" + ] + }, + { + "description": "window:allow-set-progress-bar -> Enables the set_progress_bar command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-progress-bar" + ] + }, + { + "description": "window:allow-set-resizable -> Enables the set_resizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-resizable" + ] + }, + { + "description": "window:allow-set-shadow -> Enables the set_shadow command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-shadow" + ] + }, + { + "description": "window:allow-set-size -> Enables the set_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-size" + ] + }, + { + "description": "window:allow-set-skip-taskbar -> Enables the set_skip_taskbar command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-skip-taskbar" + ] + }, + { + "description": "window:allow-set-title -> Enables the set_title command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-title" + ] + }, + { + "description": "window:allow-set-title-bar-style -> Enables the set_title_bar_style command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-title-bar-style" + ] + }, + { + "description": "window:allow-set-visible-on-all-workspaces -> Enables the set_visible_on_all_workspaces command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-set-visible-on-all-workspaces" + ] + }, + { + "description": "window:allow-show -> Enables the show command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-show" + ] + }, + { + "description": "window:allow-start-dragging -> Enables the start_dragging command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-start-dragging" + ] + }, + { + "description": "window:allow-start-resize-dragging -> Enables the start_resize_dragging command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-start-resize-dragging" + ] + }, + { + "description": "window:allow-theme -> Enables the theme command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-theme" + ] + }, + { + "description": "window:allow-title -> Enables the title command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-title" + ] + }, + { + "description": "window:allow-toggle-maximize -> Enables the toggle_maximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-toggle-maximize" + ] + }, + { + "description": "window:allow-unmaximize -> Enables the unmaximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-unmaximize" + ] + }, + { + "description": "window:allow-unminimize -> Enables the unminimize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-unminimize" + ] + }, + { + "description": "window:deny-available-monitors -> Denies the available_monitors command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-available-monitors" + ] + }, + { + "description": "window:deny-center -> Denies the center command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-center" + ] + }, + { + "description": "window:deny-close -> Denies the close command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-close" + ] + }, + { + "description": "window:deny-create -> Denies the create command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-create" + ] + }, + { + "description": "window:deny-current-monitor -> Denies the current_monitor command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-current-monitor" + ] + }, + { + "description": "window:deny-cursor-position -> Denies the cursor_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-cursor-position" + ] + }, + { + "description": "window:deny-destroy -> Denies the destroy command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-destroy" + ] + }, + { + "description": "window:deny-hide -> Denies the hide command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-hide" + ] + }, + { + "description": "window:deny-inner-position -> Denies the inner_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-inner-position" + ] + }, + { + "description": "window:deny-inner-size -> Denies the inner_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-inner-size" + ] + }, + { + "description": "window:deny-internal-toggle-maximize -> Denies the internal_toggle_maximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-internal-toggle-maximize" + ] + }, + { + "description": "window:deny-is-closable -> Denies the is_closable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-closable" + ] + }, + { + "description": "window:deny-is-decorated -> Denies the is_decorated command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-decorated" + ] + }, + { + "description": "window:deny-is-focused -> Denies the is_focused command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-focused" + ] + }, + { + "description": "window:deny-is-fullscreen -> Denies the is_fullscreen command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-fullscreen" + ] + }, + { + "description": "window:deny-is-maximizable -> Denies the is_maximizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-maximizable" + ] + }, + { + "description": "window:deny-is-maximized -> Denies the is_maximized command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-maximized" + ] + }, + { + "description": "window:deny-is-minimizable -> Denies the is_minimizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-minimizable" + ] + }, + { + "description": "window:deny-is-minimized -> Denies the is_minimized command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-minimized" + ] + }, + { + "description": "window:deny-is-resizable -> Denies the is_resizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-resizable" + ] + }, + { + "description": "window:deny-is-visible -> Denies the is_visible command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-is-visible" + ] + }, + { + "description": "window:deny-maximize -> Denies the maximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-maximize" + ] + }, + { + "description": "window:deny-minimize -> Denies the minimize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-minimize" + ] + }, + { + "description": "window:deny-monitor-from-point -> Denies the monitor_from_point command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-monitor-from-point" + ] + }, + { + "description": "window:deny-outer-position -> Denies the outer_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-outer-position" + ] + }, + { + "description": "window:deny-outer-size -> Denies the outer_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-outer-size" + ] + }, + { + "description": "window:deny-primary-monitor -> Denies the primary_monitor command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-primary-monitor" + ] + }, + { + "description": "window:deny-request-user-attention -> Denies the request_user_attention command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-request-user-attention" + ] + }, + { + "description": "window:deny-scale-factor -> Denies the scale_factor command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-scale-factor" + ] + }, + { + "description": "window:deny-set-always-on-bottom -> Denies the set_always_on_bottom command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-always-on-bottom" + ] + }, + { + "description": "window:deny-set-always-on-top -> Denies the set_always_on_top command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-always-on-top" + ] + }, + { + "description": "window:deny-set-closable -> Denies the set_closable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-closable" + ] + }, + { + "description": "window:deny-set-content-protected -> Denies the set_content_protected command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-content-protected" + ] + }, + { + "description": "window:deny-set-cursor-grab -> Denies the set_cursor_grab command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-cursor-grab" + ] + }, + { + "description": "window:deny-set-cursor-icon -> Denies the set_cursor_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-cursor-icon" + ] + }, + { + "description": "window:deny-set-cursor-position -> Denies the set_cursor_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-cursor-position" + ] + }, + { + "description": "window:deny-set-cursor-visible -> Denies the set_cursor_visible command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-cursor-visible" + ] + }, + { + "description": "window:deny-set-decorations -> Denies the set_decorations command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-decorations" + ] + }, + { + "description": "window:deny-set-effects -> Denies the set_effects command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-effects" + ] + }, + { + "description": "window:deny-set-focus -> Denies the set_focus command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-focus" + ] + }, + { + "description": "window:deny-set-fullscreen -> Denies the set_fullscreen command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-fullscreen" + ] + }, + { + "description": "window:deny-set-icon -> Denies the set_icon command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-icon" + ] + }, + { + "description": "window:deny-set-ignore-cursor-events -> Denies the set_ignore_cursor_events command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-ignore-cursor-events" + ] + }, + { + "description": "window:deny-set-max-size -> Denies the set_max_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-max-size" + ] + }, + { + "description": "window:deny-set-maximizable -> Denies the set_maximizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-maximizable" + ] + }, + { + "description": "window:deny-set-min-size -> Denies the set_min_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-min-size" + ] + }, + { + "description": "window:deny-set-minimizable -> Denies the set_minimizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-minimizable" + ] + }, + { + "description": "window:deny-set-position -> Denies the set_position command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-position" + ] + }, + { + "description": "window:deny-set-progress-bar -> Denies the set_progress_bar command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-progress-bar" + ] + }, + { + "description": "window:deny-set-resizable -> Denies the set_resizable command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-resizable" + ] + }, + { + "description": "window:deny-set-shadow -> Denies the set_shadow command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-shadow" + ] + }, + { + "description": "window:deny-set-size -> Denies the set_size command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-size" + ] + }, + { + "description": "window:deny-set-skip-taskbar -> Denies the set_skip_taskbar command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-skip-taskbar" + ] + }, + { + "description": "window:deny-set-title -> Denies the set_title command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-title" + ] + }, + { + "description": "window:deny-set-title-bar-style -> Denies the set_title_bar_style command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-title-bar-style" + ] + }, + { + "description": "window:deny-set-visible-on-all-workspaces -> Denies the set_visible_on_all_workspaces command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-set-visible-on-all-workspaces" + ] + }, + { + "description": "window:deny-show -> Denies the show command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-show" + ] + }, + { + "description": "window:deny-start-dragging -> Denies the start_dragging command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-start-dragging" + ] + }, + { + "description": "window:deny-start-resize-dragging -> Denies the start_resize_dragging command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-start-resize-dragging" + ] + }, + { + "description": "window:deny-theme -> Denies the theme command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-theme" + ] + }, + { + "description": "window:deny-title -> Denies the title command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-title" + ] + }, + { + "description": "window:deny-toggle-maximize -> Denies the toggle_maximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-toggle-maximize" + ] + }, + { + "description": "window:deny-unmaximize -> Denies the unmaximize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-unmaximize" + ] + }, + { + "description": "window:deny-unminimize -> Denies the unminimize command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-unminimize" + ] + } + ] + }, + "Value": { + "description": "All supported ACL values.", + "anyOf": [ + { + "description": "Represents a null JSON value.", + "type": "null" + }, + { + "description": "Represents a [`bool`].", + "type": "boolean" + }, + { + "description": "Represents a valid ACL [`Number`].", + "allOf": [ + { + "$ref": "#/definitions/Number" + } + ] + }, + { + "description": "Represents a [`String`].", + "type": "string" + }, + { + "description": "Represents a list of other [`Value`]s.", + "type": "array", + "items": { + "$ref": "#/definitions/Value" + } + }, + { + "description": "Represents a map of [`String`] keys to [`Value`]s.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/Value" + } + } + ] + }, + "Number": { + "description": "A valid ACL number.", + "anyOf": [ + { + "description": "Represents an [`i64`].", + "type": "integer", + "format": "int64" + }, + { + "description": "Represents a [`f64`].", + "type": "number", + "format": "double" + } + ] + }, + "Target": { + "description": "Platform target.", + "oneOf": [ + { + "description": "MacOS.", + "type": "string", + "enum": [ + "macOS" + ] + }, + { + "description": "Windows.", + "type": "string", + "enum": [ + "windows" + ] + }, + { + "description": "Linux.", + "type": "string", + "enum": [ + "linux" + ] + }, + { + "description": "Android.", + "type": "string", + "enum": [ + "android" + ] + }, + { + "description": "iOS.", + "type": "string", + "enum": [ + "iOS" + ] + } + ] + }, + "ShellAllowedArg": { + "description": "A command argument allowed to be executed by the webview API.", + "anyOf": [ + { + "description": "A non-configurable argument that is passed to the command in the order it was specified.", + "type": "string" + }, + { + "description": "A variable that is set while calling the command from the webview API.", + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\n[regex]: https://docs.rs/regex/latest/regex/#syntax", + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "ShellAllowedArgs": { + "description": "A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration.", + "anyOf": [ + { + "description": "Use a simple boolean to allow all or disable all arguments to this command configuration.", + "type": "boolean" + }, + { + "description": "A specific set of [`ShellAllowedArg`] that are valid to call for the command configuration.", + "type": "array", + "items": { + "$ref": "#/definitions/ShellAllowedArg" + } + } + ] + } + } +} \ No newline at end of file diff --git a/examples/apps/screen-pipe-app/src-tauri/null/db.sqlite b/examples/apps/screen-pipe-app/src-tauri/null/db.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..4ebf78cf96088c7148cb47caf804cc036de75a34 GIT binary patch literal 4096 zcmWFz^vNtqRY=P(%1ta$FlG>7U}9o$P*7lCU|@t|AVoG{WY8;GzzfnYK(-m98b?E5 nGz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nC=3ArfDQ*E literal 0 HcmV?d00001 diff --git a/examples/apps/screen-pipe-app/src-tauri/null/db.sqlite-shm b/examples/apps/screen-pipe-app/src-tauri/null/db.sqlite-shm new file mode 100644 index 0000000000000000000000000000000000000000..7e9f7788fe6d3abdbe579a41a28f8a93df7bdc6d GIT binary patch literal 32768 zcmeI*IZnd>5Cu?YVc*Oe!x50^xeH}D0+ckAoPvtOAc}O6qSEFmu_2@=)Gn)6!-oF*++tHn98{LiOOnIFUAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&wl0dH+{%nU>q<8Wz1pY^$ADdO$*o>09S%g3>fkEsP+OIXT zX$kxavI1S%$qi267y$tS1PBlyK!5;& GIe~Aql`TyG literal 0 HcmV?d00001 diff --git a/examples/apps/screen-pipe-app/src-tauri/null/db.sqlite-wal b/examples/apps/screen-pipe-app/src-tauri/null/db.sqlite-wal new file mode 100644 index 0000000000000000000000000000000000000000..4684f1b9e4a1c40e057a5be49d1e807c7c11442d GIT binary patch literal 107152 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 literal 0 HcmV?d00001 diff --git a/examples/apps/screen-pipe-app/src-tauri/src/main.rs b/examples/apps/screen-pipe-app/src-tauri/src/main.rs index 6821e57b0..3a8fe4c61 100644 --- a/examples/apps/screen-pipe-app/src-tauri/src/main.rs +++ b/examples/apps/screen-pipe-app/src-tauri/src/main.rs @@ -3,11 +3,18 @@ use dirs::home_dir; use log::{error, info, LevelFilter}; -use reqwest::Client; -use screenpipe_audio::{default_input_device, default_output_device, DeviceControl}; +use logs::MultiWriter; +use screenpipe_audio::{ + default_input_device, default_output_device, list_audio_devices, DeviceControl, +}; use screenpipe_server::{start_continuous_recording, DatabaseManager, ResourceMonitor, Server}; use serde::{Deserialize, Serialize}; + use serde_json::Value; +use tauri::{State, Wry}; +use tauri_plugin_shell::ShellExt; +use tauri_plugin_store::{with_store, StoreCollection}; + use std::fs::File; use std::io::Write; use std::ops::Deref; @@ -19,89 +26,18 @@ use std::{ time::Duration, }; use tauri::{ - CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem, + menu::{MenuBuilder, MenuItemBuilder}, + tray::TrayIconBuilder, + Manager, }; +use tauri_plugin_cli::CliExt; + use tauri_plugin_autostart::MacosLauncher; mod analytics; -use analytics::{start_analytics, AnalyticsManager}; -mod logs; -use logs::MultiWriter; - -async fn toggle_recording(app: &tauri::AppHandle) -> Result<(), Box> { - let client = Client::new(); - let port = app.state::(); - let base_url = format!("http://localhost:{}", *port); - - info!("Toggling recording. Base URL: {}", base_url); - - // Toggle vision recording - let vision_status: Value = client - .get(format!("{}/vision/status", base_url)) - .send() - .await? - .json() - .await?; - let is_vision_running = vision_status["is_running"].as_bool().unwrap_or(false); - info!("Current vision status: {}", is_vision_running); - - if is_vision_running { - info!("Stopping vision recording"); - client - .post(format!("{}/vision/stop", base_url)) - .send() - .await?; - } else { - info!("Starting vision recording"); - client - .post(format!("{}/vision/start", base_url)) - .send() - .await?; - } +use analytics::AnalyticsManager; - // Toggle audio devices - info!("Fetching audio devices"); - let devices: Vec = client - .get(format!("{}/audio/list", base_url)) - .send() - .await? - .json() - .await?; - - for device in devices { - let device_id = device["id"].as_str().unwrap(); - let is_running = device["is_running"].as_bool().unwrap_or(false); - info!("Audio device {}: current status {}", device_id, is_running); - - if is_running { - info!("Stopping audio device {}", device_id); - client - .post(format!("{}/audio/stop", base_url)) - .json(&serde_json::json!({"device_id": device_id})) - .send() - .await?; - } else { - info!("Starting audio device {}", device_id); - client - .post(format!("{}/audio/start", base_url)) - .json(&serde_json::json!({"device_id": device_id})) - .send() - .await?; - } - } - - // Update tray menu item - let item_handle = app.tray_handle().get_item("toggle_recording"); - if is_vision_running { - info!("Updating tray menu item to 'Start Recording'"); - item_handle.set_title("Start Recording")?; - } else { - info!("Updating tray menu item to 'Stop Recording'"); - item_handle.set_title("Stop Recording")?; - } - - info!("Toggle recording completed successfully"); - Ok(()) -} +use crate::analytics::start_analytics; +mod logs; fn ensure_local_data_dir( custom_path: Option, @@ -125,49 +61,26 @@ async fn initialize_database(local_data_dir: Arc) -> Arc SystemTray { - let quit = CustomMenuItem::new("quit".to_string(), "Quit"); - let send_feedback = CustomMenuItem::new("send_feedback".to_string(), "Send Feedback"); - let toggle_analytics = CustomMenuItem::new("toggle_analytics".to_string(), "Disable Analytics"); - let toggle_autostart = CustomMenuItem::new("toggle_autostart".to_string(), "Disable Autostart"); - - let tray_menu = SystemTrayMenu::new() - .add_item(send_feedback) - .add_item(toggle_analytics) - .add_item(toggle_autostart) - .add_native_item(SystemTrayMenuItem::Separator) - .add_item(quit); - - SystemTray::new().with_menu(tray_menu) +#[derive(Default)] +struct TrayState { + menu: Option>, } -#[derive(Serialize, Deserialize, Default)] +#[derive(Serialize, Deserialize)] struct Preferences { autostart_enabled: bool, } -fn get_preferences_path() -> PathBuf { - home_dir() - .unwrap() - .join(".screenpipe") - .join("preferences.json") -} - -fn load_preferences() -> Preferences { - let path = get_preferences_path(); - fs::read_to_string(&path) - .map(|contents| serde_json::from_str(&contents).unwrap_or_default()) - .unwrap_or_default() -} - -fn save_preferences(prefs: &Preferences) { - let path = get_preferences_path(); - fs::create_dir_all(path.parent().unwrap()).unwrap(); - fs::write(path, serde_json::to_string_pretty(prefs).unwrap()).unwrap(); +impl Default for Preferences { + fn default() -> Self { + Self { + autostart_enabled: true, // Set to true by default + } + } } async fn setup_server_and_recording( - app: &tauri::App, + app: tauri::AppHandle, db: Arc, local_data_dir: Arc, port: u16, @@ -188,18 +101,21 @@ async fn setup_server_and_recording( if !disable_audio { info!("Initializing audio devices..."); + let all_audio_devices = list_audio_devices().unwrap_or_default(); + + for device in all_audio_devices { + let device_control = DeviceControl { + is_running: false, + is_paused: false, + }; + info!("Audio device: {:?}", device.to_string()); + devices_status.insert(device, device_control); + } + if let Ok(input_device) = default_input_device() { info!("Default input device found: {:?}", input_device.to_string()); audio_devices.push(Arc::new(input_device.clone())); - devices_status.insert( - input_device, - DeviceControl { - is_running: true, - is_paused: false, - }, - ); - } else { - info!("No default input device found"); + devices_status.get_mut(&input_device).unwrap().is_running = true; } if let Ok(output_device) = default_output_device() { info!( @@ -207,15 +123,7 @@ async fn setup_server_and_recording( output_device.to_string() ); audio_devices.push(Arc::new(output_device.clone())); - devices_status.insert( - output_device, - DeviceControl { - is_running: true, - is_paused: false, - }, - ); - } else { - info!("No default output device found"); + devices_status.get_mut(&output_device).unwrap().is_running = true; } if audio_devices.is_empty() { @@ -224,17 +132,19 @@ async fn setup_server_and_recording( info!("Using audio devices:"); for device in &audio_devices { info!(" {}", device); - - let device_control = DeviceControl { - is_running: true, - is_paused: false, - }; let device_clone = device.deref().clone(); let sender_clone = audio_devices_control_sender.clone(); - // send signal after everything started tokio::spawn(async move { tokio::time::sleep(Duration::from_secs(15)).await; - let _ = sender_clone.send((device_clone, device_control)).await; + let _ = sender_clone + .send(( + device_clone, + DeviceControl { + is_running: true, + is_paused: false, + }, + )) + .await; }); } } @@ -309,53 +219,67 @@ async fn main() { release: sentry::release_name!(), ..Default::default() })); - let prefs = load_preferences(); - let autostart_enabled = if prefs.autostart_enabled { - "true" - } else { - "false" - }; let app = tauri::Builder::default() + .plugin(tauri_plugin_updater::Builder::new().build()) + .plugin(tauri_plugin_store::Builder::new().build()) + .plugin(tauri_plugin_shell::init()) + .plugin(tauri_plugin_cli::init()) .plugin(tauri_plugin_autostart::init( MacosLauncher::LaunchAgent, - Some(vec![autostart_enabled]), + None, )) + .manage(TrayState::default()) .setup(move |app| { - let matches = app.get_cli_matches().unwrap(); + let cli = app.cli().matches().expect("Failed to get CLI matches"); + + let local_data_dir = Arc::new( + ensure_local_data_dir( + cli.args + .get("data-dir") + .and_then(|v| Some(v.value.to_string())), + ) + .expect("Failed to ensure local data directory"), + ); - let custom_data_dir = matches + let port = cli .args - .get("data-dir") - .and_then(|v| v.value.as_str().map(String::from)); - - let fps = matches + .get("port") + .and_then(|v| v.value.as_u64()) + .unwrap_or(3000) as u16; + let fps = cli .args .get("fps") .and_then(|v| v.value.as_f64()) - .unwrap_or(1.0); - let audio_chunk_duration = matches + .unwrap_or(30.0); + let audio_chunk_duration = cli .args .get("audio-chunk-duration") .and_then(|v| v.value.as_u64()) - .unwrap_or(30); - let port = matches + .unwrap_or(5); + let disable_audio = cli .args - .get("port") - .and_then(|v| v.value.as_u64()) - .unwrap_or(3035) as u16; - let disable_audio = matches.args.get("disable-audio").is_none(); - let memory_threshold = matches + .get("disable-audio") + .and_then(|v| v.value.as_bool()) + .unwrap_or(false); + let memory_threshold = cli .args .get("memory-threshold") .and_then(|v| v.value.as_f64()) .unwrap_or(80.0); - let runtime_threshold = matches + let runtime_threshold = cli .args .get("runtime-threshold") .and_then(|v| v.value.as_u64()) - .unwrap_or(60); - let debug = matches.args.get("debug").is_some(); + .unwrap_or(3600); + + app.manage(port); + + let debug = cli + .args + .get("debug") + .and_then(|v| v.value.as_bool()) + .unwrap_or(false); let mut builder = env_logger::Builder::new(); builder @@ -368,7 +292,6 @@ async fn main() { builder.filter_module("screenpipe", LevelFilter::Debug); } - let local_data_dir = Arc::new(ensure_local_data_dir(custom_data_dir).unwrap()); // Add file logging let log_dir = home_dir() .ok_or("Failed to get home directory")? @@ -388,115 +311,136 @@ async fn main() { let app_name = "screenpipe"; let interval_hours = 1; // Send event every 1 hour - match start_analytics(posthog_api_key, app_name, interval_hours) { - Ok(analytics_manager) => { - app.manage(analytics_manager); - } - Err(e) => { - error!("Failed to start analytics: {}", e); - } - } + let path = log_dir.join("store.bin"); - let tray_handle = app.tray_handle(); - let autostart_item = tray_handle.get_item("toggle_autostart"); - if prefs.autostart_enabled { - autostart_item.set_title("Disable Autostart").unwrap(); - } else { - autostart_item.set_title("Enable Autostart").unwrap(); + // create file if not exists + if !path.exists() { + let _ = File::create(path.clone()).unwrap(); } - app.manage(prefs); + let stores = app.app_handle().state::>(); + + let _ = with_store(app.app_handle().clone(), stores, path, |store| { + // Note that values must be serde_json::Value instances, + // otherwise, they will not be compatible with the JavaScript bindings. + // store.insert("some-key".to_string(), json!({ "value": 5 }))?; + + // Get a value from the store. + // let value = store + // .get("some-key") + // .expect("Failed to get value from store"); + // println!("{}", value); // {"value":5} + + // You can manually save the store after making changes. + // Otherwise, it will save upon graceful exit as described above. + store.save()?; + + let is_analytics_enabled = store + .get("analytics_enabled") + .unwrap_or(&Value::Bool(true)) + .as_bool() + .unwrap_or(true); + + if is_analytics_enabled { + match start_analytics(posthog_api_key, app_name, interval_hours) { + Ok(analytics_manager) => { + app.manage(analytics_manager); + } + Err(e) => { + error!("Failed to start analytics: {}", e); + } + } + } - // Store configuration in app state - app.manage(Arc::clone(&local_data_dir)); - app.manage(port); - app.manage(fps); - app.manage(audio_chunk_duration); - app.manage(disable_audio); - app.manage(memory_threshold); - app.manage(runtime_threshold); + Ok(()) + }); - Ok(()) - }) - .system_tray(make_tray()) - .on_system_tray_event(|app, event| match event { - SystemTrayEvent::MenuItemClick { id, .. } => { - match id.as_str() { - "send_feedback" => { - // Implement send_feedback logic - // open email to louis@screenpi.pe - let email = "louis@screenpi.pe"; - let subject = "Screenpipe Feedback"; - let body = r#"Please enter your feedback here... - -... or let's chat? -https://cal.com/louis030195/screenpipe - "#; - let url = format!("mailto:{}?subject={}&body={}", email, subject, body); - let app_handle = app.app_handle(); - tauri::async_runtime::spawn(async move { - if let Err(e) = - tauri::api::shell::open(&app_handle.shell_scope(), url, None) - { + let handle = app.app_handle().clone(); + tauri::async_runtime::spawn(async move { + let db = initialize_database(local_data_dir.clone()).await; + handle.manage(db.clone()); + + setup_server_and_recording( + handle, + db, + local_data_dir, + port, + fps, + audio_chunk_duration, + disable_audio, + memory_threshold, + runtime_threshold, + ) + .await; + }); + + let quit_item = MenuItemBuilder::with_id("quit", "Quit").build(app)?; + let send_feedback_item = + MenuItemBuilder::with_id("send_feedback", "Send Feedback").build(app)?; + let toggle_analytics_item = + MenuItemBuilder::with_id("toggle_analytics", "Disable Analytics").build(app)?; + let toggle_autostart_item = + MenuItemBuilder::with_id("toggle_autostart", "Disable Autostart").build(app)?; + + let menu = MenuBuilder::new(app) + .item(&send_feedback_item) + .item(&toggle_analytics_item) + .item(&toggle_autostart_item) + .separator() + .item(&quit_item) + .build()?; + + app.manage(TrayState { + menu: Some(menu.clone()), + }); + + let _tray = TrayIconBuilder::new() + .menu(&menu) + .on_menu_event(move |app, event| { + let tray_state: State = app.state(); + let menu = tray_state.menu.as_ref().unwrap(); + + match event.id().as_ref() { + "quit" => { + std::process::exit(0); + } + "send_feedback" => { + let email = "louis@screenpi.pe"; + let subject = "Screenpipe Feedback"; + let body = r#"Please enter your feedback here... + + ... or let's chat? + https://cal.com/louis030195/screenpipe + "#; + let url = format!("mailto:{}?subject={}&body={}", email, subject, body); + let app_handle = app.app_handle(); + if let Err(e) = app_handle.shell().open(url, None) { error!("Failed to open URL: {}", e); } - }); - } - "toggle_analytics" => { - let analytics_manager = app.state::>(); - let is_enabled = analytics_manager.toggle_analytics(); - let item_handle = app.tray_handle().get_item("toggle_analytics"); - if is_enabled { - item_handle.set_title("Disable Analytics").unwrap(); - } else { - item_handle.set_title("Enable Analytics").unwrap(); } - } - "quit" => { - std::process::exit(0); - } - "toggle_recording" => { - let app_handle = app.app_handle(); - tauri::async_runtime::spawn(async move { - if let Err(e) = toggle_recording(&app_handle).await { - error!("Error toggling recording: {}", e); + "toggle_analytics" => { + let analytics_manager = app.state::>(); + let is_enabled = analytics_manager.toggle_analytics(); + if let Some(item) = menu.get("toggle_analytics") { + if is_enabled { + let _ = + item.as_menuitem().unwrap().set_text("Enable Analytics"); + } else { + let _ = + item.as_menuitem().unwrap().set_text("Disable Analytics"); + } } - }); + } + _ => {} } - _ => {} - } - } - _ => {} + }) + .build(app)?; + + Ok(()) }) .build(tauri::generate_context!()) .expect("error while building tauri application"); - // Initialize the database after the app is built - let local_data_dir = app.state::>(); - let db = initialize_database(Arc::clone(&local_data_dir)).await; - app.manage(db.clone()); - - // Setup server and recording after database initialization - let port = *app.state::(); - let fps = *app.state::(); - let audio_chunk_duration = *app.state::(); - let disable_audio = *app.state::(); - let memory_threshold = *app.state::(); - let runtime_threshold = *app.state::(); - - setup_server_and_recording( - &app, - db, - local_data_dir.inner().clone(), - port, - fps, - audio_chunk_duration, - disable_audio, - memory_threshold, - runtime_threshold, - ) - .await; - // Run the app app.run(|_, _| {}); } diff --git a/examples/apps/screen-pipe-app/src-tauri/tauri.conf.json b/examples/apps/screen-pipe-app/src-tauri/tauri.conf.json index 107c5c59f..96fdfc144 100644 --- a/examples/apps/screen-pipe-app/src-tauri/tauri.conf.json +++ b/examples/apps/screen-pipe-app/src-tauri/tauri.conf.json @@ -3,62 +3,50 @@ "build": { "beforeBuildCommand": "pnpm run build", "beforeDevCommand": "pnpm run dev", - "devPath": "http://localhost:3000", - "distDir": "../out" + "frontendDist": "../out", + "devUrl": "http://localhost:3000" }, - "package": { - "productName": "screenpipe", - "version": "0.1.0" - }, - "tauri": { - "systemTray": { - "iconPath": "icons/generated/Assets.xcassets/AppIcon.appiconset/1024.png", - "iconAsTemplate": true + "bundle": { + "active": true, + "category": "DeveloperTool", + "copyright": "", + "targets": "all", + "externalBin": [], + "icon": [ + "icons/generated/Assets.xcassets/AppIcon.appiconset/32.png", + "icons/generated/Assets.xcassets/AppIcon.appiconset/128.png", + "icons/generated/Assets.xcassets/AppIcon.appiconset/256.png", + "icons/generated/Assets.xcassets/AppIcon.appiconset/512.png", + "icons/generated/Assets.xcassets/AppIcon.appiconset/1024.png", + "icons/generated/icon.icns", + "icons/generated/icon.ico" + ], + "windows": { + "certificateThumbprint": null, + "digestAlgorithm": "sha256", + "timestampUrl": "" }, - "allowlist": { - "all": false + "longDescription": "", + "macOS": { + "entitlements": null, + "exceptionDomain": "", + "frameworks": [], + "providerShortName": null, + "signingIdentity": null }, - "bundle": { - "active": true, - "category": "DeveloperTool", - "copyright": "", + "resources": [], + "shortDescription": "", + "linux": { "deb": { "depends": [] - }, - "externalBin": [], - "icon": [ - "icons/generated/Assets.xcassets/AppIcon.appiconset/32.png", - "icons/generated/Assets.xcassets/AppIcon.appiconset/128.png", - "icons/generated/Assets.xcassets/AppIcon.appiconset/256.png", - "icons/generated/Assets.xcassets/AppIcon.appiconset/512.png", - "icons/generated/Assets.xcassets/AppIcon.appiconset/1024.png", - "icons/generated/icon.icns", - "icons/generated/icon.ico" - ], - "identifier": "com.screenpi.pe", - "longDescription": "", - "macOS": { - "entitlements": null, - "exceptionDomain": "", - "frameworks": [], - "providerShortName": null, - "signingIdentity": null - }, - "resources": [], - "shortDescription": "", - "targets": "all", - "windows": { - "certificateThumbprint": null, - "digestAlgorithm": "sha256", - "timestampUrl": "" } }, - "security": { - "csp": null - }, - "updater": { - "active": false - }, + "createUpdaterArtifacts": true + }, + "productName": "screenpipe", + "version": "0.1.0", + "identifier": "com.screenpi.pe", + "plugins": { "cli": { "description": "Screen Pipe App CLI", "longDescription": "Command-line interface for Screen Pipe App", @@ -102,6 +90,21 @@ "description": "Enable debug mode" } ] + }, + "updater": { + "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDIyQjQ2RkQzMUNBOUFDMTcKUldRWHJLa2MwMiswSWl3RlBGUW5zYUE0Zm0vNFFRRTltNUZZTUVxR2FxUDNtSWdUSHgyL3JNcmcK", + "endpoints": [ + "https://github.com/louis030195/screenpipe/releases/latest/download/latest.json" + ] + } + }, + "app": { + "security": { + "csp": null + }, + "trayIcon": { + "iconPath": "icons/generated/Assets.xcassets/AppIcon.appiconset/1024.png", + "iconAsTemplate": true } } } \ No newline at end of file From 552dd6bfe68f35528034359fb505c69d1ec5f7e0 Mon Sep 17 00:00:00 2001 From: Louis Beaumont Date: Thu, 18 Jul 2024 12:51:56 +0200 Subject: [PATCH 5/6] example: add dioxus example --- Cargo.toml | 2 +- .../apps/screenpipe-app-dioxus/.gitignore | 9 + .../apps/screenpipe-app-dioxus/Cargo.toml | 66 ++++ .../apps/screenpipe-app-dioxus/Dioxus.toml | 43 +++ examples/apps/screenpipe-app-dioxus/README.md | 15 + .../screenpipe-app-dioxus/assets/header.svg | 20 ++ .../screenpipe-app-dioxus/assets/main.css | 40 +++ examples/apps/screenpipe-app-dioxus/input.css | 3 + .../screenpipe-app-dioxus/src/analytics.rs | 145 +++++++++ .../apps/screenpipe-app-dioxus/src/logs.rs | 26 ++ .../apps/screenpipe-app-dioxus/src/main.rs | 290 ++++++++++++++++++ .../screenpipe-app-dioxus/tailwind.config.js | 9 + 12 files changed, 667 insertions(+), 1 deletion(-) create mode 100644 examples/apps/screenpipe-app-dioxus/.gitignore create mode 100644 examples/apps/screenpipe-app-dioxus/Cargo.toml create mode 100644 examples/apps/screenpipe-app-dioxus/Dioxus.toml create mode 100644 examples/apps/screenpipe-app-dioxus/README.md create mode 100644 examples/apps/screenpipe-app-dioxus/assets/header.svg create mode 100644 examples/apps/screenpipe-app-dioxus/assets/main.css create mode 100644 examples/apps/screenpipe-app-dioxus/input.css create mode 100644 examples/apps/screenpipe-app-dioxus/src/analytics.rs create mode 100644 examples/apps/screenpipe-app-dioxus/src/logs.rs create mode 100644 examples/apps/screenpipe-app-dioxus/src/main.rs create mode 100644 examples/apps/screenpipe-app-dioxus/tailwind.config.js diff --git a/Cargo.toml b/Cargo.toml index 5e0532dd0..d26669263 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["screenpipe-server", "screenpipe-vision", "screenpipe-audio", "examples/apps/screen-pipe-app/src-tauri"] +members = ["screenpipe-server", "screenpipe-vision", "screenpipe-audio", "examples/apps/screen-pipe-app/src-tauri", "examples/apps/screenpipe-app-dioxus"] exclude = [] resolver = "2" diff --git a/examples/apps/screenpipe-app-dioxus/.gitignore b/examples/apps/screenpipe-app-dioxus/.gitignore new file mode 100644 index 000000000..884ebcaf5 --- /dev/null +++ b/examples/apps/screenpipe-app-dioxus/.gitignore @@ -0,0 +1,9 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ +/dist/ +/static/ +/.dioxus/ + +# These are backup files generated by rustfmt +**/*.rs.bk diff --git a/examples/apps/screenpipe-app-dioxus/Cargo.toml b/examples/apps/screenpipe-app-dioxus/Cargo.toml new file mode 100644 index 000000000..502cb97ea --- /dev/null +++ b/examples/apps/screenpipe-app-dioxus/Cargo.toml @@ -0,0 +1,66 @@ +[package] +name = "screenpipe-app" +version = "0.1.0" +authors = ["Louis Beaumont "] +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +dioxus = { version = "0.5.1", features = ["desktop", "router"] } + +# Debug +tracing = "0.1.40" +dioxus-logger = "0.5.0" + +serde_json = "1.0" +serde = { version = "1.0", features = ["derive"] } + +screenpipe-vision = { path = "../../../screenpipe-vision" } + +axum = "0.7.5" + +# Logging +log = "0.4.17" +env_logger = "0.11.3" + +# Tokio +tokio = { version = "1.36.0", features = ["full"] } + +# Directory management +dirs = "5.0" + +# HTTP client +reqwest = { version = "0.12", features = ["json"] } + +# Uuid +uuid = { version = "1.10.0", features = ["v4"] } + +# Sentry +sentry = "0.34.0" + +# Chrono +chrono = "0.4.3" + +anyhow = "1.0" + +# M series MacOS +[target.'cfg(target_os = "macos")'.dependencies] +screenpipe-server = { path = "../../../screenpipe-server", features = ["metal"] } +screenpipe-audio = { path = "../../../screenpipe-audio", features = ["metal"] } + +# Linux +[target.'cfg(target_os = "linux")'.dependencies] +screenpipe-server = { path = "../../../screenpipe-server", features = [] } +screenpipe-audio = { path = "../../../screenpipe-audio", features = [] } + +# Windows +[target.'cfg(target_os = "windows")'.dependencies] +screenpipe-server = { path = "../../../screenpipe-server", features = [] } +screenpipe-audio = { path = "../../../screenpipe-audio", features = [] } + +[features] +cuda = ["screenpipe-server/cuda", "screenpipe-audio/cuda"] +metal = ["screenpipe-server/metal", "screenpipe-audio/metal"] +bundle = [] \ No newline at end of file diff --git a/examples/apps/screenpipe-app-dioxus/Dioxus.toml b/examples/apps/screenpipe-app-dioxus/Dioxus.toml new file mode 100644 index 000000000..d06449881 --- /dev/null +++ b/examples/apps/screenpipe-app-dioxus/Dioxus.toml @@ -0,0 +1,43 @@ +[application] + +# App (Project) Name +name = "screenpipe-app" + +# Dioxus App Default Platform +# desktop, web +default_platform = "desktop" + +# `build` & `serve` dist path +out_dir = "dist" + +# assets file folder +asset_dir = "assets" + +[web.app] + +# HTML title tag content +title = "screenpipe-app" + +[web.watcher] + +# when watcher trigger, regenerate the `index.html` +reload_html = true + +# which files or dirs will be watcher monitoring +watch_path = ["src", "assets"] + +# include `assets` in web platform +[web.resource] + +# CSS style file + +style = ["tailwind.css"] + +# Javascript code file +script = [] + +[web.resource.dev] + +# Javascript code file +# serve: [dev-server] only +script = [] diff --git a/examples/apps/screenpipe-app-dioxus/README.md b/examples/apps/screenpipe-app-dioxus/README.md new file mode 100644 index 000000000..736b91124 --- /dev/null +++ b/examples/apps/screenpipe-app-dioxus/README.md @@ -0,0 +1,15 @@ +# Development + +1. Install npm: https://docs.npmjs.com/downloading-and-installing-node-js-and-npm +2. Install the tailwind css cli: https://tailwindcss.com/docs/installation +3. Run the following command in the root of the project to start the tailwind CSS compiler: + +```bash +npx tailwindcss -i ./input.css -o ./assets/tailwind.css --watch +``` + +Run the following command in the root of the project to start the Dioxus dev server: + +```bash +dx serve --hot-reload --platform desktop +``` \ No newline at end of file diff --git a/examples/apps/screenpipe-app-dioxus/assets/header.svg b/examples/apps/screenpipe-app-dioxus/assets/header.svg new file mode 100644 index 000000000..59c96f2f2 --- /dev/null +++ b/examples/apps/screenpipe-app-dioxus/assets/header.svg @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/examples/apps/screenpipe-app-dioxus/assets/main.css b/examples/apps/screenpipe-app-dioxus/assets/main.css new file mode 100644 index 000000000..affbeb048 --- /dev/null +++ b/examples/apps/screenpipe-app-dioxus/assets/main.css @@ -0,0 +1,40 @@ +body { + background-color: #111216; +} + +#main { + margin: 0; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif +} + +#links { + width: 400px; + text-align: left; + font-size: x-large; + color: white; + display: flex; + flex-direction: column; +} + +#links a { + color: white; + text-decoration: none; + margin-top: 20px; + margin: 10px; + border: white 1px solid; + border-radius: 5px; + padding: 10px; +} + +#links a:hover { + background-color: #1f1f1f; + cursor: pointer; +} + +#header { + max-width: 1200px; +} diff --git a/examples/apps/screenpipe-app-dioxus/input.css b/examples/apps/screenpipe-app-dioxus/input.css new file mode 100644 index 000000000..bd6213e1d --- /dev/null +++ b/examples/apps/screenpipe-app-dioxus/input.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; \ No newline at end of file diff --git a/examples/apps/screenpipe-app-dioxus/src/analytics.rs b/examples/apps/screenpipe-app-dioxus/src/analytics.rs new file mode 100644 index 000000000..5d3c281bc --- /dev/null +++ b/examples/apps/screenpipe-app-dioxus/src/analytics.rs @@ -0,0 +1,145 @@ +use log::{error, info}; +use reqwest::Client; +use serde_json::json; +use std::fs; +use std::sync::{Arc, Mutex}; +use std::time::Duration; +use tokio::time::interval; +use uuid::Uuid; + +pub struct AnalyticsManager { + client: Client, + posthog_api_key: String, + distinct_id: String, + interval: Duration, + enabled: Arc>, + api_host: String, +} + +impl AnalyticsManager { + pub fn new(posthog_api_key: String, distinct_id: String, interval_hours: u64) -> Self { + Self { + client: Client::new(), + posthog_api_key, + distinct_id, + interval: Duration::from_secs(interval_hours * 3600), + enabled: Arc::new(Mutex::new(true)), + api_host: "https://eu.i.posthog.com".to_string(), + } + } + + pub async fn send_event( + &self, + event: &str, + properties: Option, + ) -> Result<(), Box> { + if !*self.enabled.lock().unwrap() { + return Ok(()); + } + + let posthog_url = format!("{}/capture/", self.api_host); + + let mut payload = json!({ + "api_key": self.posthog_api_key, + "event": event, + "properties": { + "distinct_id": self.distinct_id, + "$lib": "rust-reqwest", + "timestamp": chrono::Utc::now().to_rfc3339(), + }, + }); + + if let Some(props) = properties { + if let Some(payload_props) = payload["properties"].as_object_mut() { + payload_props.extend(props.as_object().unwrap_or(&serde_json::Map::new()).clone()); + } + } + + let response = self.client.post(posthog_url).json(&payload).send().await?; + + if !response.status().is_success() { + return Err(format!("PostHog API error: {}", response.status()).into()); + } + + Ok(()) + } + + pub async fn start_periodic_event(&self) { + let mut interval = interval(self.interval); + + loop { + interval.tick().await; + if *self.enabled.lock().unwrap() { + if let Err(e) = self.send_event("app_still_running", None).await { + error!("Failed to send periodic PostHog event: {}", e); + } + } + } + } + + pub fn toggle_analytics(&self) -> bool { + let mut enabled = self.enabled.lock().unwrap(); + *enabled = !*enabled; + *enabled + } + + pub async fn track_search(&self) -> Result<(), Box> { + if !*self.enabled.lock().unwrap() { + return Ok(()); + } + + self.send_event("search_request", None).await + } +} + +pub fn get_or_create_unique_id(app_name: &str) -> Result> { + let home_dir = dirs::home_dir().ok_or("Failed to get home directory")?; + let app_dir = home_dir.join(format!(".{}", app_name)); + let id_file = app_dir.join("unique_id"); + + if !app_dir.exists() { + fs::create_dir_all(&app_dir)?; + } + + if id_file.exists() { + Ok(fs::read_to_string(id_file)?) + } else { + let new_id = Uuid::new_v4().to_string(); + fs::write(id_file, &new_id)?; + Ok(new_id) + } +} + +pub fn start_analytics( + posthog_api_key: String, + app_name: &str, + interval_hours: u64, +) -> Result, Box> { + let distinct_id = get_or_create_unique_id(app_name)?; + let analytics_manager = Arc::new(AnalyticsManager::new( + posthog_api_key, + distinct_id, + interval_hours, + )); + + // Send initial event at boot + tokio::spawn({ + let analytics_manager = analytics_manager.clone(); + async move { + if let Err(e) = analytics_manager.send_event("app_started", None).await { + error!("Failed to send initial PostHog event: {}", e); + } + info!("Analytics started"); + } + }); + + // Start periodic events + tokio::spawn({ + let analytics_manager = analytics_manager.clone(); + async move { + analytics_manager.start_periodic_event().await; + } + }); + + Ok(analytics_manager) +} diff --git a/examples/apps/screenpipe-app-dioxus/src/logs.rs b/examples/apps/screenpipe-app-dioxus/src/logs.rs new file mode 100644 index 000000000..96aac57b6 --- /dev/null +++ b/examples/apps/screenpipe-app-dioxus/src/logs.rs @@ -0,0 +1,26 @@ +use std::io::Write; +pub struct MultiWriter { + writers: Vec>, +} + +impl MultiWriter { + pub fn new(writers: Vec>) -> Self { + MultiWriter { writers } + } +} + +impl Write for MultiWriter { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + for writer in &mut self.writers { + writer.write_all(buf)?; + } + Ok(buf.len()) + } + + fn flush(&mut self) -> std::io::Result<()> { + for writer in &mut self.writers { + writer.flush()?; + } + Ok(()) + } +} diff --git a/examples/apps/screenpipe-app-dioxus/src/main.rs b/examples/apps/screenpipe-app-dioxus/src/main.rs new file mode 100644 index 000000000..15090b56d --- /dev/null +++ b/examples/apps/screenpipe-app-dioxus/src/main.rs @@ -0,0 +1,290 @@ +#![cfg_attr(feature = "bundle", windows_subsystem = "windows")] + +use dioxus::desktop::{muda::*, use_wry_event_handler}; +use dioxus::prelude::*; +use dirs::home_dir; +use log::{error, info, LevelFilter}; +use logs::MultiWriter; +use screenpipe_server::DatabaseManager; +use sentry; +use std::fs::{self, File}; +use std::io::Write; +use std::ops::Deref; +use std::path::PathBuf; +use std::sync::Arc; +mod analytics; +use analytics::AnalyticsManager; +use tokio::runtime::Runtime; + +use crate::analytics::start_analytics; +mod logs; + +use screenpipe_audio::{ + default_input_device, default_output_device, list_audio_devices, DeviceControl, +}; +use screenpipe_server::{ResourceMonitor, Server}; +use std::sync::atomic::AtomicBool; +use std::time::Duration; +use tokio::sync::mpsc; + +async fn setup_server_and_recording( + db: Arc, + local_data_dir: Arc, + port: u16, + fps: f64, + audio_chunk_duration: u64, + disable_audio: bool, + memory_threshold: f64, + runtime_threshold: u64, + analytics_manager: Arc, +) { + info!("Setting up server and recording..."); + + let (audio_devices_control_sender, audio_devices_control_receiver) = mpsc::channel(64); + let mut audio_devices = Vec::new(); + let mut devices_status = std::collections::HashMap::new(); + + if !disable_audio { + info!("Initializing audio devices..."); + let all_audio_devices = list_audio_devices().unwrap_or_default(); + + for device in all_audio_devices { + let device_control = DeviceControl { + is_running: false, + is_paused: false, + }; + info!("Audio device: {:?}", device.to_string()); + devices_status.insert(device, device_control); + } + + if let Ok(input_device) = default_input_device() { + info!("Default input device found: {:?}", input_device.to_string()); + audio_devices.push(Arc::new(input_device.clone())); + devices_status.get_mut(&input_device).unwrap().is_running = true; + } + if let Ok(output_device) = default_output_device() { + info!( + "Default output device found: {:?}", + output_device.to_string() + ); + audio_devices.push(Arc::new(output_device.clone())); + devices_status.get_mut(&output_device).unwrap().is_running = true; + } + + if audio_devices.is_empty() { + error!("No audio devices available. Audio recording will be disabled."); + } else { + info!("Using audio devices:"); + for device in &audio_devices { + info!(" {}", device); + let device_clone = device.deref().clone(); + let sender_clone = audio_devices_control_sender.clone(); + tokio::spawn(async move { + tokio::time::sleep(Duration::from_secs(15)).await; + let _ = sender_clone + .send(( + device_clone, + DeviceControl { + is_running: true, + is_paused: false, + }, + )) + .await; + }); + } + } + } else { + info!("Audio recording is disabled"); + } + + // Start resource monitoring + ResourceMonitor::new(memory_threshold, runtime_threshold, false) + .start_monitoring(Duration::from_secs(10)); + + let db_record = db.clone(); + let db_server = db.clone(); + + let (_control_tx, control_rx) = mpsc::channel(64); + let vision_control = Arc::new(AtomicBool::new(true)); + let vision_control_server_clone = vision_control.clone(); + + // Spawn continuous recording task + let _recording_task = tokio::spawn({ + let local_data_dir = local_data_dir.clone(); + async move { + let audio_chunk_duration = Duration::from_secs(audio_chunk_duration); + screenpipe_server::start_continuous_recording( + db_record, + local_data_dir, + fps, + audio_chunk_duration, + control_rx, + vision_control, + audio_devices_control_receiver, + ) + .await + } + }); + + // API plugin for analytics + let api_plugin = move |req: &axum::http::Request| { + if req.uri().path() == "/search" { + let analytics_manager = analytics_manager.clone(); + tokio::spawn(async move { + if let Err(e) = analytics_manager.track_search().await { + error!("Failed to track search request: {}", e); + } + }); + } + }; + + // Spawn server task + tokio::spawn(async move { + let server = Server::new( + db_server, + std::net::SocketAddr::from(([0, 0, 0, 0], port)), + vision_control_server_clone, + audio_devices_control_sender, + ); + info!("Starting server..."); + + if let Err(e) = server.start(devices_status, api_plugin).await { + error!("Failed to start server: {}", e); + } + }); + + info!("Server started on http://localhost:{}", port); +} + +async fn initialize_database(local_data_dir: Arc) -> Arc { + Arc::new( + DatabaseManager::new(&format!("{}/db.sqlite", local_data_dir)) + .await + .unwrap(), + ) +} + +fn get_local_dir(custom_path: Option) -> anyhow::Result { + let default_path = home_dir() + .ok_or("Failed to get home directory") + .unwrap() + .join(".screenpipe"); + + let local_data_dir = custom_path.map(PathBuf::from).unwrap_or(default_path); + + fs::create_dir_all(&local_data_dir)?; + Ok(local_data_dir) +} + +async fn start_screenpipe() -> anyhow::Result<()> { + // Initialize Sentry + let _guard = sentry::init(("https://cf682877173997afc8463e5ca2fbe3c7@o4507617161314304.ingest.us.sentry.io/4507617170161664", sentry::ClientOptions { + release: sentry::release_name!(), + ..Default::default() + })); + + // Set up logging + let mut builder = env_logger::Builder::new(); + builder + .filter(None, LevelFilter::Info) + .filter_module("tokenizers", LevelFilter::Error) + .filter_module("rusty_tesseract", LevelFilter::Error) + .filter_module("symphonia", LevelFilter::Error); + + let base_dir = get_local_dir(None)?; + fs::create_dir_all(&base_dir)?; + + let log_file = File::create(format!("{}/screenpipe.log", base_dir.to_string_lossy()))?; + let multi_writer = MultiWriter::new(vec![ + Box::new(log_file) as Box, + Box::new(std::io::stdout()) as Box, + ]); + + builder.target(env_logger::Target::Pipe(Box::new(multi_writer))); + builder.format_timestamp_secs().init(); + + // Initialize local data directory and database + let local_data_dir = Arc::new( + get_local_dir(None) + .unwrap() + .join("data") + .to_string_lossy() + .into_owned(), + ); + let db = initialize_database(local_data_dir.clone()).await; + + // Start analytics + let posthog_api_key = "phc_Bt8GoTBPgkCpDrbaIZzJIEYt0CrJjhBiuLaBck1clce".to_string(); + let app_name = "screenpipe"; + let interval_hours = 1; + let analytics_manager = start_analytics(posthog_api_key, app_name, interval_hours).unwrap(); + + // Setup server and recording + setup_server_and_recording( + db, + local_data_dir, + 3000, // default port + 30.0, // default fps + 5, // default audio_chunk_duration + false, // default disable_audio + 80.0, // default memory_threshold + 3600, // default runtime_threshold + analytics_manager, + ) + .await; + + Ok(()) +} + +fn main() { + // Create a Tokio runtime + let rt = Runtime::new().unwrap(); + + // Start Screenpipe in the background + if let Err(e) = rt.block_on(start_screenpipe()) { + eprintln!("Failed to start Screenpipe: {}", e); + std::process::exit(1); + } + // Create a menu bar that only contains the edit menu + let menu = Menu::new(); + let edit_menu = Submenu::new("Edit", true); + + edit_menu + .append_items(&[ + &PredefinedMenuItem::undo(None), + &PredefinedMenuItem::redo(None), + &PredefinedMenuItem::separator(), + &PredefinedMenuItem::cut(None), + &PredefinedMenuItem::copy(None), + &PredefinedMenuItem::paste(None), + &PredefinedMenuItem::select_all(None), + &MenuItem::with_id("switch-text", "Switch text", true, None), + ]) + .unwrap(); + + menu.append(&edit_menu).unwrap(); + + // Create a desktop config that overrides the default menu with the custom menu + let config = dioxus::desktop::Config::new().with_menu(menu); + + // Launch the app with the custom menu + LaunchBuilder::new().with_cfg(config).launch(app) +} + +fn app() -> Element { + let mut text = use_signal(String::new); + // You can use the `use_muda_event_handler` hook to run code when a menu event is triggered. + use_wry_event_handler(move |muda_event, _| { + // if muda_event.id() == "switch-text" { + // text.set("Switched to text".to_string()); + // } + }); + + rsx! { + div { + h1 { "Welcome to screen | ⭐️" } + // p { "Text: {text}" } + p { "It's running! Check examples on Github on how to use your data now :)" } + } + } +} diff --git a/examples/apps/screenpipe-app-dioxus/tailwind.config.js b/examples/apps/screenpipe-app-dioxus/tailwind.config.js new file mode 100644 index 000000000..2a69d5803 --- /dev/null +++ b/examples/apps/screenpipe-app-dioxus/tailwind.config.js @@ -0,0 +1,9 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + mode: "all", + content: ["./src/**/*.{rs,html,css}", "./dist/**/*.html"], + theme: { + extend: {}, + }, + plugins: [], +}; From 2ebbea533e6743874b1d415375b6d8cee7bf8ac5 Mon Sep 17 00:00:00 2001 From: Louis Beaumont Date: Thu, 18 Jul 2024 15:39:35 +0200 Subject: [PATCH 6/6] chore: update dioxus example --- .../apps/screenpipe-app-dioxus/Cargo.toml | 4 + .../apps/screenpipe-app-dioxus/Dioxus.toml | 11 +- .../screenpipe-app-dioxus/assets/1024.png | Bin 0 -> 120113 bytes .../screenpipe-app-dioxus/assets/icon.icns | Bin 0 -> 42860 bytes .../screenpipe-app-dioxus/assets/icon.ico | Bin 0 -> 13778 bytes .../screenpipe-app-dioxus/src/analytics.rs | 2 +- .../apps/screenpipe-app-dioxus/src/main.rs | 315 +++++++++++------- 7 files changed, 207 insertions(+), 125 deletions(-) create mode 100644 examples/apps/screenpipe-app-dioxus/assets/1024.png create mode 100644 examples/apps/screenpipe-app-dioxus/assets/icon.icns create mode 100644 examples/apps/screenpipe-app-dioxus/assets/icon.ico diff --git a/examples/apps/screenpipe-app-dioxus/Cargo.toml b/examples/apps/screenpipe-app-dioxus/Cargo.toml index 502cb97ea..3ee0f560a 100644 --- a/examples/apps/screenpipe-app-dioxus/Cargo.toml +++ b/examples/apps/screenpipe-app-dioxus/Cargo.toml @@ -43,8 +43,12 @@ sentry = "0.34.0" # Chrono chrono = "0.4.3" +# Errors anyhow = "1.0" +# Auto launch +auto-launch = "0.5.0" + # M series MacOS [target.'cfg(target_os = "macos")'.dependencies] screenpipe-server = { path = "../../../screenpipe-server", features = ["metal"] } diff --git a/examples/apps/screenpipe-app-dioxus/Dioxus.toml b/examples/apps/screenpipe-app-dioxus/Dioxus.toml index d06449881..6d914ac74 100644 --- a/examples/apps/screenpipe-app-dioxus/Dioxus.toml +++ b/examples/apps/screenpipe-app-dioxus/Dioxus.toml @@ -1,7 +1,7 @@ [application] # App (Project) Name -name = "screenpipe-app" +name = "screenpipe" # Dioxus App Default Platform # desktop, web @@ -13,10 +13,17 @@ out_dir = "dist" # assets file folder asset_dir = "assets" +# [bundle] +icon = [ + # "assets/icon.icns", # for macOS + "assets/icon.ico", # for Windows + # "assets/1024.png" # for Linux and as a fallback +] + [web.app] # HTML title tag content -title = "screenpipe-app" +title = "screenpipe" [web.watcher] diff --git a/examples/apps/screenpipe-app-dioxus/assets/1024.png b/examples/apps/screenpipe-app-dioxus/assets/1024.png new file mode 100644 index 0000000000000000000000000000000000000000..fcc2cd849e97ab4a5527dd4d78ed3d8c0c2925a3 GIT binary patch literal 120113 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 G_J05`@*m*< literal 0 HcmV?d00001 diff --git a/examples/apps/screenpipe-app-dioxus/assets/icon.icns b/examples/apps/screenpipe-app-dioxus/assets/icon.icns new file mode 100644 index 0000000000000000000000000000000000000000..a62b42c0dac25f4ea74c06f48b509f60e127d404 GIT binary patch literal 42860 zcmagG1C%GvvM%~-+qP}nwx(@&PusR_+qN~$Y1`AbZTFl1-g}*U?tACmo0VA^5i3_# zt*EH{zR0zzERAiQ0Dv-UOJgR+zr6_n0D%3eNJt0=9R~eZMm2Nxu>Wb#O!!v@{HIs= z+gtoq(Jd`Z9035(zvABp3IXxY7yyE?owXy-zeL2pXJTU$Q?q}K0RVsiAb;CGJpcgw z_W=CW|CYbg8GkE$D*>4Q(f%{tKjOd2|4Rpj00R22`fUOr0RV|Oni@LWIdT(98#*bP zIufdxIyza}*%C6*b1^c~Gkq%qVE@hp1ONjC1ps~P08j)4B_$RAd;Qi0paT7mR^b29 z3iAK8#smIw7oha-{d^~Fher9g`H`~9&c(}g+79X(E8u{OS$rKTwTIp^Afw-bowLQ^ z(TD0B`!;m*L4Q z;UXy!UH^^RNxY*!9hwkdbQ$o?_Et=mQ6rl!cNn&1C2d_P3^4*L2gsIdH{Te>#1}tS zRs?wLk+OU(GhKMjZAXuARe42U;F&_qB_KRXIg+!fzv-5$Zii<6%QfOka6T&n#@#w zivWNj5yKt7c^)bQ57?*8b4Ud@zxgJiL?B^sHij-CV|?0O!4M(UPT@#j-(gee&}f)B0B#iuOh_h2WsBH-Cq!FiHJcl1y@}Wa2Vtmmd}=X z8iVw4=7R;z-}Tl3v!Ul5V~C#Pe?az}d7Sgd&l!25^VWfBR7(+)vhY7X+g#Z2S0TCK zLA#aP5Z1Sw6z;T7=&CcHb( zwW5})UgWrEZ=U`|Pn8qw2eojm6}uTc62cI5XoH{u?3O~vNjWs)5{ZLEHNv+8rERq* zY}j6j^JHIRJpeEutbgF$#c2_ct^aoOoLB&KmN>!9;uq)XuFHzx_c_M-H|$LA5K(XJ zXV=yK#vL1|)5qb&)5ghmh*oHCGhaC;8`Kkz|nFUN(9IHeO z;cW>KuKrM46HpD(w|H*Dt+;SpRnHB$p$oX^!t$+bGILww#lW~|#;9|YGai{x13%M(ZqSK)tio{0jwBGl(AjgHt^mXWL>hD3^f}u zH`jeg0Yy)mP{ZG$s}#qz6)EiY`mUnUEfWXli@wmihO$lHzxs;^j#vf5J0c^Ppfz8@ zTpe9c6gJ1RNT~Ri_Edc;0yj=+FXC(-Jc+Iihj4&eMC^C};#lcRVk^`&>m(Qba zeP$pxuH}rts{Fs)W>j&YH6TdLix%EA^BoC|kcV_A*^7LXdl&)!JO`E(6`stdn}&0c z9&;SDfN9^bK5iLqk-N1+4UWc{UB;S-ef2BDluNb+;}(>a=BUi(C6!9Gfr60X(6&<@ z!1*KbU;dp{^kH_d=4FX+Mch_W00hzDiT(e z*fAbf@ohq%hK3ve*tpERSXIG9tA~A&bbK)&-nNkgx4;=k9iq}I%Y&xrWKs;+?6uC% zIa(PB7j{q$a;%PriVY9&cNjzQH+0AwN7b$6U3~RCJpL*qY~n$ZnQz}Dmo8dyns{Zj<403+YNk*UXON`I>Vs;Gxnu?=HMZjBZOg5=fe$!5RY3ZMzMYIN z4MCj=+ri zDzPmima%V5zPE1qwv!YGu?)A#Ps{|DSdE zu^*DNQk>b6MEaZA-aUK!UF*UyZF<`!_5e#yVEJ6TfjGuJuG&xry~_C16MP8~J)#xh zurbV}d>UMwLS~;9nbWlasS1KttI}W-X>R_RDuaq29N|2EI_|eAv$QHlYvBWqC{C83=r+jtfO`dE<}22Q=lbg|U^squ2vX;hQXb=E z&XBrFI}H8#fw24JI1GPk)niQFYAQXLc{mnL!jm4e)L%{0oZ1;o*t?aL43XwaT!s-| zbN;Uda@Tnyx5vKj)L(p{hy9V~9iQgIHh>?;1H77hu++*7!AYr{*i|6b_jevwaa?o< znXXtk5(DS6r~}WZ;^qW>8W(mx?CM%{=-P97jbsfT_X(1MXXG5hD=bEpBG)(~J$jFx zZBn#TcIi2AzLhCR(A!jUnRyr-O~_5zhzZZic6u_9=dC7{!02URz5XNXeiG|SLXRqd zlW&&It1UzV+@(?1k6(uLVlO&}+Pq%FC>15CLqea^m6505u2C9#gDAJZyqd{tax~qo z|Hzl*Y({)AOW))|{wnvFgCB;XP9hMxdto`OgVi%HLjt$#BWb=w)8{;hrZ-gE@r_l5 z6D5cOGfV7v%hS_AC1;4s*GsHvMw*wdIElu$(1X5kOo?!=_{3@$Sh}xon84hPe8{=F ziLCdqvuic2yEm)b2M@hJu9l-jE0wmjR$G|5N2(?t_~n^sH!vUblCsxX#$j&)yPQ%Q zZA3f0=IzELB=pOXB3~>ZSYuB^$rCEav^IaH_TljNz62S|;JuK*q1Aaw2GguXXQ=Y{P4TL%*(0fzXwv6ztI;pSnq9)w&7=C^+~IZ{uv)Ib?Ub4CbqZesTvRX9Y-dQUyuAj_v zGZO7@oG)2IL&?}pp>r@%!juez+SOCt6%AIDz;d-m28R#vOy%+=vCvwD?2;Gi8AjGC znVvS|ebi3=R|JjNYU{E_>U!h0gLQ{BXg2|0uPULWB%`Lk>nGUz)0S&Tug|*+KzeBY z5oDW}Bmu|t_UI`Yx-=tHjdN~o1sEC;=P(BXwd3LlzHFOUsgHD03kM*M@FNKy+&efl`0V;eLj`9RP>3dO4ZS7r|h>I~2`La6Tzt~DDwv`KKI&olO zi}In4)`O-$Rh+W5xEkrDu3b_RDD`q@D)jG`2)urYpE&_ucFmjUSdP5-Dh~JuXnu!K z+AUJegm}vR2ujqbyceOO76!wLFbSDp+-Un(P-f8b^HF!y%Zs)6J}QMAfT-Jw&WP}3 zJNN$%X}rk^+yfB+2o0Sx7N+a#Mma{0)&v|!$SFHYhhVo@?L?$F8hxR-Kn^NQeOp~Y zmNT(CNcE8N@A`82KrhxM!$W1~r$vNgbj*7&&_$j+zp-=Il4C_q0m;|tDSkSg@fE$Hq@{xgQ_p!EawC*ME_fpBip>=&80&*^U@J z?f1q)OL%iIL72SLwEr9>nAR#7RjLyLpTzLcX_58XGjMtfZa5|qQL>bx85OJQu%XeI zK^<;5EAmv`AecmNY13jw-ITA^Re`}R9gvHyWV>3Ddak=4H8CbQJr6Xs-%OGJ%_|2*4fmQ<=$SuW_?%eS-3Co=`=i3*-VdG}@^b8qA2nNZc7-ABpdW z=)AfSZym68mV25|^I|Bnd{~@>9w$b@@WG?s-K(eef+L1-bXkyh%Q61qw;YzmSM2&2 zs!qr(&<(?{tM^wwDx>|a(r-OGu!W2R=gG#%D`GIYFIqYyT1XvIvHiNdiAjC^TqWd~ zM7hx%lTu&a5cci31?{ujXPrr49uTWLOf@g`nMBcX<|@JV-VDP{BVDS7Z^Rty{;KNc zS!lN<@eE@flI_1Q8HV~Yf@fTJ`Q=nXJRDQPA0~-J5Q?Nq;wR1C! zzI9U3J6sfOi~LD@*d}p=3cs3?$7>Hm2?JLiMsd^WzRhhOxWYZVqdK&af#3wzFbnB= z`gsqSQiQH_Bd)&v`)+$HU8>mQ$h~$?;Gtq|TFcQzuS%oQrz{Z)8kpOi;TcSMX z5->Cq1R*}M^pG@ESWS$j(w%E{-}i)L>l8s~-;srmXkp zXL24D<5l8m$<{gVjkyo@f4oG@yo@eg#&k1OJSE#NUUYzRE~^Pv4kboF%3iJFNnIHN zM0Xl|%6JN}r`@WPBr&rwecr>L9?t{`2UQ3*JO+Q|hegy^y{?ah-_y(SKJ@`a73o!# zL`Sq6XD!SnRvI8%AnFgL42wYt=2wq-;qgIv)j_3$fb%cC{ynn`uj-twN) z6oyJdL?re@K|%#)%@Itu3VMT<`zYc|1BO6F#--+yRZ9H9O9}Evw&cu6 zzKc}_CzLSaS>3SaMOUhf2yC0QAJAUv+&@FUU34X?)SLX+FvYm7rQJ~o>&RE{hX-FJcFEWiD0GRX~4eU3F|))`xo)=W{IRg?2hStxjC@aB`Gpy0oIPLOB_=clHq{`uz`-6?QCXe{XN zjVn*@Mc+5z<@RROLN9ajPPcFx%mX`YospsMHBikOQwf0+4zN;?_i7iy974iDNHPDF zEuK79BRV3x_+l+o?xB#0_f-}zCtPT>k6M`bO;9+{~(q-I${Q?>@tH_WRnr3*R zoR+(!X7)=xU4P0{nMNfb+}&8WwZpc}P>D>0qCnAF8CXLnq>@g0^};N=f76m^nV5QJ zL|&TVP~{4EJ;n!0H@3c5!yGD%hL`m+Wb$nfk-{>;+oQCej>o+PD7=!LaUII<6}$hwZaNQnEOyeGgF>5WG=`zFS<8m5>E-yIqXDdx0v?a{mqwz1) zK0%69x`UW6t|W!cTDdZn2VY(*Ug~=(6Qyp3!L3xmCGr~danMwbt=@M!NUGeJ;c+@g zhh{5(3)8Ud(j!4wv6Def>U%OcweqEmmyfP4OpS=u`AuD4yW6MR-2CiELY5I5QZ2?iCj2eMvfNLe z5;e0Bv`K`3VeJCq&5OTS%#BX?X|{<|)Q7-`;&p)&h`gt-o-*}i^wn0eqfY^T_hCat`zji9)VDU)Kz@M$dYZFVfUy8+} zs4)?#->_l!pn`GuN3>6(-S9<8Jc?`gb!0lKef(6(5^t<3UT6KA3 zWk%J6KIYOIy^h1Psu%wCU*yNrVu+HB2npg&LE$U5L`frdFxws8*q zxuwqF%bpl!;g}G?&IT_6wrCvLyrdw4o=vi(gn#8SrKfWrVX}22j#a}XnAi8Jlgx}- zpq|aQBc)=?ZzSo!DY*9lLYLj?rx4S0a%v7Hb1+oQl#5H5@#MRQCjN2r`E@>O40Spr zc(l3Z;%f}+bqeyVIS3|0g$LO0S!W*v-k=Mj$%C;)Tz(fv0N<&$9^EiSy_`osP#tb<&_p=Zm8@da4) zt-g{>VwVPMzUsEB8edywgW)8TN6`GL){h58K;55iim6_kIEKG-M%V-!y}wE0xac&3 zr3z2d)P~tf5u}rI+$b?L2&!1V*|V_E=Q|yWw5EhW-6GTU%G2r8T38g?ntx8T7U*Kq zx{^X(+BBZI*B&X_$-7Nrt2+6aL6EFPly}3Zzl&c$1#5cPWhTR0^FB;8HS%SJqEwas zA$Zm5_Ct5O?5DTt==rMMr~SJUU3-UOBs>Ufp3EXnY$-h9I}TolYL@+2Qz>;s&n?^( zVljavq6w70ePlQ?qG|arka22o3V5Tn~_p&_7N=Nro-(1 zOJh~9|EaAhy1G+b)Y){)n-`8#51z@D?(GC5OlwSmx;7)f{~O|RhSG2Mt$KUO=c@+# zQ~eh~#n$Vy-2IlH>Vp4A^0&!yUgE?nTl@cxko-qMB46+$@lgc@F#RN)F~2&mQ`RK? z9&ua7q_H(wBLuPty}p^AJ1TKD&R7Z;@{qxmSE5Coqo& z#DZxCw(>}^A_qS>u}8%mXS5sj6pg<`LgN1$V)AzT_?>yE#qNm@@rRGz9eU;NOv15_ zzu(7}U z&ll zIOv|NJ){apuY%+~_6rv#5yf{-oQg92raFtS3J*W?sAoZoxGJkW8wmdxe)()cw|eg5 z>5pk&H>USC+|bSI_86hJ=qqS!Z}Lc4Y4mp<=eI{9{?JyX8%ihXiRijfc9$_ADR~li zE;)WiXTg&GaqgsEd#O+bVl^WE1kjmyfn|(Oml>oGNrYe&%NrXB#}rSk8?V4Frdt`qgg?Dm z)%+e4Wu+im=d(USiK;5)>M*AWWiyfBu9@|uPgU;c!%3rkO8#^`2iU>_EyBMr z9p%-^z78B%toptguQo<+5#?P?s*%|v(V@D>>f8@8Vb1FTsT&_UR|S7Tb1%*0cMRNo zmBY3g9{7)5k*b#_$tun%1YTWx$X)>pp#^0_-=Ch(T}mdatA65YdBJ(Vjn?^ zvJOAb2OF6FY->?8&OU<19KONEiAQM^n$D=9zAP-zv2UUll1k6>L(LNd-J^kYo5QR! zd*dz%2X_H9!VB_`ZSC=CI@J&5KTX^bv~w%q?rIT2A_}Ip7!%l^BAuVlCFc5@uTQ)( z@T4b_9wIDn99`U*_8DGq`WBe5H7Dj(4LyNMF&vT;STUp)`4VFla8B=D#{7#s;4LiN z#&p_e42cr170vhOUp0iAp8MSIFnidSJgt6xbNqz=_R@08`Vf?+SJU*@Q^BQhrSh&@ z4A-B7=wKUaWi_#IE0F%ivoznxdKQPmEZ>7XO@9VORYdS-N7~+B2uAVWN+A5gtysB< zvx^l$XPsigh{jxy62hsqh-VbNy;o^qtUvAE&C$%h(r(HICHlLUU&+}%pbM@NHTk^J zbx5f@|56Xb8qOcJQ=~D|H`f1J{O~G>mL>n^6mQnO!u3tg=0cd4YTJ96n}2cE(Ns~q zSd>EjXYjRH=fQ$t#U@O^DYW&k6lkSs0Yh23GyR9&4|uyOrD9dlg(JY=+VJC45iL3* zd5Vf3`3~TMkKh-B_$4NXTaIk%hi+UFW)r!-yrcWROk9f32|b1B`|3W)H!*rT_tnAy z-%~&%2vJt$+b2W%ixA7}NOCm{ML?`ehPHd>{R%|4htkPIyOu@D*c>)Kvy|44!DGvv z`m{V8V#8BK&-zl_JWV0J$Av)YbE@VVQ}Cmuv4wA!m|ALso>2Y!MCEvE&Qeza-f-XG zam0{HQ+~8wx1wJSi|>-I}eK6$YJyU~0; z{;eWxVtPHyUs46y;=#svTv#5c36_cC>(27<1IC*=4*?-6UF?HG#>xmho#PINKv)boPq5Vv;XYu-YC$BC8$m9mSB7A_GjD4cqn z?sOY_N=%Jt<=N_#7(sD)71Y#z(_O}fA~ta^pz}MR1IKE*=%^FJ(z#s-v4j5GUhgQ7 znQajRNDETssOD8(Xc)5(i{#ER%&fR+0C5O2IkT0@>B!IjK=4aGM8Q+jk3z#~TTmzg zQq6_cR+!6}sS5GYX!DzY?%plDS`E_@^*ZE8?QLOmXmhFhq zaA4BN?ij+}S|0|9i2M`Ccm2W{@g`(JmtNr60jYy^W33qc>9nUFFP@`K?$ZAvpr_N$ z8o~tba>2`hhtSS8YaQqhh?n!$D*Twrrb?6n53zuoJe~hVTCQOxLa!oQUx0v(pnEq? zoE6d4vXyOv02d@tN?Yp4o|)PX3j;bYq1TJ&c&uOVfh8hJ@`N53o}>qvSLS0=-!^!F z&JG3WnyBl`sYoN?U}~x!cA2@P2eZ4nWwpXKE%IG$UP$fjuwJjW$A$*XNk?1%eq0N-J|Km zvoYLeatS4rK1)!@ydia5ES$NS1EO&PYM04KOWO-_z>ilBRT#^0*@vY@E)6?~cJjI- z?~YKkG;q}0dKGC2g(@a; zmZ=;|AF&Tmbp61=spEfDitZL`S8^O8biwjGhd)4On8YTp7QQ&sVh)`aoj8Pyj5GuNYysMzs}uHJ^ZyE;fO`K4a$;Mru&zjO zhH3csnfbsi|6_Y2p{2MiM|gx~%xldT_{li%clfu~Ba6`U=^dU{qv>6+;K~rB^?LoX zF-ku;l&KwPi}1OS@;pN8BF0MR@~pA)`l{8pnP&!!axMF}G14k*9hgK@Dc>;Ni{|^V zU*=n_Y9bNweQuELY1wRW=x$z&+N|?(JK%Uy@IaI>bdETX^N$XjunT47MZrU}eP8VR z465(N+Gk$2XzVNL5{qU*7J=&)JE=J4L<$%pszt|^Yx?VCDv!oY$&#hC0%hOh0DHDX zDNCiZ2;m&5TvK0=#SE2F*bCG&=zoJ&RlO^ zI$cHqSX=dH8yS{*+cTu_=qT1aE={8%4MGQ$@G0gH`}E%|YP-qN240%E$>If>8?*!1b>F77f2 z0$woM-`Lj@>8)U@gU?Lxu#nj&gPalgep z!Hhi_8K339tj6tF3CqjtFF!ueI_3OlZdqLKD;(Rje22#`M+_}wNYedHC&-?W!|(Xi zUumB6iR&@#W!Ep`2`EMk@^FI=g@3D5xOPx3PxDFIvc(N`U#a0C=KDP(bP^MRP&eaV zNmLctH;;x){T|bv9bq%>BJS2P;y!OZSM78Eqs%gGaY%6VMHEJmD zv2GN0BReKST>Zf9?Vjk}j8gKgrpQo{vTL-|rVCxoqnQzIL0u z2SHz!&B?jGT5l%f`IeAPO=Ni*oCsPANBv+{)+t^uFMw;D4n-6}E7&{IB2>z~%b-S1 z%JdDmArh;EI5_~O>bfucBn$_Mv~Jo72`L|ofx@T*OHoAqlLFmoTWzr}8SCNQO2p}9 zl=C*_?=EjS4*$ahe7atK4fhIip$NZ+Tn+=9YR|xRur;B=jaNKoMY(li58rdv`D@0y z#tK|Ox4otMBioR;NSuA2%xp$R9T#cEfgs84NE_(nfbgar*D>yZ&#ksa7G5qYRJ;d^ zP|yKFBoPNva}gDEFX)yFtn|lK6L`~{lsVk*ajsX>@ABZTR_n1LRxcmqOLn!peh&$#CJ=chr}6uTDV1%9t%Q8!RBeZ?5t;~o$yxal zNU7i1=)U+wgNp(`7cuw%=?|`CZT}GbKd_}=d`yh9)+sAjt*T@)s501L)Sxb_Kict_ zYrElTwBNxFnK9D4F{*PgoO3aNQ0W>ewM{fyC>tEM&_XxigimNs+ua;2nZCU*Jd#q3 zRIMblKGxxMwYrx|GUbqp1gpkqYaX7k4JOtCAnAQ!!y&%?3hZ6bd0X&?z=*fX+w~#~ zP?=IPE04|uhl#^Y1rHa&xj%hq)i{_F06#q9thpDO%qeUiAsV&=sBVOgI(7W6_DCEp zJ6a_F2Oc$wvtIht=PJ0h$F9LZLNBSSv;u;M#zH&#chN_DzR%(g(6m_?xy)&QiqI#$oIB~{$z(*BH za@r0!K;(bAdA5z*5WT-SXUfE>UNFSzYQpbc$Z;mPWoL>Ee1Kcnr%8b92#ypF8@}!O z(hwzovNw#(j@JPwAzkd0*?;?;ilEkPx>9l6$5cE3q~3wd?ZYJ@6JI$7=7Eo(JcDkw zq_5H+=A8B{Bq+%6+^Jc1IM!Ljk&1^DmT7M6(M|%j>sHU74Z?J_%;QsVIZWBKN0ANU zKc8rQbk;AADF0wEHYZO=l$;=5bLzd~V&3$r`tKgX=)q{HB%YBJimLOW_w$N3=ajc= z06|7U>^r?P4)D5mDkFgjmS1A)M*8E%vt|eAo%VPgZvg4^aV8dr3r{WjIld^DdRGn@ za1u&t5t#-bDLC`uC!(Yt^xa@g94_6Exc7Qm1~mzhJRY?-at7c6p~Du&?5$RUnz>MH zjj8SCR78AnfXse@}^fi&@R%#u4$&NL_nJ;)Z0=gXt?1a@lrM7FwbjJ?-85_z_I=U$-NT7AgR^8O6D}W-5TP8TzMuugg$yff zmJJF6Rg{h#y-g}a;I8(-z7#?)o&wECkidMCzJtyN24lqcP0hgb#K>6wr$JDp?0>wS ztTY!PP{N@QrrhC;DWDTYM_acED7nCW@bGUt{L*++IGH7lcxlp1ElSMSCJ>NNHAqj~u?fZJOaB7q9m!Yd5NUudwv-0UrNE7ThsqSIe@1)^^ z!G+{Ep;ohWBl?dVoHO6$x-+~B5Czk~C%}yNo6Dhhz3N9=FD6yy&6lG+ewAM=AU z3{)`cj?iyfZ`YKq5f>xc?gB){Ln8hZnh{Hh)M}GSp9C}aK2`nXN_8TyaI?xkKac0^7M&=FS5!=k&sY@I-%4(Fh8TUd+kXK*h@XB6Y=ntV=L!VRyhgroqo zXT;pZX7aL71?Y6k6s2Nf3suCkY99>v26TloBB>5VH}Z(8v!`SO(ee)#?DJxT%%E4* zQ9RHVaTTxEpA|fg+GPkPhlvEeucQS8M!?w8gPC=ia#khwYv5=E&82r9^t7f zhGL3Y^Y8<_JLR-O{^B5SR$kD0n53=iM8e$g7cDc|B}u5`G2r?b2TF5mA2?gNsG`EH z-7;+xFZE9)G|Tp?%#S*OBE)jMD;h;bUUO@Yz^im*b^@HYc>)=?Z+NmKQ-N)x$x=83 z2CYiulQSB6UVLaeW4e>9#>?6n=0MOBX>#~bFXb)JOw;k(dWJUzbp6}STU92>ggqR9 z5>`F{u{j!o9e~xuCe+#!dkigew~vR+Z=X(O&H+h+yPb=NaLCk2eBiJB$I>I&b9UIr zNZ{ksO!K9e0ohS*4yq_Wuz?y4eb;Ztl5) z)D&<^KZ!}`^I8*(BS`_h?b);VrBepJF%*%@Db#Q|Vgou5uL%nJVqVDmSgI(P=f=fzmrob)EOVKDhb$3%G;46(3Hzg}5ZQYc;ukJBXR$d}NLu~J;I-y(pzb!i@YL>`3BPP?kKBgi zG7snxrLFug^ZG%71pC+|xm?8{`lRM$%t7dAHt~(vjs;`N`s3#7PD^d!&h22@?{~3|_FSoX+HK9=Zg_DpvS* zZglau!?_Pab69D2;PF@QxF38+{XjpT?rvLxA6AZ2NJDFEb*2ru6=Xrn1!c8YjIRR9 zS{CLNe#4|hT3+cuEwWPPpivd+TzH%79zMPqjjKhjQLt|(EK(iYXbDPWI3KONTmE(m zbr)XJHWvSRtilBu>=}7765|JMV_^kPJ{jzbyPSjnI$r=W>3=>z+WT=R_7;s}+@+{; z+b^2qH|VN07YjsU^`GpZkQ~WpeJ;Ob(H1=tHiio>G`u6-soRCR%=-F5e;9gPMt zG~_@W4|CyC^xRc=pUA2Q)tmM6bp@2m`3Zs-)yx;h?**yr>s!tv9q)>ahmLrU?T@Xe zz>4-t`6N#mC2ltm%|0RD=z>nC4C3))6PnWA*-u3R)|Z29vY=6mx9cQdPeHoQ{iww% zrVM@O5N*|-HYhe#>bllbl%L|FqdfXHbB@GkT)(NQPB5tm>4=Qa>Vd*+%^pxmy5lFz zY;w0g)dFO9v7cJHHsyvd1Y}Ai2d5jIMwhNN0}k~={U4kw-a~8HI*{iCnZLmmEGKlrJnhSVL|;0748MFx$Rh+xKU!H zSS4|zmZrgXL&1=V%k!EecS5Y)Wv8U!JV)#vAJK*iQ($oQK^L<_;QWca_c;0N-Npk$ z^2Q$iepE#xgNPsY!LeckZF2E}t}j%S!l<5BG;Ps7!}mZ;2Re9$zJyMplSGOJs}oKM zZ6m;0fmhS`+x+KR)yl36&5X|Xo;rYe#{HX%^Y|(1g;1gWE#$5L|rwPj( zlo(8|Jqq1O*pz*NMB!lxw--ST#5RJR*^PdS|2Q_PS zwft$YJTcgl$1c5rD|-koFDt@}O~KLQ?G+K1)oAu%ZPj;RFVG!aPFF1`6}`c2VU>-` z%}eGuQMOS6LH_mJ84uTcu-rlx!;Ly7dQF$5UO%(LN!7(`Jy4z1*^0{t8EXWh6@!wMZHRWbm5%TbwiEm2e0;e=tFY1j;D3 z1L~*ZFl6Rei&Ri)mmx$x$5kSKT%{^qi51mU68t^)Bq;xq_&_kVN7`?YGnQJOc^vK}5r zy%{?0-ZLhIv>jK82a zx_bE7d8{@KrV^-p8+l;;4bo);2Omsr6C*Z6H(Qu4Qs#Yb1-=@}Q~?Q-!gD9qh)$wd zYBoA4HL>OGmul4VbyXCE8gunefm(bM-!OM9NRtAsqeedXa_f{{3x)RS~u0gKCTolxUZAColl6u1@KT;9 zTNmHR+x*G7!?*5`_`!nH&-ni#U;Ljo>rvB5<*sa$a_%ftgL0hC(h=m>&Mo@ZRH7n5 z-H=SE#+OUnFDcvhV{qaZK3Fhtgp(sf#=bc^JS24==!KG%OP$Eut7~p=O;~8)*`0W1 zdBE2L0uGkc9}IWa3^FTq*v&dzPro%Qs>sWq@BiiY$y zPh*?w7M|+37p*Nn&xw#2KFS_nDq}=!xD!Bn`t-}_jjs{!M6NFRtcHZ+b)!k+Qqguy zjV(JQe$_N7*skdZ6Ev7%!IbqQN1k}JXMWz1{tooa3~t5y{0u|#GBA@$_^df1o|xWq zAn3HlfU|r-tPkDf%Isj`^0R9;R$f&7u{73@8V=4B3TBJ~<1Lf1YQvDWz_MGV@4_;nnu`+9)g5!{;I36# z8dg5ouq7Hf2+ezfvdD=RaqJ@yV0Kbg=Ebnn;M-*#bI~j98DH9_(Y)b1!`$%(u?$rh zwSfPJxpxT81ZdlZW81d<#7-u*olI=owr$&(*iI(4ZQD-Hynp?hvwAn*srsrnz3Hm1 z>h8O$FWgrcwWT_8C;#Ca3m5*uB7ku+%p8>+6^>3CopN+#PBg!AvoBs$nNTdeqb!G^ z=_0jxq`k2qM_nS-D~>{L!3Z z+_hihkKMcyBp?R*4z zV@X<4w2Pu0HP93@_R#O?pIEqcPr=5b0-A_h&)@j4o}=rM*4=`UgajC7}m( z%C<r5V>El+ujOaf zvk2fh;FJwI?;=^*fp)+@+h@lOwgrl56p4xkU~)w_2rAHmiA_)I4ysn3SbNZ6Lt2FW z(vlL=alGvoBxkiP8M3le><_YWPMrQI@E{)-XL@n;Gdi6oUaJH`jLoU~$P5XAxwk)7 z=<-Mjy92v2Y%p3(XX#BhRUR<8v z&xl3xuXfO#!MR8JEIlzp8gdLSu;n0oic~nIhmA6`%R=JmLEwjkD8#)W5mdS9pl(P; z5)1j=-9$c5-u7%fK;yg`!{v*U)xSRLbRYJ{x38^?fQ2#^@+~68jB|Kbo(sYFKF2g* z!J$?q9Bk5T$GtudYQI zPaNcB;pT|%TeZSxo(kB8cEUwLhXe`n({!b@8tXZ*PL~Qa%sv` zX@Z@G1o0-W7O<4mMsk44gq!%eUw@2@!k%&c-3>NsQmtxm273W?+e(yK)&!b6YcI^| zaSEGr4}ZPq$e#mJ+|c|^#1z9z=M?Ma{o44858))27WMFB^co;O6dXg3%yM})X)apn z!6nk#s5L4R)p}x7=q#(-BqROu7U^-c-2<|*3py+)JZR|5&=n!Gv=9j{Q1$p}ymMMG zpcJT_!m{^MC*M zCHUdlE_3!!%VD;B?$8FX{Z6V#|QNcILyZ?QCUPm4@ulvM)Trv3ykmCEL%e;;J{ zMPx=)#oq2e`h)>9Q5>m3L^6oUtN^+h_!1h*1)aC%{5=b*7|3aj{n3oHrn!Ohzj=B` z8m-nluskK_qxtcVeX8W)h4%*uJ*AoX!L~|WYHglo&&9wzkJmAT`2Dj@?F9yLc@{+61d(u4>prYEN zek4*p#?$Yog6`RbR*&fpx%V7Z(TBL&Qej>^%Ez996d(b}kDa@b!ujABi14YMH;d$Y z$YqaG{_!pE&6QI9qfy{cpNo|%Q1Y#Z6gkn(^^u{R2t#_5HzC^rdFcca)-xM$fk|z*F_a24@@7p#wCn=X9k3@Gj{#D@00&I{-`K(YK8EkCU;g!Bf z?{Y4_NG+smmoH8)1y)hVhW;5U7Q@bd$PS}D&g=xcli0hAuq;KBC+B5E3wd66*6oNg zMzMQDnIG(C9eQJ9W;PLmTAl}jQT^Q+`Kl$1^s(n1<)T%Z0~cU`zQn(Z-7HY7K=%JEaLKD zrOO5jl3~0vr$mw!fgYOF_a@eb;_bfFT1Bq@Cd_+F2O`i6TSLf2Fqf!s?`(X3wVXGd zX>(++xXhnfzO&wC@(92oe9@B%>*u#7=Qwv}=(QY*U#g9zml{!A9~5)4#T&?l!O}Bx zNJ&AKYuCMowW`9&;4pc8aX32uU4Dv`GGxsiH?(Z1)~ z_1g60Ff1U0$iL*f6JosMGXLQ+eZ@PG?_+M7RqV|+EkfUOC z9#XY(O=Gxyh^noW>jP}Rt%Kv{k@1&BoVCi`IJ^uOt#)uqc7-5Qft~A#jovURfy92% zi{2+actKmCuZptk{5419O}m1K4MDv+!>Q9Hws)X1%B}tck|JU59}|*es+lUf(2mpOdWX8= z?Y)934M%S<;|2I;=uAWKm9l?>-%G3bAl$u{E$V(t&7d+tWdk+EY@Gu~2}1%c$sHC=|9XTLRUpY=(Gm5D6lf=k?j%}RKY;Jn8lAr`MMSveQ@XIG zaN#{AlHWBx!^=qyYoqY1138_(6WIWMUa`2?{I%zE$hOwP8URO{N|ju)bRf+%i(WL+ zOxO9epNMkb{`f}*b6H68m8y^Efe-sTzmv#1QjA0h{DWiy+@L*a_)m=c^yBJCP#!Up z&tT$Wa-RKt!hWQCs2Fsb!*U8cJd1pBNiD3c2?ZH)r|1s&dM&YFo%ODpxcvDuyQ6!h z6AryMkTi*GAHbEnLdzV4l+j0-Ng^8W^5-6H<8R!n(j zw%L-v_E}tR*UNGe-}zTM$KZ!>WtEn)V0r7Y!l;LI0p}swSp}YMN0=J()Z`G=~i4OqGu=d>Q2(YS&_Wjohkjqu>(3oqaWp0Ts>re3EJD9EyZq;6T@PHD{o zUIA~}++KIku89&J=Ex{PH2(HH&*;HuXiR1PL)_dITB`%_*sPI!Y-RNb;omjg{mr?b zAg=m2%Q0OP-Mu1>d`82IR#N2`_M&*&ud1M=>hR2VsRRy6Xf;FdHG9*mCR`m2+;eH4mC+*O%~oqNef<66MV*Gy>gTVPQuS{8e(n6JW{ z!n=M&VS_!&EoWnOBNPU*2*0w&!OQiSf(%9h%Up8Uea$?muA5OySC8ZaDgh68)oJFV zPM7yLiI8G4Dm$Q6mRH&^1Xx!TC!7L95dCx9Mm%ob;PmGg^)zi64kDq0h!7Dh;A&&4 zW?BVlLvZ@UppT(V0zT#FFr+w_QKTdmUJ&84vQoxc!N5nBY89v&=XeCoYM;H zBScdxxfcVe31itKYfM}(y!1X$om%bk=zTi5&xdb|BsWJ^w~81oAQHH>TG@=I&3T)@ zG>E}aX(VJb=mJT2XXABEhV39U@OlCw?hHiqT$j1|{!$v&*z&{9n#Xh+crDFX%BUDw zP0)pod8TG1gklJLIJf*_&rdIdV4;7jwi3|wTg(m~J|>KEp$dL+se0Ct897me10d&I z==4!XE4b%-f72@6p9Ab%Vw3GG`+L=+o7)|jr*ex*>F>$W!4RW1)uj8DFDSPh;tSnF z1CzEyC%wll&+>eNN@Yee+MBznVO%$y6sh%$sgp88(%~L zNg2>mWg!bbD>Mj$8^l5;`5GZ9)7#3PWh$e=GENxnb7CF*YlruQ|dn!u@OyH%`=QOQjrgNp6`uY+Z3$#w$^BMR?M!mpm?rCLi=SJ>hF3ttf zP0!P{`w!45ydtW@_dv^~%%L&?>)QbMJYh zAo!cYmJKTpXsXB@)`;b73-n}nc?}|#dW|?gzhMA;=g85`F8@&*j}S{iu<^H@ z@1MPZ@vr!6BHCbsa@eDb>13!$N4c^+E>q9*HHHV_|F_KVzPd{eF2brdsRkGis{SG$ z9!L4eIS6IOmwMX1b(xkMZ+S<*^u$chAmO_3#{zdCWk1|7P@<@S=t(;tN*Jk$ z7ety_S;9eq?Xwd5UQjJ2JQiV*cghLe`>4B}%M;cJV$WmL(>s3$mmdl^CJ-?5Y3mGO zCt8cZOC08EdW}a>9Hq}axR5f=_Ma`?y5I=eS>lms#~{p?nrenGDQ1X{Fm$@$L>+Ql z2|EZij7jIMED;31ByQHp(~J4lagg0ZBUpgraK6`f=Q2p#eFb7E zW^+29c=MA$1ecGw{Kf~Y_aP`rnU+;tv2O(U>oh%1VsAjS?nn&^0Yr9TK5X8|M=@?n zDb?H`7yn7rZ4*hdqzQAJF@y)~k0u;V@OsC%99V`3BQ-o;Mf|vR;&zwYZxamfvLHYJ zQs~c_k_EO{b}rUg3w7!j33@8+((sqxdR^CHIw0fcYG}fEwtZoMUL_qBDb4pE4T8AB z_vD%awh@wngxS@x8bsMLzk9^aHp9peCH(*_ER73Rz#%T>6RYH-v%qYhe#dBZe~mcL z%%Z+}<`4Dp5}1l$fS{O|DhwTO3 zWWXY~F7Fr7pa995ir@sL+xU`9%TKx}k6X=Ij5sa(Lm~`RnYdfD@0D-1%f4K}Z=+HuRM9~JUvAfB z5ri+usIH~SFJL0m^oq{#cjXm}ao|UOt;Vi??lQRMh!`?f8 z;Tyk(M91#TAnIETq0LbB$Ysj>ITc``&D^_@`2GDq-gd^hg0!4z!x%NTnzp?$qX+x@ zHRtJbv9Lzzzay7{qjdqYKTpIAJWwIe%By0WXC+Z0);ihWT`^^cV-FcX#gW0N4^ z)k3w1UV-euRPl7F5VVBU`82`T9^Qpl3XxWT_8#jGVZ;YmAU*Bbb;O4%;^PJGPOeq= z(jYM-FzC};?n#tjkyA*_<}@;^Hx~&`=Z(myNlHlY``5wk-ej`1;H7fi&>IixDI1td z=DA#z$HZ|DQt0%ZhnsckI`EX4H6|PH{I!e3$`#g*skcfe&*~Hs`koQO*sI3hh=1P?RPEwMmt6+7y6L@xtP4ioyP2eblEMFQ)}&-u%Ip2n6Z=SaX6YN)uT4Q8F1ht z&Wnut-W!dpkcyjA;@#InFE%0Y&r2se{+NvQRqG>^dcw)}IP*IJBfRZ5>=uMXFv+d} zi`*@GgrC3?ohdR&I; zhL?o0E^ie0bbQy#9ouBDT%a3et9Wu{^YKgQ%%eIPBZRuHi9?}PI7&>Ozo<()wteLH zwv81U2VKGX`yZ>O2rLy_m)i!AWhjOCHfhiL1JGDZvBfO;1~=hXf-^RKX~Pa>XhEb%24A*(NW8cU*QZ90QV~9ovhtjul=h}xF?Nj$#FYy35(4(Y^2gYo*+H*AcUQ`Oe&=& zH|3`J+##oZao#-fX@hh}VX_2#wR5^ zl{!8htEuv6SDJvC1WgR1Se$6_S>{$61w8_YoU_8_!N6G)Wn4qj!;#=!mzB!Wf&ZdMoeoDLa`90brGMc#Lu7iwMlf}y^L~_kY>!RXqI(_tPQ?(ETrkFEu|y#+VQPj- z5hXyR@Hh8YBhtV+PU`Hduo0S8gA(#e$8oLPbbU6k;!Banul)1G@zmoFaO~zMHbeTR zy#R(iAM<^r!}x~B&;8NAx*WdK*jAPkaOm1xe(a=_Oeav;GnB5c4M-!P78fb5Orcen z4MG8}#PM`<=SfvQ&)+-9x_R;FaPjl&t4J2IvXdZ}Iz7}{#&{ir&5+#JbGnzag=yRY z0CJV1d{lR=xtO2@S;_!|5Kd!+ADdC%34_)JMUpR2Zrl9owzKB)9}dpuRLXU$I==BA zs0NuUjL20=^Kam1#867^$yHu%^l@W-BdJZnDgpYJ*~Wh`j7n)G!_cmQ^fD~}rW5L-5-P${_qu=UJC5BX`MOSCY+pL3aS`1-(xP4e*IjhMDGcT5xPz^u zL7GvdLSOO|MpTiCbQ6mNY->Km^JMUvetO))vy?EHMP~ozl<=$#x~E&%W(umTFme*i zTB`Tw=N$LAgF5<<;o4J294t5p1sDG%88bEh;7G5j87Ka>Q8mt?xd*Hu)3_N0pH>kj z(hwtWbL4TPf)dHjm<-z-J6zF8tbphkj)s{52s6;?zh-7PLr3<>bVhM#;9C?LpMM+& zS7zlKWV$xjUIy(j{z4lAYt;=JL4IPQWhV3v#{M8@V%tX?PZZ#e4cT+GY4v?J?e|{E z-ARP3Uu}v#!du)3mH*ZSxD_hFr1H#}DL}Wo{52YRmIylP zz_2}*`2|RZ(DX!tlw;okNrg7h2%2MZ)04_3;WgM_-Mf$HLv}@DJpc2=BV?PSF6k`Y z#R>&CI`9~kiyroMuf@4elya+Nig8LchYm!(33RcKyN2sh0Vt= zMZDcTC-Vp*Tk=ud7woOAg>PXa5f-EX6Z+!1YKKQcKIkEfuP& zG*@TsGTtN+DBzOg&gF%hB*M~*1j%sBoso2dx34y!c{_NX&jobAEcTf%s&(LvRQv30 z>YL6%pf&d0>*~vmt-yyPZTe0>m*V!QZXRJ`OP=S2(_dOXC+iPcGK^k@R5{D{Z$P6- zOHcV7+>neIi6A;L5lZRPddFZeV?uQl`?iXu5yUto`64}cI1v2S|kLCSw{vqtRwWu$kPNk*g@Q=Sb6UI?2&tC*mB-1bL+ z9?|~Bt=kKP()~PBk+nN=zBszBVXyyC=zwS(GD?RUxyS}ruR)}K)v4KW113$5Q{rsP zw|~=}AkG6CvMd1!Xd0T)54{Wg;a9*E5-7C0F(65Xqeng&TDQtHVDz1ZoqDQMuBL5w zL^s%RfjtS$NH>=AiMVv|ntd2NA+m4v#+VtA_}yL)(N+1L5>jR-2uwlB2vNS{k$aulRt(C2;?3LPWWs@p*{1?5wx5NnZ`0;AXTQ6AtK8xBz44~v~ z#6jKD_xHQpfaFTxX-b0kb52rRSP-qr*|3GdZa3~GXh-n$ux2qh-f^bGkR)$% zZknk~ckug=IzXv_kdqRkRdFyHu_qBzT$85YkIVM}=Qe^bI*eBEe0n_M2=2Dc0q2k3 zlkrg|rQl!KA;`o(RgNx}q%^Khx5ABqKE%ZWf|kVHXZZnB4#+r@Xl)IVyKMNsEuqA1 zvKrNYWbvr6i|>C)m+#XOhcx}E+Cd8pG}t@91?w6C_Sv zyusPjjOIeIMsDEcst^0v#jk(9bBq@6tnF~v{SD>Q2L$&5#GvUH&Ue-N^!mvL(Ncj% zY=_R_>8udZ0h$9^#GTlo)A@T;gQbZK6PhD0$Q(1WayE0j!+{mM$cFG0ZBom5Ff;E> z`&h{jnD5C~b4uvjO)HDkm6ft}XuqT;x?C2G0BJ7uz18YF#}TWCY>N&%P)?kiAs#|< zr2bh6BGiMZ^|danTb7`D+&!vCtv15)bLW-3#KWAok|vmkQ#&l#?wD?u6PvhJ52oX5 z%kZ#!$sP9yHo$a_%yxd=Mp=vPZVtl~)VPJNl1yZ>j#e_dm1=@BIr~jVmH%MJ5>xME z$%FMFt14xL|B$yJDwp%$FQd$oR2wUi@4>yFLSK}l@C;(Gv>M!VfAc_s!x(ZVO%47s zGx$6lVc%`*UJj(XDavCUJ^;F{LPDd*$PROMi~@8jXSroN@dfkCGs>A+etQ91AhJcX zi00JdmskM~*X+Jyz5}a~e@`J5sWIT5<`nZ-La3vbOylL{t7(->I;LrE=SKya)RO)@ zJjsTuIrc7E#>nb4|IK(AxrRWyZMqI-r4GwMPYP$2CR-3VJszshXy_ZYFkd2A`f306 zEV+^K5!6gctXTe`Su+OWg~)N2L8kz$=?ze9irkN&ov_qQey;7wV2loLgEcdL5)|vq zBn6vRVBn6&YVdCTI*FNS$mr^i5?E_yEm9T|z9+0(fhYPr^W%4s>iQlomY$%5tQF9W zYki#C*4pHivC-9G%AF54UbhNvt>E}HkswO%d`O5}CM1k)bkc#C6{bUPi660N3=BCg zjFrHwsh98ggX;ox@uNpw&}u6*=8v6-vXA+@alTbvERqfY2WO3ARks%*_c0P9Tz=Qv z@wGSn?1_qQtZ@krF_*U?1JzmgR``o#c+ZWMc}%5CXv&FQla_Vy(nh5n0o`4KO1B#` z)m>Qi+?-8%fu?Rps`uqF+IqFs*Xq*n`9P*LSNGN*$;C;cI@~Cu{eCR{&zRSsa{iDE zVyDt>*|>(-e&tb1%~!0VnwBe%4Q!mF^e!i!1y1s7u6j*^T5tpXFnD5E(tVC-;7CmFNHx(bfE<3zf~;|Y|BU6V zb&HK{=KsgPW>Ifvw;qjl#Qw=be}skI=B__3T6_Ej5G8+K?08vi=fXvUz9{&44tbpl zbl2VFFMVtX+*Id2OK+KNhrZNwZw8S9xt!kI=py=nzBE@|uYX*Y}%lB9f3Am93O6x_PfNVJU> zao#1F#h1Qbqm9^X`>QB%&Op)_2-?Ee*?)*h0wAS@E+)p#GX{=_o$*Wg98I_}nLE&T z(F=U}Gcgp@=6q(YEgD|G0SfNbs>iqrQKjKz@(dK|qLi4t{9kq@a9%lvd`gd4@Q}1b zoS7o+P~{-izO`Q=b3-L0I?46eFyf9toPHXCUrD(izHZL6l-qmizCbU$o$xbKKmMa? zn7pEgEfHmu9q=-3??Rj}ch|V@y2-nRv;etr zx~dccIfEv@*Z7s4jO7T{uTP!bd3qCSBJ8W$ue!)zzx9jDV*w}$Q%IBR`ys2tRER-*ZcpsLCtP{LFCsr3wDzQefqWsQwSLE)Si0Gpj5Z#z@Z#O7#}CJnJTODp$wjUt4JL? zt{uqoHcK=`?870Ycy=M>L@14*f8&7eEei>+os6Qt2{$}l<>AF@Y4-4FG+0wH^HUo` zCxeY*2T+J#dqtcefeWOjhrh^^ABAy1JvCA3~J&p!d!<+eDnNo z_DVNWE|yHqr+7BeN@q**)S8@>?)(iuJaox_0(u0|=(BzU5NHz*`of1B*cxy zG2j&@vr17*futhS!D26z&D)C>0ySC~+4+fAOgfW&az?j6sl z^Y{w(Cx`T+)Xb;wBuVy4jRpveR6CeyX}BF58N27AHHNKJ7>rNuL7LuD>Yccz zztz&v+F#^})c|l$^ylSc@>SqPfpG-T;GC#TiYW|P!_+@#srJp5n_Z<$2o(TBteG?a z*M}9s1>f|}Bz&LVEWLt`#Wm2~pxjK>HUe}x0F_LcKnJ4LRX;hx&fv>{WC+P`+(B(^ z-`eQM7prgP&LuK>k#Yzx*@72p`lBG|_)JV#0*u$aIdw4;qhR>M_c3{i*sfNHF59LM z*jXFQ#1wp<@Dje(@S#Y%fvKfR))T_g9*ZyA?oM-IpAG__+NT<&lxKv1OF8561xVCL$}v*Wu9Uc{5p2|rkC22FmhzvWe}p54AE&%z%LV0s&jo;iRgdfi|9Ad*9(*- zP7k&v<1}Nn=##XG0xSXXWdQ+)HuYSx6)xgFC+-*|gKnzkMFgY){=)^J=t?UdObm25 z;C3XwPhU(8WA&8fI8t#%2w*AeQIPy5f{Dx(`Zw zhr=W@fZgX(SOkzTw--ujkN4&?`D*VDwwJ{to5PqXOS!Y63>4E-gL_`_4bk^ zl0gckPCca~W~rnh6i3858bEZK<{q(UY|>Q!a) zj{!P`rIHHG!BdG)Q-w+)WG&9t$tsSX4d3b=SS<~y4AaTa{B<5YT36#|yL3(Vw8XY)`9}kX{W#@_Xf0^dqLLrv*D*iTGR%~VJcLOI z=P;G##n#Z@Uyq>Cf2hz_xhbtf4}jd~hD2q(&#^^8QFFfL`XR1OWX7`zpZPXA1o!kD zw(_GEq>M@BqHQO5WjG%jj+h1~UP3Jayv|_@tbqO09LP9RE1gb@bzFeeB&_RH=FSk( z=3g9k2TDxTU#BC}7k{`jIWO?dhs^}W;;prPh`!Vpf+L36kd%&zkSgK~_p2Xq15Wnk z!dZ(99?VUsHI8R3kz8g%ka7rcqB$dOl*%VNsMq$4NQf!3+(^&@wgDli%Zm#)Q4HER zfN=~>7173-#WgQK?V+y%Tx%bYB20cfjB+8x1xs;Y_Z$px-Qj&O;`KTuvKBCkb9CkD zL%DNeYJ97d2efgPu^FvfAU3u(L0j$3>fuKLN5ecj;SKuzJ*~eEz1=L63?&wRTuRsR zw-)j8{QF$$aN1~e)0aB(KjcJPdC|Va5_>+zT|~&rr_eWZv_qx*KlVtH>ZLBU(jWyv znut@j(`=z@U(o4^23Yq9FS`A{)NTC|;oOUm$n8KVhIJ&UY@E;nIO#e~lg&aLmgLIU z%=J1NqiDFpxbU_{8&s_UOARNv7XILlRIP3;HjIuxe*e=L`JT1jFOLA@nm2FI#(2B@ zX;3ucY#b0aP3M<)+DjrBCGap&wyqfB&yb4iC0r9&hC`Kv-lzimjxqWvC_m(MB2XZE zDm3;$x5sqFRPY*IxikYDp0M(GAX&`i7{wV&s`j(+obzXM^Ns3E#-h{TprQJl)6cgt z#mlT7bR7;)6}hH)Hh;K65tJ$w2>A8}t5tx^($VYVa3S&isu$=cwZxNR4>*8+I6(w$ zt8fQcw~bE%e!xY6ec@E$zO+FkErTC(CAC zC{3Y;5cNs0Qh9-GnCW~B1A1H;zukALp0E5&7mtmV#QI8$zBX0EQ^V^Q-^zObc(5M9OC-i^eU)tZB1J6BtGZ;x?MI{^k$*u0mme zZIWLRqVb7=w>Bh1&v=yh%;A9Tg+L26w0bBciBcGYkRCgp;Krp!&Ti0Bh|j}xTRRVj z)rp2i^sYC2Lp56m34aHZPt7I=f{HNlmz2tR5!3^=0pesXTJ2c`y!}v<-oW`i6$-Yu zhq{aB$e$~H!zHV~%j`;gxds5~a+Vv%Njw>9H-|73#VQ5|<7d6SA>y7IybO|uW*D1Z zu)FkkBP#0D33$hogqQg<^-GVrHaQF=SvH{aUaxb?^~z(kd<%!Wf6;`?x1WY#81@rS zp`jo-&9beniJKF!5eS5W;F>#*g)_FAdj}1CIo6BV7U6q2%AmgXr6YWAtFMbxSBcVJ zQ@*QX-fOARHsrvJ3k{Xt4asTa*gF6RdNt89eu*C;WtuW45+vvC{u`4Q4oZ>URQhB( zYB%pN3l}Uix`@9t=0MKf<1KNy(nJb2s8R^9a)1iwyqbC^(V}VSiK%Eg01}W{M(B29nxqjc18fnv&Fqd|8HI)I0&ZbWb+)k3Qf#j@ z{+{NFS8x3yUNMfc-6W|dR#aK26Y+8tde(ucq8R_#>2x$XiBftmkFEBM4<)Fs`@Ob& zG~U7%l*P;1N>!U>a7~i2-P^or!%~xl`BD6Ly8iFZSo!H|$>1)uglwL#ugSE~os=~G zuijgPJf2+!1?V7LsgiOOsxW)FL$jbj12uY7dO@9ZWgw}g-%$M^VniVYqVB&s58VK7 zl5Z3l-L(OcK75%0CX)6eZo}U2%crVqHFMj*`;)aDT?ccrDPxYaexoKu(DTV$eVxJH zbG9_{JB;j0sF#aE${dSj)@UTHI~)4aUEA2~I52HN>I*r;!UX{gJ~u67Jik8LTvIsk?+q+5Sd8E*5VU_Y@nYaX1a+$%NukC$ZH~RUa?eYE zN1z|Q$5V!(W%~Im_jzHjOr@&sBN<_7q8;(-H0>cm(cvyNtaq`=h{MfE^+;F589gaa z;bFsfkD2~(w3vR3riC^$)#^I6-J?XX#yw zFzQ&wqnP`poCS%ufzpS|qyxO4`17&b3(9c{Sa!IEC!Q3rU&4w23aPPZA=M_a+*H{i z?6+r!BK5#*F&^+T6o-$NN@Tf*UBeyqVCq0g&G!7;)TaHw6H*pPwxwt1GLA4jUlq&! z{tUfwE%xd@?FJQq-l!)7>f0Z`DAawKXANQ*o2?s(%e;%6Ox0i+SytkT@n$VY_efO;K+L}Oayz&S088S(p6^6Y z(&z*&f(dd+*e#$U!{1qq!Y0$D*&ZwAg0u4UM?sa(qsCmNQna;IQ3NKfw`he*e!nqQ8Cn_45}Q-Lc7TJ+v){e?hp!`~I|4K3n$GATU5Yq>G2_ zc@X>Lgs>rGQY^SO|KO+NCNKUAehuh%AWoD@VaoGzcV`dU<90)U!h9m~35$rfU+GDQ z<7wA<5m5!3=}8-fy|i8ml|RkHw*d@p{K{Bu&sNmxrC{l*x!}V|IE%cwP_!nqb;NHA0o0vMa{UOyIx1-=@z4c#ziNQ1Hl@&@W z3n-1q5=0UAt-p{Jg z1n|#sHbjf+hl2d6tcqQM5fRgz>=a{VS3La?CA&m*_+I72xGCfJl}$NM+C40Lz-tb2 zDTN{;!sd8ulk}-%=poY$NdRj^%QJ=0d-n`a%*&T|@jQHZUeLle;>wmPplQ`KYZx%P z8DYA&nF%YZ8KYJ`cZqo6ay`rLYRN|gnGI_E+VmFvA7Yc9#QGMegaN%lkHh*f&FLrx z!P=vOt1zI974-c?L)jZ-q}w4L_PG4Tlvj1{zJ_`v+u4`SI3%y)Xn$pv0`-o!J20UWT1g^OM8AM=A=7Dw%3N!3qzA{`$8|k3~$+sh*~F~ z!R~LpR)4xS8D+Vy_O${Kh1@DkI{9;-x&rJTv0jhv zm?@N!6U187q;nE{QI7>Ut?Bl*wC=Ab9|PVgXif(a$db zm&A+d#}RIP`tlHD#V0xJSC%f;dCP<*RI7$)!L#q8TJYX~ z6lr#f{4GjTRVKgIu`zd8Es9h_LA zs>4_Z0Q-QvKQ(&;795(-OeJuVvn>(kv2#DFDm=eBNhgqKWunNTz0hhH5=F3bCt4wv z2Ca>9lzktIOnML9^qr?nvTTK5wkR7ZNoPd1MyHdobV>JvtbvlYWpjIEYzN~zFyiH% z9{N>RRrnIgh+84JqixmdUp%N%3H>fy{a%gs`K^ zcJVkO9$g=12hZ65QtE9mQ8tl>mrN&J>p~5VmtBbh`1fK$z~vw=3oJt*HEot33(mZg zNLVo8fB3){Zl)tE%Uv5ZdaMj5Z2K$-d2Qp7X#k)|fjXVzMeW&o@Z{ctoJ*UW!U1kM zzB{WRog@d{G9A(oV|JLhM^cmIhBOWLP%oqDo}n&EKt-^_M7 z1v%`Nz+1l*p$Jhc@?PnYJ>TK5xfR6+2+@_@s|0>k$X3BK`NrpkZdt#GjT6{gzltAr z@cmh>Ah<%tZkAzvQpFtdJl^G(eJo>`0N(B5#ctAw1~NH->PQh0N)x3P9*vgfbctEo^!P;*FHq?k<7R< zx!cXllSh?@whiq&HrV+7<`90U`mP_|g#Bh#0oDYdafG4c0ZBaFJ_tWCYFPq8Q5(+I z+UquLv#b-ejA|P-HJVr5YnVQRe47~mns4pgn9Ng-zC8FQgX&Je9aVV!3|)e7cObc! zVXjUlqWsu)Sxc#HNuArlt@UgY-!0OscWG3r*eW2bS(Vz>uF3yh{*tUeZ;a?o`Uv=4 zPw+QI;Tu?wq@XQ1g~{)3WxDl)>Hd?;`O!LNJ0@oj!DmC+yPn47RcM<&9= zX8#H@%yiZgnh_44IPj_qX7-;Z-)q6nF|eEjn5h7@Ix}s{zdH_BSRAU*>2o+unX<7*kHcIMyfM`GdjMN`Q?kwEzp7f$l1~$~W0N zn#I;~Xa*bj;OZ13gtd%>q~^U@7a@c=S5Sp@`+x!ciLSV@e+So>4&J6&LDy=AiqxRU zVyY$4U6}z#IHoiRXfOWxHKiuwia?P>)Jzd#;ri4;EW>XvF_8un?F)r+{zA*04{J@N zX-D@QG#zvDavymxXLFp~5%p>EW=GftWZZbfc>KpQJ!}*56JIsVOsNvM3y#h~w;}|c;ov3xj^ahU_wNx*Oh*q@!`PpY=a5wF z+3`RaMLwN5OeL>c0-1_<@!O0E=?zdvx3-o6HPx(%yYJX3rNqtWr`)TxM$!YBJS37) z9&XTj#n)=QY2c9!rmDxLHK0jjjVYL-isCIGYUnu*NqO952EM$GQH&-?Z9c)C_$_a` zSj=IKGhlK}Jc-{!#PoNfNi>4Jb=L-65G_;2zjkuLw`g>gdRSRotU{BW3{OCDMx2_# zLg^9*leMG02Ia+an;O8BF864ot7XAMk^wdEq~DJ=}Mi zKr0A_*<3FPLHD$C65^g(=zAhmtqxdfYTg2i!6j{bcrI5Wdg}EMA|mxK&%yUntd7z@ z#kKSzrF6epZ*Zh+9=ZaLl*OmqZjDMgj$1*o{h#K}sk;(}3A3?n+crBVwrzG!+_7!5W20mH z#I|iG9d~Tb`w!;ko3-X2)K#ro_3Ya94Q^ypeqr>VrRVU^8nP(|NUYzCewO{r-~_@$ zDVxO2F=!s+hN;<92<|^hz~ZCxJaM`}`Mu^TTE0}q<)p11B<0~h)eBF-`MT+$-Mq3Z z58Ea^g?AOdeT_Sc8t8hZZrn|B>S03^2QuSS6&qW;m_%lXP=3OBT-ER!A%YDnB4v+z z1#xFr&N55s>{4h%rgk|cJ@&4Uu1Mf-HUw?1+~JP`{0Ud^sHFi8T`43VFU?Jx03U^? zW>}6Sl2rT@)T>iZAVWE(tC7>=kG;c(NC^v6kkr&(a(XCX?mq+DoEsg0@JWf{11YEa zd>XV_K&xdMhbHuvG0V}N)q&!_r>9PF<;I4rfok24^TbTH77YyX&Y)2`|C-IcYt!Vie**~U8LL%YA@=oD$qREVJr{3 z%lf330$MNgM@R}h(EoCF0&IXp^%`MKe}ND#zTSmPOTJ@a+dj_cZ-vQz>*lidmD$@a7~)^*+x~ zhfVwTq^r`RAq>mNZgz|cS5mjH^yy{SM)XT^o}WptmS zxbon&N!B-tExNczfi=z5@wy@Yk(1<3b48qb)^m^|dtT{1L8B_U^9P&eP?~lWu;3!n zYK*6;GQ+Mb>U#e zWBNAMWcu`yX#_1q`hjG+F`)=V^|!9!EKyWzbf68Y(>aC6Wfwba?{-kWBPfykc8Ja{ z?;{OKz<__olRosqXqb`Y#T#xDYP{mcSS-J=062DbrbVLf@gA-RDRC^F+pE%t=-{C< z^>8CVAV(@{8H-1C@&tH~>!O6CjC%q9@2&3+#bOWq@G9x5+Y{MWhoCa1Jdi$yONfW&;xF5sNvz zRi?qJVDNAeZvv>~z#;T>`w_3KvponkFkdU-(i5oC^ew*sB6`^akg?Uvo0}M7@V`t| z_6PEh{<^p*dvVJ~uGFS-7`4LSCPx!F?Z{F{h|E5^d~ZS`8t}qGiDdSkgE*tL=(s9B z{yg%eJ40ifr&w}rWH`E^9SdYq)Gl8|?D+WT%%GuoO2n&+b@q-yu0mA7|Bm$oIyf($yq5$Q>uASAizq*< zXaH_ddle=ym_Jt+hgbO9MC>Gdd!eZ%FpZMk)ytzK;AKRi* z2LiXZU-?~Io%AlH)hLnCua3~U<|1Lrny0>o^lbStbY4m5$FAOCC^J-3t=FV?89i#O zJh#s9Z}hx{>dN>?49PPh$vE`#D~Gd47bwdAbZqs~d@xyR@nYfw>KI(D*4(#QM+Ubs``t4r%g*-} zZXc=T85^gG>ok|nv{(Rgqwyje%;eBL+C)ohH7eymT-o9aWwek=+Iyp%kE{ux3-`|+ zuc>z8*#76Qe zCg4N=GJR`JquHZkMs^~kv9#k__XuTSoDOr^Wi!44mx#=(pk*{%Jd$@RbQnJRTCA0J#e`Zh$m8v!>zwV}NszcFJON_K+@$av%eAYC>8-2FV{~Uwk+#t-rb7E#H z=v5;r(^(5*1rdFe%s6iYD5lvlbSqh(a>wX(-Mf3Y8Z20yeW8KsN0UYVO5Qq7NHa%i zPT$;2cYV#>V$-m+Iiu;}Q$wBaxY-;>4t;|8ac&|__PcyCCLb|ca2YPXsJPWis=2?q z*{SR1ZUIJpQob!TaM1%8z0NBT*$NfJqHMyA#B=?Fl>VVCyD(PyAuFr0hMIB(yiXMz z<6ffM=?s=}rVs2dqn88Pb`fNqiS8^sH`!&gB0W>Ud3CB=$#YhH!?5`+?BM!lfwuih zJBx+C`U#%lt)kuBTp7ADtyL$o9N< zFPxN!^nZ;u{0o9M*KI(Sl_O-jF_*KYx7v8+v|3|CB_WW*$|&`i=9p(eYl#$dcCTU0 zJNVND{C!sGK*xmbzd_Uqc%rezpzEExwkth?SjLA_T zQ5G}mC@JAECe6fMK~xe{C0ELXF5636jVD}FS~;Z7gg>1gZ+$GE36Doik8ev&80?B= zz#W1K-#A_99m{Y1`Zg#c9vb!3DntbZ-ArnlYL!myFsNP0C~`qJiZhMyZb1O@JsEfQ zW$)+Ojyvwp#Ff!s@wJ<=7OZJmO@{>E8N%lztlYcGoP&~&YBSW+B&m<4TJ6x$%x2`~ z<9=&9_0zoI_yrUz0%r(U#%Wf^C#^KI+Klhb;%+eINysE{=uMWgBDy|`d_m^6O3#;u z)%@VqKm6q6s(uou-at;qc#sood@;sJjnC!Ql{L)fxLSUNuyM7FQ7spebAL?bknlwE zporH;Tp@o3slG4Jgi6 z+QDrMUihZYofQIr6$Dt}w7u~qzpk4u5yz{VI;Ng-moXNAjEXyhyirjKTND%Xm`|gI zFa01OH1G^mrRxX9+hS80N~C=F%nleeP?KdFE?D68_*f5k={K-Fk4byZ{C5!Vh2_+n zfaYi$W@Oh$YCs#b(RrKXLmBNf0?k4d!SSv8HaOJ2aS~#1p1k{e;tOWg6Q3@pg6FJw zLGaRhY}DYq*9J2ZuOZ;NN#Z5Tp%%BOVGz^Qs?^Rs#O!9wFMLIU!lAGZzr)#h&OU6J zC#|*U#N0*2e*DAU;y0_qmxkMpSM5&uNCJ~w#)3Jn%OdI?PL zp_vW~^f>k~#4f=4gvBa;qxe*e&5JA>!&^ja>`Dp?;h!|;Jrj>|wBKKwrg@wL>$gXO zpR87`cJY#pvx>k3?5wN&9jL$CO`a$oQ`Cmj4pT><=_M0S=UYj*`!S1)^kh@o;}^-G zG%!auSUia3MM_u#KE+QP=O=WkJ7L4{jS7hkd{Gcj`co5)bCx#A$vW(j;_G#gthB7nPzY5_%c-7Co+ezkkjV}FBH`QyF2AbmiL4_d+m4PU z{4hjef>aVGTw)Cqr;dW>w;G1cFUF52_p}2Cz0Ow;!&mW&G}l{ZcafkzCgv@j$%?kF z{DNa;^WLY;z1q=DS4jYDqKyAM{O5bDM2APInp(40ULxlXA?}?8M71Qr$_UmVxK)9_ z^&{j2d&Z~MqZNq}N&Y%1)!AAFSL{JgPyGdw+r@Z51M5<=Q_XWAyR7_~WI>%ymygT8 z1;LLG>AaJi&;|J(hP}HouuEF(nPI<8Rr98?nKWWkMF zgTJ4+2FWn8t_idtSrZ&ZjUwlz2&EVQJl5;fKPrjkYc?!>JUhG@gK7?Z^H8_dtT1ge-Pe4kfU8l^A@!Ik#)~BhxXF-x|8k zsc!3L38m#hEAJF_Ri|Y8-@y;UVvEE6X14)f!Pqj=F2g+q$MMKzqqi!8&~#uM(sYle z4~xj8arC^M=Xs5U;_X_8bw*!Q^tYLQ`hO#S!5(WYLPJjkF&o5QM6b6Qxpc2{G1w5a ztYkRXpUf6U`R?Bb4`C+rJNzfrOL_pF9!`ZPqNjxwPb|6tyqHk z)aTPERNSaXhl3r~#Oglo!A*m%wWfpgH+lN1A)RSXyJ_T#U>&lXVSfL{{!k2bF6xDm zmto=!VB}iep=~2YNq|Ix60>nMnYJgad2hDQe5dqWYTZ$}p(Y#pCV&t%VDHneGWZmD z{=7RW*@|pJ8%SD^LPXEKSCW3=aQYVF!N{>o-h84DiI?Qs4XWnSgx08%7ra0^jQ2+% zEj5@*K}#(74AwV6-+?bBPS+S86?E|$tLK2O{k!Um!4?vl2Scqj=Y~AxKA9(KY4r@E zPAw63cqlYMFkGo97)>*S{^oQ7Mj$t@*&DX5(M2$m?MfV$c&j!vX$fINSD%(-0nD&@ zh}Gr2a(w)1Rzn^{-_tpK2n#PurA(j z+CA+8dXt^Q?(n;UP9v1BR$xgRj(6*$t(jEb|6r(kZH0v@a7alxF)ey85B+Kw(Ec~9 zIL3;{tuY4q++Oud;^LUKAbaLO9Im1i|tEkI)u1Cev z-N7ZSQOsL7rpd96E~0Cbb`FCI0V8l)zc}yIsZc=V)xqbA1Z|xxUB)-#^*kIIqR~T( zN0NH@QuCY|<erYH%O7vf0w;KyFn-2-bVVMn|}vO9#Q`S5+xG6h~$frd{yiS;(AN z=Dm?n`xq3Wz@!e;)qz&WK;oe&d^K&%qbZ_8-pWxy!O*y_|Esgj5MVa(^PHW@*UMKW zQDj4%9oBFV(-2{OCgyD!IE7cTcu0OJ$GcQ4bg(`&qsfx+fRL{HXN& zyB81!jBm{NOR2x3WI*9;KeD+bsIz`9jxS+o>rMuvdn*txlC=c1F0N&w@81mu3-IN2zl!C;T#H&2wUIJ z2L)^;N-Kg1_f4@=?vPV$xY*U8OW^#tUYN7B6&){{1iO$)K;?oCWvpjfhsu0^V~J}o zA2+a;%4w1NdxM2+4j4)&lMs0mY9> z07jayH^a;x0f#;uXZta9MeSm{0oS2gWWnILb#fWkTxEgo<8RhtlQ)ATUB%Z^ME|Q7 z;5yL+or6{`U`9yAi}rffTuMI5L-SG%b*RFdazTdoLE?K<>6~I9(SQ3&3)CieUT#qZ2WZgr*%$NGx z1*fG%h+M`KB0TH#W*19qjyI)J@5Z70G(yua6 zWI|sZ(Mj7&!8iW*f1}u^@&n$mFu5KJZ5+2qKh2opFmDhPT#vJg-Z}8OG%pY7U*88} zVbpqoD9KF;NOgGDh$z$`e$%41YbojJWFAYA1|bK1jJ9nQ;K?*Yx&FCQbV#z5u;(8M zs|Jk%VYImo98Y>E(U0&CkNqqLx#FaKNmF9zEYTvW1pjHI08C$E(L=cH1N#ialLh}9 zjzwQ4ep>j0B%-rRa+r3oz1;j8D{l@@cT|Fn*Ulh4Ff2$MU|E_QfYYoUP{!zfON1HY zN9Rt3ldySYH2qdF*Cp~MnHM0_51a}+cb9lt^9J3N15m5@Xp!ki_KXkv-Gkq}g)I%% zkf|}qGiuES6B~?nAli8_tvE7fFBylUCL=hBl6lXsiLNBXhTHN^RBo02jMvYM(g`x> z<3Kd&`^fZ!>QA4|YEJYiMnM9F(eD_qR1a-=hFk94tzY8)eo}+?8Z0em`;_ghN@brD z1r-w?7dTw6v%M_3-wh4VHwD3b_&1O@ISbANJ5SVKWS^ct*TFJSoO8LmQAa=wmo23m z!;8~yIWVu0O8tx0`)%k}YI7wP;xLvbkw*3HVyudivVH`@5TrU|j5e5O&M6WbJpWZ8 zyNTAt`2x~f^>zN{ui4qea`-@Coa#s-(nD|!WCuEReQU`JHq?FAhNrUKx;!z*k#B9k z9Hr)*<2oq_j-)V9Zxh;awtsp6ym8Pl>XLD`e18U@RDVUtD*V)ANpl=ZhcBA9xo!)j z7?zk~cT+{$V6%we2ZjLpT)X)54P%&ObeCvq(=&Q_M!BEl=r`IrMY0Q+EBc*M37l}8 z)+_V^GHIC}4UtE9rqGO$jJvRmPF_6u`s#5p>wg6c$s(+$im&o^A1ubG(i0gf&ZhQ>(~JZ1fx zs2g47DZeV2nCO={J*!6GlXVDQZfC`NXiV4(phA!!AGyi0>pyvKx}-|sP-l218$?q= za9ri&cw;ukYW*%ZvDHo~KbkE4zG{~`4huK+Gh3l|LmT|m??EZ5wFIi8&>y)=^H51` zA#qGpJ$#R3NXjF+@e`C*&My7WNE&uIH~Q=XpAUl`ys0_PRuM<@NG-La-|AclX8n+j zZc4GX!cd0N+Jfg1?RRMn|A0sHkgqgvkj&@cR26Y7`s35s<21y2BEwX7omRsrC`5n>+EW>v236ivm$MzA4~wJ0#E zWRD8YlLsT7!?qeir(A-p(;cx*WXh<%w>~K=^9P%ds#1G%BBMf4DR!tKPDF$ zp+nZzYHG2lMZ4$Jfv$vYSC_yZ7e~DPO?qcOD8M-=rjlnMb%GJ~#v5-e6fHyNyjmsR zi>b7hg;;lBa_rXa3=KRX0PRVA1|D41qaqiL>ZE|iQuf5wH*;>qj^%HabVT~JtEq{X zo2lTO5y64YyJlGWu*;qZTXHhCP>w#_5H=VYc2QX=OICl#$o=U#pYb3dhQ_x7=@tu+^oJC3&85R^HUz)q8a1Q~M__ibpOTkQkslnpPCXE9Fy zD+IfWPG-)Iw}bv?U6avo^8tZ+Zivo1@xPDc-nEIP$Duro^L#1At$U^G)Um>2Pdoi! zE3(aF&7cs+LEi*EVcaH zPm2H5L!;ujPb4W$RVtl%HY*OVZwsm;J@wUYFL=yTm?YEt+)SZr45duf0=tncBvT@QYBAAO`}4rWvFg$c)$(#A0p+ zyt69WM%Nw-b0|_V**jQt6q2+y_Ema?nRLOA<-e^|DMXUQo(~E*pia{wfpJW=;k>@S z77&_J`rs#Z<}bb;{EXmy_vN1|RlbH)SUWqGwapo1WLZI<3A8|f zO{M8>i46tqexZ|7h_rm49A3hSw4lMNoS$=pU^#^SjF`#m@XUDpWB4aY z3R}nz*+R{?l%w+<9FX#=?5v^StoGO6>@2$&)IggqzcbcRB z2=ZwJjOOC3@etqC78(`$;#Q-i=oQy4JW4UhquW2gMjKB^Fokmm3H8A5lyJa;*o zAFSB9ZR1tAk1N<2`ffA$h3J-)`e56L;?C$JOJ&*C1&V{JDZ#-@hle zv$LBN-EEKSr2Fik3j%eL(Vt|35db+k`6t(5c7sASuATN1Znd*Dfe75*x6{Qqn%$*D zo(J=7Pm44&Myy__pGo zzkj)J(})NIVU%9$e5_k87;*Vdg;P-S;Y}w-bmIIgVu8&RB{5zB1c50;j{UEMnvN## zUk_X}p#aB`P<1bM#rf^`i#T`2fbOw}{(JxCWnp3T1ES97r^n|HPT7%6(ujt0Q1*rt zqIsQj?S2&5)}lx}oEt>9UGVf_84^I^!N~f0Ch>cfo#P+Ot~+%@D0$R4m-|wBPWP6t zKN=U!3!d@Fmh+&ukG=?EWM(e-DG);hn5Dse^mPO;{no@sVzCpv*%WxvzE|m(1{}N1 z(p^@Kv=nks41h!tIb!!$vSnPJyWse=60Ayjl!GO7lUbcK7JuB4?)_NP5e6pW6&qjx zx1gR1yPYif3K^<%S_M#l+K$K`{04VW;4UcY0rAPvSO$8))Xp|2x=N8W{lW+CaKO-q#}of918&iP@7KgPzrN-u zZU!HgVois?#u9_UF$@r(L@!MZ42Xg9ngCed>Bx!jADwp*4E(J;v7fQGbMZ#JCsfE& z0Y|(5?4}(ga?mj84?1q%wC6-q{Q(}KPcUU`A+;!{Y0Hxve6KDP`Ta7Sw)4sVjN$5E zAo}Xz*Z5ur(i}E9@V&yZ2U_L^m75S&&;ohDIZ!#ZaxF3I*fJM41(Pi#Uhe>_v?9gMVUScMa0AaL8jn%dDKCNyOTSW2j;GQ{O3e6nHnlNrB(7)*48x9|;DHb3mkydV9`YZ1)SY8$PZp+<^)ETy z_skTR)dz37a?xI^Q&yj`=H>wFQe|{W3CDY2PJYGd?;l`nuSFP_jF8e^?f9*IuhlH( z!&9W+W!l3?xEY?=b<`mS{VNaqF%P}aufFj~!%-f__7DgPaC$dSBe|!cEp}6j2HT>p zErIVMY#+1C1DF=#C>jLrwo{}hTNah6Q`SBrF)Z*N!QDHtWxn)|W?& z2tVm)J4n@7uMWFv$4UFsHyt-n*Zm>EmvWe^hAXq=>qo9uL(Rq)Bmr#mLIj zI~`@#=7<^FsRdTl#1*yKWu0_m3CBxNG6xVm@~q|t=@QWxaw{65+kc<)q;Vz@S9!X? z0eCC3osPw<8#{4^LelG4Xg~af%C7xmlYZzB1Hb`aTZYak={nxJv(WexbsEXcJye+R z;+@|_M@G1vO=2J|pRyYZACt*$9?`fH1*FgAz}o6f&q0D9=oRBW>c;feX+aWc)z3-~bQ+J_U~SCpZ zRNgu7lM;)r&8-#JX0dDB)HWNdTqI zct?NAwFeK%&!Az#Am2qH_xjl!3EY3jwRpO9xjukmKb(9VUpucYxCP2)+L`@!JfRm| zwY|XYa@ql4{zfRQ0hlIQU9@b{J2gmEo`A-80fGMxtW7uC#UN-)y()@^KPUR(NffK= zug86OIkkJMf%s$5u@kAI>{)K2ace|D$}#K9Fq*pJ5#&c7TBRWz7(|ekMV{?Re69?& zGWOeAMdCf|jk>sz?(gAQ_V!LY<61p8Au$1JG3c)trV+><_hE8)(F%&{SN?K@pZ<6Y zex*ha$qy*-fiM@JXHb@XjS}89AEp~qV3Z+Jtw$1T)6p^3$1Gts`4^UbK{s_k$eQN~ z@VD(e@D$Kdtuk5urCmDz@rB-X?*+{N5@?U0Gw`WTzEbCM?u)%)PiS~uNk;tY3_Fu9N#niFwi?4TLT82dK$49^3X zTvw*jCb$6!&>_=FP!L#M{5PYU*A1WAk6JWfo0t_h?9ZH5D|=?;;CH{OeMyH>AF!^} zPFEF@h?RXV@>zE7MgK!pnF79euK#xF=X=@xZ|M$l?Me0%=?tN_P9zFO@y%$H`{sU6 zoYHDl^XJe~Zs9~|Pv~sTKg`Bh-st-&R=$6lfbVaBcippjLa6069lzRa+rTHel-v)) zyu<&>K16Je+ucZ>W`Zf-acW?xU1sk7W9!r4(*4*lar#SPCS~mt9#83^Qq{^|Fph?v zO8ZB4hdmNeWbW@gi25VU#PYGIiR%rs*lA|s*!dNpvvRfJuMFd3pkkhcyny(&`l9>i zEQ6&pcIU0T8{SFFTlvSwaw7g5W|dn{-;#aJ@IhsvWjY79{#7LW`xy5x#2WV59u>v| zrOkX`0M^`;CP)K)j7$gJcKmh~VhLSx-ThA%Wv*bR>#brB_pAg+Sc-6UN&2G)j^bbeXT>SgxNPagyx%>k(D=otl0-%563{L@%ptT)=F86frQjfHhBY68S;! zXh=-ZJ^OM7r>UrTa%O>7I%BS*ywf|i^Uj8GITzGJm5ol^IPv76n^rZQ3cE7N$t+Iq zP=LUe^`xu>deOspx8oa@HJW>IhqUnbenCSphOODS$NaB(eoIi!uZya7e2^)ia8IWP z$pKJB&`rqex82VXbDgFYji7er(~AY)VD|l`_(<7`w6IP*qfxfmE+<0b;0d$Cphib& zT=d_C_JOH$c88k|o@j?tZd$=S%RiqD3B+e#*gm zo_D*2LwBGZb~l<-_TmIaqhjEwLY-0Dk)tR3W#g?&P3<(wcp<9S^Z|?ETc5X6EyvLr z&TGyVKD_1U>|QafE1cFcP=urbm?CuQ8~jKP`MU?Dwp=Y#H>Bemj>y+qql{`7bctwzTd2=e zp9@Kh-&_B1-#yfGbQL91^$t1PT>ZJ?A=Bp*)Gt*oj(a_}Yca-FhC+U0@t?HUI@l@2 z)?!`F6@D#X_h~j@j*ZiA&&xZI7~UJsZz&#B-K?*?^u8yo4%AfSz!@=c2#q-MaK9D7F}&fe zHM=hUQ=ukN`qCaEi;vgu4_v!(;MkPa_1MO+r_$N$Pr|oPtv|-Sy#xQl4_v$KhAt6I4$@Rva zmN2fOnarfR$B6A|;@SXdsxN7}rd&6AwR&IW7V6Do8nturnB!F4Br!H>W?4W_%1di zQrncVzC{GGMpT9AsdNuthnh>po-8^nO+UGr`zD`gDi7gq6+|_c6F|3J&U6)Pu>q7^ zppa`bUplmx|F&Y9_BG{CJr}1>1eIR6_AGoN<}(J%`G`@fQ*jT~wKmJ#QurpH?2>DH z-lKBwjb*9ybD5|d=S%Y0h=KTWHFD^BiNXDa#GEvX(S)?>neqz1NxQ8WWH&-1r@iW4 zrq!&^eh_PXEccLRlXzyyUCy@5JBy0D!ZyE!d+HA#kE1!LruzEbrETMqYILrGUpGBa zQ>8v84n3eCw;e`*^ikS{zKOGHkES!@kU*$7pSj6%w0xK$5AdkYjkPS4j@yNjnRow|~1XAo#Ys<%2pF3>${O3h;orlnqpQ-592Kk5F|2OE3PS@d@CZV{#}`JTM%W zy_~8l~H#yANB(BO6VtH3$qc1{7>G^lV z-EGr?1X?G;w!+>mmy`LvmNoDIbhxjON_=iMhe`8aa&xbO z=Y7e>qZ8RKJYdFU3gC|j-DS?x=1)XE^j+t#|b080Vbj`YVelE@X^U~gd3etkF z8Gt=FNvS&pp|t&9(*B(!AZ`J(&sm-^KGC08AkR zoCeZ;c`tBsQ~S=@tnXG6g%kz&q)76-#=XXd(r4_Rrla&X1R=Lp=X-e@`i^Lc=$K3) zR}8EnKpP0|;)PNMHSje4+Dy>!W27w3(6E*k#R*shQN@B=)38%C0#3aC**auwRnUE zD=RsqIkFRpx$fuyKNX%h-?@|eU|+O^=id5-`E16W1Gh08sr%YPh|&pc>uaZ7J=Cyy z%%t#;wW9HYK9i$bcVe;?^YZv+;A9z0s4kjxit{Qj@Aya&+o>q`9Y4a+uBa#PofG07YrRt%I^r+%0I}W-<0= zr-jX+2Z@!|oA~R{m5C!!u~3HgW)Ye}h6 zp7=GLIXdAl(fLkc(5PYR{f8ib6(=?WkzAKc*1#K5@4M7B88q${!Vi4jW2fxn_o=3e zv;Ky>@zVT$KRR^v%?^Z68axG(jKJtdEIs)0*uRch($y^jQa|gXX*U;SKpa8~HXf7M z>DjPJLWWDq`A|~gBUgkV;3<6edf z9ag8n!1rSo?`g&`rMh@EI?>Kg6G6PvT+rOSg4#Jv9Mq$kYk`N`&*j6~s8|gnN7t4% zVAwI<5VB~RMT^15ThA+c6Euy_uN zQPTx$QSdEZ)9~DTpt!+)|MYYG@#2qGR-ee7%qAuesxet35)JboL zj(nur6$FbMENUFl{eC3hCS+V9bRjjq)%NNy3Rt;5_32;?C-jl-an0HU_9_zHQ3X;B zh!U6=6->Sge!?g@S4(Y+$!)h$ZolJL8pcv-GDXMCA4(0SHph38Yr@|nj^qTKXy@E5 z-7~1-eQ#10-_`v3VR!V=$Ago%TkBLTLCW8ch?};npUkEH!{pAxk-y0TA1*vC{mNll zyCq}(xPxS3FRi%VJ%{Oh3oTvBa+Q$1f`kRf|D#in@M?A!&rR%$JSp)zfA9Y5I$i!X zOTKJ%Vw;H!*jqe#;LtlV7Ely%Y>oBCW7>FmrTS~@WoAyq35JOaCx!!H$~Qb#{YR32 z!rXwZF~Fv#v; zOr_bEWk@ps=jEQF%99^14Tmk;Xg}YMF+CR@nzSTC(13Oxmx736SL8(X;uhIwDD9^3&FKZrpPUq+&!<{eSug< zW(`=HuARY{RBdaJV8>?%AvOz3RJWMxTvVuy`!ykRy{59LGwpX$wEy{Z5AfQ&X=&mdbo^V9 z_yKWXuS2RMt{EdEm1r74k(}G=(XE#aao0V$1Djn~G`QqWQObuQogy7({OmwosBt6c zWoBw~tLM{z=n%FJnvQ3!K;{$e2SRD@qLGzO>VsxT8WDE12baO#Ub>lCb{wzRC_NlY0 z!yV=E1qpxjF~@R-XZ!{*y1**fi_H>3>Mi1}b6~?}dnOe{k)d)I63tJ>hO& zN@qv5LSGC%$s7zv3`Pyev`_CNEp!ivVCy>wQ$LZqwhh|vP2i3;5!%Nyy?=g8h>s@y zry4$lj$(f7oK!TCrpp1X36R7=B>99tInUGa^#!@^FFP2!$Jf$@E_bZzi_dLGex+dI zxK)q&H`DD7^~#~=_YI(9m9HIx+jejfZ%$Co>XVl&lb*)`;{m^Hb!VMzC$;1*h#l&_2uCp8efvFDq$_^PNVx7 zsi--tr!gBMm0VfaCEA?h+?fxvMLBVn@x9&tJUp$PA-`Ze_M@rlkv1>wOhMgptIH-! zepuIK`VRYhxob|*y;btzA{wYqlKCgB2QT7kB zYUL)hLjVLzoLubLEXl%~7eO6M>aA7&2yx>}cB$|I>PkA&c8GkXgqXMCP5#8VXBl*J z!6f{jOOQLN6k&Zj7>erOl$Qae05M`#F+-fzU>gA%G@tlhoU_$3`(fcw?C55MeTa3R zWddqUzU{?e$gjSjxq+Y$TrUlHR&I8Rwmk<<$@u%-_+Agty+7r0-?DygD+9jjQs5GbP^Xiw%;CtO8S~I0SJe%Ye%l{aHzcHSee~ z6#cnF_x*y1zlv;bH;M4byufK0Xt72Q7Q&AE%)(dq*9+z_zWHAQ>+YgYr@qfbW#(!k-4fNyrtgiK+ml%9mxZOqlIKWc3iueJ1J%e1|>GSVbbZ!3k$E0u0#)cw~hhu6u&OUI-iFtD=4 zr-R`*k6jV_B$NJgSj3HX`!x7}EO50KW!tID#;rZbABVe z?0?7Ol-^?Vv{(H-)&qw-aC(?eDsaK+Jz@>rVe9o$<>-o4mu+S|^!sdlWet5F1A#p1 ztH!_XKQ-C2C4?r4i!&PXzyq=vJLe)1e@cC4a)nT-!@PrR2sAdfkRGx*pd;rosuTRC z!65vzh0+~o9q4o4bh9?Dr3H7nrfQ{DnQ*p3vjLaa{?1;5W^Eo9!@j&d?-|~L9;B~Y_7ydLORxfgj2B$FfsPb17 z1&cv^Uv)LhtPA5ov(Df}9uFI1P3ED6?Zs zCU@vO=12tQqE1r{|K}-y#m8|TRL`y)rmGUqCTHmP*iH@Mjsk^S0u!ydVM5`(!QNClW36--_d& zb+rdj=04Ets&|oFe_)=Xaq)N5J&7xYS?zBs&kLhc@`b42y+glvQieW|g>%&pStEgm zeVEe{viwn7k*UIW4I24xk-P`39{czfp48HmD{RPu81chBYGXpE7@Z!>U&HZ)6)Xl+*d+JJKW@ouIKI|i#!hX z#i-Cf%=AW21&Yd&V+y_o5n5FAR(k>x2cE5`C&~n!;=C!dt@lnRpRT-L?W!%l$dRK? z4o+yK?~03l>T_WYtz?hcwPANi0dZJef8-FOB=|kuk#uLF*Zk9LHB9{bLS!3CAeeQg zfl}+B&&hWWd*fqb$%9_#Ybmza;-_WBzDw6cZB%H51`|snCiKl~xSpM*2w>WRAS%kb zovm&V9GL*^%(t&al!bDfXKL((8K&EdEz8!e)~%G19NA=1K0m5og-y539(c(wMf4Gi~#wO;Lvszeo^pn6T`z(lTv& zm`xlzV9{fG$4XAdqs~h}8%n>h?F8)&xCrMO+u@4{rYYUCR<`n6hX@5_@iV|BK%I3( zQug!}_7Cz0eH9i7<7A-D>mWz%7FxevftRPexR34~EBLtYkNWTva_3WVPy`|#@LYz+ zlYuR|vb%PD*a@j+*KQ?8JoBYp&vQh%-R%SEQY_1lKLN%X^P4=QI02KkGtJkPZ{uS# zS9w=I@_o1V6(eV+(d++W%1Nb*%yo|S{AE(-%^ph)?rn^OYAQq7+10+p?V8r-GY!tj z|75?zKdTV+m@BUHZ_(~f2c+wjaZ!kc@)S{g%$4z1Py)jEztBC_YI;Nj4lk9t47haY zgLLMob{lb9>nzuBcgi9AVnNUUmE$~n>k};PSTu^z)Mu19C=o%#^|ebQ9F4~3vnn& zv+QY!-g#fw8vjG^eP~|Q97$H`BMQ$0UQY=!AMR(EzoXFIhUjlt=%4n~q;uYHF(!mj zr2l%^*FngT2|g=18bp%=Z__KlDolod(BpDNj;A#&lsEhWfH=TN_p+@^)HY0bz}Z_ioct0E1e?z&d4~I%{J-r=^^zNmVt74}-$<^4c=7|R~^xPTvKJ^>%-J^Hfhx%}$ z&-M5^#}^l(=j^_(QYg-PQ0>V1?(&rxomH4vixpSfuZB}|IcX&(slL;hCqyRL72em8ii|=I)Xtkc$vA8>esDx% z<+$IyAIo@IYVO{3Z*Bd7fL;As`7iJk!qTK+S(vd}nG`Gjt;liOicwOPO6Y}N(Sto$ zD!mp)AE>Wlk2eygQfJWft;*Nj{N3R95L(TH=p;!6?i(liEHFaEv$~-5M{py8fDmv~ z0S&k6vI0-1Gb26G8ZTudvW016e~?c9x{zz};cHd2G zM$d|ft$d}5kkxJ23-$Q4mPT7&| zx4Yd;clkR922L>rULJt1vfPqXpp;wVoji31S4goZRv*GVX5~QjX+Y)@XNI|4x#sSC zV?>qsD8L;jZKSipLS%B;>-ZYY{rtD0mgE786f0u?$g+sY1#f3v-w&AgF$iax zZ&486*Na|CnvwN+L)VLh@tJ}{Chm^ESAF(nYpTTk0xN2zhF0=7sdH4gO_o_ftYzBh z3u9-Y(iZO;N3ZjiE9FqP4JOL4QR=Pcrtf~uBi%u~sr<;!6PEJ7FH*pls5#t&&Pq0!5gL z+J8@f&?Ra<#FLOqurTV;w7E@@k`yFGDgB+bq0pH(RB>*-u(~K!>aBBb&2piXk3Wj- zKXQ^?`Q21VOfFv86O)OhTip!6>|>*gQ%Zf7A1|nc1Gbx|^|I4P9=LrrA`_)JyFv>& zPl79W%@syDaL*yOMU|%8tPUUufL$(6VkB?bi05HW;ttYmwksX^(S;|MLQT`6`gnBUTSx*bLD7p=se6*&v|8zuRKSKc8DuJ;Yr+Rog>tSnMO-?48D9<)A1V@bi7Zg zMDNg(`6`k!I=o3Uj4zs0sS`n=Lsdc5Z0gzqh6}q`VEi*7_dI2iYx{MixKT^)aTzPU znIFl-QKPqfX^F9}CtE__l^ThDU7hAk)ET8$bpM?A%VM=vY|D6=X#J(|(5}NR{|U=^ zcd%qSBx_<1Gfei_R&i{38*bDZ*W50Ck7O>9lsF!LNX7}6cKr1h-)~%rB5`o$KU~X? z46Z!Qdh=IJhAO)>7S5!!(TKd}#$ItUm-0J^h2Lis`sd5?>M&a>PFfckGkfo=mjpI% zR`Eqi{}4~f1FVqyEj&l8*Hd)VRh$F|Fm4i-%7F6zn2wL}#uF*b(rS2Qj->0F{8q0i@^a|b96 z)~UrDjO12^E1JSgMd+qiDI_!^*AGNz&jJ`F)HxIb5_!Y_e)#VCpdXvuSXLMt7k$pR zznXtXzx^pZz}p=Ba)x?^&ohY|g&ne|WL`*}qirloakMX4=|zp3aR>7w9m{3=x<5vG!vzZ^ zffqrLE@MUdyy0|56@OP__;kxPUzTdEuTz{s*{1*VccV_3h@Sbdrh_-dVS{#}4nfz& zChZXGUX8_03uf+vg~Sd$_S(20({Cr|xzqTXhT5qw&Fx|Dh>B7l1e$xno%`;WC%2Lc zdDiHS4tz9eIhJpFwUCHX968GpP{fH4%s!5bmemHTW=YPT;h6Vre*M@hBsrg!)7W3b~$zS6zON6f@!v zFcyVhx2pYq|5w@K0z39TXUbLz5)(GacFc*IYw}}Nk7~<=FhYe5bK|ERqPd24=ro5REC3V>$V7eOVw_>pt)^k&u^s>U=v_B zAB-eid${vPs&}h#!8_>O%t(>ACy}PH7{yLH&g$Dm%(7@4eKzKIdbDWz3^}`YvEKCL zF!;_l762CwzyktgnI)`Z-g>u?i4;c2MD51$ETZt|sJ&$#JgYixiN^28Es>>US#)RZ zh}w&}xw&OQP!gd98~qRJJ7pJQJ?an?!E`?1l?fiFLkvo_Qr5H|=iUHwz9C!uG=e@U zGn(OPv<7@NL7f{%{MW9L@kHaUbBAwUpNqy{g#Jm_+g&S3``ty#^R!1C|B6_6dn#QLb2YI4^5*}~*JS<&=>J3Zf0G~swEuT;CvxEs51=d6ho)nH SUl6Wi0k?FFw5v58WB(s>?*9k? literal 0 HcmV?d00001 diff --git a/examples/apps/screenpipe-app-dioxus/src/analytics.rs b/examples/apps/screenpipe-app-dioxus/src/analytics.rs index 5d3c281bc..c53ee2a1e 100644 --- a/examples/apps/screenpipe-app-dioxus/src/analytics.rs +++ b/examples/apps/screenpipe-app-dioxus/src/analytics.rs @@ -77,7 +77,7 @@ impl AnalyticsManager { } } - pub fn toggle_analytics(&self) -> bool { + pub fn _toggle_analytics(&self) -> bool { let mut enabled = self.enabled.lock().unwrap(); *enabled = !*enabled; *enabled diff --git a/examples/apps/screenpipe-app-dioxus/src/main.rs b/examples/apps/screenpipe-app-dioxus/src/main.rs index 15090b56d..7b8d6f95d 100644 --- a/examples/apps/screenpipe-app-dioxus/src/main.rs +++ b/examples/apps/screenpipe-app-dioxus/src/main.rs @@ -1,102 +1,147 @@ #![cfg_attr(feature = "bundle", windows_subsystem = "windows")] -use dioxus::desktop::{muda::*, use_wry_event_handler}; use dioxus::prelude::*; use dirs::home_dir; use log::{error, info, LevelFilter}; use logs::MultiWriter; use screenpipe_server::DatabaseManager; use sentry; +use std::collections::HashMap; use std::fs::{self, File}; use std::io::Write; -use std::ops::Deref; use std::path::PathBuf; use std::sync::Arc; mod analytics; use analytics::AnalyticsManager; -use tokio::runtime::Runtime; use crate::analytics::start_analytics; mod logs; use screenpipe_audio::{ - default_input_device, default_output_device, list_audio_devices, DeviceControl, + default_input_device, default_output_device, list_audio_devices, parse_audio_device, + AudioDevice, DeviceControl, }; use screenpipe_server::{ResourceMonitor, Server}; use std::sync::atomic::AtomicBool; use std::time::Duration; -use tokio::sync::mpsc; +use tokio::sync::mpsc::{self, Sender}; -async fn setup_server_and_recording( - db: Arc, - local_data_dir: Arc, - port: u16, - fps: f64, - audio_chunk_duration: u64, - disable_audio: bool, - memory_threshold: f64, - runtime_threshold: u64, - analytics_manager: Arc, -) { - info!("Setting up server and recording..."); +use auto_launch::AutoLaunchBuilder; - let (audio_devices_control_sender, audio_devices_control_receiver) = mpsc::channel(64); +fn setup_auto_launch() -> anyhow::Result<()> { + let auto_launch = AutoLaunchBuilder::new() + .set_app_name("screenpipe") + .set_app_path(std::env::current_exe()?.to_str().unwrap()) + .build()?; + + auto_launch.enable()?; + println!("Auto-launch enabled: {}", auto_launch.is_enabled()?); + + Ok(()) +} + +async fn initialize_audio( + disable_audio: bool, + custom_devices: &[String], + audio_devices_control_sender: Arc>, +) -> (Vec>, HashMap) { let mut audio_devices = Vec::new(); - let mut devices_status = std::collections::HashMap::new(); - - if !disable_audio { - info!("Initializing audio devices..."); - let all_audio_devices = list_audio_devices().unwrap_or_default(); - - for device in all_audio_devices { - let device_control = DeviceControl { - is_running: false, - is_paused: false, - }; - info!("Audio device: {:?}", device.to_string()); - devices_status.insert(device, device_control); - } + let mut devices_status = HashMap::new(); + + if disable_audio { + info!("Audio recording is disabled"); + return (audio_devices, devices_status); + } + + info!("Initializing audio devices..."); + let all_audio_devices = list_audio_devices().unwrap_or_default(); + + for device in all_audio_devices { + let device_control = DeviceControl { + is_running: false, + is_paused: false, + }; + info!("Audio device: {:?}", device.to_string()); + devices_status.insert(device, device_control); + } + if custom_devices.is_empty() { if let Ok(input_device) = default_input_device() { info!("Default input device found: {:?}", input_device.to_string()); - audio_devices.push(Arc::new(input_device.clone())); - devices_status.get_mut(&input_device).unwrap().is_running = true; + audio_devices.push(Arc::new(input_device)); } if let Ok(output_device) = default_output_device() { info!( "Default output device found: {:?}", output_device.to_string() ); - audio_devices.push(Arc::new(output_device.clone())); - devices_status.get_mut(&output_device).unwrap().is_running = true; + audio_devices.push(Arc::new(output_device)); } - - if audio_devices.is_empty() { - error!("No audio devices available. Audio recording will be disabled."); - } else { - info!("Using audio devices:"); - for device in &audio_devices { - info!(" {}", device); - let device_clone = device.deref().clone(); - let sender_clone = audio_devices_control_sender.clone(); - tokio::spawn(async move { - tokio::time::sleep(Duration::from_secs(15)).await; - let _ = sender_clone - .send(( - device_clone, - DeviceControl { - is_running: true, - is_paused: false, - }, - )) - .await; - }); + } else { + for device_str in custom_devices { + if let Ok(device) = parse_audio_device(device_str) { + info!("Custom device added: {:?}", device.to_string()); + audio_devices.push(Arc::new(device)); + } else { + error!("Failed to parse audio device: {}", device_str); } } + } + + if audio_devices.is_empty() { + error!("No audio devices available. Audio recording will be disabled."); } else { - info!("Audio recording is disabled"); + info!("Using audio devices:"); + // for device in &audio_devices { + // info!(" {}", device); + // let device_clone = (**device).clone(); + // let sender_clone = audio_devices_control_sender.clone(); + // spawn(async move { + // tokio::time::sleep(Duration::from_secs(15)).await; + // let _ = sender_clone + // .send(( + // device_clone, + // DeviceControl { + // is_running: true, + // is_paused: false, + // }, + // )) + // .await; + // }); + // } } + (audio_devices, devices_status) +} + +async fn setup_server_and_recording( + db: Arc, + local_data_dir: Arc, + port: u16, + fps: f64, + audio_chunk_duration: u64, + disable_audio: bool, + memory_threshold: f64, + runtime_threshold: u64, + analytics_manager: Arc, +) -> anyhow::Result<( + Arc>, + Vec>, +)> { + info!("Setting up server and recording..."); + + let (audio_devices_control_sender, audio_devices_control_receiver) = mpsc::channel(64); + let audio_devices_control_sender = Arc::new(audio_devices_control_sender); + let audio_sender_for_server = audio_devices_control_sender.clone(); + let audio_sender_for_return = audio_devices_control_sender.clone(); + + let (audio_devices, devices_status) = initialize_audio( + disable_audio, + &[], // No custom devices for the app version + audio_devices_control_sender, + ) + .await; + // Start resource monitoring ResourceMonitor::new(memory_threshold, runtime_threshold, false) .start_monitoring(Duration::from_secs(10)); @@ -109,28 +154,27 @@ async fn setup_server_and_recording( let vision_control_server_clone = vision_control.clone(); // Spawn continuous recording task - let _recording_task = tokio::spawn({ - let local_data_dir = local_data_dir.clone(); - async move { - let audio_chunk_duration = Duration::from_secs(audio_chunk_duration); - screenpipe_server::start_continuous_recording( - db_record, - local_data_dir, - fps, - audio_chunk_duration, - control_rx, - vision_control, - audio_devices_control_receiver, - ) - .await + spawn(async move { + let audio_chunk_duration = Duration::from_secs(audio_chunk_duration); + if let Err(e) = screenpipe_server::start_continuous_recording( + db_record, + local_data_dir, + fps, + audio_chunk_duration, + control_rx, + vision_control, + audio_devices_control_receiver, + ) + .await + { + log::error!("Continuous recording error: {:?}", e); } }); - // API plugin for analytics let api_plugin = move |req: &axum::http::Request| { if req.uri().path() == "/search" { let analytics_manager = analytics_manager.clone(); - tokio::spawn(async move { + spawn(async move { if let Err(e) = analytics_manager.track_search().await { error!("Failed to track search request: {}", e); } @@ -139,12 +183,12 @@ async fn setup_server_and_recording( }; // Spawn server task - tokio::spawn(async move { + spawn(async move { let server = Server::new( db_server, std::net::SocketAddr::from(([0, 0, 0, 0], port)), vision_control_server_clone, - audio_devices_control_sender, + audio_sender_for_server.as_ref().clone(), // Clone the inner Sender ); info!("Starting server..."); @@ -154,6 +198,8 @@ async fn setup_server_and_recording( }); info!("Server started on http://localhost:{}", port); + + Ok((audio_sender_for_return, audio_devices)) } async fn initialize_database(local_data_dir: Arc) -> Arc { @@ -176,7 +222,10 @@ fn get_local_dir(custom_path: Option) -> anyhow::Result { Ok(local_data_dir) } -async fn start_screenpipe() -> anyhow::Result<()> { +async fn start_screenpipe() -> anyhow::Result<( + Arc>, + Vec>, +)> { // Initialize Sentry let _guard = sentry::init(("https://cf682877173997afc8463e5ca2fbe3c7@o4507617161314304.ingest.us.sentry.io/4507617170161664", sentry::ClientOptions { release: sentry::release_name!(), @@ -220,71 +269,93 @@ async fn start_screenpipe() -> anyhow::Result<()> { let analytics_manager = start_analytics(posthog_api_key, app_name, interval_hours).unwrap(); // Setup server and recording - setup_server_and_recording( + let (audio_devices_control_sender, audio_devices) = setup_server_and_recording( db, local_data_dir, - 3000, // default port - 30.0, // default fps - 5, // default audio_chunk_duration + 3030, // default port + 1.0, // default fps + 30, // default audio_chunk_duration false, // default disable_audio 80.0, // default memory_threshold 3600, // default runtime_threshold analytics_manager, ) - .await; + .await?; - Ok(()) + Ok((audio_devices_control_sender, audio_devices)) } fn main() { - // Create a Tokio runtime - let rt = Runtime::new().unwrap(); - - // Start Screenpipe in the background - if let Err(e) = rt.block_on(start_screenpipe()) { - eprintln!("Failed to start Screenpipe: {}", e); - std::process::exit(1); + if let Err(e) = setup_auto_launch() { + eprintln!("Failed to set up auto-launch: {}", e); } - // Create a menu bar that only contains the edit menu - let menu = Menu::new(); - let edit_menu = Submenu::new("Edit", true); - - edit_menu - .append_items(&[ - &PredefinedMenuItem::undo(None), - &PredefinedMenuItem::redo(None), - &PredefinedMenuItem::separator(), - &PredefinedMenuItem::cut(None), - &PredefinedMenuItem::copy(None), - &PredefinedMenuItem::paste(None), - &PredefinedMenuItem::select_all(None), - &MenuItem::with_id("switch-text", "Switch text", true, None), - ]) - .unwrap(); - - menu.append(&edit_menu).unwrap(); - - // Create a desktop config that overrides the default menu with the custom menu - let config = dioxus::desktop::Config::new().with_menu(menu); - - // Launch the app with the custom menu - LaunchBuilder::new().with_cfg(config).launch(app) + + launch_desktop(app) } fn app() -> Element { - let mut text = use_signal(String::new); - // You can use the `use_muda_event_handler` hook to run code when a menu event is triggered. - use_wry_event_handler(move |muda_event, _| { - // if muda_event.id() == "switch-text" { - // text.set("Switched to text".to_string()); - // } + let mut recording = use_signal(|| false); + let mut audio_sender = use_signal(|| None::>>); + let mut audio_devices = use_signal(|| Vec::new()); + + use_future(move || async move { + match start_screenpipe().await { + Ok((sender, devices)) => { + audio_sender.set(Some(sender)); + audio_devices.set(devices); + } + Err(e) => { + eprintln!("Failed to start Screenpipe: {}", e); + std::process::exit(1); + } + } }); + let start_recording = move |_| { + let mut recording = recording.clone(); + let sender = audio_sender.read().clone(); + let devices = audio_devices.read().clone(); + spawn(async move { + if let Some(sender) = sender { + for device in &devices { + let _ = sender + .send(( + (**device).clone(), + DeviceControl { + is_running: true, + is_paused: false, + }, + )) + .await; + } + recording.set(true); + } + }); + }; rsx! { div { h1 { "Welcome to screen | ⭐️" } - // p { "Text: {text}" } - p { "It's running! Check examples on Github on how to use your data now :)" } + p { + "It's running. We record your screen 24/7! Click the button below to start recording audio." + } + br {} + + button { + onclick: start_recording, + disabled: "{recording}", + "Start Recording microphone" + // "{if *recording { "Recording..." } else { "Start Recording" }}" + } + br {} + + a { + href: "https://github.com/louis030195/screen-pipe", + "Github" + } + br {} + p { + "Send feedback: louis@screenpi.pe" + } } } }