diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..14cbffa --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,95 @@ +name: WDIO (Linux) + +on: [] + +jobs: + wdio: + runs-on: ubuntu-22.04 + container: + image: debian:12 + + steps: + # 1️⃣ Checkout repo + - name: Checkout repo + uses: actions/checkout@v4 + + # 2️⃣ Node.js + npm cache + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + + # 3️⃣ Rust toolchain + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.rust-targets || '' }} + + # 4️⃣ Rust build cache + - name: Cache Rust + uses: Swatinem/rust-cache@v2 + with: + workspaces: | + src-tauri -> target + + # 5️⃣ Install npm dependencies + - name: Install dependencies + run: npm install + + - name: Install test dependencies + run: npm install + working-directory: test + + # 6️⃣ System dependencies (GTK / WebKit / Tauri) + - name: Install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + pkg-config \ + libglib2.0-dev \ + libgtk-3-dev \ + libwebkit2gtk-4.1-dev \ + libayatana-appindicator3-dev \ + librsvg2-dev \ + xvfb \ + webkit2gtk-driver \ + xkb-data + + # 7️⃣ Generate icons + - name: Generate icons + run: npm run gen-icons + + # # 8️⃣ Build Tauri app + # - name: Build app + # env: + # TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + # TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + # run: npm run tauri build + + # 9️⃣ Install tauri-driver + - name: Install tauri-driver + run: cargo install tauri-driver + + - name: Download test data + run: | + mkdir -p test/dtm-test-data/projects + curl -L \ + https://github.com/kcjerrell/dtm/releases/download/test-data-v1/test-projects.zip \ + -o test/dtm-test-data/test-projects.zip + unzip -q test/dtm-test-data/test-projects.zip -d test/dtm-test-data/projects + + - name: WebdriverIO (Linux) + run: xvfb-run yarn test + working-directory: test + + # 11️⃣ Upload artifacts on failure + - name: Upload artifacts on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: wdio-artifacts + path: | + test/logs/* + test/screenshots/* + $HOME/.local/share/com.kcjer.dtm/logs \ No newline at end of file diff --git a/.gitignore b/.gitignore index b7ba4c8..d4b687f 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ notes.md *.mp4 stats.html temp/ +src-tauri/test_data diff --git a/package-lock.json b/package-lock.json index b564e7d..195b204 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "dtm", - "version": "0.1.1", + "version": "0.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dtm", - "version": "0.1.1", + "version": "0.2.1", "dependencies": { "@chakra-ui/react": "^3.30.0", "@emotion/react": "^11.14.0", @@ -24,6 +24,7 @@ "@tauri-apps/plugin-window-state": "~2", "@tauri-store/valtio": "^3.2.0", "@uiw/react-json-view": "^2.0.0-alpha.40", + "ahooks": "^3.9.6", "async-mutex": "^0.5.0", "derive-valtio": "^0.2.0", "eventemitter3": "^5.0.1", @@ -52,19 +53,31 @@ "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.1", "@types/fs-extra": "^11.0.4", + "@types/mocha": "^10.0.10", + "@types/node": "^25.1.0", "@types/plist": "^3.0.5", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", + "@wdio/cli": "^9.23.2", + "@wdio/concise-reporter": "^9.23.3", + "@wdio/globals": "^9.23.0", + "@wdio/local-runner": "^9.23.2", + "@wdio/mocha-framework": "^9.23.2", + "@wdio/spec-reporter": "^9.23.2", + "@wdio/types": "^9.23.2", + "@wdio/visual-service": "^9.1.2", "babel-plugin-react-compiler": "^1.0.0", "dotenv": "^17.2.3", "dotenv-cli": "^11.0.0", + "expect-webdriverio": "^5.6.4", "fs-extra": "^11.3.3", "globals": "^17.0.0", "jiti": "^2.6.1", "jsdom": "^27.4.0", "react-redux": "^9.2.0", "rollup-plugin-visualizer": "^6.0.5", + "tscanner": "^0.1.3", "typescript": "^5.9.3", "vite": "^7.3.1", "vite-bundle-visualizer": "^1.2.1", @@ -1585,3405 +1598,8319 @@ "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", "license": "MIT" }, - "node_modules/@internationalized/date": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.10.0.tgz", - "integrity": "sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - } - }, - "node_modules/@internationalized/number": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.5.tgz", - "integrity": "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" + "node_modules/@inquirer/ansi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz", + "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "node_modules/@inquirer/checkbox": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz", + "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", + "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "node_modules/@inquirer/confirm": { + "version": "5.1.21", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz", + "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "node_modules/@inquirer/core": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz", + "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", + "dev": true, "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.3" + }, "engines": { - "node": ">=6.0.0" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "node_modules/@inquirer/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@octokit/auth-token": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", - "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", + "node_modules/@inquirer/core/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, "engines": { - "node": ">= 20" + "node": ">=8" } }, - "node_modules/@octokit/core": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz", - "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", + "node_modules/@inquirer/editor": { + "version": "4.2.23", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz", + "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/auth-token": "^6.0.0", - "@octokit/graphql": "^9.0.3", - "@octokit/request": "^10.0.6", - "@octokit/request-error": "^7.0.2", - "@octokit/types": "^16.0.0", - "before-after-hook": "^4.0.0", - "universal-user-agent": "^7.0.0" + "@inquirer/core": "^10.3.2", + "@inquirer/external-editor": "^1.0.3", + "@inquirer/type": "^3.0.10" }, "engines": { - "node": ">= 20" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@octokit/endpoint": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.2.tgz", - "integrity": "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ==", + "node_modules/@inquirer/expand": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz", + "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/types": "^16.0.0", - "universal-user-agent": "^7.0.2" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { - "node": ">= 20" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@octokit/graphql": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz", - "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==", + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/request": "^10.0.6", - "@octokit/types": "^16.0.0", - "universal-user-agent": "^7.0.0" + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" }, "engines": { - "node": ">= 20" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@octokit/openapi-types": { - "version": "27.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", - "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", + "node_modules/@inquirer/figures": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", + "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz", - "integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==", + "node_modules/@inquirer/input": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz", + "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/types": "^16.0.0" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, "engines": { - "node": ">= 20" + "node": ">=18" }, "peerDependencies": { - "@octokit/core": ">=6" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@octokit/plugin-request-log": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-6.0.0.tgz", - "integrity": "sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==", + "node_modules/@inquirer/number": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz", + "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", "dev": true, "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, "engines": { - "node": ">= 20" + "node": ">=18" }, "peerDependencies": { - "@octokit/core": ">=6" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz", - "integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==", + "node_modules/@inquirer/password": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz", + "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/types": "^16.0.0" + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, "engines": { - "node": ">= 20" + "node": ">=18" }, "peerDependencies": { - "@octokit/core": ">=6" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@octokit/request": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.7.tgz", - "integrity": "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA==", + "node_modules/@inquirer/prompts": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.10.1.tgz", + "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/endpoint": "^11.0.2", - "@octokit/request-error": "^7.0.2", - "@octokit/types": "^16.0.0", - "fast-content-type-parse": "^3.0.0", - "universal-user-agent": "^7.0.2" + "@inquirer/checkbox": "^4.3.2", + "@inquirer/confirm": "^5.1.21", + "@inquirer/editor": "^4.2.23", + "@inquirer/expand": "^4.0.23", + "@inquirer/input": "^4.3.1", + "@inquirer/number": "^3.0.23", + "@inquirer/password": "^4.0.23", + "@inquirer/rawlist": "^4.1.11", + "@inquirer/search": "^3.2.2", + "@inquirer/select": "^4.4.2" }, "engines": { - "node": ">= 20" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@octokit/request-error": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz", - "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==", + "node_modules/@inquirer/rawlist": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz", + "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/types": "^16.0.0" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { - "node": ">= 20" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@octokit/rest": { - "version": "22.0.1", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-22.0.1.tgz", - "integrity": "sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw==", + "node_modules/@inquirer/search": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz", + "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/core": "^7.0.6", - "@octokit/plugin-paginate-rest": "^14.0.0", - "@octokit/plugin-request-log": "^6.0.0", - "@octokit/plugin-rest-endpoint-methods": "^17.0.0" + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { - "node": ">= 20" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@octokit/types": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", - "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", + "node_modules/@inquirer/select": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz", + "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/openapi-types": "^27.0.0" + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@pandacss/is-valid-prop": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@pandacss/is-valid-prop/-/is-valid-prop-1.8.0.tgz", - "integrity": "sha512-ni3nGvk7K7OwvS5QWljnPgLaNhfcqFJnCYQxyEgUBXcAd/hEbwMhXjfuL/VFczWPERJITJdi1FB/giau3pF+DQ==", - "license": "MIT" - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.53", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz", - "integrity": "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==", + "node_modules/@inquirer/type": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz", + "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz", - "integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==", - "cpu": [ - "arm" - ], + "node_modules/@internationalized/date": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.10.0.tgz", + "integrity": "sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@internationalized/number": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.5.tgz", + "integrity": "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz", - "integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==", - "cpu": [ - "arm64" - ], + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz", - "integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==", - "cpu": [ - "arm64" - ], + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz", - "integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==", - "cpu": [ - "x64" - ], + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "license": "MIT" }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz", - "integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==", - "cpu": [ - "arm64" - ], + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz", - "integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==", - "cpu": [ - "x64" - ], + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz", - "integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==", - "cpu": [ - "arm" - ], + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz", - "integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==", - "cpu": [ - "arm" - ], + "node_modules/@jest/diff-sequences": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", + "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz", - "integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==", - "cpu": [ - "arm64" - ], + "node_modules/@jest/expect-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", + "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@jest/get-type": "30.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz", - "integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==", - "cpu": [ - "arm64" - ], + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz", - "integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==", - "cpu": [ - "loong64" - ], + "node_modules/@jest/pattern": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", + "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@types/node": "*", + "jest-regex-util": "30.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz", - "integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==", - "cpu": [ - "loong64" - ], + "node_modules/@jest/schemas": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz", - "integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==", - "cpu": [ - "ppc64" - ], + "node_modules/@jest/types": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", + "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz", - "integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==", - "cpu": [ - "ppc64" - ], + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz", - "integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==", - "cpu": [ - "riscv64" - ], + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz", - "integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==", - "cpu": [ - "riscv64" - ], + "node_modules/@jimp/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/core/-/core-1.6.0.tgz", + "integrity": "sha512-EQQlKU3s9QfdJqiSrZWNTxBs3rKXgO2W+GxNXDtwchF3a4IqxDheFX1ti+Env9hdJXDiYLp2jTRjlxhPthsk8w==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@jimp/file-ops": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "await-to-js": "^3.0.0", + "exif-parser": "^0.1.12", + "file-type": "^16.0.0", + "mime": "3" + }, + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz", - "integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==", - "cpu": [ - "s390x" - ], + "node_modules/@jimp/diff": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/diff/-/diff-1.6.0.tgz", + "integrity": "sha512-+yUAQ5gvRC5D1WHYxjBHZI7JBRusGGSLf8AmPRPCenTzh4PA+wZ1xv2+cYqQwTfQHU5tXYOhA0xDytfHUf1Zyw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@jimp/plugin-resize": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "pixelmatch": "^5.3.0" + }, + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz", - "integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==", - "cpu": [ - "x64" - ], + "node_modules/@jimp/file-ops": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/file-ops/-/file-ops-1.6.0.tgz", + "integrity": "sha512-Dx/bVDmgnRe1AlniRpCKrGRm5YvGmUwbDzt+MAkgmLGf+jvBT75hmMEZ003n9HQI/aPnm/YKnXjg/hOpzNCpHQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz", - "integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==", - "cpu": [ - "x64" - ], + "node_modules/@jimp/js-bmp": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/js-bmp/-/js-bmp-1.6.0.tgz", + "integrity": "sha512-FU6Q5PC/e3yzLyBDXupR3SnL3htU7S3KEs4e6rjDP6gNEOXRFsWs6YD3hXuXd50jd8ummy+q2WSwuGkr8wi+Gw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "bmp-ts": "^1.0.9" + }, + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz", - "integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==", - "cpu": [ - "x64" - ], + "node_modules/@jimp/js-gif": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/js-gif/-/js-gif-1.6.0.tgz", + "integrity": "sha512-N9CZPHOrJTsAUoWkWZstLPpwT5AwJ0wge+47+ix3++SdSL/H2QzyMqxbcDYNFe4MoI5MIhATfb0/dl/wmX221g==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "gifwrap": "^0.10.1", + "omggif": "^1.0.10" + }, + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz", - "integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==", - "cpu": [ - "arm64" - ], + "node_modules/@jimp/js-jpeg": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/js-jpeg/-/js-jpeg-1.6.0.tgz", + "integrity": "sha512-6vgFDqeusblf5Pok6B2DUiMXplH8RhIKAryj1yn+007SIAQ0khM1Uptxmpku/0MfbClx2r7pnJv9gWpAEJdMVA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "jpeg-js": "^0.4.4" + }, + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz", - "integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==", - "cpu": [ - "arm64" - ], + "node_modules/@jimp/js-png": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/js-png/-/js-png-1.6.0.tgz", + "integrity": "sha512-AbQHScy3hDDgMRNfG0tPjL88AV6qKAILGReIa3ATpW5QFjBKpisvUaOqhzJ7Reic1oawx3Riyv152gaPfqsBVg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "pngjs": "^7.0.0" + }, + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz", - "integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==", - "cpu": [ - "ia32" - ], + "node_modules/@jimp/js-tiff": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/js-tiff/-/js-tiff-1.6.0.tgz", + "integrity": "sha512-zhReR8/7KO+adijj3h0ZQUOiun3mXUv79zYEAKvE0O+rP7EhgtKvWJOZfRzdZSNv0Pu1rKtgM72qgtwe2tFvyw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "utif2": "^4.1.0" + }, + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz", - "integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==", - "cpu": [ - "x64" - ], + "node_modules/@jimp/plugin-blit": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-1.6.0.tgz", + "integrity": "sha512-M+uRWl1csi7qilnSK8uxK4RJMSuVeBiO1AY0+7APnfUbQNZm6hCe0CCFv1Iyw1D/Dhb8ph8fQgm5mwM0eSxgVA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz", - "integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==", - "cpu": [ - "x64" - ], + "node_modules/@jimp/plugin-blit/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "node_modules/@jimp/plugin-blur": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-1.6.0.tgz", + "integrity": "sha512-zrM7iic1OTwUCb0g/rN5y+UnmdEsT3IfuCXCJJNs8SZzP0MkZ1eTvuwK9ZidCuMo4+J3xkzCidRwYXB5CyGZTw==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/utils": "1.6.0" + }, + "engines": { + "node": ">=18" + } }, - "node_modules/@swc/helpers": { - "version": "0.5.18", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.18.tgz", - "integrity": "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==", - "license": "Apache-2.0", + "node_modules/@jimp/plugin-circle": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-1.6.0.tgz", + "integrity": "sha512-xt1Gp+LtdMKAXfDp3HNaG30SPZW6AQ7dtAtTnoRKorRi+5yCJjKqXRgkewS5bvj8DEh87Ko1ydJfzqS3P2tdWw==", + "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^2.8.0" + "@jimp/types": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" } }, - "node_modules/@tauri-apps/api": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.9.1.tgz", - "integrity": "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw==", - "license": "Apache-2.0 OR MIT", + "node_modules/@jimp/plugin-circle/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/tauri" + "url": "https://github.com/sponsors/colinhacks" } }, - "node_modules/@tauri-apps/cli": { - "version": "2.9.6", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.9.6.tgz", - "integrity": "sha512-3xDdXL5omQ3sPfBfdC8fCtDKcnyV7OqyzQgfyT5P3+zY6lcPqIYKQBvUasNvppi21RSdfhy44ttvJmftb0PCDw==", + "node_modules/@jimp/plugin-color": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-1.6.0.tgz", + "integrity": "sha512-J5q8IVCpkBsxIXM+45XOXTrsyfblyMZg3a9eAo0P7VPH4+CrvyNQwaYatbAIamSIN1YzxmO3DkIZXzRjFSz1SA==", "dev": true, - "license": "Apache-2.0 OR MIT", - "bin": { - "tauri": "tauri.js" - }, + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "tinycolor2": "^1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-color/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@jimp/plugin-contain": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-1.6.0.tgz", + "integrity": "sha512-oN/n+Vdq/Qg9bB4yOBOxtY9IPAtEfES8J1n9Ddx+XhGBYT1/QTU/JYkGaAkIGoPnyYvmLEDqMz2SGihqlpqfzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/plugin-blit": "1.6.0", + "@jimp/plugin-resize": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-contain/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@jimp/plugin-cover": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-1.6.0.tgz", + "integrity": "sha512-Iow0h6yqSC269YUJ8HC3Q/MpCi2V55sMlbkkTTx4zPvd8mWZlC0ykrNDeAy9IJegrQ7v5E99rJwmQu25lygKLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/plugin-crop": "1.6.0", + "@jimp/plugin-resize": "1.6.0", + "@jimp/types": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-cover/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@jimp/plugin-crop": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-1.6.0.tgz", + "integrity": "sha512-KqZkEhvs+21USdySCUDI+GFa393eDIzbi1smBqkUPTE+pRwSWMAf01D5OC3ZWB+xZsNla93BDS9iCkLHA8wang==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-crop/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@jimp/plugin-displace": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-1.6.0.tgz", + "integrity": "sha512-4Y10X9qwr5F+Bo5ME356XSACEF55485j5nGdiyJ9hYzjQP9nGgxNJaZ4SAOqpd+k5sFaIeD7SQ0Occ26uIng5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-displace/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@jimp/plugin-dither": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-1.6.0.tgz", + "integrity": "sha512-600d1RxY0pKwgyU0tgMahLNKsqEcxGdbgXadCiVCoGd6V6glyCvkNrnnwC0n5aJ56Htkj88PToSdF88tNVZEEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jimp/types": "1.6.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-fisheye": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-1.6.0.tgz", + "integrity": "sha512-E5QHKWSCBFtpgZarlmN3Q6+rTQxjirFqo44ohoTjzYVrDI6B6beXNnPIThJgPr0Y9GwfzgyarKvQuQuqCnnfbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-fisheye/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@jimp/plugin-flip": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-1.6.0.tgz", + "integrity": "sha512-/+rJVDuBIVOgwoyVkBjUFHtP+wmW0r+r5OQ2GpatQofToPVbJw1DdYWXlwviSx7hvixTWLKVgRWQ5Dw862emDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jimp/types": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-flip/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@jimp/plugin-hash": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-hash/-/plugin-hash-1.6.0.tgz", + "integrity": "sha512-wWzl0kTpDJgYVbZdajTf+4NBSKvmI3bRI8q6EH9CVeIHps9VWVsUvEyb7rpbcwVLWYuzDtP2R0lTT6WeBNQH9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/js-bmp": "1.6.0", + "@jimp/js-jpeg": "1.6.0", + "@jimp/js-png": "1.6.0", + "@jimp/js-tiff": "1.6.0", + "@jimp/plugin-color": "1.6.0", + "@jimp/plugin-resize": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "any-base": "^1.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-mask": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-1.6.0.tgz", + "integrity": "sha512-Cwy7ExSJMZszvkad8NV8o/Z92X2kFUFM8mcDAhNVxU0Q6tA0op2UKRJY51eoK8r6eds/qak3FQkXakvNabdLnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jimp/types": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-mask/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@jimp/plugin-print": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-1.6.0.tgz", + "integrity": "sha512-zarTIJi8fjoGMSI/M3Xh5yY9T65p03XJmPsuNet19K/Q7mwRU6EV2pfj+28++2PV2NJ+htDF5uecAlnGyxFN2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/js-jpeg": "1.6.0", + "@jimp/js-png": "1.6.0", + "@jimp/plugin-blit": "1.6.0", + "@jimp/types": "1.6.0", + "parse-bmfont-ascii": "^1.0.6", + "parse-bmfont-binary": "^1.0.6", + "parse-bmfont-xml": "^1.1.6", + "simple-xml-to-json": "^1.2.2", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-print/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@jimp/plugin-quantize": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-quantize/-/plugin-quantize-1.6.0.tgz", + "integrity": "sha512-EmzZ/s9StYQwbpG6rUGBCisc3f64JIhSH+ncTJd+iFGtGo0YvSeMdAd+zqgiHpfZoOL54dNavZNjF4otK+mvlg==", + "dev": true, + "license": "MIT", + "dependencies": { + "image-q": "^4.0.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-quantize/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@jimp/plugin-resize": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-1.6.0.tgz", + "integrity": "sha512-uSUD1mqXN9i1SGSz5ov3keRZ7S9L32/mAQG08wUwZiEi5FpbV0K8A8l1zkazAIZi9IJzLlTauRNU41Mi8IF9fA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-resize/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@jimp/plugin-rotate": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-1.6.0.tgz", + "integrity": "sha512-JagdjBLnUZGSG4xjCLkIpQOZZ3Mjbg8aGCCi4G69qR+OjNpOeGI7N2EQlfK/WE8BEHOW5vdjSyglNqcYbQBWRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/plugin-crop": "1.6.0", + "@jimp/plugin-resize": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-rotate/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@jimp/plugin-threshold": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-1.6.0.tgz", + "integrity": "sha512-M59m5dzLoHOVWdM41O8z9SyySzcDn43xHseOH0HavjsfQsT56GGCC4QzU1banJidbUrePhzoEdS42uFE8Fei8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/plugin-color": "1.6.0", + "@jimp/plugin-hash": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-threshold/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@jimp/types": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/types/-/types-1.6.0.tgz", + "integrity": "sha512-7UfRsiKo5GZTAATxm2qQ7jqmUXP0DxTArztllTcYdyw6Xi5oT4RaoXynVtCD4UyLK5gJgkZJcwonoijrhYFKfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/types/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@jimp/utils": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-1.6.0.tgz", + "integrity": "sha512-gqFTGEosKbOkYF/WFj26jMHOI5OH2jeP1MmC/zbK6BF6VJBf8rIC5898dPfSzZEbSA0wbbV5slbntWVc5PKLFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jimp/types": "1.6.0", + "tinycolor2": "^1.6.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@octokit/auth-token": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", + "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/core": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz", + "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^6.0.0", + "@octokit/graphql": "^9.0.3", + "@octokit/request": "^10.0.6", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "before-after-hook": "^4.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/endpoint": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.2.tgz", + "integrity": "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/graphql": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz", + "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^10.0.6", + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", + "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz", + "integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-6.0.0.tgz", + "integrity": "sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz", + "integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/request": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.7.tgz", + "integrity": "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^11.0.2", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "fast-content-type-parse": "^3.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/request-error": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz", + "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/rest": { + "version": "22.0.1", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-22.0.1.tgz", + "integrity": "sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/core": "^7.0.6", + "@octokit/plugin-paginate-rest": "^14.0.0", + "@octokit/plugin-request-log": "^6.0.0", + "@octokit/plugin-rest-endpoint-methods": "^17.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/types": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", + "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^27.0.0" + } + }, + "node_modules/@pandacss/is-valid-prop": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@pandacss/is-valid-prop/-/is-valid-prop-1.8.0.tgz", + "integrity": "sha512-ni3nGvk7K7OwvS5QWljnPgLaNhfcqFJnCYQxyEgUBXcAd/hEbwMhXjfuL/VFczWPERJITJdi1FB/giau3pF+DQ==", + "license": "MIT" + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@promptbook/utils": { + "version": "0.69.5", + "resolved": "https://registry.npmjs.org/@promptbook/utils/-/utils-0.69.5.tgz", + "integrity": "sha512-xm5Ti/Hp3o4xHrsK9Yy3MS6KbDxYbq485hDsFvxqaNA7equHLPdo8H8faTitTeb14QCDfLW4iwCxdVYu5sn6YQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/webgptorg/promptbook/blob/main/README.md#%EF%B8%8F-contributing" + } + ], + "license": "CC-BY-4.0", + "dependencies": { + "spacetrim": "0.11.59" + } + }, + "node_modules/@puppeteer/browsers": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.11.2.tgz", + "integrity": "sha512-GBY0+2lI9fDrjgb5dFL9+enKXqyOPok9PXg/69NVkjW3bikbK9RQrNrI3qccQXmDNN7ln4j/yL89Qgvj/tfqrw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.4.3", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.5.0", + "semver": "^7.7.3", + "tar-fs": "^3.1.1", + "yargs": "^17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@puppeteer/browsers/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz", + "integrity": "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz", + "integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz", + "integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz", + "integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz", + "integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz", + "integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz", + "integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz", + "integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz", + "integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz", + "integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz", + "integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz", + "integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz", + "integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz", + "integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz", + "integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz", + "integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz", + "integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz", + "integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz", + "integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz", + "integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz", + "integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz", + "integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz", + "integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz", + "integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz", + "integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz", + "integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinclair/typebox": { + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@swc/helpers": { + "version": "0.5.18", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.18.tgz", + "integrity": "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tauri-apps/api": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.9.1.tgz", + "integrity": "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw==", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@tauri-apps/cli": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.9.6.tgz", + "integrity": "sha512-3xDdXL5omQ3sPfBfdC8fCtDKcnyV7OqyzQgfyT5P3+zY6lcPqIYKQBvUasNvppi21RSdfhy44ttvJmftb0PCDw==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "bin": { + "tauri": "tauri.js" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + }, + "optionalDependencies": { + "@tauri-apps/cli-darwin-arm64": "2.9.6", + "@tauri-apps/cli-darwin-x64": "2.9.6", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.9.6", + "@tauri-apps/cli-linux-arm64-gnu": "2.9.6", + "@tauri-apps/cli-linux-arm64-musl": "2.9.6", + "@tauri-apps/cli-linux-riscv64-gnu": "2.9.6", + "@tauri-apps/cli-linux-x64-gnu": "2.9.6", + "@tauri-apps/cli-linux-x64-musl": "2.9.6", + "@tauri-apps/cli-win32-arm64-msvc": "2.9.6", + "@tauri-apps/cli-win32-ia32-msvc": "2.9.6", + "@tauri-apps/cli-win32-x64-msvc": "2.9.6" + } + }, + "node_modules/@tauri-apps/cli-darwin-arm64": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.9.6.tgz", + "integrity": "sha512-gf5no6N9FCk1qMrti4lfwP77JHP5haASZgVbBgpZG7BUepB3fhiLCXGUK8LvuOjP36HivXewjg72LTnPDScnQQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-darwin-x64": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.9.6.tgz", + "integrity": "sha512-oWh74WmqbERwwrwcueJyY6HYhgCksUc6NT7WKeXyrlY/FPmNgdyQAgcLuTSkhRFuQ6zh4Np1HZpOqCTpeZBDcw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.9.6.tgz", + "integrity": "sha512-/zde3bFroFsNXOHN204DC2qUxAcAanUjVXXSdEGmhwMUZeAQalNj5cz2Qli2elsRjKN/hVbZOJj0gQ5zaYUjSg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-gnu": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.9.6.tgz", + "integrity": "sha512-pvbljdhp9VOo4RnID5ywSxgBs7qiylTPlK56cTk7InR3kYSTJKYMqv/4Q/4rGo/mG8cVppesKIeBMH42fw6wjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-musl": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.9.6.tgz", + "integrity": "sha512-02TKUndpodXBCR0oP//6dZWGYcc22Upf2eP27NvC6z0DIqvkBBFziQUcvi2n6SrwTRL0yGgQjkm9K5NIn8s6jw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-riscv64-gnu": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.9.6.tgz", + "integrity": "sha512-fmp1hnulbqzl1GkXl4aTX9fV+ubHw2LqlLH1PE3BxZ11EQk+l/TmiEongjnxF0ie4kV8DQfDNJ1KGiIdWe1GvQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-gnu": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.9.6.tgz", + "integrity": "sha512-vY0le8ad2KaV1PJr+jCd8fUF9VOjwwQP/uBuTJvhvKTloEwxYA/kAjKK9OpIslGA9m/zcnSo74czI6bBrm2sYA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-musl": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.9.6.tgz", + "integrity": "sha512-TOEuB8YCFZTWVDzsO2yW0+zGcoMiPPwcUgdnW1ODnmgfwccpnihDRoks+ABT1e3fHb1ol8QQWsHSCovb3o2ENQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-arm64-msvc": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.9.6.tgz", + "integrity": "sha512-ujmDGMRc4qRLAnj8nNG26Rlz9klJ0I0jmZs2BPpmNNf0gM/rcVHhqbEkAaHPTBVIrtUdf7bGvQAD2pyIiUrBHQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-ia32-msvc": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.9.6.tgz", + "integrity": "sha512-S4pT0yAJgFX8QRCyKA1iKjZ9Q/oPjCZf66A/VlG5Yw54Nnr88J1uBpmenINbXxzyhduWrIXBaUbEY1K80ZbpMg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-x64-msvc": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.9.6.tgz", + "integrity": "sha512-ldWuWSSkWbKOPjQMJoYVj9wLHcOniv7diyI5UAJ4XsBdtaFB0pKHQsqw/ItUma0VXGC7vB4E9fZjivmxur60aw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/plugin-clipboard-manager": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.3.2.tgz", + "integrity": "sha512-CUlb5Hqi2oZbcZf4VUyUH53XWPPdtpw43EUpCza5HWZJwxEoDowFzNUDt1tRUXA8Uq+XPn17Ysfptip33sG4eQ==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, + "node_modules/@tauri-apps/plugin-dialog": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.5.0.tgz", + "integrity": "sha512-I0R0ygwRd9AN8Wj5GnzCogOlqu2+OWAtBd0zEC4+kQCI32fRowIyuhPCBoUv4h/lQt2bM39kHlxPHD5vDcFjiA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, + "node_modules/@tauri-apps/plugin-fs": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.4.5.tgz", + "integrity": "sha512-dVxWWGE6VrOxC7/jlhyE+ON/Cc2REJlM35R3PJX3UvFw2XwYhLGQVAIyrehenDdKjotipjYEVc4YjOl3qq90fA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, + "node_modules/@tauri-apps/plugin-http": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-http/-/plugin-http-2.5.5.tgz", + "integrity": "sha512-4hTS7AIBLmj8opDM3s8muEp7PBJQEiGDFvFF4fdMscQCOwhzXJf5hIZEHC867eH2Ck145Oce+H0AU0G/k9TbNg==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, + "node_modules/@tauri-apps/plugin-log": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-log/-/plugin-log-2.8.0.tgz", + "integrity": "sha512-a+7rOq3MJwpTOLLKbL8d0qGZ85hgHw5pNOWusA9o3cf7cEgtYHiGY/+O8fj8MvywQIGqFv0da2bYQDlrqLE7rw==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, + "node_modules/@tauri-apps/plugin-opener": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-opener/-/plugin-opener-2.5.3.tgz", + "integrity": "sha512-CCcUltXMOfUEArbf3db3kCE7Ggy1ExBEBl51Ko2ODJ6GDYHRp1nSNlQm5uNCFY5k7/ufaK5Ib3Du/Zir19IYQQ==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, + "node_modules/@tauri-apps/plugin-process": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-process/-/plugin-process-2.3.1.tgz", + "integrity": "sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, + "node_modules/@tauri-apps/plugin-shell": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.3.4.tgz", + "integrity": "sha512-ktsRWf8wHLD17aZEyqE8c5x98eNAuTizR1FSX475zQ4TxaiJnhwksLygQz+AGwckJL5bfEP13nWrlTNQJUpKpA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, + "node_modules/@tauri-apps/plugin-store": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-store/-/plugin-store-2.4.2.tgz", + "integrity": "sha512-0ClHS50Oq9HEvLPhNzTNFxbWVOqoAp3dRvtewQBeqfIQ0z5m3JRnOISIn2ZVPCrQC0MyGyhTS9DWhHjpigQE7A==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, + "node_modules/@tauri-apps/plugin-updater": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-updater/-/plugin-updater-2.9.0.tgz", + "integrity": "sha512-j++sgY8XpeDvzImTrzWA08OqqGqgkNyxczLD7FjNJJx/uXxMZFz5nDcfkyoI/rCjYuj2101Tci/r/HFmOmoxCg==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.6.0" + } + }, + "node_modules/@tauri-apps/plugin-window-state": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-window-state/-/plugin-window-state-2.4.1.tgz", + "integrity": "sha512-OuvdrzyY8Q5Dbzpj+GcrnV1iCeoZbcFdzMjanZMMcAEUNy/6PH5pxZPXpaZLOR7whlzXiuzx0L9EKZbH7zpdRw==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, + "node_modules/@tauri-store/shared": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tauri-store/shared/-/shared-0.10.2.tgz", + "integrity": "sha512-hnEBbe/m9UG5ATSBp4yJOosLkX5QLblVsGIvz7mtBAqmzeWFfjP4+8X/T81L+bCH6+ref/0vsR9Ekex138kAfg==", + "license": "MIT", + "dependencies": { + "@tauri-apps/api": "^2.8.0", + "es-toolkit": "^1.39.10" + }, + "funding": { + "url": "https://github.com/sponsors/ferreira-tb" + } + }, + "node_modules/@tauri-store/valtio": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@tauri-store/valtio/-/valtio-3.2.0.tgz", + "integrity": "sha512-q78gtEYyojwpYXXf5gJUmCpT56lcYOL4bvPEg9oPQ1HTdhKPjimEgD7W/2X113S/K5PJVvZyC10p4Ac5qvYZPw==", + "license": "MIT", + "dependencies": { + "@tauri-apps/api": "^2.8.0", + "@tauri-store/shared": "0.10.2", + "valtio": "^2.1.7" + }, + "funding": { + "url": "https://github.com/sponsors/ferreira-tb" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/react": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.1.tgz", + "integrity": "sha512-gr4KtAWqIOQoucWYD/f6ki+j5chXfcPc74Col/6poTyqTmn7zRmodWahWRCp8tYd+GMqBonw6hstNzqjbs6gjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tscanner/cli-darwin-arm64": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@tscanner/cli-darwin-arm64/-/cli-darwin-arm64-0.1.3.tgz", + "integrity": "sha512-JJP2EFXZv5SwvCw5mxw5OFCYZraa8ByZJmwamhVqhkS3HrjdKt/zODqb63vHoykfjMKU67DKsMw6grtxHFJVMw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@tscanner/cli-darwin-x64": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@tscanner/cli-darwin-x64/-/cli-darwin-x64-0.1.3.tgz", + "integrity": "sha512-jAbnSF9FskKrIKN5l3dz6x0b+TpYyIpqIvA86dyC6Chhd6GauXm2Kg6jGp6EIckMgZFUz9WVJ0J6glV4rx9HUw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@tscanner/cli-linux-arm64": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@tscanner/cli-linux-arm64/-/cli-linux-arm64-0.1.3.tgz", + "integrity": "sha512-D0pvrf3kNyoZX0CFx7IZCLHdd/+x2YasYrobjQV6s0p4Uh59fjGg/olu1dsHFPksrOqa/tQa6FanhOBLYzQq5g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@tscanner/cli-linux-x64": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@tscanner/cli-linux-x64/-/cli-linux-x64-0.1.3.tgz", + "integrity": "sha512-1aU9ks/YqUjDQVmpKvYBK/W06dMYHcS2Tv1nIZaehcSqvDSfxSyLojQliiNcnDDWRvTmvYeVljyCB4JhKi7Y+A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@tscanner/cli-win32-x64": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@tscanner/cli-win32-x64/-/cli-win32-x64-0.1.3.tgz", + "integrity": "sha512-ruhz30Iq7jd8YFYXrLZjfRv+TysEW/V2Qpt3APArT9asO2as2fqTAabFrowTtYq3MJyA4vz+DoSz51fEx2u7ng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/fs-extra": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", + "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/jsonfile": "*", + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/js-cookie": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz", + "integrity": "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==", + "license": "MIT" + }, + "node_modules/@types/jsonfile": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mocha": { + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.1.0.tgz", + "integrity": "sha512-t7frlewr6+cbx+9Ohpl0NOTKXZNV9xHRmNOvql47BFJKcEG1CxtxlPEEe+gR9uhVWM4DwhnvTF110mIL4yP9RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "node_modules/@types/plist": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.5.tgz", + "integrity": "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "xmlbuilder": ">=11.0.1" + } + }, + "node_modules/@types/react": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", + "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", + "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", + "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@uiw/react-json-view": { + "version": "2.0.0-alpha.40", + "resolved": "https://registry.npmjs.org/@uiw/react-json-view/-/react-json-view-2.0.0-alpha.40.tgz", + "integrity": "sha512-j8YgmUrLAokX0k3TJC1+Rae3G2XS2hTYA9SsnQVWeQpn/PiqxwG8mI4A5TCASUTltPtpM/9Yp+mRm7L4Wjy8rw==", + "license": "MIT", + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.10.0", + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.2.tgz", + "integrity": "sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.5", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.53", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@vitest/expect": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.16.tgz", + "integrity": "sha512-eshqULT2It7McaJkQGLkPjPjNph+uevROGuIMJdG3V+0BSR2w9u6J9Lwu+E8cK5TETlfou8GRijhafIMhXsimA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.0.16", + "@vitest/utils": "4.0.16", + "chai": "^6.2.1", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.16.tgz", + "integrity": "sha512-yb6k4AZxJTB+q9ycAvsoxGn+j/po0UaPgajllBgt1PzoMAAmJGYFdDk0uCcRcxb3BrME34I6u8gHZTQlkqSZpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.0.16", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.16.tgz", + "integrity": "sha512-eNCYNsSty9xJKi/UdVD8Ou16alu7AYiS2fCPRs0b1OdhJiV89buAXQLpTbe+X8V9L6qrs9CqyvU7OaAopJYPsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.16.tgz", + "integrity": "sha512-VWEDm5Wv9xEo80ctjORcTQRJ539EGPB3Pb9ApvVRAY1U/WkHXmmYISqU5E79uCwcW7xYUV38gwZD+RV755fu3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.0.16", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.16.tgz", + "integrity": "sha512-sf6NcrYhYBsSYefxnry+DR8n3UV4xWZwWxYbCJUt2YdvtqzSPR7VfGrY0zsv090DAbjFZsi7ZaMi1KnSRyK1XA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.16", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.16.tgz", + "integrity": "sha512-4jIOWjKP0ZUaEmJm00E0cOBLU+5WE0BpeNr3XN6TEF05ltro6NJqHWxXD0kA8/Zc8Nh23AT8WQxwNG+WeROupw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.16.tgz", + "integrity": "sha512-h8z9yYhV3e1LEfaQ3zdypIrnAg/9hguReGZoS7Gl0aBG5xgA410zBqECqmaF/+RkTggRsfnzc1XaAHA6bmUufA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.16", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@wdio/cli": { + "version": "9.23.2", + "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-9.23.2.tgz", + "integrity": "sha512-D6KZGomfNmjFhSWYdfR7Ojik5qWEpPoR4g5LQPzbFwiii/RkTudLcMFcCO6s7HTMLDQDWryOStV2KK6KqrIF8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/snapshot": "^2.1.1", + "@wdio/config": "9.23.2", + "@wdio/globals": "9.23.0", + "@wdio/logger": "9.18.0", + "@wdio/protocols": "9.23.2", + "@wdio/types": "9.23.2", + "@wdio/utils": "9.23.2", + "async-exit-hook": "^2.0.1", + "chalk": "^5.4.1", + "chokidar": "^4.0.0", + "create-wdio": "9.21.0", + "dotenv": "^17.2.0", + "import-meta-resolve": "^4.0.0", + "lodash.flattendeep": "^4.4.0", + "lodash.pickby": "^4.6.0", + "lodash.union": "^4.6.0", + "read-pkg-up": "^10.0.0", + "tsx": "^4.7.2", + "webdriverio": "9.23.2", + "yargs": "^17.7.2" + }, + "bin": { + "wdio": "bin/wdio.js" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/cli/node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@wdio/cli/node_modules/@vitest/snapshot": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", + "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@wdio/cli/node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@wdio/cli/node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@wdio/concise-reporter": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/@wdio/concise-reporter/-/concise-reporter-9.23.3.tgz", + "integrity": "sha512-RH+biPjpFkpDEsXImasPHxzY/bXsbNcpEzN2/w9q+0UQl8fWb8kyrR4BcyI+mCNR2hGwoCtBb1C3rMVqo/oVFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/reporter": "9.23.3", + "@wdio/types": "9.23.3", + "chalk": "^5.0.1", + "pretty-ms": "^9.0.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/concise-reporter/node_modules/@types/node": { + "version": "20.19.33", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.33.tgz", + "integrity": "sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@wdio/concise-reporter/node_modules/@wdio/reporter": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-9.23.3.tgz", + "integrity": "sha512-ObIvV+FydWGsvt7kqRBCq5ItAzWhWiWG63t5P0mQKrADCtuJMjrI0Y/IrYQzcv2KnYcmkMKOQLwXFWp8D+D/OA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0", + "@wdio/logger": "9.18.0", + "@wdio/types": "9.23.3", + "diff": "^8.0.2", + "object-inspect": "^1.12.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/concise-reporter/node_modules/@wdio/types": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-9.23.3.tgz", + "integrity": "sha512-Ufjh06DAD7cGTMORUkq5MTZLw1nAgBSr2y8OyiNNuAfPGCwHEU3EwEfhG/y0V7S7xT5pBxliqWi7AjRrCgGcIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/concise-reporter/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@wdio/config": { + "version": "9.23.2", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-9.23.2.tgz", + "integrity": "sha512-19Z+AIQ1NUpr6ncTumjSthm6A7c3DbaGTp+VCdcyN+vHYOK4WsWIomSk+uSbFosYFQVGRjCaHaeGSnC8GNPGYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/logger": "9.18.0", + "@wdio/types": "9.23.2", + "@wdio/utils": "9.23.2", + "deepmerge-ts": "^7.0.3", + "glob": "^10.2.2", + "import-meta-resolve": "^4.0.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/dot-reporter": { + "version": "9.23.2", + "resolved": "https://registry.npmjs.org/@wdio/dot-reporter/-/dot-reporter-9.23.2.tgz", + "integrity": "sha512-3+5y7P4GS7UTIgr6zPhxKHMmDSwiNjgdwnWIUYXr2eQLcpnPGhc9GL1IEDgQEAcziXG9BfaKzZQHi+vH89PR5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/reporter": "9.23.2", + "@wdio/types": "9.23.2", + "chalk": "^5.0.1" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/globals": { + "version": "9.23.0", + "resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-9.23.0.tgz", + "integrity": "sha512-OmwPKV8c5ecLqo+EkytN7oUeYfNmRI4uOXGIR1ybP7AK5Zz+l9R0dGfoadEuwi1aZXAL0vwuhtq3p0OL3dfqHQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.20.0" + }, + "peerDependencies": { + "expect-webdriverio": "^5.3.4", + "webdriverio": "^9.0.0" + }, + "peerDependenciesMeta": { + "expect-webdriverio": { + "optional": false + }, + "webdriverio": { + "optional": false + } + } + }, + "node_modules/@wdio/image-comparison-core": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@wdio/image-comparison-core/-/image-comparison-core-1.1.2.tgz", + "integrity": "sha512-Wvm4iGwONoWlcw7xMGl4UxNYj6aqqrQJXMAJlNik4bpubiGKIVa0NRG05kRVqn8UvOwS1CHfd/9xdXw5a+1DAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/logger": "^9.18.0", + "@wdio/types": "^9.20.0", + "jimp": "^1.6.0" + } + }, + "node_modules/@wdio/local-runner": { + "version": "9.23.2", + "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-9.23.2.tgz", + "integrity": "sha512-tS8l2iaQc5aQav2LYYXx296F9KpdrU4/dmw5t9n9baXgdu8CKyGEd9orhTFQ7fYR55wFJ/85toQNOvIQHtIZrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0", + "@wdio/logger": "9.18.0", + "@wdio/repl": "9.16.2", + "@wdio/runner": "9.23.2", + "@wdio/types": "9.23.2", + "@wdio/xvfb": "9.23.2", + "exit-hook": "^4.0.0", + "expect-webdriverio": "^5.3.4", + "split2": "^4.1.0", + "stream-buffers": "^3.0.2" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/local-runner/node_modules/@types/node": { + "version": "20.19.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", + "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@wdio/local-runner/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@wdio/logger": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-9.18.0.tgz", + "integrity": "sha512-HdzDrRs+ywAqbXGKqe1i/bLtCv47plz4TvsHFH3j729OooT5VH38ctFn5aLXgECmiAKDkmH/A6kOq2Zh5DIxww==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.1.2", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "safe-regex2": "^5.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/logger/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@wdio/logger/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@wdio/mocha-framework": { + "version": "9.23.2", + "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-9.23.2.tgz", + "integrity": "sha512-V1wx8A8vMAExricXlCv0jzQOJTAgvgM/646QFr65U028+lqAGU23EkFp5H1WJj9I9jCHJTfMkxtUrPv0v7y63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mocha": "^10.0.6", + "@types/node": "^20.11.28", + "@wdio/logger": "9.18.0", + "@wdio/types": "9.23.2", + "@wdio/utils": "9.23.2", + "mocha": "^10.3.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/mocha-framework/node_modules/@types/node": { + "version": "20.19.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", + "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@wdio/mocha-framework/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@wdio/protocols": { + "version": "9.23.2", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-9.23.2.tgz", + "integrity": "sha512-pmCYOYI2N89QCC8IaiHwaWyP0mR8T1iKkEGpoTq2XVihp7VK/lfPvieyeZT5/e28MadYLJsDQ603pbu5J1NRDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@wdio/repl": { + "version": "9.16.2", + "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-9.16.2.tgz", + "integrity": "sha512-FLTF0VL6+o5BSTCO7yLSXocm3kUnu31zYwzdsz4n9s5YWt83sCtzGZlZpt7TaTzb3jVUfxuHNQDTb8UMkCu0lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/repl/node_modules/@types/node": { + "version": "20.19.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", + "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@wdio/repl/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@wdio/reporter": { + "version": "9.23.2", + "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-9.23.2.tgz", + "integrity": "sha512-+L1knNyQl+Xs+/VkM5JOX/HINe+g3ZVWt0Scsb9DcOCll8xG8jisxArutZLo+UuV6Bm1BzqfJJb/+ae04EuRAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0", + "@wdio/logger": "9.18.0", + "@wdio/types": "9.23.2", + "diff": "^8.0.2", + "object-inspect": "^1.12.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/reporter/node_modules/@types/node": { + "version": "20.19.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", + "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@wdio/reporter/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@wdio/runner": { + "version": "9.23.2", + "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-9.23.2.tgz", + "integrity": "sha512-joFHYO4jnDixsBRM6tJ/nVeH15UNIthIAp2Yky+yPsh1HkM+x9gZG5ZT0TnSXw/E2tQRb2yO3d+jsEHedsE0jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.11.28", + "@wdio/config": "9.23.2", + "@wdio/dot-reporter": "9.23.2", + "@wdio/globals": "9.23.0", + "@wdio/logger": "9.18.0", + "@wdio/types": "9.23.2", + "@wdio/utils": "9.23.2", + "deepmerge-ts": "^7.0.3", + "webdriver": "9.23.2", + "webdriverio": "9.23.2" + }, + "engines": { + "node": ">=18.20.0" + }, + "peerDependencies": { + "expect-webdriverio": "^5.3.4", + "webdriverio": "^9.0.0" + }, + "peerDependenciesMeta": { + "expect-webdriverio": { + "optional": false + }, + "webdriverio": { + "optional": false + } + } + }, + "node_modules/@wdio/runner/node_modules/@types/node": { + "version": "20.19.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", + "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@wdio/runner/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@wdio/spec-reporter": { + "version": "9.23.2", + "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-9.23.2.tgz", + "integrity": "sha512-9uwbrOFgPuF5NqixiU9db46HNJERN04beefNh4f4usJSP41Mbru0isps64qKkWSpFJhYl1LZrSGELezxH9bZ6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/reporter": "9.23.2", + "@wdio/types": "9.23.2", + "chalk": "^5.1.2", + "easy-table": "^1.2.0", + "pretty-ms": "^9.0.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/types": { + "version": "9.23.2", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-9.23.2.tgz", + "integrity": "sha512-ryfrERGsNp+aCcrTE1rFU6cbmDj8GHZ04R9k52KNt2u1a6bv3Eh5A/cUA0hXuMdEUfsc8ePLYdwQyOLFydZ0ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/types/node_modules/@types/node": { + "version": "20.19.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", + "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@wdio/types/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@wdio/utils": { + "version": "9.23.2", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-9.23.2.tgz", + "integrity": "sha512-+QfgXUWeA940AXT5l5UlrBKoHBk9GLSQE3BA+7ra1zWuFvv6SHG6M2mwplcPlOlymJMqXy8e7ZgLEoLkXuvC1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@puppeteer/browsers": "^2.2.0", + "@wdio/logger": "9.18.0", + "@wdio/types": "9.23.2", + "decamelize": "^6.0.0", + "deepmerge-ts": "^7.0.3", + "edgedriver": "^6.1.2", + "geckodriver": "^6.1.0", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.2.24", + "mitt": "^3.0.1", + "safaridriver": "^1.0.0", + "split2": "^4.2.0", + "wait-port": "^1.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/visual-service": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@wdio/visual-service/-/visual-service-9.1.2.tgz", + "integrity": "sha512-FYyv4kXWqm4LmX62VwC/uR0khRFlSmvUVDyyKWLiIMdzQGiXLYOotxGs5E/wQcHHZPPv+/1wWFJLoE3w1rWt+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/globals": "^9.23.0", + "@wdio/image-comparison-core": "1.1.2", + "@wdio/logger": "^9.18.0", + "@wdio/types": "^9.20.0", + "expect-webdriverio": "^5.6.1" + } + }, + "node_modules/@wdio/xvfb": { + "version": "9.23.2", + "resolved": "https://registry.npmjs.org/@wdio/xvfb/-/xvfb-9.23.2.tgz", + "integrity": "sha512-48KiET6Phmu7SIQgpTXSn7eRJK6MJdTKib2MLT5WTKIJ+t0OyGKl/ESXi6tzFrGFPzLkvogSIRy8O2sKM0PcbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/logger": "9.18.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.8.tgz", + "integrity": "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14.6" + } + }, + "node_modules/@zag-js/accordion": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/accordion/-/accordion-1.31.1.tgz", + "integrity": "sha512-3sGi4EZpGBz/O1IVkk9dzzWzP5vVVOj4Li6C+jHOnrgaWPouA/mBTP5L9HEL8qtFsECFZwpNo486eqiCmeHoGw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/anatomy": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/anatomy/-/anatomy-1.31.1.tgz", + "integrity": "sha512-BhIhf3Q0tRA0Jugd7AJfUBzeAb/iATBsw7KyYThMGcPWmrWssL7KWr5AB6RufzGKU7+DCb1QEhlqd4NSOJaYxQ==", + "license": "MIT" + }, + "node_modules/@zag-js/angle-slider": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/angle-slider/-/angle-slider-1.31.1.tgz", + "integrity": "sha512-SfWrgnM0zMLX82rsIJOqWk430UnPA17UFGcDqMDRwXy1Wx4yptmx0aFAsSXnRnw4Ee7WaulF2RWBli6O6iYRCA==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/rect-utils": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/aria-hidden": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/aria-hidden/-/aria-hidden-1.31.1.tgz", + "integrity": "sha512-SoNt4S2LkHNWPglQczWN0E5vAV15MT1GoK9MksZzbkMhl+pkDTdLytpXsQ1IgalC1YUng0XNps/Wt6P3uDuzTA==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.31.1" + } + }, + "node_modules/@zag-js/async-list": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/async-list/-/async-list-1.31.1.tgz", + "integrity": "sha512-BDZEmr4KKh3JASgkXouOwoTWRS1UPE3gdZYZ7Sk7SJ1i8+Pk6zUQ4FnxaoF/cSAdCXyjSSr92Kns2bTk/QuNkQ==", + "license": "MIT", + "dependencies": { + "@zag-js/core": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/auto-resize": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/auto-resize/-/auto-resize-1.31.1.tgz", + "integrity": "sha512-qzWHibjBekSmFweG+EWY8g0lRzKtok7o9XtQ+JFlOu3s6x4D02z2YDzjDdfSLmS7j0NxISnwQkinWiDAZEYHog==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.31.1" + } + }, + "node_modules/@zag-js/avatar": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/avatar/-/avatar-1.31.1.tgz", + "integrity": "sha512-Grosi2hRn4wfDYlPd8l+d4GCIFMsoj6ZFqii+1k14AqTDiCUJ/J0jCvOrRHkvkpEqektjuSD7e/GCX+yawqkuQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/bottom-sheet": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/bottom-sheet/-/bottom-sheet-1.31.1.tgz", + "integrity": "sha512-ZBbIpYyZX2zQeqW36aODVi9/I4J3zS1XmIHUjeXmfmf6TlQUA1ydgYl7ipREfmCzNWX2LEA5ZnPJQw0UBcrB8w==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/aria-hidden": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dismissable": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/focus-trap": "1.31.1", + "@zag-js/remove-scroll": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/carousel": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/carousel/-/carousel-1.31.1.tgz", + "integrity": "sha512-228Ol86G/lg8crcomy5cALkUYdOHCHcvJnSOQzeUj80JNjlELzrjBpaAj4lx8dZocfwou2Sg4NyZJ+mISSc+Dg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/scroll-snap": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/checkbox": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/checkbox/-/checkbox-1.31.1.tgz", + "integrity": "sha512-oLS8bqhimckLl6coCNmKPPUmB8wIbVhtkpLwLPLgz4vhhUe7gnpB5dea14Ow2JTBnmug8bMh/bJDtuPa9qQuTw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/focus-visible": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/clipboard": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/clipboard/-/clipboard-1.31.1.tgz", + "integrity": "sha512-pv/gOmD9DMg+YmSMjahyd5oSp7/v9K0uQ3att6fPeaNMjB42b3tnY1S1GNVy5Ltf/qHDab6WVwlEN+1zKHXaYw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/collapsible": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/collapsible/-/collapsible-1.31.1.tgz", + "integrity": "sha512-eCC5G6bBZUwF8z2XULQXUNRxqte9I2Sv+WJ2brycPn1a68uYD76RzFBmLQ2er95VbshUdeo8nRuX8MooAFuYzg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/collection": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/collection/-/collection-1.31.1.tgz", + "integrity": "sha512-ecpfyfCj8Y0/GUPuHYsLxexIrx10VuR3Wd0H+lamcki3lYgQxZrpLRFMwgTqmI/m7t3zhm5QeEvMUJ1H14YMLA==", + "license": "MIT", + "dependencies": { + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/color-picker": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/color-picker/-/color-picker-1.31.1.tgz", + "integrity": "sha512-AWNZth49iEDxqh1DBZNSKpfEM/FF+MjL5bgUHVctnHdkpFsZLynJorWQQ4hNXNDFEc/I5w10KSxVCcO6tsPGFw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/color-utils": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dismissable": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/popper": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/color-utils": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/color-utils/-/color-utils-1.31.1.tgz", + "integrity": "sha512-HdjTRU8C0tO6hK+PBVlu8iQH1MJaAnJAEdq2FcD97mq0PiPhrSj6iOftnrvPsE4CRieVFjnJWOvaubWFc4VmHA==", + "license": "MIT", + "dependencies": { + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/combobox": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/combobox/-/combobox-1.31.1.tgz", + "integrity": "sha512-IT0getSAGzngdRL20iX/iAh2d7DzVoMDDppOsOFBG2owKAgLpj8uLvUhy+lcrm6N8yxYOya89D6Aef7V5KdwlQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/aria-hidden": "1.31.1", + "@zag-js/collection": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dismissable": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/popper": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/core": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/core/-/core-1.31.1.tgz", + "integrity": "sha512-RaMJeqtjxG6k7iFD3WQnlyFJVT3yfQN+pJygAHH37GsMtiNzQQJOoesjb0LV9T27jwMXeNUzrh3MSDr1/0yVcQ==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/date-picker": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/date-picker/-/date-picker-1.31.1.tgz", + "integrity": "sha512-AOWN/IskGidVQt5g+uE9cILqJBTclE6OG1GC9WSWuyP/y4F+PdP/781SgYpYCZg/6pMGbL01PFKKb7xOOCeZAg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/date-utils": "1.31.1", + "@zag-js/dismissable": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/live-region": "1.31.1", + "@zag-js/popper": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + }, + "peerDependencies": { + "@internationalized/date": ">=3.0.0" + } + }, + "node_modules/@zag-js/date-utils": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/date-utils/-/date-utils-1.31.1.tgz", + "integrity": "sha512-+Aq9g/rqLeiRmnazgdZMc59gAxqxbw3GGy8AngrtNipgRtMhPlzGa3S4Qsq1yau6OKaHZ13uckUS+MhLNbBY+Q==", + "license": "MIT", + "peerDependencies": { + "@internationalized/date": ">=3.0.0" + } + }, + "node_modules/@zag-js/dialog": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/dialog/-/dialog-1.31.1.tgz", + "integrity": "sha512-iaWlYQ6TYoVjM/X5+UZVZzKiMboE50GnEzGUpbhbeRNRiLqSu5dODSFzior1G4kde/ns5eN+BTf/Tm6AT4N2og==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/aria-hidden": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dismissable": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/focus-trap": "1.31.1", + "@zag-js/remove-scroll": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/dismissable": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/dismissable/-/dismissable-1.31.1.tgz", + "integrity": "sha512-jCdJwQmEkG6PlrN13fUk2l7ZclSu54FZwmT4xOtQpEbaiAiESm5KI5oyFh5jDPY47Goa28UJkEjWXVgKXKWb0g==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.31.1", + "@zag-js/interact-outside": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/dom-query": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/dom-query/-/dom-query-1.31.1.tgz", + "integrity": "sha512-2tCZLwSfoXm62gwl0neiAN6u5VnzUhy5wHtKbX+klqGFatnca3Bm++H9+4PHMrwUWRbPg3H5N151lKFEOQhBfQ==", + "license": "MIT", + "dependencies": { + "@zag-js/types": "1.31.1" + } + }, + "node_modules/@zag-js/editable": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/editable/-/editable-1.31.1.tgz", + "integrity": "sha512-JMICHw4/x0YqDy/n+I+TeaXlFbTA0j9w3UqOWMwUFQ+dAsq4JLXeqZDXu19MQN6yaTFdOpG1EFw4FEVTsu+d3Q==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/interact-outside": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/file-upload": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/file-upload/-/file-upload-1.31.1.tgz", + "integrity": "sha512-cp7qMiXKrIcTfDamOz9wlnJLeBF8gucTI7Y+iKaP+hiIW+OG254GElfQiqXNDad3HUmD+Dt8Tx6uAzL/mw3sbQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/file-utils": "1.31.1", + "@zag-js/i18n-utils": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/file-utils": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/file-utils/-/file-utils-1.31.1.tgz", + "integrity": "sha512-MDDz52IdPh/mPUYrqUXvh7qDckJHs+mt5gjfx0N89qh2JNXuRU14zPotOKTzIKM4o+HFZkAT6BAfMpr9CX/0ug==", + "license": "MIT", + "dependencies": { + "@zag-js/i18n-utils": "1.31.1" + } + }, + "node_modules/@zag-js/floating-panel": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/floating-panel/-/floating-panel-1.31.1.tgz", + "integrity": "sha512-Pjgd/wjdglZ90dtq/LC4o5sc6w0m+RehhPmJcIzq9T+E/Xrb6qrhf06QhxB9LwSj4DG/gIv87gmD2qF1VH7cRQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/popper": "1.31.1", + "@zag-js/rect-utils": "1.31.1", + "@zag-js/store": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/focus-trap": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/focus-trap/-/focus-trap-1.31.1.tgz", + "integrity": "sha512-omgUhAz1r81pYAujqYIIavdTKJzDRExioSiqhnx/xq10a6Q/xavMFflq8w7edMc9JHkTOnr9E5qh9abCVJjhpQ==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.31.1" + } + }, + "node_modules/@zag-js/focus-visible": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-1.31.1.tgz", + "integrity": "sha512-GC59A3yd7tj8aKhzvhrM+CEZZraXm5y/SpfIjz1J7kGV6eeXbUtjkbe75g99Ve8iJYfQVQlAj2GyN3oniHc5Zw==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.31.1" + } + }, + "node_modules/@zag-js/highlight-word": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/highlight-word/-/highlight-word-1.31.1.tgz", + "integrity": "sha512-nQw7t8LgWXW+6Z5E/p6T+OST0DDXp35mrFCzrkJL54aVTZ3GuLyIP2p0/HGQr2hE/KKLbZEs5i6UcXF84tiI4g==", + "license": "MIT" + }, + "node_modules/@zag-js/hover-card": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/hover-card/-/hover-card-1.31.1.tgz", + "integrity": "sha512-R74kz2wPgGwB3jKQeD91kdtlvVKpffWBJHqw8yCBd95GXGVmhym+BPoCToJzcqiemP8+0EtSuVPU9IHaSuJnSg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dismissable": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/popper": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/i18n-utils": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/i18n-utils/-/i18n-utils-1.31.1.tgz", + "integrity": "sha512-SARkFuo1+Q0WcNv4jqvxp5hjCOqu/gBa7p6BTh7v5Bo00QhKRM/bCvVt0EB6V+h2oejrZfkwZ0MwbpQiL6L2aQ==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.31.1" + } + }, + "node_modules/@zag-js/image-cropper": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/image-cropper/-/image-cropper-1.31.1.tgz", + "integrity": "sha512-hFuy4I3jIJ/iyJsnfbLX1l/cJtN42j7lwhw8TeWVX8Y+hHxFPMSKx7AQirt/hALUbyy7QsQgAd5IslpsYq1Nlg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/interact-outside": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/interact-outside/-/interact-outside-1.31.1.tgz", + "integrity": "sha512-oxBAlBqcatlxGUmhwUCRYTADIBrVoyxM1YrFzR1R8jhvVR/QCaxoLAyKwcA3mWXlZ8+NlXb7n5ELE11BZb/rEg==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/json-tree-utils": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/json-tree-utils/-/json-tree-utils-1.31.1.tgz", + "integrity": "sha512-wrNek2UBE69FWpo2f0E2MxiboBS+Uop79LeQU2jNDujA1o3x6b1Lp2r7Fl1sfnUWMdKVVQb44oqfIj2g3CTEmQ==", + "license": "MIT" + }, + "node_modules/@zag-js/listbox": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/listbox/-/listbox-1.31.1.tgz", + "integrity": "sha512-LcTIr4I9eN4MR1nSRfQfseWgj4ybOXXAY2o5dBpEBL67dnCSX3swNb/4LQO+ebj077BViQb66pBb1KSoeHGkEQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/collection": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/focus-visible": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/live-region": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/live-region/-/live-region-1.31.1.tgz", + "integrity": "sha512-RBx8jk1dgvkEUuFs77SBZn0WwvEkeZgVawVu6XUAy4ENfhP0D/qkvwNk+Els8InKmr1gWKajD7sh+g8M40Ex6A==", + "license": "MIT" + }, + "node_modules/@zag-js/marquee": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/marquee/-/marquee-1.31.1.tgz", + "integrity": "sha512-Rt7+zy7CDOxXm0PqaTcmuWxcrZOPOpZY4T6IxOZk4ZcOXJQ2v7CkF3EK0pdI9PyI6Zpk/YIwQkENjidT55db0A==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/menu": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/menu/-/menu-1.31.1.tgz", + "integrity": "sha512-eJPRM8tlauRTsAoJXchDBzMzL2RhXYSHmHak2IJCDMApCV51p0MqGYP8Er3DbMSQTPUFuTq779uUIarDqW+zmA==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dismissable": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/popper": "1.31.1", + "@zag-js/rect-utils": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/navigation-menu": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/navigation-menu/-/navigation-menu-1.31.1.tgz", + "integrity": "sha512-xS4aynqmB9NYicPbEW8lPPakAfDfSgIDL1pRVSD6f1+VXkHD6LgNn6jUNDNbFt65mGhLpA2IczbvLCxv0g/ISQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dismissable": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/number-input": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/number-input/-/number-input-1.31.1.tgz", + "integrity": "sha512-vn+BXEZ2/g2CMIFFyjjye/SbCeW3I/rlszL8EyBmhMcuA1l51OX2WKry6HeQNiU41uMyFg2rb1pb5KVw1gJsCg==", + "license": "MIT", + "dependencies": { + "@internationalized/number": "3.6.5", + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/pagination": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/pagination/-/pagination-1.31.1.tgz", + "integrity": "sha512-icW6FNzIKNz7iXU+prlQWpMFJedDrhmCKzzI39SY+dv5g1Gnrlc0b44PxvNl5PWFLSkB5KBT/R1WCqd8Kh4cCA==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/password-input": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/password-input/-/password-input-1.31.1.tgz", + "integrity": "sha512-AivOeNO14a39xhxVMB2TVmIjmQ89OwVz0+2IjX3JjLS2Pmia+gg9xnVd2kBIcKfnqUN4MBnzmk7t46YWJMQVVQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/pin-input": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/pin-input/-/pin-input-1.31.1.tgz", + "integrity": "sha512-k3ESoX5ve5sbWBLTCPYAzgLjRU7mVNEUiqAOhRgazOcBGV5wjGh398zWb1jr0FMxPnoAMrXDN/CQwJTmJcMKrg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/popover": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/popover/-/popover-1.31.1.tgz", + "integrity": "sha512-uCFJP3DFBkEBAre6lgGLw2xWS2ZIuT/DLeajIXb+8BmC9KCF0wY4c9qojx9F3rGMJQxcGl+WUoXENkOvkTaVhQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/aria-hidden": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dismissable": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/focus-trap": "1.31.1", + "@zag-js/popper": "1.31.1", + "@zag-js/remove-scroll": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/popper": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/popper/-/popper-1.31.1.tgz", + "integrity": "sha512-wLXcEqzn9MK1rGbsgnDH26o5ZWqR4oeb6ZepKKy0gcuJl/1S5/dr1VBvxJNMZlf9d6etvYklG5LRnIVkXCbrjA==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "1.7.4", + "@zag-js/dom-query": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/presence": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/presence/-/presence-1.31.1.tgz", + "integrity": "sha512-tv+WsBnA0abIlDuEfZMh0lRPF4cMs6kWJosNkGBwzeXnGds+KXjzpL2KDtwDgbJgN3sI0xHPMYjRy2v3ZamcDA==", + "license": "MIT", + "dependencies": { + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1" + } + }, + "node_modules/@zag-js/progress": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/progress/-/progress-1.31.1.tgz", + "integrity": "sha512-f9lIDHCRcFAG14LVEKOAPTdqPzphwIIraC6fTr9AwmNlYI6/qFDkz3jOlYVSyk5VsJAIFM/777x/CdqjliiOqg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/qr-code": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/qr-code/-/qr-code-1.31.1.tgz", + "integrity": "sha512-Rxh+HF12SgUp5rvTelp1qyLK3xkn37h2fT/L4eBQ0f8OUEo8wfowEbs36+1i61d6UuH7PJt4q/07eIf6vNVevA==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1", + "proxy-memoize": "3.0.1", + "uqr": "0.1.2" + } + }, + "node_modules/@zag-js/radio-group": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/radio-group/-/radio-group-1.31.1.tgz", + "integrity": "sha512-OfKIdEtSG0EuHM+cFVqcR+04yzZmcDRgG3j0QhoJsyS1my63ZHbwC2HNAtfPFh4U4sJx9yUexwSzPGZ6pOzIdw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/focus-visible": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/rating-group": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/rating-group/-/rating-group-1.31.1.tgz", + "integrity": "sha512-BkQUglKm4a+KXYPACYvIvBJSuEyzV0YQqjjiucwJ5UiOlK72C66VBvyGN+DqJRDnkU1K5azt6E1Ja5ANk3fgsg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/react": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/react/-/react-1.31.1.tgz", + "integrity": "sha512-a7uYH+tcw1UYbcovyVBzlh6X8KztK/b1+s8sMs4Srhd24M+hZMetV94Z0bM1Km5aNAnoS4gkH3gtJjH0OphquQ==", + "license": "MIT", + "dependencies": { + "@zag-js/core": "1.31.1", + "@zag-js/store": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + }, + "peerDependencies": { + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + } + }, + "node_modules/@zag-js/rect-utils": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/rect-utils/-/rect-utils-1.31.1.tgz", + "integrity": "sha512-lBFheAnz8+3aGDFjqlkw0Iew/F03lFjiIf26hkkcFSZu0ltNZUMG/X3XLHUnHxdfbdBguc8ons6mr2MkVvisng==", + "license": "MIT" + }, + "node_modules/@zag-js/remove-scroll": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/remove-scroll/-/remove-scroll-1.31.1.tgz", + "integrity": "sha512-gVVJuFKaCjo652RmajYmkjXKgjJWLQ5ZhZLTaLUKWM1mAarvlqnLui8jrHEHLxqpfsjQylfdhJKkWmyF8NAgTA==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.31.1" + } + }, + "node_modules/@zag-js/scroll-area": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/scroll-area/-/scroll-area-1.31.1.tgz", + "integrity": "sha512-GBXd1K3U0AHwWlJaqAMKQMZyeoxuBO6XYrVgdvzgiftQbJrZs5fuYOFyDvPLDWHTLYxaHso44/f+9EmAUAiytw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/scroll-snap": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/scroll-snap/-/scroll-snap-1.31.1.tgz", + "integrity": "sha512-YWsfhcQqiffu2X9HuB0fMnEQAu6rEOfGcvQYinvB6pjWPOvIJGxGMi/dYyy21XQDNJ9K1IcWRIo/yuaajoJyQQ==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.31.1" + } + }, + "node_modules/@zag-js/select": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/select/-/select-1.31.1.tgz", + "integrity": "sha512-vKWb8BiRY83Y3HkDNnimf6cr1yvzJh1HwZlzXFz0y47zEvlikQaf+r96obR78RgTtMjNTTV15tTXdc1/WFoYkw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/collection": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dismissable": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/popper": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/signature-pad": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/signature-pad/-/signature-pad-1.31.1.tgz", + "integrity": "sha512-bz3WtLuIZoLrJDKcdS7fPAdD/Qi9wKiKACl5cu+ftv9zg8w+qqYNLtjH9HxeUFbCtQRKqcdXjO/UZ8iL07hgsQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1", + "perfect-freehand": "^1.2.2" + } + }, + "node_modules/@zag-js/slider": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/slider/-/slider-1.31.1.tgz", + "integrity": "sha512-FILbLTMd3BnyclZ28+ippfyqzYPGK60qZapxtTERmWDC75Okf8AFnTCQf84Y8jRmBKCS1yhjF+IOtkFAENeB6w==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/splitter": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/splitter/-/splitter-1.31.1.tgz", + "integrity": "sha512-7SGBT2/xKsOzeSQEg+Otn1XV3RHrAz3jTySjBRKoEmdxubhfREqbKotbGVG65aTve11fQnmJ3Oyt3GJOeraxLA==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/steps": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/steps/-/steps-1.31.1.tgz", + "integrity": "sha512-KsBH38V3tH9/q8CDgx4sUSXLYwFdcp1crZy8hTIcN0RUiZ55PmqYKkN2znzBjTbaCW9yhP8kXsbuo2s8OIU5lQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/store": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/store/-/store-1.31.1.tgz", + "integrity": "sha512-d5ZTRciTuXOGQ3nML15kQLaTiR1wJPxT1Fu1nN659X6Rl8DPtubYaRCZ3RCk9Kyiyg2z5HxeVqDswaDvGbM9Rg==", + "license": "MIT", + "dependencies": { + "proxy-compare": "3.0.1" + } + }, + "node_modules/@zag-js/switch": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/switch/-/switch-1.31.1.tgz", + "integrity": "sha512-Jii3OSqSa9sQux+hvSRvp9dirzUF09+PAjrLjCQs+BT08EZ0XqeGvVzM0Wqf9LFy07HdLZntai3IUaXLF6byBw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/focus-visible": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/tabs": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/tabs/-/tabs-1.31.1.tgz", + "integrity": "sha512-QBq4ngpBNMNEI7Wuaq8llwHOqgcVbNHHEDC5zHg60Bf7MY5ltP8wSq6Kldu0zZRVwrLzanYoMELDUyf9H0vtnw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/tags-input": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/tags-input/-/tags-input-1.31.1.tgz", + "integrity": "sha512-V4lJe/aMIs7WVoXYfszU6E3iARLLRQFMiycu76/slb8NWJiLrkSIaMQ4FAe2pqkodgCWXA83tuaeAZRq7ouTFg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/auto-resize": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/interact-outside": "1.31.1", + "@zag-js/live-region": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/timer": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/timer/-/timer-1.31.1.tgz", + "integrity": "sha512-bXfeSbneWGOBKlD5dYq06T8CSY9Ky+qb1yIfJAFsRF4n34mpUYRdtfwpNQYyddGpkLD7oH4VibajeZXB7HaL0g==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/toast": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/toast/-/toast-1.31.1.tgz", + "integrity": "sha512-MueHEei9ol3H6tWBruLxF7yEUpV3vsJ8brTQVRRtPr/6pqBs5kGzfL4YskhQ2tiwO6egay8YrkbaS3xJfpKt4w==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dismissable": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/toggle": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/toggle/-/toggle-1.31.1.tgz", + "integrity": "sha512-HbFBuGfdyYkNvOp3cEB8Civ4E92finT4u3e4LKysB4/LboqKA0cJvFhSnHyThbROONTx06W/3CxwoSFR4o8IhA==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/toggle-group": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/toggle-group/-/toggle-group-1.31.1.tgz", + "integrity": "sha512-Mojc7mex01/gvwXfrUIIThzT7HOktZoMge9rrb6+P7rQX7ulyNXYPjQrW2tay+t54GOJ3xODo9dU7PpRzXeHbw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/tooltip": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/tooltip/-/tooltip-1.31.1.tgz", + "integrity": "sha512-pWEU5XhEPpnyl2VLrGJlyjj7+p+X0UX3Fld+WGhc/hCaWiuW2ZzD/ewDRhSOZu4/TzAO3axrPqG1YhW4fhogKQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/focus-visible": "1.31.1", + "@zag-js/popper": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/tour": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/tour/-/tour-1.31.1.tgz", + "integrity": "sha512-ZmcAevXxoENHmHG0xwdIt1oCLe2/DW1CEBFPr7YuGKc+FU3QbBVZMzcBHrJCe0nkKXhUKzHOHM78bOHD/gM76w==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dismissable": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/focus-trap": "1.31.1", + "@zag-js/interact-outside": "1.31.1", + "@zag-js/popper": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/tree-view": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/tree-view/-/tree-view-1.31.1.tgz", + "integrity": "sha512-Q+VSQz7X1XR8gT7ICWXlQOJIvzTWw/9BlF7B073UpEgAKRFlD11FmERka5y/BYqj8uE0vazcbSEA3Vc2dgCMJA==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.31.1", + "@zag-js/collection": "1.31.1", + "@zag-js/core": "1.31.1", + "@zag-js/dom-query": "1.31.1", + "@zag-js/types": "1.31.1", + "@zag-js/utils": "1.31.1" + } + }, + "node_modules/@zag-js/types": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/types/-/types-1.31.1.tgz", + "integrity": "sha512-mKw5DoeBjFykfUHv3ifCRjcogFTqp0aCCsmqQMfnf+J/mg2aXpAx76AXT1PYXAVVhxdP6qGXNd0mOQZDVrIlSQ==", + "license": "MIT", + "dependencies": { + "csstype": "3.2.3" + } + }, + "node_modules/@zag-js/utils": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/utils/-/utils-1.31.1.tgz", + "integrity": "sha512-KLm0pmOtf4ydALbaVLboL7W98TDVxwVVLvSuvtRgV53XTjlsVopTRA5/Xmzq2NhWujDZAXv7bRV603NDgDcjSw==", + "license": "MIT" + }, + "node_modules/@zip.js/zip.js": { + "version": "2.8.16", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.8.16.tgz", + "integrity": "sha512-kCjaXh50GCf9afcof6ekjXPKR//rBVIxNHJLSUaM3VAET2F0+hymgrK1GpInRIIFUpt+wsnUfgx2+bbrmc+7Tw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "bun": ">=0.7.0", + "deno": ">=1.0.0", + "node": ">=18.0.0" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ahooks": { + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/ahooks/-/ahooks-3.9.6.tgz", + "integrity": "sha512-Mr7f05swd5SmKlR9SZo5U6M0LsL4ErweLzpdgXjA1JPmnZ78Vr6wzx0jUtvoxrcqGKYnX0Yjc02iEASVxHFPjQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.21.0", + "@types/js-cookie": "^3.0.6", + "dayjs": "^1.9.1", + "intersection-observer": "^0.12.0", + "js-cookie": "^3.0.5", + "lodash": "^4.17.21", + "react-fast-compare": "^3.2.2", + "resize-observer-polyfill": "^1.5.1", + "screenfull": "^5.0.0", + "tslib": "^2.4.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-base": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", + "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/archiver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.2", + "async": "^3.2.4", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^6.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^10.0.0", + "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-exit-hook": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/async-mutex": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.5.0.tgz", + "integrity": "sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/await-to-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/await-to-js/-/await-to-js-3.0.0.tgz", + "integrity": "sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/b4a": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-react-compiler": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz", + "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/bare-events": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", + "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } + }, + "node_modules/bare-fs": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.3.tgz", + "integrity": "sha512-9+kwVx8QYvt3hPWnmb19tPnh38c6Nihz8Lx3t0g9+4GoIf3/fTgYwM4Z6NxgI+B9elLQA7mLE9PpqcWtOMRDiQ==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4", + "bare-url": "^2.2.2", + "fast-fifo": "^1.3.2" + }, + "engines": { + "bare": ">=1.16.0" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } + } + }, + "node_modules/bare-os": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", + "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "bare": ">=1.14.0" + } + }, + "node_modules/bare-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-os": "^3.0.1" + } + }, + "node_modules/bare-stream": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz", + "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "streamx": "^2.21.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-events": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-events": { + "optional": true + } + } + }, + "node_modules/bare-url": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz", + "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-path": "^3.0.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.14", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.14.tgz", + "integrity": "sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/basic-ftp": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.1.0.tgz", + "integrity": "sha512-RkaJzeJKDbaDWTIPiJwubyljaEPwpVWkm9Rt5h9Nd6h7tEXTJ3VB4qxdZBioV7JO5yLUaOKwz7vDOzlncUsegw==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 10" + "node": ">=10.0.0" + } + }, + "node_modules/before-after-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", + "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/tauri" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bmp-ts": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bmp-ts/-/bmp-ts-1.0.9.tgz", + "integrity": "sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw==", + "dev": true, + "license": "MIT" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" }, - "optionalDependencies": { - "@tauri-apps/cli-darwin-arm64": "2.9.6", - "@tauri-apps/cli-darwin-x64": "2.9.6", - "@tauri-apps/cli-linux-arm-gnueabihf": "2.9.6", - "@tauri-apps/cli-linux-arm64-gnu": "2.9.6", - "@tauri-apps/cli-linux-arm64-musl": "2.9.6", - "@tauri-apps/cli-linux-riscv64-gnu": "2.9.6", - "@tauri-apps/cli-linux-x64-gnu": "2.9.6", - "@tauri-apps/cli-linux-x64-musl": "2.9.6", - "@tauri-apps/cli-win32-arm64-msvc": "2.9.6", - "@tauri-apps/cli-win32-ia32-msvc": "2.9.6", - "@tauri-apps/cli-win32-x64-msvc": "2.9.6" + "engines": { + "node": ">=8" } }, - "node_modules/@tauri-apps/cli-darwin-arm64": { - "version": "2.9.6", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.9.6.tgz", - "integrity": "sha512-gf5no6N9FCk1qMrti4lfwP77JHP5haASZgVbBgpZG7BUepB3fhiLCXGUK8LvuOjP36HivXewjg72LTnPDScnQQ==", - "cpu": [ - "arm64" - ], + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true, - "license": "Apache-2.0 OR MIT", - "optional": true, - "os": [ - "darwin" + "license": "ISC" + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, "engines": { - "node": ">= 10" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/@tauri-apps/cli-darwin-x64": { - "version": "2.9.6", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.9.6.tgz", - "integrity": "sha512-oWh74WmqbERwwrwcueJyY6HYhgCksUc6NT7WKeXyrlY/FPmNgdyQAgcLuTSkhRFuQ6zh4Np1HZpOqCTpeZBDcw==", - "cpu": [ - "x64" - ], + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "dev": true, - "license": "Apache-2.0 OR MIT", - "optional": true, - "os": [ - "darwin" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 10" + "node": ">=8.0.0" } }, - "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { - "version": "2.9.6", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.9.6.tgz", - "integrity": "sha512-/zde3bFroFsNXOHN204DC2qUxAcAanUjVXXSdEGmhwMUZeAQalNj5cz2Qli2elsRjKN/hVbZOJj0gQ5zaYUjSg==", - "cpu": [ - "arm" - ], + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, - "license": "Apache-2.0 OR MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "MIT", "engines": { - "node": ">= 10" + "node": ">=8" } }, - "node_modules/@tauri-apps/cli-linux-arm64-gnu": { - "version": "2.9.6", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.9.6.tgz", - "integrity": "sha512-pvbljdhp9VOo4RnID5ywSxgBs7qiylTPlK56cTk7InR3kYSTJKYMqv/4Q/4rGo/mG8cVppesKIeBMH42fw6wjg==", - "cpu": [ - "arm64" - ], + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, - "license": "Apache-2.0 OR MIT", - "optional": true, - "os": [ - "linux" + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001763", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001763.tgz", + "integrity": "sha512-mh/dGtq56uN98LlNX9qdbKnzINhX0QzhiWBFEkFfsFO4QyCvL8YegrJAazCwXIeqkIob8BlZPGM3xdnY+sgmvQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } ], + "license": "CC-BY-4.0" + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 10" + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cheerio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.19.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio/node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/@tauri-apps/cli-linux-arm64-musl": { - "version": "2.9.6", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.9.6.tgz", - "integrity": "sha512-02TKUndpodXBCR0oP//6dZWGYcc22Upf2eP27NvC6z0DIqvkBBFziQUcvi2n6SrwTRL0yGgQjkm9K5NIn8s6jw==", - "cpu": [ - "arm64" - ], + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, - "license": "Apache-2.0 OR MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, "engines": { - "node": ">= 10" + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@tauri-apps/cli-linux-riscv64-gnu": { - "version": "2.9.6", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.9.6.tgz", - "integrity": "sha512-fmp1hnulbqzl1GkXl4aTX9fV+ubHw2LqlLH1PE3BxZ11EQk+l/TmiEongjnxF0ie4kV8DQfDNJ1KGiIdWe1GvQ==", - "cpu": [ - "riscv64" - ], + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", "dev": true, - "license": "Apache-2.0 OR MIT", - "optional": true, - "os": [ - "linux" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } ], + "license": "MIT", "engines": { - "node": ">= 10" + "node": ">=8" } }, - "node_modules/@tauri-apps/cli-linux-x64-gnu": { - "version": "2.9.6", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.9.6.tgz", - "integrity": "sha512-vY0le8ad2KaV1PJr+jCd8fUF9VOjwwQP/uBuTJvhvKTloEwxYA/kAjKK9OpIslGA9m/zcnSo74czI6bBrm2sYA==", - "cpu": [ - "x64" - ], + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, - "license": "Apache-2.0 OR MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "ISC", "engines": { - "node": ">= 10" + "node": ">= 12" } }, - "node_modules/@tauri-apps/cli-linux-x64-musl": { - "version": "2.9.6", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.9.6.tgz", - "integrity": "sha512-TOEuB8YCFZTWVDzsO2yW0+zGcoMiPPwcUgdnW1ODnmgfwccpnihDRoks+ABT1e3fHb1ol8QQWsHSCovb3o2ENQ==", - "cpu": [ - "x64" - ], + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "license": "Apache-2.0 OR MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, "engines": { - "node": ">= 10" + "node": ">=12" } }, - "node_modules/@tauri-apps/cli-win32-arm64-msvc": { - "version": "2.9.6", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.9.6.tgz", - "integrity": "sha512-ujmDGMRc4qRLAnj8nNG26Rlz9klJ0I0jmZs2BPpmNNf0gM/rcVHhqbEkAaHPTBVIrtUdf7bGvQAD2pyIiUrBHQ==", - "cpu": [ - "arm64" - ], + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "dev": true, - "license": "Apache-2.0 OR MIT", + "license": "MIT", "optional": true, - "os": [ - "win32" - ], "engines": { - "node": ">= 10" + "node": ">=0.8" } }, - "node_modules/@tauri-apps/cli-win32-ia32-msvc": { - "version": "2.9.6", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.9.6.tgz", - "integrity": "sha512-S4pT0yAJgFX8QRCyKA1iKjZ9Q/oPjCZf66A/VlG5Yw54Nnr88J1uBpmenINbXxzyhduWrIXBaUbEY1K80ZbpMg==", - "cpu": [ - "ia32" - ], + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "Apache-2.0 OR MIT", - "optional": true, - "os": [ - "win32" - ], + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, "engines": { - "node": ">= 10" + "node": ">=7.0.0" } }, - "node_modules/@tauri-apps/cli-win32-x64-msvc": { - "version": "2.9.6", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.9.6.tgz", - "integrity": "sha512-ldWuWSSkWbKOPjQMJoYVj9wLHcOniv7diyI5UAJ4XsBdtaFB0pKHQsqw/ItUma0VXGC7vB4E9fZjivmxur60aw==", - "cpu": [ - "x64" - ], + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, - "license": "Apache-2.0 OR MIT", - "optional": true, - "os": [ - "win32" - ], + "license": "MIT" + }, + "node_modules/commander": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", + "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 10" + "node": ">=20" } }, - "node_modules/@tauri-apps/plugin-clipboard-manager": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.3.2.tgz", - "integrity": "sha512-CUlb5Hqi2oZbcZf4VUyUH53XWPPdtpw43EUpCza5HWZJwxEoDowFzNUDt1tRUXA8Uq+XPn17Ysfptip33sG4eQ==", - "license": "MIT OR Apache-2.0", + "node_modules/compress-commons": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", + "dev": true, + "license": "MIT", "dependencies": { - "@tauri-apps/api": "^2.8.0" + "crc-32": "^1.2.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" } }, - "node_modules/@tauri-apps/plugin-dialog": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.5.0.tgz", - "integrity": "sha512-I0R0ygwRd9AN8Wj5GnzCogOlqu2+OWAtBd0zEC4+kQCI32fRowIyuhPCBoUv4h/lQt2bM39kHlxPHD5vDcFjiA==", - "license": "MIT OR Apache-2.0", - "dependencies": { - "@tauri-apps/api": "^2.8.0" + "node_modules/compress-commons/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@tauri-apps/plugin-fs": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.4.5.tgz", - "integrity": "sha512-dVxWWGE6VrOxC7/jlhyE+ON/Cc2REJlM35R3PJX3UvFw2XwYhLGQVAIyrehenDdKjotipjYEVc4YjOl3qq90fA==", - "license": "MIT OR Apache-2.0", - "dependencies": { - "@tauri-apps/api": "^2.8.0" - } + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" }, - "node_modules/@tauri-apps/plugin-http": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-http/-/plugin-http-2.5.5.tgz", - "integrity": "sha512-4hTS7AIBLmj8opDM3s8muEp7PBJQEiGDFvFF4fdMscQCOwhzXJf5hIZEHC867eH2Ck145Oce+H0AU0G/k9TbNg==", - "license": "MIT OR Apache-2.0", - "dependencies": { - "@tauri-apps/api": "^2.8.0" - } + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" }, - "node_modules/@tauri-apps/plugin-log": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-log/-/plugin-log-2.8.0.tgz", - "integrity": "sha512-a+7rOq3MJwpTOLLKbL8d0qGZ85hgHw5pNOWusA9o3cf7cEgtYHiGY/+O8fj8MvywQIGqFv0da2bYQDlrqLE7rw==", - "license": "MIT OR Apache-2.0", - "dependencies": { - "@tauri-apps/api": "^2.8.0" - } + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" }, - "node_modules/@tauri-apps/plugin-opener": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-opener/-/plugin-opener-2.5.3.tgz", - "integrity": "sha512-CCcUltXMOfUEArbf3db3kCE7Ggy1ExBEBl51Ko2ODJ6GDYHRp1nSNlQm5uNCFY5k7/ufaK5Ib3Du/Zir19IYQQ==", - "license": "MIT OR Apache-2.0", + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", "dependencies": { - "@tauri-apps/api": "^2.8.0" + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@tauri-apps/plugin-process": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-process/-/plugin-process-2.3.1.tgz", - "integrity": "sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA==", - "license": "MIT OR Apache-2.0", - "dependencies": { - "@tauri-apps/api": "^2.8.0" + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" } }, - "node_modules/@tauri-apps/plugin-shell": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.3.4.tgz", - "integrity": "sha512-ktsRWf8wHLD17aZEyqE8c5x98eNAuTizR1FSX475zQ4TxaiJnhwksLygQz+AGwckJL5bfEP13nWrlTNQJUpKpA==", - "license": "MIT OR Apache-2.0", - "dependencies": { - "@tauri-apps/api": "^2.8.0" + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" } }, - "node_modules/@tauri-apps/plugin-store": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-store/-/plugin-store-2.4.2.tgz", - "integrity": "sha512-0ClHS50Oq9HEvLPhNzTNFxbWVOqoAp3dRvtewQBeqfIQ0z5m3JRnOISIn2ZVPCrQC0MyGyhTS9DWhHjpigQE7A==", - "license": "MIT OR Apache-2.0", + "node_modules/crc32-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", + "dev": true, + "license": "MIT", "dependencies": { - "@tauri-apps/api": "^2.8.0" + "crc-32": "^1.2.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" } }, - "node_modules/@tauri-apps/plugin-updater": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-updater/-/plugin-updater-2.9.0.tgz", - "integrity": "sha512-j++sgY8XpeDvzImTrzWA08OqqGqgkNyxczLD7FjNJJx/uXxMZFz5nDcfkyoI/rCjYuj2101Tci/r/HFmOmoxCg==", - "license": "MIT OR Apache-2.0", + "node_modules/create-wdio": { + "version": "9.21.0", + "resolved": "https://registry.npmjs.org/create-wdio/-/create-wdio-9.21.0.tgz", + "integrity": "sha512-L6gsQLArY3AH5uTGpf3VfUezIsmZKufkF3ixSWqCuA/m458YVKeGghu1bBOWBdDIzqa6GX4e29dv0uVam0CTpw==", + "dev": true, + "license": "MIT", "dependencies": { - "@tauri-apps/api": "^2.6.0" + "chalk": "^5.3.0", + "commander": "^14.0.0", + "cross-spawn": "^7.0.3", + "ejs": "^3.1.10", + "execa": "^9.6.0", + "import-meta-resolve": "^4.1.0", + "inquirer": "^12.7.0", + "normalize-package-data": "^7.0.0", + "read-pkg-up": "^10.1.0", + "recursive-readdir": "^2.2.3", + "semver": "^7.6.3", + "type-fest": "^4.41.0", + "yargs": "^17.7.2" + }, + "bin": { + "create-wdio": "bin/wdio.js" + }, + "engines": { + "node": ">=12.0.0" } }, - "node_modules/@tauri-apps/plugin-window-state": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-window-state/-/plugin-window-state-2.4.1.tgz", - "integrity": "sha512-OuvdrzyY8Q5Dbzpj+GcrnV1iCeoZbcFdzMjanZMMcAEUNy/6PH5pxZPXpaZLOR7whlzXiuzx0L9EKZbH7zpdRw==", - "license": "MIT OR Apache-2.0", - "dependencies": { - "@tauri-apps/api": "^2.8.0" + "node_modules/create-wdio/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@tauri-store/shared": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@tauri-store/shared/-/shared-0.10.2.tgz", - "integrity": "sha512-hnEBbe/m9UG5ATSBp4yJOosLkX5QLblVsGIvz7mtBAqmzeWFfjP4+8X/T81L+bCH6+ref/0vsR9Ekex138kAfg==", + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, "license": "MIT", "dependencies": { - "@tauri-apps/api": "^2.8.0", - "es-toolkit": "^1.39.10" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ferreira-tb" + "engines": { + "node": ">= 8" } }, - "node_modules/@tauri-store/valtio": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@tauri-store/valtio/-/valtio-3.2.0.tgz", - "integrity": "sha512-q78gtEYyojwpYXXf5gJUmCpT56lcYOL4bvPEg9oPQ1HTdhKPjimEgD7W/2X113S/K5PJVvZyC10p4Ac5qvYZPw==", - "license": "MIT", + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@tauri-apps/api": "^2.8.0", - "@tauri-store/shared": "0.10.2", - "valtio": "^2.1.7" + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" }, "funding": { - "url": "https://github.com/sponsors/ferreira-tb" + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/@testing-library/dom": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", - "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "node_modules/css-shorthand-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/css-shorthand-properties/-/css-shorthand-properties-1.1.2.tgz", + "integrity": "sha512-C2AugXIpRGQTxaCW0N7n5jD/p5irUmCrwl03TrnMFBHDbdq44CFWR2zO7rK9xPN4Eo3pUxC4vQzQgbIpzrD1PQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.3.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "picocolors": "1.1.1", - "pretty-format": "^27.0.2" + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" }, "engines": { - "node": ">=18" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, - "node_modules/@testing-library/jest-dom": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", - "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "node_modules/css-value": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz", + "integrity": "sha512-FUV3xaJ63buRLgHrLQVlVgQnQdR4yqdLGaDu7g8CQcWjInDfM9plBTPI9FRfpahju1UBSaMckeb2/46ApS/V1Q==", + "dev": true + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz", + "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==", "dev": true, "license": "MIT", "dependencies": { - "@adobe/css-tools": "^4.4.0", - "aria-query": "^5.0.0", - "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.6.3", - "picocolors": "^1.1.1", - "redent": "^3.0.0" + "@asamuzakjp/css-color": "^4.1.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.21", + "css-tree": "^3.1.0", + "lru-cache": "^11.2.4" }, "engines": { - "node": ">=14", - "npm": ">=6", - "yarn": ">=1" + "node": ">=20" } }, - "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", - "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "node_modules/cssstyle/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "license": "MIT" }, - "node_modules/@testing-library/react": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.1.tgz", - "integrity": "sha512-gr4KtAWqIOQoucWYD/f6ki+j5chXfcPc74Col/6poTyqTmn7zRmodWahWRCp8tYd+GMqBonw6hstNzqjbs6gjw==", + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/data-urls": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.0.tgz", + "integrity": "sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.12.5" + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^15.0.0" }, "engines": { - "node": ">=18" + "node": ">=20" + } + }, + "node_modules/dayjs": { + "version": "1.11.19", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", + "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" }, - "peerDependencies": { - "@testing-library/dom": "^10.0.0", - "@types/react": "^18.0.0 || ^19.0.0", - "@types/react-dom": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" + "engines": { + "node": ">=6.0" }, "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { + "supports-color": { "optional": true } } }, - "node_modules/@types/aria-query": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", - "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "node_modules/decamelize": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.1.tgz", + "integrity": "sha512-G7Cqgaelq68XHJNGlZ7lrNQyhZGsFqpwtGFexqUv4IQdjKoSYF7ipZ9UuTJZUSQXFj/XaoBLuEVIVqr8EJngEQ==", "dev": true, "license": "MIT", - "peer": true + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deepmerge-ts": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz", + "integrity": "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", "dev": true, "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/derive-valtio": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/derive-valtio/-/derive-valtio-0.2.0.tgz", + "integrity": "sha512-6slhaFHtfaL3t5dLYaQt6s4G2xZymhu0Ktdl7OMeVk8+46RgR8ft6FL0Tr4F31W+yPH03nJe1SSP4JFy2hSMRA==", + "license": "MIT", + "peerDependencies": { + "valtio": ">=2.0.0-rc.0" } }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "node_modules/diff": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" } }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true, "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.2" - } + "peer": true }, - "node_modules/@types/chai": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, "license": "MIT", "dependencies": { - "@types/deep-eql": "*", - "assertion-error": "^2.0.1" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, - "license": "MIT" + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "dev": true, - "license": "MIT" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" }, - "node_modules/@types/fs-extra": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", - "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "@types/jsonfile": "*", - "@types/node": "*" + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/@types/jsonfile": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", - "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "@types/node": "*" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/@types/node": { - "version": "25.0.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz", - "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", + "node_modules/dotenv": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~7.16.0" + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" } }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "license": "MIT" - }, - "node_modules/@types/plist": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.5.tgz", - "integrity": "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==", + "node_modules/dotenv-cli": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-11.0.0.tgz", + "integrity": "sha512-r5pA8idbk7GFWuHEU7trSTflWcdBpQEK+Aw17UrSHjS6CReuhrrPcyC3zcQBPQvhArRHnBo/h6eLH1fkCvNlww==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*", - "xmlbuilder": ">=11.0.1" + "cross-spawn": "^7.0.6", + "dotenv": "^17.1.0", + "dotenv-expand": "^12.0.0", + "minimist": "^1.2.6" + }, + "bin": { + "dotenv": "cli.js" } }, - "node_modules/@types/react": { - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", - "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", - "devOptional": true, - "license": "MIT", + "node_modules/dotenv-expand": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-12.0.3.tgz", + "integrity": "sha512-uc47g4b+4k/M/SeaW1y4OApx+mtLWl92l5LMPP0GNXctZqELk+YGgOPIIC5elYmUH4OuoK3JLhuRUYegeySiFA==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "csstype": "^3.2.2" + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" } }, - "node_modules/@types/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "node_modules/dotenv-expand/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^19.2.0" + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" } }, - "node_modules/@types/use-sync-external-store": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", - "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true, "license": "MIT" }, - "node_modules/@uiw/react-json-view": { - "version": "2.0.0-alpha.40", - "resolved": "https://registry.npmjs.org/@uiw/react-json-view/-/react-json-view-2.0.0-alpha.40.tgz", - "integrity": "sha512-j8YgmUrLAokX0k3TJC1+Rae3G2XS2hTYA9SsnQVWeQpn/PiqxwG8mI4A5TCASUTltPtpM/9Yp+mRm7L4Wjy8rw==", + "node_modules/easy-table": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.2.0.tgz", + "integrity": "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==", + "dev": true, "license": "MIT", - "funding": { - "url": "https://jaywcjlove.github.io/#/sponsor" + "dependencies": { + "ansi-regex": "^5.0.1" }, - "peerDependencies": { - "@babel/runtime": ">=7.10.0", - "react": ">=18.0.0", - "react-dom": ">=18.0.0" + "optionalDependencies": { + "wcwidth": "^1.0.1" } }, - "node_modules/@vitejs/plugin-react": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.2.tgz", - "integrity": "sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ==", + "node_modules/edge-paths": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", + "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.28.5", - "@babel/plugin-transform-react-jsx-self": "^7.27.1", - "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-beta.53", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.18.0" + "@types/which": "^2.0.1", + "which": "^2.0.2" }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14.0.0" }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + "funding": { + "url": "https://github.com/sponsors/shirshak55" } }, - "node_modules/@vitest/expect": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.16.tgz", - "integrity": "sha512-eshqULT2It7McaJkQGLkPjPjNph+uevROGuIMJdG3V+0BSR2w9u6J9Lwu+E8cK5TETlfou8GRijhafIMhXsimA==", + "node_modules/edgedriver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-6.3.0.tgz", + "integrity": "sha512-ggEQL+oEyIcM4nP2QC3AtCQ04o4kDNefRM3hja0odvlPSnsaxiruMxEZ93v3gDCKWYW6BXUr51PPradb+3nffw==", "dev": true, + "hasInstallScript": true, "license": "MIT", "dependencies": { - "@standard-schema/spec": "^1.0.0", - "@types/chai": "^5.2.2", - "@vitest/spy": "4.0.16", - "@vitest/utils": "4.0.16", - "chai": "^6.2.1", - "tinyrainbow": "^3.0.3" + "@wdio/logger": "^9.18.0", + "@zip.js/zip.js": "^2.8.11", + "decamelize": "^6.0.1", + "edge-paths": "^3.0.5", + "fast-xml-parser": "^5.3.3", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "which": "^6.0.0" }, - "funding": { - "url": "https://opencollective.com/vitest" + "bin": { + "edgedriver": "bin/edgedriver.js" + }, + "engines": { + "node": ">=20.0.0" } }, - "node_modules/@vitest/mocker": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.16.tgz", - "integrity": "sha512-yb6k4AZxJTB+q9ycAvsoxGn+j/po0UaPgajllBgt1PzoMAAmJGYFdDk0uCcRcxb3BrME34I6u8gHZTQlkqSZpg==", + "node_modules/edgedriver/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "license": "MIT", + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/edgedriver/node_modules/which": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", + "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", + "dev": true, + "license": "ISC", "dependencies": { - "@vitest/spy": "4.0.16", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.21" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "isexe": "^3.1.1" }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^6.0.0 || ^7.0.0-0" + "bin": { + "node-which": "bin/which.js" }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@vitest/pretty-format": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.16.tgz", - "integrity": "sha512-eNCYNsSty9xJKi/UdVD8Ou16alu7AYiS2fCPRs0b1OdhJiV89buAXQLpTbe+X8V9L6qrs9CqyvU7OaAopJYPsA==", + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "tinyrainbow": "^3.0.3" + "jake": "^10.8.5" }, - "funding": { - "url": "https://opencollective.com/vitest" + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@vitest/runner": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.16.tgz", - "integrity": "sha512-VWEDm5Wv9xEo80ctjORcTQRJ539EGPB3Pb9ApvVRAY1U/WkHXmmYISqU5E79uCwcW7xYUV38gwZD+RV755fu3Q==", + "node_modules/electron-to-chromium": { + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.0.16", - "pathe": "^2.0.3" + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" } }, - "node_modules/@vitest/snapshot": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.16.tgz", - "integrity": "sha512-sf6NcrYhYBsSYefxnry+DR8n3UV4xWZwWxYbCJUt2YdvtqzSPR7VfGrY0zsv090DAbjFZsi7ZaMi1KnSRyK1XA==", + "node_modules/encoding-sniffer/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.16", - "magic-string": "^0.30.21", - "pathe": "^2.0.3" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@vitest/spy": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.16.tgz", - "integrity": "sha512-4jIOWjKP0ZUaEmJm00E0cOBLU+5WE0BpeNr3XN6TEF05ltro6NJqHWxXD0kA8/Zc8Nh23AT8WQxwNG+WeROupw==", + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "dev": true, "license": "MIT", - "funding": { - "url": "https://opencollective.com/vitest" + "dependencies": { + "once": "^1.4.0" } }, - "node_modules/@vitest/utils": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.16.tgz", - "integrity": "sha512-h8z9yYhV3e1LEfaQ3zdypIrnAg/9hguReGZoS7Gl0aBG5xgA410zBqECqmaF/+RkTggRsfnzc1XaAHA6bmUufA==", + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "4.0.16", - "tinyrainbow": "^3.0.3" + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" }, "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@xmldom/xmldom": { - "version": "0.9.8", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.8.tgz", - "integrity": "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14.6" + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/@zag-js/accordion": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/accordion/-/accordion-1.31.1.tgz", - "integrity": "sha512-3sGi4EZpGBz/O1IVkk9dzzWzP5vVVOj4Li6C+jHOnrgaWPouA/mBTP5L9HEL8qtFsECFZwpNo486eqiCmeHoGw==", + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "is-arrayish": "^0.2.1" } }, - "node_modules/@zag-js/anatomy": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/anatomy/-/anatomy-1.31.1.tgz", - "integrity": "sha512-BhIhf3Q0tRA0Jugd7AJfUBzeAb/iATBsw7KyYThMGcPWmrWssL7KWr5AB6RufzGKU7+DCb1QEhlqd4NSOJaYxQ==", + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, "license": "MIT" }, - "node_modules/@zag-js/angle-slider": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/angle-slider/-/angle-slider-1.31.1.tgz", - "integrity": "sha512-SfWrgnM0zMLX82rsIJOqWk430UnPA17UFGcDqMDRwXy1Wx4yptmx0aFAsSXnRnw4Ee7WaulF2RWBli6O6iYRCA==", + "node_modules/es-toolkit": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.43.0.tgz", + "integrity": "sha512-SKCT8AsWvYzBBuUqMk4NPwFlSdqLpJwmy6AP322ERn8W2YLIB6JBXnwMI2Qsh2gfphT3q7EKAxKb23cvFHFwKA==", "license": "MIT", - "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/rect-utils": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" - } + "workspaces": [ + "docs", + "benchmarks" + ] }, - "node_modules/@zag-js/aria-hidden": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/aria-hidden/-/aria-hidden-1.31.1.tgz", - "integrity": "sha512-SoNt4S2LkHNWPglQczWN0E5vAV15MT1GoK9MksZzbkMhl+pkDTdLytpXsQ1IgalC1YUng0XNps/Wt6P3uDuzTA==", + "node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "dev": true, + "hasInstallScript": true, "license": "MIT", - "dependencies": { - "@zag-js/dom-query": "1.31.1" + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" } }, - "node_modules/@zag-js/async-list": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/async-list/-/async-list-1.31.1.tgz", - "integrity": "sha512-BDZEmr4KKh3JASgkXouOwoTWRS1UPE3gdZYZ7Sk7SJ1i8+Pk6zUQ4FnxaoF/cSAdCXyjSSr92Kns2bTk/QuNkQ==", + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, "license": "MIT", - "dependencies": { - "@zag-js/core": "1.31.1", - "@zag-js/utils": "1.31.1" + "engines": { + "node": ">=6" } }, - "node_modules/@zag-js/auto-resize": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/auto-resize/-/auto-resize-1.31.1.tgz", - "integrity": "sha512-qzWHibjBekSmFweG+EWY8g0lRzKtok7o9XtQ+JFlOu3s6x4D02z2YDzjDdfSLmS7j0NxISnwQkinWiDAZEYHog==", + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "license": "MIT", - "dependencies": { - "@zag-js/dom-query": "1.31.1" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@zag-js/avatar": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/avatar/-/avatar-1.31.1.tgz", - "integrity": "sha512-Grosi2hRn4wfDYlPd8l+d4GCIFMsoj6ZFqii+1k14AqTDiCUJ/J0jCvOrRHkvkpEqektjuSD7e/GCX+yawqkuQ==", - "license": "MIT", + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" } }, - "node_modules/@zag-js/bottom-sheet": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/bottom-sheet/-/bottom-sheet-1.31.1.tgz", - "integrity": "sha512-ZBbIpYyZX2zQeqW36aODVi9/I4J3zS1XmIHUjeXmfmf6TlQUA1ydgYl7ipREfmCzNWX2LEA5ZnPJQw0UBcrB8w==", - "license": "MIT", - "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/aria-hidden": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dismissable": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/focus-trap": "1.31.1", - "@zag-js/remove-scroll": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@zag-js/carousel": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/carousel/-/carousel-1.31.1.tgz", - "integrity": "sha512-228Ol86G/lg8crcomy5cALkUYdOHCHcvJnSOQzeUj80JNjlELzrjBpaAj4lx8dZocfwou2Sg4NyZJ+mISSc+Dg==", - "license": "MIT", - "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/scroll-snap": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" } - }, - "node_modules/@zag-js/checkbox": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/checkbox/-/checkbox-1.31.1.tgz", - "integrity": "sha512-oLS8bqhimckLl6coCNmKPPUmB8wIbVhtkpLwLPLgz4vhhUe7gnpB5dea14Ow2JTBnmug8bMh/bJDtuPa9qQuTw==", - "license": "MIT", - "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/focus-visible": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" } }, - "node_modules/@zag-js/clipboard": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/clipboard/-/clipboard-1.31.1.tgz", - "integrity": "sha512-pv/gOmD9DMg+YmSMjahyd5oSp7/v9K0uQ3att6fPeaNMjB42b3tnY1S1GNVy5Ltf/qHDab6WVwlEN+1zKHXaYw==", + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "@types/estree": "^1.0.0" } }, - "node_modules/@zag-js/collapsible": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/collapsible/-/collapsible-1.31.1.tgz", - "integrity": "sha512-eCC5G6bBZUwF8z2XULQXUNRxqte9I2Sv+WJ2brycPn1a68uYD76RzFBmLQ2er95VbshUdeo8nRuX8MooAFuYzg==", - "license": "MIT", - "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@zag-js/collection": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/collection/-/collection-1.31.1.tgz", - "integrity": "sha512-ecpfyfCj8Y0/GUPuHYsLxexIrx10VuR3Wd0H+lamcki3lYgQxZrpLRFMwgTqmI/m7t3zhm5QeEvMUJ1H14YMLA==", + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, "license": "MIT", - "dependencies": { - "@zag-js/utils": "1.31.1" + "engines": { + "node": ">=6" } }, - "node_modules/@zag-js/color-picker": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/color-picker/-/color-picker-1.31.1.tgz", - "integrity": "sha512-AWNZth49iEDxqh1DBZNSKpfEM/FF+MjL5bgUHVctnHdkpFsZLynJorWQQ4hNXNDFEc/I5w10KSxVCcO6tsPGFw==", + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/color-utils": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dismissable": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/popper": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "bare-events": "^2.7.0" } }, - "node_modules/@zag-js/color-utils": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/color-utils/-/color-utils-1.31.1.tgz", - "integrity": "sha512-HdjTRU8C0tO6hK+PBVlu8iQH1MJaAnJAEdq2FcD97mq0PiPhrSj6iOftnrvPsE4CRieVFjnJWOvaubWFc4VmHA==", + "node_modules/execa": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", + "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/utils": "1.31.1" + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/@zag-js/combobox": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/combobox/-/combobox-1.31.1.tgz", - "integrity": "sha512-IT0getSAGzngdRL20iX/iAh2d7DzVoMDDppOsOFBG2owKAgLpj8uLvUhy+lcrm6N8yxYOya89D6Aef7V5KdwlQ==", + "node_modules/exif-parser": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", + "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==", + "dev": true + }, + "node_modules/exifr": { + "version": "7.1.3", + "resolved": "git+ssh://git@github.com/m-hayabusa/exifr.git#2cf6c14fcd8eab52a7a7de53af7fdb01a4a9f90f", + "integrity": "sha512-AxJQk4la979LUL0NrfXAozPZi0UGHVaz1ZfcfqLpl8trOv78T3QWle8sepO0ZqfyRhg8NWp4pVYauOXbHcFUUQ==", + "license": "MIT" + }, + "node_modules/exifreader": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/exifreader/-/exifreader-4.35.0.tgz", + "integrity": "sha512-qiMONyOObmwI6sIXy13vRGqlcoi9VUKr70iGI1aefP+xJsbcXp+hcyL/4J6hov/yG9UhS7Hq1OQ1hAoSEZl+RA==", + "hasInstallScript": true, + "license": "MPL-2.0", + "optionalDependencies": { + "@xmldom/xmldom": "^0.9.4" + } + }, + "node_modules/exit-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-4.0.0.tgz", + "integrity": "sha512-Fqs7ChZm72y40wKjOFXBKg7nJZvQJmewP5/7LtePDdnah/+FH9Hp5sgMujSCMPXlxOAW2//1jrW9pnsY7o20vQ==", + "dev": true, "license": "MIT", - "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/aria-hidden": "1.31.1", - "@zag-js/collection": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dismissable": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/popper": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@zag-js/core": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/core/-/core-1.31.1.tgz", - "integrity": "sha512-RaMJeqtjxG6k7iFD3WQnlyFJVT3yfQN+pJygAHH37GsMtiNzQQJOoesjb0LV9T27jwMXeNUzrh3MSDr1/0yVcQ==", + "node_modules/expect": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", + "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/dom-query": "1.31.1", - "@zag-js/utils": "1.31.1" + "@jest/expect-utils": "30.2.0", + "@jest/get-type": "30.1.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-util": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@zag-js/date-picker": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/date-picker/-/date-picker-1.31.1.tgz", - "integrity": "sha512-AOWN/IskGidVQt5g+uE9cILqJBTclE6OG1GC9WSWuyP/y4F+PdP/781SgYpYCZg/6pMGbL01PFKKb7xOOCeZAg==", + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/expect-webdriverio": { + "version": "5.6.4", + "resolved": "https://registry.npmjs.org/expect-webdriverio/-/expect-webdriverio-5.6.4.tgz", + "integrity": "sha512-Bkoqs+39fHwjos51qab7ZWmvZrYNBbzgSAIykH2CrgLOLhHJXzC30DP9lZq2MsmaUsbBnN5c5m8VqAhOHTrCRw==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/date-utils": "1.31.1", - "@zag-js/dismissable": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/live-region": "1.31.1", - "@zag-js/popper": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "@vitest/snapshot": "^4.0.16", + "deep-eql": "^5.0.2", + "expect": "^30.2.0", + "jest-matcher-utils": "^30.2.0" + }, + "engines": { + "node": ">=20" }, "peerDependencies": { - "@internationalized/date": ">=3.0.0" + "@wdio/globals": "^9.0.0", + "@wdio/logger": "^9.0.0", + "webdriverio": "^9.0.0" + }, + "peerDependenciesMeta": { + "@wdio/globals": { + "optional": false + }, + "@wdio/logger": { + "optional": false + }, + "webdriverio": { + "optional": false + } } }, - "node_modules/@zag-js/date-utils": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/date-utils/-/date-utils-1.31.1.tgz", - "integrity": "sha512-+Aq9g/rqLeiRmnazgdZMc59gAxqxbw3GGy8AngrtNipgRtMhPlzGa3S4Qsq1yau6OKaHZ13uckUS+MhLNbBY+Q==", - "license": "MIT", - "peerDependencies": { - "@internationalized/date": ">=3.0.0" + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" } }, - "node_modules/@zag-js/dialog": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/dialog/-/dialog-1.31.1.tgz", - "integrity": "sha512-iaWlYQ6TYoVjM/X5+UZVZzKiMboE50GnEzGUpbhbeRNRiLqSu5dODSFzior1G4kde/ns5eN+BTf/Tm6AT4N2og==", + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/aria-hidden": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dismissable": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/focus-trap": "1.31.1", - "@zag-js/remove-scroll": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@zag-js/dismissable": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/dismissable/-/dismissable-1.31.1.tgz", - "integrity": "sha512-jCdJwQmEkG6PlrN13fUk2l7ZclSu54FZwmT4xOtQpEbaiAiESm5KI5oyFh5jDPY47Goa28UJkEjWXVgKXKWb0g==", + "node_modules/fast-content-type-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", + "integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-xml-parser": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.4.tgz", + "integrity": "sha512-EFd6afGmXlCx8H8WTZHhAoDaWaGyuIBoZJ2mknrNxug+aZKjkp0a0dlars9Izl+jF+7Gu1/5f/2h68cQpe0IiA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], "license": "MIT", "dependencies": { - "@zag-js/dom-query": "1.31.1", - "@zag-js/interact-outside": "1.31.1", - "@zag-js/utils": "1.31.1" + "strnum": "^2.1.0" + }, + "bin": { + "fxparser": "src/cli/cli.js" } }, - "node_modules/@zag-js/dom-query": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/dom-query/-/dom-query-1.31.1.tgz", - "integrity": "sha512-2tCZLwSfoXm62gwl0neiAN6u5VnzUhy5wHtKbX+klqGFatnca3Bm++H9+4PHMrwUWRbPg3H5N151lKFEOQhBfQ==", + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/types": "1.31.1" + "pend": "~1.2.0" } }, - "node_modules/@zag-js/editable": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/editable/-/editable-1.31.1.tgz", - "integrity": "sha512-JMICHw4/x0YqDy/n+I+TeaXlFbTA0j9w3UqOWMwUFQ+dAsq4JLXeqZDXu19MQN6yaTFdOpG1EFw4FEVTsu+d3Q==", + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, "license": "MIT", - "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/interact-outside": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/@zag-js/file-upload": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/file-upload/-/file-upload-1.31.1.tgz", - "integrity": "sha512-cp7qMiXKrIcTfDamOz9wlnJLeBF8gucTI7Y+iKaP+hiIW+OG254GElfQiqXNDad3HUmD+Dt8Tx6uAzL/mw3sbQ==", + "node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/file-utils": "1.31.1", - "@zag-js/i18n-utils": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@zag-js/file-utils": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/file-utils/-/file-utils-1.31.1.tgz", - "integrity": "sha512-MDDz52IdPh/mPUYrqUXvh7qDckJHs+mt5gjfx0N89qh2JNXuRU14zPotOKTzIKM4o+HFZkAT6BAfMpr9CX/0ug==", + "node_modules/file-type": { + "version": "16.5.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", + "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/i18n-utils": "1.31.1" + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" } }, - "node_modules/@zag-js/floating-panel": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/floating-panel/-/floating-panel-1.31.1.tgz", - "integrity": "sha512-Pjgd/wjdglZ90dtq/LC4o5sc6w0m+RehhPmJcIzq9T+E/Xrb6qrhf06QhxB9LwSj4DG/gIv87gmD2qF1VH7cRQ==", - "license": "MIT", + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/popper": "1.31.1", - "@zag-js/rect-utils": "1.31.1", - "@zag-js/store": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "minimatch": "^5.0.1" } }, - "node_modules/@zag-js/focus-trap": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/focus-trap/-/focus-trap-1.31.1.tgz", - "integrity": "sha512-omgUhAz1r81pYAujqYIIavdTKJzDRExioSiqhnx/xq10a6Q/xavMFflq8w7edMc9JHkTOnr9E5qh9abCVJjhpQ==", - "license": "MIT", + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", "dependencies": { - "@zag-js/dom-query": "1.31.1" + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@zag-js/focus-visible": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-1.31.1.tgz", - "integrity": "sha512-GC59A3yd7tj8aKhzvhrM+CEZZraXm5y/SpfIjz1J7kGV6eeXbUtjkbe75g99Ve8iJYfQVQlAj2GyN3oniHc5Zw==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/dom-query": "1.31.1" + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@zag-js/highlight-word": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/highlight-word/-/highlight-word-1.31.1.tgz", - "integrity": "sha512-nQw7t8LgWXW+6Z5E/p6T+OST0DDXp35mrFCzrkJL54aVTZ3GuLyIP2p0/HGQr2hE/KKLbZEs5i6UcXF84tiI4g==", + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", "license": "MIT" }, - "node_modules/@zag-js/hover-card": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/hover-card/-/hover-card-1.31.1.tgz", - "integrity": "sha512-R74kz2wPgGwB3jKQeD91kdtlvVKpffWBJHqw8yCBd95GXGVmhym+BPoCToJzcqiemP8+0EtSuVPU9IHaSuJnSg==", + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dismissable": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/popper": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@zag-js/i18n-utils": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/i18n-utils/-/i18n-utils-1.31.1.tgz", - "integrity": "sha512-SARkFuo1+Q0WcNv4jqvxp5hjCOqu/gBa7p6BTh7v5Bo00QhKRM/bCvVt0EB6V+h2oejrZfkwZ0MwbpQiL6L2aQ==", - "license": "MIT", + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", "dependencies": { - "@zag-js/dom-query": "1.31.1" + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@zag-js/image-cropper": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/image-cropper/-/image-cropper-1.31.1.tgz", - "integrity": "sha512-hFuy4I3jIJ/iyJsnfbLX1l/cJtN42j7lwhw8TeWVX8Y+hHxFPMSKx7AQirt/hALUbyy7QsQgAd5IslpsYq1Nlg==", + "node_modules/framer-motion": { + "version": "12.25.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.25.0.tgz", + "integrity": "sha512-mlWqd0rApIjeyhTCSNCqPYsUAEhkcUukZxH3ke6KbstBRPcxhEpuIjmiUQvB+1E9xkEm5SpNHBgHCapH/QHTWg==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "motion-dom": "^12.24.11", + "motion-utils": "^12.24.10", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } } }, - "node_modules/@zag-js/interact-outside": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/interact-outside/-/interact-outside-1.31.1.tgz", - "integrity": "sha512-oxBAlBqcatlxGUmhwUCRYTADIBrVoyxM1YrFzR1R8jhvVR/QCaxoLAyKwcA3mWXlZ8+NlXb7n5ELE11BZb/rEg==", + "node_modules/fs-extra": { + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", + "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/dom-query": "1.31.1", - "@zag-js/utils": "1.31.1" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" } }, - "node_modules/@zag-js/json-tree-utils": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/json-tree-utils/-/json-tree-utils-1.31.1.tgz", - "integrity": "sha512-wrNek2UBE69FWpo2f0E2MxiboBS+Uop79LeQU2jNDujA1o3x6b1Lp2r7Fl1sfnUWMdKVVQb44oqfIj2g3CTEmQ==", - "license": "MIT" + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" }, - "node_modules/@zag-js/listbox": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/listbox/-/listbox-1.31.1.tgz", - "integrity": "sha512-LcTIr4I9eN4MR1nSRfQfseWgj4ybOXXAY2o5dBpEBL67dnCSX3swNb/4LQO+ebj077BViQb66pBb1KSoeHGkEQ==", + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, "license": "MIT", - "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/collection": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/focus-visible": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/@zag-js/live-region": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/live-region/-/live-region-1.31.1.tgz", - "integrity": "sha512-RBx8jk1dgvkEUuFs77SBZn0WwvEkeZgVawVu6XUAy4ENfhP0D/qkvwNk+Els8InKmr1gWKajD7sh+g8M40Ex6A==", - "license": "MIT" + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/@zag-js/marquee": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/marquee/-/marquee-1.31.1.tgz", - "integrity": "sha512-Rt7+zy7CDOxXm0PqaTcmuWxcrZOPOpZY4T6IxOZk4ZcOXJQ2v7CkF3EK0pdI9PyI6Zpk/YIwQkENjidT55db0A==", + "node_modules/geckodriver": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-6.1.0.tgz", + "integrity": "sha512-ZRXLa4ZaYTTgUO4Eefw+RsQCleugU2QLb1ME7qTYxxuRj51yAhfnXaItXNs5/vUzfIaDHuZ+YnSF005hfp07nQ==", + "dev": true, + "hasInstallScript": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "@wdio/logger": "^9.18.0", + "@zip.js/zip.js": "^2.8.11", + "decamelize": "^6.0.1", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "modern-tar": "^0.7.2" + }, + "bin": { + "geckodriver": "bin/geckodriver.js" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/@zag-js/menu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/menu/-/menu-1.31.1.tgz", - "integrity": "sha512-eJPRM8tlauRTsAoJXchDBzMzL2RhXYSHmHak2IJCDMApCV51p0MqGYP8Er3DbMSQTPUFuTq779uUIarDqW+zmA==", + "node_modules/get-port": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", + "integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==", + "dev": true, "license": "MIT", - "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dismissable": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/popper": "1.31.1", - "@zag-js/rect-utils": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@zag-js/navigation-menu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/navigation-menu/-/navigation-menu-1.31.1.tgz", - "integrity": "sha512-xS4aynqmB9NYicPbEW8lPPakAfDfSgIDL1pRVSD6f1+VXkHD6LgNn6jUNDNbFt65mGhLpA2IczbvLCxv0g/ISQ==", + "node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dismissable": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@zag-js/number-input": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/number-input/-/number-input-1.31.1.tgz", - "integrity": "sha512-vn+BXEZ2/g2CMIFFyjjye/SbCeW3I/rlszL8EyBmhMcuA1l51OX2WKry6HeQNiU41uMyFg2rb1pb5KVw1gJsCg==", + "node_modules/get-tsconfig": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.1.tgz", + "integrity": "sha512-EoY1N2xCn44xU6750Sx7OjOIT59FkmstNc3X6y5xpz7D5cBtZRe/3pSlTkDJgqsOk3WwZPkWfonhhUJfttQo3w==", + "dev": true, "license": "MIT", "dependencies": { - "@internationalized/number": "3.6.5", - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/@zag-js/pagination": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/pagination/-/pagination-1.31.1.tgz", - "integrity": "sha512-icW6FNzIKNz7iXU+prlQWpMFJedDrhmCKzzI39SY+dv5g1Gnrlc0b44PxvNl5PWFLSkB5KBT/R1WCqd8Kh4cCA==", + "node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" } }, - "node_modules/@zag-js/password-input": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/password-input/-/password-input-1.31.1.tgz", - "integrity": "sha512-AivOeNO14a39xhxVMB2TVmIjmQ89OwVz0+2IjX3JjLS2Pmia+gg9xnVd2kBIcKfnqUN4MBnzmk7t46YWJMQVVQ==", + "node_modules/gifwrap": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.10.1.tgz", + "integrity": "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "image-q": "^4.0.0", + "omggif": "^1.0.10" } }, - "node_modules/@zag-js/pin-input": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/pin-input/-/pin-input-1.31.1.tgz", - "integrity": "sha512-k3ESoX5ve5sbWBLTCPYAzgLjRU7mVNEUiqAOhRgazOcBGV5wjGh398zWb1jr0FMxPnoAMrXDN/CQwJTmJcMKrg==", - "license": "MIT", + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "dev": true, + "license": "ISC", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@zag-js/popover": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/popover/-/popover-1.31.1.tgz", - "integrity": "sha512-uCFJP3DFBkEBAre6lgGLw2xWS2ZIuT/DLeajIXb+8BmC9KCF0wY4c9qojx9F3rGMJQxcGl+WUoXENkOvkTaVhQ==", - "license": "MIT", + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/aria-hidden": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dismissable": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/focus-trap": "1.31.1", - "@zag-js/popper": "1.31.1", - "@zag-js/remove-scroll": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/@zag-js/popper": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/popper/-/popper-1.31.1.tgz", - "integrity": "sha512-wLXcEqzn9MK1rGbsgnDH26o5ZWqR4oeb6ZepKKy0gcuJl/1S5/dr1VBvxJNMZlf9d6etvYklG5LRnIVkXCbrjA==", + "node_modules/globals": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.0.0.tgz", + "integrity": "sha512-gv5BeD2EssA793rlFWVPMMCqefTlpusw6/2TbAVMy0FzcG8wKJn4O+NqJ4+XWmmwrayJgw5TzrmWjFgmz1XPqw==", + "dev": true, "license": "MIT", - "dependencies": { - "@floating-ui/dom": "1.7.4", - "@zag-js/dom-query": "1.31.1", - "@zag-js/utils": "1.31.1" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@zag-js/presence": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/presence/-/presence-1.31.1.tgz", - "integrity": "sha512-tv+WsBnA0abIlDuEfZMh0lRPF4cMs6kWJosNkGBwzeXnGds+KXjzpL2KDtwDgbJgN3sI0xHPMYjRy2v3ZamcDA==", + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", - "dependencies": { - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1" + "engines": { + "node": ">=8" } }, - "node_modules/@zag-js/progress": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/progress/-/progress-1.31.1.tgz", - "integrity": "sha512-f9lIDHCRcFAG14LVEKOAPTdqPzphwIIraC6fTr9AwmNlYI6/qFDkz3jOlYVSyk5VsJAIFM/777x/CdqjliiOqg==", + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/@zag-js/qr-code": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/qr-code/-/qr-code-1.31.1.tgz", - "integrity": "sha512-Rxh+HF12SgUp5rvTelp1qyLK3xkn37h2fT/L4eBQ0f8OUEo8wfowEbs36+1i61d6UuH7PJt4q/07eIf6vNVevA==", + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1", - "proxy-memoize": "3.0.1", - "uqr": "0.1.2" + "react-is": "^16.7.0" } }, - "node_modules/@zag-js/radio-group": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/radio-group/-/radio-group-1.31.1.tgz", - "integrity": "sha512-OfKIdEtSG0EuHM+cFVqcR+04yzZmcDRgG3j0QhoJsyS1my63ZHbwC2HNAtfPFh4U4sJx9yUexwSzPGZ6pOzIdw==", - "license": "MIT", + "node_modules/hosted-git-info": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz", + "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==", + "dev": true, + "license": "ISC", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/focus-visible": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/@zag-js/rating-group": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/rating-group/-/rating-group-1.31.1.tgz", - "integrity": "sha512-BkQUglKm4a+KXYPACYvIvBJSuEyzV0YQqjjiucwJ5UiOlK72C66VBvyGN+DqJRDnkU1K5azt6E1Ja5ANk3fgsg==", + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, - "node_modules/@zag-js/react": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/react/-/react-1.31.1.tgz", - "integrity": "sha512-a7uYH+tcw1UYbcovyVBzlh6X8KztK/b1+s8sMs4Srhd24M+hZMetV94Z0bM1Km5aNAnoS4gkH3gtJjH0OphquQ==", + "node_modules/htmlfy": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/htmlfy/-/htmlfy-0.8.1.tgz", + "integrity": "sha512-xWROBw9+MEGwxpotll0h672KCaLrKKiCYzsyN8ZgL9cQbVumFnyvsk2JqiB9ELAV1GLj1GG/jxZUjV9OZZi/yQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], "license": "MIT", "dependencies": { - "@zag-js/core": "1.31.1", - "@zag-js/store": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" - }, - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" } }, - "node_modules/@zag-js/rect-utils": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/rect-utils/-/rect-utils-1.31.1.tgz", - "integrity": "sha512-lBFheAnz8+3aGDFjqlkw0Iew/F03lFjiIf26hkkcFSZu0ltNZUMG/X3XLHUnHxdfbdBguc8ons6mr2MkVvisng==", - "license": "MIT" + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } }, - "node_modules/@zag-js/remove-scroll": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/remove-scroll/-/remove-scroll-1.31.1.tgz", - "integrity": "sha512-gVVJuFKaCjo652RmajYmkjXKgjJWLQ5ZhZLTaLUKWM1mAarvlqnLui8jrHEHLxqpfsjQylfdhJKkWmyF8NAgTA==", + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/dom-query": "1.31.1" + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" } }, - "node_modules/@zag-js/scroll-area": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/scroll-area/-/scroll-area-1.31.1.tgz", - "integrity": "sha512-GBXd1K3U0AHwWlJaqAMKQMZyeoxuBO6XYrVgdvzgiftQbJrZs5fuYOFyDvPLDWHTLYxaHso44/f+9EmAUAiytw==", + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" } }, - "node_modules/@zag-js/scroll-snap": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/scroll-snap/-/scroll-snap-1.31.1.tgz", - "integrity": "sha512-YWsfhcQqiffu2X9HuB0fMnEQAu6rEOfGcvQYinvB6pjWPOvIJGxGMi/dYyy21XQDNJ9K1IcWRIo/yuaajoJyQQ==", - "license": "MIT", - "dependencies": { - "@zag-js/dom-query": "1.31.1" + "node_modules/human-signals": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" } }, - "node_modules/@zag-js/select": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/select/-/select-1.31.1.tgz", - "integrity": "sha512-vKWb8BiRY83Y3HkDNnimf6cr1yvzJh1HwZlzXFz0y47zEvlikQaf+r96obR78RgTtMjNTTV15tTXdc1/WFoYkw==", + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/collection": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dismissable": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/popper": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@zag-js/signature-pad": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/signature-pad/-/signature-pad-1.31.1.tgz", - "integrity": "sha512-bz3WtLuIZoLrJDKcdS7fPAdD/Qi9wKiKACl5cu+ftv9zg8w+qqYNLtjH9HxeUFbCtQRKqcdXjO/UZ8iL07hgsQ==", + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/image-q": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/image-q/-/image-q-4.0.0.tgz", + "integrity": "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1", - "perfect-freehand": "^1.2.2" + "@types/node": "16.9.1" } }, - "node_modules/@zag-js/slider": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/slider/-/slider-1.31.1.tgz", - "integrity": "sha512-FILbLTMd3BnyclZ28+ippfyqzYPGK60qZapxtTERmWDC75Okf8AFnTCQf84Y8jRmBKCS1yhjF+IOtkFAENeB6w==", + "node_modules/image-q/node_modules/@types/node": { + "version": "16.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz", + "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==", + "dev": true, + "license": "MIT" + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@zag-js/splitter": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/splitter/-/splitter-1.31.1.tgz", - "integrity": "sha512-7SGBT2/xKsOzeSQEg+Otn1XV3RHrAz3jTySjBRKoEmdxubhfREqbKotbGVG65aTve11fQnmJ3Oyt3GJOeraxLA==", + "node_modules/import-from-esm": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.4.tgz", + "integrity": "sha512-7EyUlPFC0HOlBDpUFGfYstsU7XHxZJKAAMzCT8wZ0hMW7b+hG51LIKTDcsgtz8Pu6YC0HqRVbX+rVUtsGMUKvg==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "debug": "^4.3.4", + "import-meta-resolve": "^4.0.0" + }, + "engines": { + "node": ">=16.20" } }, - "node_modules/@zag-js/steps": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/steps/-/steps-1.31.1.tgz", - "integrity": "sha512-KsBH38V3tH9/q8CDgx4sUSXLYwFdcp1crZy8hTIcN0RUiZ55PmqYKkN2znzBjTbaCW9yhP8kXsbuo2s8OIU5lQ==", + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true, "license": "MIT", - "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/@zag-js/store": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/store/-/store-1.31.1.tgz", - "integrity": "sha512-d5ZTRciTuXOGQ3nML15kQLaTiR1wJPxT1Fu1nN659X6Rl8DPtubYaRCZ3RCk9Kyiyg2z5HxeVqDswaDvGbM9Rg==", + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, "license": "MIT", - "dependencies": { - "proxy-compare": "3.0.1" + "engines": { + "node": ">=8" } }, - "node_modules/@zag-js/switch": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/switch/-/switch-1.31.1.tgz", - "integrity": "sha512-Jii3OSqSa9sQux+hvSRvp9dirzUF09+PAjrLjCQs+BT08EZ0XqeGvVzM0Wqf9LFy07HdLZntai3IUaXLF6byBw==", - "license": "MIT", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/focus-visible": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/@zag-js/tabs": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/tabs/-/tabs-1.31.1.tgz", - "integrity": "sha512-QBq4ngpBNMNEI7Wuaq8llwHOqgcVbNHHEDC5zHg60Bf7MY5ltP8wSq6Kldu0zZRVwrLzanYoMELDUyf9H0vtnw==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "12.11.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-12.11.1.tgz", + "integrity": "sha512-9VF7mrY+3OmsAfjH3yKz/pLbJ5z22E23hENKw3/LNSaA/sAt3v49bDRY+Ygct1xwuKT+U+cBfTzjCPySna69Qw==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/prompts": "^7.10.1", + "@inquirer/type": "^3.0.10", + "mute-stream": "^2.0.0", + "run-async": "^4.0.6", + "rxjs": "^7.8.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@zag-js/tags-input": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/tags-input/-/tags-input-1.31.1.tgz", - "integrity": "sha512-V4lJe/aMIs7WVoXYfszU6E3iARLLRQFMiycu76/slb8NWJiLrkSIaMQ4FAe2pqkodgCWXA83tuaeAZRq7ouTFg==", + "node_modules/intersection-observer": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.12.2.tgz", + "integrity": "sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==", + "deprecated": "The Intersection Observer polyfill is no longer needed and can safely be removed. Intersection Observer has been Baseline since 2019.", + "license": "Apache-2.0" + }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "dev": true, "license": "MIT", - "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/auto-resize": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/interact-outside": "1.31.1", - "@zag-js/live-region": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "engines": { + "node": ">= 12" } }, - "node_modules/@zag-js/timer": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/timer/-/timer-1.31.1.tgz", - "integrity": "sha512-bXfeSbneWGOBKlD5dYq06T8CSY9Ky+qb1yIfJAFsRF4n34mpUYRdtfwpNQYyddGpkLD7oH4VibajeZXB7HaL0g==", + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@zag-js/toast": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/toast/-/toast-1.31.1.tgz", - "integrity": "sha512-MueHEei9ol3H6tWBruLxF7yEUpV3vsJ8brTQVRRtPr/6pqBs5kGzfL4YskhQ2tiwO6egay8YrkbaS3xJfpKt4w==", + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dismissable": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@zag-js/toggle": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/toggle/-/toggle-1.31.1.tgz", - "integrity": "sha512-HbFBuGfdyYkNvOp3cEB8Civ4E92finT4u3e4LKysB4/LboqKA0cJvFhSnHyThbROONTx06W/3CxwoSFR4o8IhA==", + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, "license": "MIT", - "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@zag-js/toggle-group": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/toggle-group/-/toggle-group-1.31.1.tgz", - "integrity": "sha512-Mojc7mex01/gvwXfrUIIThzT7HOktZoMge9rrb6+P7rQX7ulyNXYPjQrW2tay+t54GOJ3xODo9dU7PpRzXeHbw==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "license": "MIT", - "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@zag-js/tooltip": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/tooltip/-/tooltip-1.31.1.tgz", - "integrity": "sha512-pWEU5XhEPpnyl2VLrGJlyjj7+p+X0UX3Fld+WGhc/hCaWiuW2ZzD/ewDRhSOZu4/TzAO3axrPqG1YhW4fhogKQ==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "license": "MIT", - "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/focus-visible": "1.31.1", - "@zag-js/popper": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "engines": { + "node": ">=8" } }, - "node_modules/@zag-js/tour": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/tour/-/tour-1.31.1.tgz", - "integrity": "sha512-ZmcAevXxoENHmHG0xwdIt1oCLe2/DW1CEBFPr7YuGKc+FU3QbBVZMzcBHrJCe0nkKXhUKzHOHM78bOHD/gM76w==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "license": "MIT", "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dismissable": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/focus-trap": "1.31.1", - "@zag-js/interact-outside": "1.31.1", - "@zag-js/popper": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@zag-js/tree-view": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/tree-view/-/tree-view-1.31.1.tgz", - "integrity": "sha512-Q+VSQz7X1XR8gT7ICWXlQOJIvzTWw/9BlF7B073UpEgAKRFlD11FmERka5y/BYqj8uE0vazcbSEA3Vc2dgCMJA==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "license": "MIT", - "dependencies": { - "@zag-js/anatomy": "1.31.1", - "@zag-js/collection": "1.31.1", - "@zag-js/core": "1.31.1", - "@zag-js/dom-query": "1.31.1", - "@zag-js/types": "1.31.1", - "@zag-js/utils": "1.31.1" + "engines": { + "node": ">=0.12.0" } }, - "node_modules/@zag-js/types": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/types/-/types-1.31.1.tgz", - "integrity": "sha512-mKw5DoeBjFykfUHv3ifCRjcogFTqp0aCCsmqQMfnf+J/mg2aXpAx76AXT1PYXAVVhxdP6qGXNd0mOQZDVrIlSQ==", + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, "license": "MIT", - "dependencies": { - "csstype": "3.2.3" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@zag-js/utils": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/@zag-js/utils/-/utils-1.31.1.tgz", - "integrity": "sha512-KLm0pmOtf4ydALbaVLboL7W98TDVxwVVLvSuvtRgV53XTjlsVopTRA5/Xmzq2NhWujDZAXv7bRV603NDgDcjSw==", + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, "license": "MIT" }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "dev": true, "license": "MIT", "engines": { - "node": ">= 14" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" + "dependencies": { + "is-docker": "^2.0.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "engines": { + "node": ">=8" } }, - "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "dequal": "^2.0.3" + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, "engines": { - "node": ">=12" + "node": ">=10" } }, - "node_modules/async-mutex": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.5.0.tgz", - "integrity": "sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==", + "node_modules/jest-diff": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", + "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", + "dev": true, "license": "MIT", "dependencies": { - "tslib": "^2.4.0" + "@jest/diff-sequences": "30.0.1", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=10", - "npm": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/babel-plugin-react-compiler": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz", - "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", + "node_modules/jest-diff/node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.26.0" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/baseline-browser-mapping": { - "version": "2.9.14", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.14.tgz", - "integrity": "sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==", + "node_modules/jest-diff/node_modules/pretty-format": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", + "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", "dev": true, - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.js" + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/before-after-hook": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", - "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", + "node_modules/jest-diff/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "Apache-2.0" + "license": "MIT" }, - "node_modules/bidi-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", - "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "node_modules/jest-matcher-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz", + "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==", "dev": true, "license": "MIT", "dependencies": { - "require-from-string": "^2.0.2" + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "jest-diff": "30.2.0", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" - }, - "bin": { - "browserslist": "cli.js" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "node_modules/jest-matcher-utils/node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/jest-matcher-utils/node_modules/pretty-format": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", + "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "dev": true, "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, "engines": { - "node": ">=6" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001763", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001763.tgz", - "integrity": "sha512-mh/dGtq56uN98LlNX9qdbKnzINhX0QzhiWBFEkFfsFO4QyCvL8YegrJAazCwXIeqkIob8BlZPGM3xdnY+sgmvQ==", + "node_modules/jest-matcher-utils/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" + "license": "MIT" }, - "node_modules/chai": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "node_modules/jest-message-util": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz", + "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.2.0", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "micromatch": "^4.0.8", + "pretty-format": "30.2.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, "engines": { - "node": ">=18" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=12" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/jest-message-util/node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=7.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", + "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, "license": "MIT" }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "node_modules/jest-mock": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz", + "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==", + "dev": true, "license": "MIT", "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "@jest/types": "30.2.0", + "@types/node": "*", + "jest-util": "30.2.0" }, "engines": { - "node": ">=10" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/cosmiconfig/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "license": "ISC", + "node_modules/jest-regex-util": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", + "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 6" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "node_modules/jest-util": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", + "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", "dev": true, "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.2" }, "engines": { - "node": ">= 8" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/css-tree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", - "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { - "mdn-data": "2.12.2", - "source-map-js": "^1.0.1" + "color-convert": "^2.0.1" }, "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cssstyle": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz", - "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==", + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/css-color": "^4.1.1", - "@csstools/css-syntax-patches-for-csstree": "^1.0.21", - "css-tree": "^3.1.0", - "lru-cache": "^11.2.4" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=20" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/cssstyle/node_modules/lru-cache": { - "version": "11.2.4", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", - "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "node_modules/jimp": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/jimp/-/jimp-1.6.0.tgz", + "integrity": "sha512-YcwCHw1kiqEeI5xRpDlPPBGL2EOpBKLwO4yIBJcXWHPj5PnA5urGq0jbyhM5KoNpypQ6VboSoxc9D8HyfvngSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/diff": "1.6.0", + "@jimp/js-bmp": "1.6.0", + "@jimp/js-gif": "1.6.0", + "@jimp/js-jpeg": "1.6.0", + "@jimp/js-png": "1.6.0", + "@jimp/js-tiff": "1.6.0", + "@jimp/plugin-blit": "1.6.0", + "@jimp/plugin-blur": "1.6.0", + "@jimp/plugin-circle": "1.6.0", + "@jimp/plugin-color": "1.6.0", + "@jimp/plugin-contain": "1.6.0", + "@jimp/plugin-cover": "1.6.0", + "@jimp/plugin-crop": "1.6.0", + "@jimp/plugin-displace": "1.6.0", + "@jimp/plugin-dither": "1.6.0", + "@jimp/plugin-fisheye": "1.6.0", + "@jimp/plugin-flip": "1.6.0", + "@jimp/plugin-hash": "1.6.0", + "@jimp/plugin-mask": "1.6.0", + "@jimp/plugin-print": "1.6.0", + "@jimp/plugin-quantize": "1.6.0", + "@jimp/plugin-resize": "1.6.0", + "@jimp/plugin-rotate": "1.6.0", + "@jimp/plugin-threshold": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/jpeg-js": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "license": "MIT", "engines": { - "node": "20 || >=22" + "node": ">=14" } }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, - "node_modules/data-urls": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.0.tgz", - "integrity": "sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==", + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.4.0.tgz", + "integrity": "sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==", "dev": true, "license": "MIT", "dependencies": { + "@acemir/cssom": "^0.9.28", + "@asamuzakjp/dom-selector": "^6.7.6", + "@exodus/bytes": "^1.6.0", + "cssstyle": "^5.3.4", + "data-urls": "^6.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.0", "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^15.0.0" + "whatwg-url": "^15.1.0", + "ws": "^8.18.3", + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=20" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, - "engines": { - "node": ">=6.0" + "peerDependencies": { + "canvas": "^3.0.0" }, "peerDependenciesMeta": { - "supports-color": { + "canvas": { "optional": true } } }, - "node_modules/decimal.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", - "dev": true, - "license": "MIT" - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, "engines": { "node": ">=6" } }, - "node_modules/derive-valtio": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/derive-valtio/-/derive-valtio-0.2.0.tgz", - "integrity": "sha512-6slhaFHtfaL3t5dLYaQt6s4G2xZymhu0Ktdl7OMeVk8+46RgR8ft6FL0Tr4F31W+yPH03nJe1SSP4JFy2hSMRA==", - "license": "MIT", - "peerDependencies": { - "valtio": ">=2.0.0-rc.0" - } + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" }, - "node_modules/dom-accessibility-api": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "license": "MIT", - "peer": true - }, - "node_modules/dotenv": { - "version": "17.2.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", - "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" + "bin": { + "json5": "lib/cli.js" }, - "funding": { - "url": "https://dotenvx.com" + "engines": { + "node": ">=6" } }, - "node_modules/dotenv-cli": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-11.0.0.tgz", - "integrity": "sha512-r5pA8idbk7GFWuHEU7trSTflWcdBpQEK+Aw17UrSHjS6CReuhrrPcyC3zcQBPQvhArRHnBo/h6eLH1fkCvNlww==", + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "dev": true, "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.6", - "dotenv": "^17.1.0", - "dotenv-expand": "^12.0.0", - "minimist": "^1.2.6" + "universalify": "^2.0.0" }, - "bin": { - "dotenv": "cli.js" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/dotenv-expand": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-12.0.3.tgz", - "integrity": "sha512-uc47g4b+4k/M/SeaW1y4OApx+mtLWl92l5LMPP0GNXctZqELk+YGgOPIIC5elYmUH4OuoK3JLhuRUYegeySiFA==", + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", "dev": true, - "license": "BSD-2-Clause", + "license": "(MIT OR GPL-3.0-or-later)", "dependencies": { - "dotenv": "^16.4.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" } }, - "node_modules/dotenv-expand/node_modules/dotenv": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/electron-to-chromium": { - "version": "1.5.267", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", - "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, - "license": "ISC" + "license": "MIT" }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } }, - "node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "engines": { + "node": ">= 0.6.3" } }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, "license": "MIT", "dependencies": { - "is-arrayish": "^0.2.1" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, "license": "MIT" }, - "node_modules/es-toolkit": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.43.0.tgz", - "integrity": "sha512-SKCT8AsWvYzBBuUqMk4NPwFlSdqLpJwmy6AP322ERn8W2YLIB6JBXnwMI2Qsh2gfphT3q7EKAxKb23cvFHFwKA==", + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, "license": "MIT", - "workspaces": [ - "docs", - "benchmarks" - ] + "dependencies": { + "safe-buffer": "~5.1.0" + } }, - "node_modules/esbuild": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", - "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.2", - "@esbuild/android-arm": "0.27.2", - "@esbuild/android-arm64": "0.27.2", - "@esbuild/android-x64": "0.27.2", - "@esbuild/darwin-arm64": "0.27.2", - "@esbuild/darwin-x64": "0.27.2", - "@esbuild/freebsd-arm64": "0.27.2", - "@esbuild/freebsd-x64": "0.27.2", - "@esbuild/linux-arm": "0.27.2", - "@esbuild/linux-arm64": "0.27.2", - "@esbuild/linux-ia32": "0.27.2", - "@esbuild/linux-loong64": "0.27.2", - "@esbuild/linux-mips64el": "0.27.2", - "@esbuild/linux-ppc64": "0.27.2", - "@esbuild/linux-riscv64": "0.27.2", - "@esbuild/linux-s390x": "0.27.2", - "@esbuild/linux-x64": "0.27.2", - "@esbuild/netbsd-arm64": "0.27.2", - "@esbuild/netbsd-x64": "0.27.2", - "@esbuild/openbsd-arm64": "0.27.2", - "@esbuild/openbsd-x64": "0.27.2", - "@esbuild/openharmony-arm64": "0.27.2", - "@esbuild/sunos-x64": "0.27.2", - "@esbuild/win32-arm64": "0.27.2", - "@esbuild/win32-ia32": "0.27.2", - "@esbuild/win32-x64": "0.27.2" + "dependencies": { + "immediate": "~3.0.5" } }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/locate-app": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/locate-app/-/locate-app-2.5.0.tgz", + "integrity": "sha512-xIqbzPMBYArJRmPGUZD9CzV9wOqmVtQnaAn3wrj3s6WYW0bQvPI7x+sPYUGmDTYMHefVK//zc6HEYZ1qnxIK+Q==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/hejny/locate-app/blob/main/README.md#%EF%B8%8F-contributing" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@promptbook/utils": "0.69.5", + "type-fest": "4.26.0", + "userhome": "1.0.1" } }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", + "node_modules/locate-app/node_modules/type-fest": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.0.tgz", + "integrity": "sha512-OduNjVJsFbifKb57UqZ2EMP1i4u64Xwow3NYXUtBbD4vIwJdQd4+xl8YDou1dlm4DVrtwT/7Ky8z8WyCULVfxw==", + "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=10" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "^1.0.0" + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "license": "MIT" }, - "node_modules/exifr": { - "version": "7.1.3", - "resolved": "git+ssh://git@github.com/m-hayabusa/exifr.git#2cf6c14fcd8eab52a7a7de53af7fdb01a4a9f90f", - "integrity": "sha512-AxJQk4la979LUL0NrfXAozPZi0UGHVaz1ZfcfqLpl8trOv78T3QWle8sepO0ZqfyRhg8NWp4pVYauOXbHcFUUQ==", + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "dev": true, "license": "MIT" }, - "node_modules/exifreader": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/exifreader/-/exifreader-4.35.0.tgz", - "integrity": "sha512-qiMONyOObmwI6sIXy13vRGqlcoi9VUKr70iGI1aefP+xJsbcXp+hcyL/4J6hov/yG9UhS7Hq1OQ1hAoSEZl+RA==", - "hasInstallScript": true, - "license": "MPL-2.0", - "optionalDependencies": { - "@xmldom/xmldom": "^0.9.4" - } - }, - "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.0.0" - } + "license": "MIT" }, - "node_modules/fast-content-type-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", - "integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==", + "node_modules/lodash.pickby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", + "integrity": "sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], "license": "MIT" }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } + "license": "MIT" }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "node_modules/lodash.zip": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", + "integrity": "sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==", + "dev": true, "license": "MIT" }, - "node_modules/framer-motion": { - "version": "12.25.0", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.25.0.tgz", - "integrity": "sha512-mlWqd0rApIjeyhTCSNCqPYsUAEhkcUukZxH3ke6KbstBRPcxhEpuIjmiUQvB+1E9xkEm5SpNHBgHCapH/QHTWg==", + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, "license": "MIT", "dependencies": { - "motion-dom": "^12.24.11", - "motion-utils": "^12.24.10", - "tslib": "^2.4.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, - "peerDependencies": { - "@emotion/is-prop-valid": "*", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" + "engines": { + "node": ">=10" }, - "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fs-extra": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", - "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=14.14" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", + "node": ">=10" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, "license": "MIT", "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globals": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.0.0.tgz", - "integrity": "sha512-gv5BeD2EssA793rlFWVPMMCqefTlpusw6/2TbAVMy0FzcG8wKJn4O+NqJ4+XWmmwrayJgw5TzrmWjFgmz1XPqw==", + "node_modules/loglevel": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">= 0.6.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" } }, - "node_modules/globrex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", - "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "node_modules/loglevel-plugin-prefix": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", + "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", "dev": true, "license": "MIT" }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, - "license": "ISC" + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" + "peer": true, + "bin": { + "lz-string": "bin/bin.js" } }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "license": "BSD-3-Clause", + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", "dependencies": { - "react-is": "^16.7.0" + "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/html-encoding-sniffer": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", - "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { - "@exodus/bytes": "^1.6.0" + "braces": "^3.0.3", + "picomatch": "^2.3.1" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + "node": ">=8.6" } }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, "engines": { - "node": ">= 14" + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", "dev": true, "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" + "bin": { + "mime": "cli.js" }, "engines": { - "node": ">= 14" + "node": ">=10.0.0" } }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/import-from-esm": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.4.tgz", - "integrity": "sha512-7EyUlPFC0HOlBDpUFGfYstsU7XHxZJKAAMzCT8wZ0hMW7b+hG51LIKTDcsgtz8Pu6YC0HqRVbX+rVUtsGMUKvg==", + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "debug": "^4.3.4", - "import-meta-resolve": "^4.0.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=16.20" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/import-meta-resolve": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", - "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, "license": "MIT", "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, - "license": "MIT", + "license": "ISC", "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true, "license": "MIT" }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "node_modules/mocha": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" }, - "engines": { - "node": ">= 0.4" + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "node_modules/mocha/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "license": "MIT", - "bin": { - "is-docker": "cli.js" + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">=8" + "node": ">= 8.10.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "node_modules/mocha/node_modules/diff": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz", + "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==", "dev": true, - "license": "MIT" + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", "dependencies": { - "is-docker": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "license": "ISC" + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "node_modules/jiti": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } }, - "node_modules/jsdom": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.4.0.tgz", - "integrity": "sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==", + "node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", "dependencies": { - "@acemir/cssom": "^0.9.28", - "@asamuzakjp/dom-selector": "^6.7.6", - "@exodus/bytes": "^1.6.0", - "cssstyle": "^5.3.4", - "data-urls": "^6.0.0", - "decimal.js": "^10.6.0", - "html-encoding-sniffer": "^6.0.0", - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.6", - "is-potential-custom-element-name": "^1.0.1", - "parse5": "^8.0.0", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^6.0.0", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^8.0.0", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^15.1.0", - "ws": "^8.18.3", - "xml-name-validator": "^5.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" - }, - "peerDependencies": { - "canvas": "^3.0.0" + "node": ">=10" }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" + "dependencies": { + "p-limit": "^3.0.2" }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "node_modules/mocha/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/jsonfile": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "node_modules/mocha/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" + "engines": { + "node": ">=8.6" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "node_modules/mocha/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "yallist": "^3.0.2" + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" } }, - "node_modules/lz-string": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", - "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "license": "MIT", - "peer": true, - "bin": { - "lz-string": "bin/bin.js" + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" } }, - "node_modules/mdn-data": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", - "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "node_modules/mocha/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, - "license": "CC0-1.0" + "license": "ISC", + "engines": { + "node": ">=10" + } }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "node_modules/mocha/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "node_modules/modern-tar": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/modern-tar/-/modern-tar-0.7.3.tgz", + "integrity": "sha512-4W79zekKGyYU4JXVmB78DOscMFaJth2gGhgfTl2alWE4rNe3nf4N2pqenQ0rEtIewrnD79M687Ouba3YGTLOvg==", "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=18.0.0" } }, "node_modules/motion": { @@ -5033,6 +9960,16 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/nanoid": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.6.tgz", @@ -5051,6 +9988,16 @@ "node": "^18 || >=20" } }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/next-themes": { "version": "0.4.6", "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", @@ -5068,6 +10015,100 @@ "dev": true, "license": "MIT" }, + "node_modules/normalize-package-data": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-7.0.1.tgz", + "integrity": "sha512-linxNAT6M0ebEYZOx2tO6vBEFsVgnPpv+AVjk0wJHfaUIbq31Jm3T6vvZaarnOeWDh8ShnwXuaAyM7WT3RzErA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^8.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/obug": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", @@ -5079,6 +10120,23 @@ ], "license": "MIT" }, + "node_modules/omggif": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/open": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", @@ -5097,6 +10155,86 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dev": true, + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true, + "license": "(MIT AND Zlib)" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5109,6 +10247,31 @@ "node": ">=6" } }, + "node_modules/parse-bmfont-ascii": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", + "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-bmfont-binary": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", + "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-bmfont-xml": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.6.tgz", + "integrity": "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-parse-from-string": "^1.0.0", + "xml2js": "^0.5.0" + } + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -5127,6 +10290,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse5": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", @@ -5140,6 +10316,69 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream/node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -5156,6 +10395,30 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -5165,10 +10428,31 @@ "node": ">=8" } }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/peek-readable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", + "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "dev": true, "license": "MIT" }, @@ -5197,6 +10481,29 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pixelmatch": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.3.0.tgz", + "integrity": "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "pngjs": "^6.0.0" + }, + "bin": { + "pixelmatch": "bin/pixelmatch" + } + }, + "node_modules/pixelmatch/node_modules/pngjs": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", + "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.13.0" + } + }, "node_modules/plist": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", @@ -5220,6 +10527,16 @@ "node": ">=10.0.0" } }, + "node_modules/pngjs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", + "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.19.0" + } + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -5292,12 +10609,92 @@ "license": "MIT", "peer": true }, + "node_modules/pretty-ms": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz", + "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/proxy-compare": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-3.0.1.tgz", "integrity": "sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==", "license": "MIT" }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "license": "MIT" + }, "node_modules/proxy-memoize": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/proxy-memoize/-/proxy-memoize-3.0.1.tgz", @@ -5307,6 +10704,17 @@ "proxy-compare": "^3.0.0" } }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -5317,96 +10725,365 @@ "node": ">=6" } }, + "node_modules/query-selector-shadow-dom": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz", + "integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/react": { "version": "19.2.3", "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.3" + } + }, + "node_modules/react-error-boundary": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-6.0.3.tgz", + "integrity": "sha512-5guqn2UYpCFjE8UDMA8J7Kke+YSGBFrKQRJb3XdcaGZXYINZfQXgBt3ifY6MvjkN7QROc5A8zclyoSCwrcRUKw==", + "license": "MIT", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT" + }, + "node_modules/react-hotkeys-hook": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/react-hotkeys-hook/-/react-hotkeys-hook-5.2.1.tgz", + "integrity": "sha512-xbKh6zJxd/vJHT4Bw4+0pBD662Fk20V+VFhLqciCg+manTVO4qlqRqiwFOYelfHN9dBvWj9vxaPkSS26ZSIJGg==", + "license": "MIT", + "workspaces": [ + "packages/*" + ], + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/react-icons": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-redux": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", + "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.1.0.tgz", + "integrity": "sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.1", + "normalize-package-data": "^6.0.0", + "parse-json": "^7.0.0", + "type-fest": "^4.2.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-10.1.0.tgz", + "integrity": "sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^6.3.0", + "read-pkg": "^8.1.0", + "type-fest": "^4.2.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/read-pkg/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-pkg/node_modules/lines-and-columns": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", + "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/read-pkg/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/read-pkg/node_modules/parse-json": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz", + "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.21.4", + "error-ex": "^1.3.2", + "json-parse-even-better-errors": "^3.0.0", + "lines-and-columns": "^2.0.3", + "type-fest": "^3.8.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/parse-json/node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dev": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", + "node_modules/readable-web-to-node-stream": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz", + "integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==", + "dev": true, "license": "MIT", "dependencies": { - "scheduler": "^0.27.0" + "readable-stream": "^4.7.0" }, - "peerDependencies": { - "react": "^19.2.3" + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" } }, - "node_modules/react-error-boundary": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-6.0.3.tgz", - "integrity": "sha512-5guqn2UYpCFjE8UDMA8J7Kke+YSGBFrKQRJb3XdcaGZXYINZfQXgBt3ifY6MvjkN7QROc5A8zclyoSCwrcRUKw==", - "license": "MIT", - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0" + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.1.0" } }, - "node_modules/react-hotkeys-hook": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/react-hotkeys-hook/-/react-hotkeys-hook-5.2.1.tgz", - "integrity": "sha512-xbKh6zJxd/vJHT4Bw4+0pBD662Fk20V+VFhLqciCg+manTVO4qlqRqiwFOYelfHN9dBvWj9vxaPkSS26ZSIJGg==", - "license": "MIT", - "workspaces": [ - "packages/*" - ], - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" } }, - "node_modules/react-icons": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", - "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, "license": "MIT", - "peerDependencies": { - "react": "*" + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" - }, - "node_modules/react-redux": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", - "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", "dev": true, "license": "MIT", "dependencies": { - "@types/use-sync-external-store": "^0.0.6", - "use-sync-external-store": "^1.4.0" - }, - "peerDependencies": { - "@types/react": "^18.2.25 || ^19", - "react": "^18.0 || ^19", - "redux": "^5.0.0" + "minimatch": "^3.0.5" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "redux": { - "optional": true - } + "engines": { + "node": ">=6.0.0" } }, - "node_modules/react-refresh": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", - "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "node_modules/recursive-readdir/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/recursive-readdir/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, "engines": { - "node": ">=0.10.0" + "node": "*" } }, "node_modules/redent": { @@ -5443,6 +11120,12 @@ "node": ">=0.10.0" } }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "license": "MIT" + }, "node_modules/resolve": { "version": "1.22.11", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", @@ -5472,6 +11155,43 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/resq": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resq/-/resq-1.11.0.tgz", + "integrity": "sha512-G10EBz+zAAy3zUd/CDoBbXRL6ia9kOo3xRHrMDsHljI0GDkhYlyjwoCx5+3eCC4swi1uCoZQhskuJkj7Gp57Bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^2.0.1" + } + }, + "node_modules/ret": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.5.0.tgz", + "integrity": "sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/rgb2hex": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.2.5.tgz", + "integrity": "sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==", + "dev": true, + "license": "MIT" + }, "node_modules/rollup": { "version": "4.55.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz", @@ -5558,6 +11278,94 @@ "node": ">= 12" } }, + "node_modules/run-async": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-4.0.6.tgz", + "integrity": "sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safaridriver": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safaridriver/-/safaridriver-1.0.1.tgz", + "integrity": "sha512-jkg4434cYgtrIF2AeY/X0Wmd2W73cK5qIEFE3hDrrQenJH/2SDJIXGvPAigfvQTcE9+H31zkiNHbUqcihEiMRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex2": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-5.0.0.tgz", + "integrity": "sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "ret": "~0.5.0" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", + "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -5577,6 +11385,18 @@ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, + "node_modules/screenfull": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz", + "integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -5587,6 +11407,39 @@ "semver": "bin/semver.js" } }, + "node_modules/serialize-error": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-12.0.0.tgz", + "integrity": "sha512-ZYkZLAvKTKQXWuh5XpBw7CdbSzagarX39WyZ2H07CDLC5/KfsRGlIXV8d4+tfqX1M7916mRqR1QfNHSij+c9Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^4.31.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true, + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -5607,16 +11460,90 @@ "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-xml-to-json": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/simple-xml-to-json/-/simple-xml-to-json-1.2.3.tgz", + "integrity": "sha512-kWJDCr9EWtZ+/EYYM5MareWj2cRnZGF93YDNpH4jQiHB+hBIZnfPFSQiVMzZOdk+zXWqTZ/9fTeQNu2DqeiudA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.12.2" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" } }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true, - "license": "ISC" - }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -5636,6 +11563,92 @@ "node": ">=0.10.0" } }, + "node_modules/spacetrim": { + "version": "0.11.59", + "resolved": "https://registry.npmjs.org/spacetrim/-/spacetrim-0.11.59.tgz", + "integrity": "sha512-lLYsktklSRKprreOm7NXReW8YiX2VBjbgmXYEziOoGf/qsJqAEACaDvoTtUOycwjpaSh+bT8eu0KrJn7UNxiCg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/hejny/spacetrim/blob/main/README.md#%EF%B8%8F-contributing" + } + ], + "license": "Apache-2.0" + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -5650,6 +11663,38 @@ "dev": true, "license": "MIT" }, + "node_modules/stream-buffers": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.3.tgz", + "integrity": "sha512-pqMqwQCso0PBJt2PQmDO0cFj0lyqmiwOMiMSkVtRokl7e+ZTRYgDHKnuZNbqjiJXgsg4nuqtD/zxuo9KqTp0Yw==", + "dev": true, + "license": "Unlicense", + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/streamx": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "events-universal": "^1.0.0", + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -5665,6 +11710,22 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -5678,6 +11739,33 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -5691,12 +11779,69 @@ "node": ">=8" } }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strnum": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", + "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/strtok3": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", "license": "MIT" }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -5716,6 +11861,33 @@ "dev": true, "license": "MIT" }, + "node_modules/tar-fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/tauri-plugin-clipboard-api": { "version": "2.1.11", "resolved": "https://registry.npmjs.org/tauri-plugin-clipboard-api/-/tauri-plugin-clipboard-api-2.1.11.tgz", @@ -5767,6 +11939,16 @@ "tslib": "^2.1.0" } }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -5774,6 +11956,13 @@ "dev": true, "license": "MIT" }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", + "dev": true, + "license": "MIT" + }, "node_modules/tinyexec": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", @@ -5841,6 +12030,37 @@ "node": ">=14.14" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/token-types": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", + "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/tough-cookie": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", @@ -5867,6 +12087,30 @@ "node": ">=20" } }, + "node_modules/tscanner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/tscanner/-/tscanner-0.1.3.tgz", + "integrity": "sha512-SClAEZl8wnBrp+R31RYDcyFpWODep3/4qH8kS4pzzrv616G6BXLjJDQoU+GSLL5Ec4OG4iYK3tZD4M18Q9/G6Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "zod": "^4.1.12" + }, + "bin": { + "tscanner": "dist/main.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@tscanner/cli-darwin-arm64": "0.1.3", + "@tscanner/cli-darwin-x64": "0.1.3", + "@tscanner/cli-linux-arm64": "0.1.3", + "@tscanner/cli-linux-x64": "0.1.3", + "@tscanner/cli-win32-x64": "0.1.3" + } + }, "node_modules/tsconfck": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", @@ -5894,6 +12138,39 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", @@ -5908,6 +12185,16 @@ "node": ">=14.17" } }, + "node_modules/undici": { + "version": "7.19.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.19.2.tgz", + "integrity": "sha512-4VQSpGEGsWzk0VYxyB/wVX/Q7qf9t5znLRgs0dzszr9w9Fej/8RVNQ+S20vdXSAyra/bJ7ZQfGv6ZMj7UEbzSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, "node_modules/undici-types": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", @@ -5915,6 +12202,19 @@ "dev": true, "license": "MIT" }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/universal-user-agent": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", @@ -5969,16 +12269,50 @@ "integrity": "sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==", "license": "MIT" }, - "node_modules/use-sync-external-store": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", - "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "node_modules/urlpattern-polyfill": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.1.0.tgz", + "integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/userhome": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/userhome/-/userhome-1.0.1.tgz", + "integrity": "sha512-5cnLm4gseXjAclKowC4IjByaGsjtAoV6PrOQOljplNB54ReUYJP8HdAFq2muHinSDAh09PPX/uXDPfdxRHvuSA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/utif2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/utif2/-/utif2-4.1.0.tgz", + "integrity": "sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w==", "dev": true, "license": "MIT", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + "dependencies": { + "pako": "^1.0.11" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, "node_modules/valibot": { "version": "0.40.0", "resolved": "https://registry.npmjs.org/valibot/-/valibot-0.40.0.tgz", @@ -5993,6 +12327,17 @@ } } }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "node_modules/valtio": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/valtio/-/valtio-2.3.0.tgz", @@ -6292,6 +12637,190 @@ "node": ">=18" } }, + "node_modules/wait-port": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/wait-port/-/wait-port-1.1.0.tgz", + "integrity": "sha512-3e04qkoN3LxTMLakdqeWth8nih8usyg+sf1Bgdf9wwUkp05iuK1eSY/QpLvscT/+F/gA89+LpUmmgBtesbqI2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "commander": "^9.3.0", + "debug": "^4.3.4" + }, + "bin": { + "wait-port": "bin/wait-port.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/wait-port/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wait-port/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/wait-port/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webdriver": { + "version": "9.23.2", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.23.2.tgz", + "integrity": "sha512-HZy3eydZbmex0pbyLwHaDsAyZ+S+V4XQTdGK/nAOi4uPa74U6yT9vXqtb+3B+5/LDM7L8kTD6Z3b1y4gB4pmTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0", + "@types/ws": "^8.5.3", + "@wdio/config": "9.23.2", + "@wdio/logger": "9.18.0", + "@wdio/protocols": "9.23.2", + "@wdio/types": "9.23.2", + "@wdio/utils": "9.23.2", + "deepmerge-ts": "^7.0.3", + "https-proxy-agent": "^7.0.6", + "undici": "^6.21.3", + "ws": "^8.8.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/webdriver/node_modules/@types/node": { + "version": "20.19.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", + "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/webdriver/node_modules/undici": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz", + "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/webdriver/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/webdriverio": { + "version": "9.23.2", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.23.2.tgz", + "integrity": "sha512-VjfTw1bRJdBrzjoCu7BGThxn1JK2V7mAGvxibaBrCNIayPPQjLhVDNJPOVEiR7txM6zmOUWxhkCDxHjhMYirfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.11.30", + "@types/sinonjs__fake-timers": "^8.1.5", + "@wdio/config": "9.23.2", + "@wdio/logger": "9.18.0", + "@wdio/protocols": "9.23.2", + "@wdio/repl": "9.16.2", + "@wdio/types": "9.23.2", + "@wdio/utils": "9.23.2", + "archiver": "^7.0.1", + "aria-query": "^5.3.0", + "cheerio": "^1.0.0-rc.12", + "css-shorthand-properties": "^1.1.1", + "css-value": "^0.0.1", + "grapheme-splitter": "^1.0.4", + "htmlfy": "^0.8.1", + "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", + "lodash.clonedeep": "^4.5.0", + "lodash.zip": "^4.2.0", + "query-selector-shadow-dom": "^1.0.1", + "resq": "^1.11.0", + "rgb2hex": "0.2.5", + "serialize-error": "^12.0.0", + "urlpattern-polyfill": "^10.0.0", + "webdriver": "9.23.2" + }, + "engines": { + "node": ">=18.20.0" + }, + "peerDependencies": { + "puppeteer-core": ">=22.x || <=24.x" + }, + "peerDependenciesMeta": { + "puppeteer-core": { + "optional": true + } + } + }, + "node_modules/webdriverio/node_modules/@types/node": { + "version": "20.19.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", + "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/webdriverio/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, "node_modules/webidl-conversions": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", @@ -6302,6 +12831,33 @@ "node": ">=20" } }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/whatwg-mimetype": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", @@ -6359,6 +12915,13 @@ "node": ">=8" } }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -6377,6 +12940,41 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -6393,6 +12991,13 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, "node_modules/ws": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", @@ -6425,6 +13030,37 @@ "node": ">=18" } }, + "node_modules/xml-parse-from-string": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", + "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xml2js/node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, "node_modules/xmlbuilder": { "version": "15.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", @@ -6486,6 +13122,130 @@ "engines": { "node": ">=12" } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yauzl/node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zip-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 62e82ff..7f5f15e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "dtm", "author": "kcjerrell", "private": true, - "version": "0.2.1", + "version": "0.3.0", "type": "module", "scripts": { "dev": "tauri dev", @@ -16,7 +16,9 @@ "tauri": "dotenv -- tauri", "gen-icons": "tauri icon ./app-icon.png", "generate:entities": "dotenv -e .env -- sh -c 'sea-orm-cli generate entity --database-url \"$DB_URL\" --ignore-tables images_fts,images_fts_data,images_fts_docsize,images_fts_idx,images_fts_config,images_fts_content --output-dir src-tauri/entity/src --with-serde serialize --entity-format dense'", - "version": "tsx ./scripts/version.ts" + "version": "tsx ./scripts/version.ts", + "wdio": "wdio run ./wdio.conf.ts", + "test:release": "USE_RELEASE=true wdio run ./wdio.conf.ts" }, "dependencies": { "@chakra-ui/react": "^3.30.0", @@ -35,6 +37,7 @@ "@tauri-apps/plugin-window-state": "~2", "@tauri-store/valtio": "^3.2.0", "@uiw/react-json-view": "^2.0.0-alpha.40", + "ahooks": "^3.9.6", "async-mutex": "^0.5.0", "derive-valtio": "^0.2.0", "eventemitter3": "^5.0.1", @@ -63,19 +66,31 @@ "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.1", "@types/fs-extra": "^11.0.4", + "@types/mocha": "^10.0.10", + "@types/node": "^25.1.0", "@types/plist": "^3.0.5", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", + "@wdio/cli": "^9.23.2", + "@wdio/concise-reporter": "^9.23.3", + "@wdio/globals": "^9.23.0", + "@wdio/local-runner": "^9.23.2", + "@wdio/mocha-framework": "^9.23.2", + "@wdio/spec-reporter": "^9.23.2", + "@wdio/types": "^9.23.2", + "@wdio/visual-service": "^9.1.2", "babel-plugin-react-compiler": "^1.0.0", "dotenv": "^17.2.3", "dotenv-cli": "^11.0.0", + "expect-webdriverio": "^5.6.4", "fs-extra": "^11.3.3", "globals": "^17.0.0", "jiti": "^2.6.1", "jsdom": "^27.4.0", "react-redux": "^9.2.0", "rollup-plugin-visualizer": "^6.0.5", + "tscanner": "^0.1.3", "typescript": "^5.9.3", "vite": "^7.3.1", "vite-bundle-visualizer": "^1.2.1", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 608a407..55cf31c 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -515,6 +515,21 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "bit-set" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0481a0e032742109b1133a095184ee93d88f3dc9e0d28a5d033dc77a073f44f" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22" + [[package]] name = "bitflags" version = "1.3.2" @@ -1606,19 +1621,21 @@ dependencies = [ [[package]] name = "dtm" -version = "0.2.1" +version = "0.3.0" dependencies = [ "anyhow", "base64 0.22.1", "bytemuck", "byteorder", "bytes", + "cc", "chrono", "entity", "flatbuffers", "flate2", "fpzip-sys", "futures", + "futures-util", "half", "image", "little_exif", @@ -1633,10 +1650,13 @@ dependencies = [ "once_cell", "png 0.18.0", "quick-xml 0.38.4", + "regex", "sea-orm", "sea-query", "serde", "serde_json", + "sevenz-rust", + "sha2", "sqlx", "tauri", "tauri-build", @@ -1927,6 +1947,17 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "filetime_creation" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c25b5d475550e559de5b0c0084761c65325444e3b6c9e298af9cefe7a9ef3a5f" +dependencies = [ + "cfg-if", + "filetime", + "windows-sys 0.52.0", +] + [[package]] name = "find-msvc-tools" version = "0.1.7" @@ -3404,6 +3435,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +[[package]] +name = "lzma-rust" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baab2bbbd7d75a144d671e9ff79270e903957d92fb7386fd39034c709bd2661" +dependencies = [ + "byteorder", +] + [[package]] name = "mac" version = "0.1.1" @@ -3726,6 +3766,16 @@ dependencies = [ "serde", ] +[[package]] +name = "nt-time" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2de419e64947cd8830e66beb584acc3fb42ed411d103e3c794dda355d1b374b5" +dependencies = [ + "chrono", + "time", +] + [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -5894,6 +5944,23 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "sevenz-rust" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26482cf1ecce4540dc782fc70019eba89ffc4d87b3717eb5ec524b5db6fdefef" +dependencies = [ + "bit-set", + "byteorder", + "crc", + "filetime_creation", + "js-sys", + "lzma-rust", + "nt-time", + "sha2", + "wasm-bindgen", +] + [[package]] name = "sha1" version = "0.10.6" @@ -7219,7 +7286,9 @@ dependencies = [ "bytes", "libc", "mio", + "parking_lot", "pin-project-lite", + "signal-hook-registry", "socket2 0.6.1", "tokio-macros", "windows-sys 0.61.2", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 01f5525..8b76e23 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -3,7 +3,7 @@ members = ["migration", "entity", ".", "fpzip-sys"] [package] name = "dtm" -version = "0.2.1" +version = "0.3.0" description = "A little app for reading Draw Things Metadata" authors = ["kcjerrell"] edition = "2021" @@ -14,6 +14,7 @@ crate-type = ["staticlib", "cdylib", "rlib"] [build-dependencies] tauri-build = { version = "2", features = [] } +cc = "1.0" [dependencies] # Local Modules @@ -53,7 +54,7 @@ sea-orm = { version = "2.0.0-rc", features = [ # "debug-print" ] } futures = "0.3.28" -tokio = "1.48.0" +tokio = { version = "1.48.0", features = ["full"] } mime = "0.3.17" once_cell = "1.21.3" moka = { version = "0.12.11", features = ["future"] } @@ -73,6 +74,10 @@ sea-query = "1.0.0-rc.20" unicode-normalization = "0.1.25" log = "0.4" tauri-plugin-log = "2" +sevenz-rust = "0.6.1" +sha2 = "0.10.9" +futures-util = "0.3.31" +regex = "1.12.2" # macOS-only [target."cfg(target_os = \"macos\")".dependencies] diff --git a/src-tauri/build.rs b/src-tauri/build.rs index d860e1e..caa9b7e 100644 --- a/src-tauri/build.rs +++ b/src-tauri/build.rs @@ -1,3 +1,60 @@ fn main() { + #[cfg(target_os = "macos")] + { + use std::process::Command; + use std::env; + use std::path::PathBuf; + + println!("cargo:rerun-if-changed=src/swift/FolderPicker.swift"); + + let out_dir = env::var("OUT_DIR").unwrap(); + let target = env::var("TARGET").unwrap(); + let out_path = PathBuf::from(&out_dir); + let swift_file = "src/swift/FolderPicker.swift"; + let lib_name = "FolderPicker"; + let lib_path = out_path.join(format!("lib{}.a", lib_name)); + + // Map Rust target to Swift target + let swift_target = if target.contains("x86_64") { + "x86_64-apple-macosx14.0" + } else if target.contains("aarch64") { + "arm64-apple-macosx14.0" + } else { + panic!("Unsupported target architecture: {}", target); + }; + + let status = Command::new("swiftc") + .args(&[ + "-emit-library", + "-static", + "-target", swift_target, + "-o", lib_path.to_str().unwrap(), + swift_file + ]) + .status() + .expect("Failed to run swiftc"); + + if !status.success() { + panic!("swiftc failed"); + } + + // Find Swift library path + let swiftc_path_output = Command::new("xcrun") + .args(&["-f", "swiftc"]) + .output() + .expect("Failed to find swiftc"); + + let swiftc_path = String::from_utf8(swiftc_path_output.stdout).unwrap(); + let swiftc_path = swiftc_path.trim(); + let swift_lib_path = std::path::Path::new(swiftc_path) + .parent().unwrap() // bin + .parent().unwrap() // usr + .join("lib/swift/macosx"); + + println!("cargo:rustc-link-search=native={}", out_dir); + println!("cargo:rustc-link-search=native={}", swift_lib_path.display()); + println!("cargo:rustc-link-lib=static={}", lib_name); + } + tauri_build::build() } diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index e0f8ecc..6a2a45a 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -56,9 +56,6 @@ ] }, "http:default", - "nspopover:allow-hide-popover", - "nspopover:allow-is-popover-shown", - "nspopover:allow-show-popover", "opener:allow-open-path", "opener:allow-open-url", "opener:allow-default-urls", diff --git a/src-tauri/entity/src/images.rs b/src-tauri/entity/src/images.rs index dcc69e6..439c263 100644 --- a/src-tauri/entity/src/images.rs +++ b/src-tauri/entity/src/images.rs @@ -16,12 +16,14 @@ pub struct Model { #[sea_orm(column_type = "Blob", nullable)] pub thumbnail_half: Option>, pub clip_id: i64, + pub num_frames: Option, pub wall_clock: DateTimeUtc, pub model_id: Option, pub refiner_id: Option, #[sea_orm(column_type = "Float", nullable)] pub refiner_start: Option, pub upscaler_id: Option, + pub upscaler_scale_factor: Option, #[sea_orm(column_type = "Text")] pub prompt: String, #[sea_orm(column_type = "Text")] diff --git a/src-tauri/entity/src/projects.rs b/src-tauri/entity/src/projects.rs index 446e3ac..7b64f1b 100644 --- a/src-tauri/entity/src/projects.rs +++ b/src-tauri/entity/src/projects.rs @@ -9,10 +9,12 @@ use serde::Serialize; pub struct Model { #[sea_orm(primary_key)] pub id: i64, + pub fingerprint: String, #[sea_orm(unique)] pub path: String, pub filesize: Option, pub modified: Option, + pub missing_on: Option, pub excluded: bool, #[sea_orm(has_many)] pub images: HasMany, diff --git a/src-tauri/entity/src/watch_folders.rs b/src-tauri/entity/src/watch_folders.rs index 517ab88..8a1b456 100644 --- a/src-tauri/entity/src/watch_folders.rs +++ b/src-tauri/entity/src/watch_folders.rs @@ -1,6 +1,5 @@ //! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.19 -use crate::enums::ItemType; use sea_orm::entity::prelude::*; use serde::Serialize; @@ -12,8 +11,6 @@ pub struct Model { pub id: i64, pub path: String, pub recursive: Option, - #[sea_orm(num_enum)] - pub item_type: ItemType, pub last_updated: Option, } diff --git a/src-tauri/fpzip-sys/build.rs b/src-tauri/fpzip-sys/build.rs index 7ce1058..4cc25f7 100644 --- a/src-tauri/fpzip-sys/build.rs +++ b/src-tauri/fpzip-sys/build.rs @@ -32,7 +32,13 @@ fn main() { println!("cargo:rustc-link-lib=static=fpzip"); // Link C++ standard library - println!("cargo:rustc-link-lib=c++"); + // Link C++ standard library + let target = env::var("TARGET").unwrap(); + if target.contains("apple") { + println!("cargo:rustc-link-lib=c++"); + } else { + println!("cargo:rustc-link-lib=stdc++"); + } // Generate bindings let bindings = bindgen::Builder::default() diff --git a/src-tauri/migration/src/lib.rs b/src-tauri/migration/src/lib.rs index 2c605af..cd1f128 100644 --- a/src-tauri/migration/src/lib.rs +++ b/src-tauri/migration/src/lib.rs @@ -7,6 +7,8 @@ pub struct Migrator; #[async_trait::async_trait] impl MigratorTrait for Migrator { fn migrations() -> Vec> { - vec![Box::new(m20220101_000001_create_table::Migration)] + vec![ + Box::new(m20220101_000001_create_table::Migration), + ] } } diff --git a/src-tauri/migration/src/m20220101_000001_create_table.rs b/src-tauri/migration/src/m20220101_000001_create_table.rs index b43bdf9..a8a52fb 100644 --- a/src-tauri/migration/src/m20220101_000001_create_table.rs +++ b/src-tauri/migration/src/m20220101_000001_create_table.rs @@ -33,6 +33,13 @@ impl MigrationTrait for Migration { .not_null() .default(false), ) + .col( + ColumnDef::new(Projects::Fingerprint) + .string() + .not_null() + .default(""), + ) + .col(ColumnDef::new(Projects::MissingOn).big_integer().null()) .to_owned(), ) .await?; @@ -241,6 +248,12 @@ impl MigrationTrait for Migration { .not_null() .default(false), ) + .col(ColumnDef::new(Images::NumFrames).small_integer().null()) + .col( + ColumnDef::new(Images::UpscalerScaleFactor) + .small_unsigned() + .null(), + ) .foreign_key( ForeignKey::create() .name("fk_images_project") @@ -387,25 +400,18 @@ impl MigrationTrait for Migration { .primary_key() .auto_increment(), ) - .col(ColumnDef::new(WatchFolders::Path).string().not_null()) + .col( + ColumnDef::new(WatchFolders::Path) + .string() + .not_null() + .unique_key(), + ) .col( ColumnDef::new(WatchFolders::Recursive) .boolean() .default(false), ) - .col( - ColumnDef::new(WatchFolders::ItemType) - .tiny_integer() - .not_null(), - ) .col(ColumnDef::new(WatchFolders::LastUpdated).integer().null()) - .index( - Index::create() - .name("idx_watch_folders_path_item_type") - .col(WatchFolders::Path) - .col(WatchFolders::ItemType) - .unique(), - ) .to_owned(), ) .await?; @@ -468,6 +474,8 @@ enum Projects { Filesize, Modified, Excluded, + Fingerprint, + MissingOn, } #[derive(Iden)] @@ -531,6 +539,8 @@ enum Images { HasCustom, HasScribble, HasShuffle, + NumFrames, + UpscalerScaleFactor, } #[derive(Iden)] @@ -555,6 +565,5 @@ enum WatchFolders { Id, Path, Recursive, - ItemType, LastUpdated, } diff --git a/src-tauri/src/bookmarks.rs b/src-tauri/src/bookmarks.rs new file mode 100644 index 0000000..f408ba6 --- /dev/null +++ b/src-tauri/src/bookmarks.rs @@ -0,0 +1,128 @@ +use tauri::command; + +#[cfg(target_os = "macos")] +mod ffi { + use std::os::raw::c_char; + + extern "C" { + pub fn open_dt_folder_picker(default_path: *const c_char) -> *mut c_char; + pub fn free_string_ptr(ptr: *mut c_char); + pub fn start_accessing_security_scoped_resource(bookmark: *const c_char) -> *mut c_char; + pub fn stop_all_security_scoped_resources(); + pub fn stop_accessing_security_scoped_resource(bookmark: *const c_char); + } +} + +#[derive(serde::Serialize)] +pub struct PickFolderResult { + pub path: String, + pub bookmark: String, +} + +#[command] +pub async fn pick_draw_things_folder( + default_path: Option, +) -> Result, String> { + #[cfg(target_os = "macos")] + { + use std::ffi::{CStr, CString}; + use std::ptr; + + // This function must run on the main thread for UI + // In Tauri v2, commands are async by default on a thread pool. + // NSOpenPanel should ideally be run on main thread. + // However, let's try calling it directly first. If it crashes/hangs, we'll need dispatch. + + let c_default_path = match default_path { + Some(path) => Some(CString::new(path).map_err(|e| e.to_string())?), + None => None, + }; + + let ptr_arg = match &c_default_path { + Some(c_str) => c_str.as_ptr(), + None => ptr::null(), + }; + + let ptr = unsafe { ffi::open_dt_folder_picker(ptr_arg) }; + + if ptr.is_null() { + return Ok(None); + } + + let c_str = unsafe { CStr::from_ptr(ptr) }; + let full_result = c_str.to_string_lossy().into_owned(); + + unsafe { ffi::free_string_ptr(ptr) }; + + // Parse "path|bookmark" + if let Some((path, bookmark)) = full_result.split_once('|') { + Ok(Some(PickFolderResult { + path: path.to_string(), + bookmark: bookmark.to_string(), + })) + } else { + Err("Failed to parse picker result".to_string()) + } + } + + #[cfg(not(target_os = "macos"))] + { + Err("Unsupported platform".to_string()) + } +} + +#[command] +pub async fn resolve_bookmark(bookmark: String) -> Result { + #[cfg(target_os = "macos")] + { + use std::ffi::{CStr, CString}; + + let c_bookmark = CString::new(bookmark).map_err(|e| e.to_string())?; + + let ptr = unsafe { ffi::start_accessing_security_scoped_resource(c_bookmark.as_ptr()) }; + + if ptr.is_null() { + return Err("Failed to resolve bookmark or start accessing resource".to_string()); + } + + let c_str = unsafe { CStr::from_ptr(ptr) }; + let result = c_str.to_string_lossy().into_owned(); + + unsafe { ffi::free_string_ptr(ptr) }; + + Ok(result) + } + + #[cfg(not(target_os = "macos"))] + { + Err("Unsupported platform".to_string()) + } +} + +#[command] +pub async fn stop_accessing_bookmark(bookmark: String) -> Result<(), String> { + #[cfg(target_os = "macos")] + { + use std::ffi::CString; + + let c_bookmark = CString::new(bookmark).map_err(|e| e.to_string())?; + + unsafe { + ffi::stop_accessing_security_scoped_resource(c_bookmark.as_ptr()); + }; + + Ok(()) + } + + #[cfg(not(target_os = "macos"))] + { + Err("Unsupported platform".to_string()) + } +} + +pub fn cleanup_bookmarks() { + #[cfg(target_os = "macos")] + unsafe { + ffi::stop_all_security_scoped_resources(); + } +} diff --git a/src-tauri/src/clipboard/linux.rs b/src-tauri/src/clipboard/linux.rs index 3e8f4d9..81d88a6 100644 --- a/src-tauri/src/clipboard/linux.rs +++ b/src-tauri/src/clipboard/linux.rs @@ -1,86 +1,19 @@ -pub fn get_clipboard(pasteboard: Option) -> Result, String> { - unsafe { - match pasteboard.as_deref() { - Some("drag") => Ok(NSPasteboard::pasteboardWithName(&*NSPasteboardNameDrag)), - Some("general") | None => Ok(NSPasteboard::generalPasteboard()), - Some(other) => return Err(format!("Unknown pasteboard name: {other}")), - } - } -} - -pub fn write_clipboard_binary(ty: String, data: Vec) -> Result<(), String> { - let pb = get_clipboard(None)?; // general pasteboard only - let ns_type = NSString::from_str(&ty); - - // Convert Vec into NSData - let binding = NSData::from_vec(data); - let ns_data = binding.as_ref(); - - unsafe { - pb.clearContents(); - let ok = pb.setData_forType(Some(ns_data), &ns_type); - if !ok { - return Err(format!("Failed to write binary data for {}", ty)); - } - } +pub fn write_clipboard_binary(_ty: String, _data: Vec) -> Result<(), String> { Ok(()) } -pub fn read_clipboard_binary(ty: String, pasteboard: Option) -> Result, String> { - let pb = get_clipboard(pasteboard)?; - let ns_type = NSString::from_str(&ty); - let type_array = NSArray::from_slice(&[&*ns_type]); - - if unsafe { pb.availableTypeFromArray(&*type_array) }.is_none() { - return Err(format!("Type {} not available", ty)); - } - - let data: Option> = unsafe { pb.dataForType(&*ns_type) }; - let data = data.ok_or_else(|| format!("Failed to read binary data for {}", ty))?; - let bytes = unsafe { data.as_bytes_unchecked() }; - - Ok(bytes.to_vec()) +pub fn read_clipboard_binary(_ty: String, _pasteboard: Option) -> Result, String> { + Ok(Vec::new()) } pub fn read_clipboard_strings( - types: Vec, - pasteboard: Option, + _types: Vec, + _pasteboard: Option, ) -> Result, String> { - let pb = get_clipboard(pasteboard)?; - let mut results = std::collections::HashMap::new(); - - for ty in types { - let ns_type = NSString::from_str(&ty); - let type_array = NSArray::from_slice(&[&*ns_type]); - - // Only proceed if available - if unsafe { pb.availableTypeFromArray(&*type_array) }.is_none() { - continue; - } - - // Try to read as NSString - if let Some(s) = unsafe { pb.stringForType(&*ns_type) } { - results.insert(ty, s.to_string()); - } - } - - Ok(results) + Ok(std::collections::HashMap::new()) } -pub fn read_clipboard_types(pasteboard: Option) -> Result, String> { - // Select pasteboard based on argument - let pb: Retained = get_clipboard(pasteboard)?; - - // Get available types (NSArray) - let available = unsafe { pb.types() }.ok_or("Failed to get available types")?; - - // Convert NSArray → Vec - let mut result = Vec::with_capacity(available.len()); - for i in 0..available.len() { - let ty: Retained = available.objectAtIndex(i); - result.push(ty.to_string()); - } - - Ok(result) +pub fn read_clipboard_types(_pasteboard: Option) -> Result, String> { + Ok(Vec::new()) } diff --git a/src-tauri/src/ffmpeg.rs b/src-tauri/src/ffmpeg.rs new file mode 100644 index 0000000..5fa5896 --- /dev/null +++ b/src-tauri/src/ffmpeg.rs @@ -0,0 +1,191 @@ +use futures_util::StreamExt; +use std::io::Write; +use std::path::PathBuf; +use tauri::{AppHandle, Emitter, Manager}; +use tauri_plugin_http::reqwest; +use tokio::fs; +use tokio::process::Command; + +const FFMPEG_URL: &str = "https://evermeet.cx/ffmpeg/ffmpeg-8.0.1.7z"; +const FFMPEG_MD5: &str = "845140e046f7abbfcf480d70eb1657ca09eb8fa775834518a1f43a5b867c96f9"; + +#[derive(Clone, serde::Serialize, Default)] +struct DownloadProgress { + progress: f64, + total: Option, + received: u64, + msg: Option, +} + +pub async fn get_ffmpeg_path(app: &AppHandle) -> Result { + Ok(app + .path() + .app_data_dir() + .map_err(|e| e.to_string())? + .join("bin") + .join("ffmpeg")) +} + +pub async fn check_ffmpeg(app: &AppHandle) -> Result { + let path = get_ffmpeg_path(app).await?; + Ok(path.exists()) +} + +pub async fn download_ffmpeg(app: AppHandle) -> Result<(), String> { + let app_data_dir = app.path().app_data_dir().map_err(|e| e.to_string())?; + let temp_dir = app_data_dir.join("temp"); + fs::create_dir_all(&temp_dir) + .await + .map_err(|e| e.to_string())?; + + let bin_dir = app_data_dir.join("bin"); + fs::create_dir_all(&bin_dir) + .await + .map_err(|e| e.to_string())?; + + let ffmpeg_7z = temp_dir.join("ffmpeg.7z"); + + // Download FFmpeg + // The redirect to the latest .7z works through reqwest + let client = reqwest::Client::new(); + let res = client + .get(FFMPEG_URL) + .send() + .await + .map_err(|e| e.to_string())?; + + let total_size = res.content_length(); + let mut downloaded: u64 = 0; + let mut stream = res.bytes_stream(); + + let mut file = std::fs::File::create(&ffmpeg_7z).map_err(|e| e.to_string())?; + + while let Some(item) = stream.next().await { + let chunk = item.map_err(|e| e.to_string())?; + file.write_all(&chunk).map_err(|e| e.to_string())?; + downloaded += chunk.len() as u64; + + let _ = app.emit( + "ffmpeg_download_progress", + DownloadProgress { + progress: total_size + .map(|s| downloaded as f64 / s as f64) + .unwrap_or(0.0), + total: total_size, + received: downloaded, + msg: Some("progress".to_string()), + }, + ); + } + + let _ = app.emit( + "ffmpeg_download_progress", + DownloadProgress { + msg: Some("verifying".to_string()), + ..Default::default() + }, + ); + + if !verify_checksum(&ffmpeg_7z, &FFMPEG_MD5).is_ok_and(|v| v) { + return Err("Signature verification failed".to_string()); + } + + let _ = app.emit( + "ffmpeg_download_progress", + DownloadProgress { + msg: Some("extracting".to_string()), + ..Default::default() + }, + ); + + // Extract + // sevenz-rust can extract the .7z file directly + sevenz_rust::decompress_file(&ffmpeg_7z, &bin_dir).map_err(|e| e.to_string())?; + + // Cleanup + let _ = fs::remove_file(&ffmpeg_7z).await; + + let _ = app.emit( + "ffmpeg_download_progress", + DownloadProgress { + msg: Some("installing".to_string()), + ..Default::default() + }, + ); + + // Set executable permission on Unix + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + let ffmpeg_path = bin_dir.join("ffmpeg"); + if ffmpeg_path.exists() { + let mut perms = fs::metadata(&ffmpeg_path) + .await + .map_err(|e| e.to_string())? + .permissions(); + perms.set_mode(0o755); + fs::set_permissions(&ffmpeg_path, perms) + .await + .map_err(|e| e.to_string())?; + } + } + + let _ = app.emit( + "ffmpeg_download_progress", + DownloadProgress { + msg: Some("done".to_string()), + ..Default::default() + }, + ); + + Ok(()) +} + +pub async fn call_ffmpeg(app: &AppHandle, args: Vec) -> Result { + let ffmpeg_path = get_ffmpeg_path(app).await?; + + if !ffmpeg_path.exists() { + return Err("FFmpeg not found. Please download it first.".to_string()); + } + + let output = Command::new(ffmpeg_path) + .args(args) + .output() + .await + .map_err(|e| e.to_string())?; + + if output.status.success() { + Ok(String::from_utf8_lossy(&output.stdout).to_string()) + } else { + Err(String::from_utf8_lossy(&output.stderr).to_string()) + } +} + +use sha2::{Digest, Sha256}; +use std::fs::File; +use std::io::{BufReader, Read}; +use std::path::Path; + +fn sha256_file(path: &Path) -> Result { + let file = File::open(path)?; + let mut reader = BufReader::new(file); + + let mut hasher = Sha256::new(); + let mut buffer = [0u8; 8192]; + + loop { + let n = reader.read(&mut buffer)?; + if n == 0 { + break; + } + hasher.update(&buffer[..n]); + } + + let hash = hasher.finalize(); + Ok(format!("{:x}", hash)) +} + +fn verify_checksum(path: &Path, expected: &str) -> Result { + let actual = sha256_file(path)?; + Ok(actual.eq_ignore_ascii_case(expected)) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 2bcfef4..e0b697d 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -8,7 +8,10 @@ use tauri_plugin_window_state::StateFlags; mod clipboard; +mod bookmarks; +mod ffmpeg; mod projects_db; +mod vid; use once_cell::sync::Lazy; use tokio::runtime::Runtime; @@ -16,11 +19,6 @@ use tokio::runtime::Runtime; pub static TOKIO_RT: Lazy = Lazy::new(|| Runtime::new().expect("Failed to create Tokio runtime")); -// #[tauri::command] -// fn get_tensor(project_file: String, name: String) -> Result { -// let project = dt_project::DTProject::new(&project_file).unwrap(); -// Ok(project.get_tensor(name).unwrap()) -// } #[tauri::command] fn read_clipboard_types(pasteboard: Option) -> Result, String> { @@ -45,6 +43,21 @@ fn write_clipboard_binary(ty: String, data: Vec) -> Result<(), String> { clipboard::write_clipboard_binary(ty, data) } +#[tauri::command] +async fn ffmpeg_check(app: tauri::AppHandle) -> Result { + ffmpeg::check_ffmpeg(&app).await +} + +#[tauri::command] +async fn ffmpeg_download(app: tauri::AppHandle) -> Result<(), String> { + ffmpeg::download_ffmpeg(app).await +} + +#[tauri::command] +async fn ffmpeg_call(app: tauri::AppHandle, args: Vec) -> Result { + ffmpeg::call_ffmpeg(&app, args).await +} + #[tauri::command] async fn fetch_image_file(url: String) -> Result, String> { let resp = reqwest::get(&url).await.map_err(|e| e.to_string())?; @@ -115,7 +128,7 @@ pub fn run() { .plugin(tauri_plugin_clipboard_manager::init()) .plugin(tauri_plugin_opener::init()) .plugin(tauri_plugin_valtio::Builder::new().build()) - .plugin(tauri_plugin_nspopover::init()) + // .plugin(tauri_plugin_nspopover::init()) .plugin( tauri_plugin_log::Builder::new() .filter(|metadata| { @@ -123,6 +136,15 @@ pub fn run() { && !metadata.target().starts_with("sqlx") }) .level(LevelFilter::Debug) + .clear_targets() + .targets(vec![ + tauri_plugin_log::Target::new(tauri_plugin_log::TargetKind::Webview), + tauri_plugin_log::Target::new(tauri_plugin_log::TargetKind::LogDir { + file_name: Some("dtm.log".to_string()), + }), + tauri_plugin_log::Target::new(tauri_plugin_log::TargetKind::Stdout), + ]) + .max_file_size(200000) .build(), ) .invoke_handler(tauri::generate_handler![ @@ -140,8 +162,10 @@ pub fn run() { projects_db_project_remove, projects_db_project_scan, projects_db_project_update_exclude, + projects_db_project_bulk_update_missing_on, projects_db_image_count, // #unused projects_db_image_list, + projects_db_get_clip, projects_db_image_rebuild_fts, projects_db_watch_folder_list, projects_db_watch_folder_add, @@ -156,7 +180,17 @@ pub fn run() { dt_project_find_predecessor_candidates, dt_project_get_tensor_raw, // #unused dt_project_get_tensor_size, - dt_project_decode_tensor + dt_project_decode_tensor, + vid::create_video_from_frames, + vid::save_all_clip_frames, + vid::check_pattern, + ffmpeg_check, + ffmpeg_download, + ffmpeg_download, + ffmpeg_call, + bookmarks::pick_draw_things_folder, + bookmarks::resolve_bookmark, + bookmarks::stop_accessing_bookmark ]) .register_asynchronous_uri_scheme_protocol("dtm", |_ctx, request, responder| { std::thread::spawn(move || { @@ -183,7 +217,7 @@ pub fn run() { .title("DTM") .inner_size(800.0, 600.0) .min_inner_size(600.0, 400.0) - .visible(false) + .visible(true) .disable_drag_drop_handler(); // set transparent title bar only when building for macOS @@ -209,6 +243,12 @@ pub fn run() { // .init(); Ok(()) }) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); + .build(tauri::generate_context!()) + .expect("error while running tauri application") + .run(|_app_handle, event| match event { + tauri::RunEvent::Exit => { + bookmarks::cleanup_bookmarks(); + }, + _ => {} + }); } diff --git a/src-tauri/src/projects_db/commands.rs b/src-tauri/src/projects_db/commands.rs index 31bc84b..e5f7a07 100644 --- a/src-tauri/src/projects_db/commands.rs +++ b/src-tauri/src/projects_db/commands.rs @@ -2,11 +2,20 @@ use serde_json::Value; use tauri::Emitter; use crate::projects_db::{ - dt_project::{ProjectRef, TensorHistoryExtra, TensorRaw}, + dt_project::ProjectRef, + dtos::{ + image::{ListImagesOptions, ListImagesResult}, + model::ModelExtra, + project::ProjectExtra, + tensor::{ + TensorHistoryClip, TensorHistoryExtra, TensorHistoryImport, TensorRaw, TensorSize, + }, + text::TextHistoryNode as TextHistoryNodeDTO, + watch_folder::WatchFolderDTO, + }, filters::ListImagesFilter, - projects_db::{ListImagesResult, ModelExtra, ProjectExtra}, tensors::decode_tensor, - DTProject, ProjectsDb, TensorHistoryImport, + DTProject, ProjectsDb, }; #[derive(serde::Serialize, Clone)] @@ -53,7 +62,7 @@ pub async fn projects_db_project_add( path: String, ) -> Result { let pdb = ProjectsDb::get_or_init(&app_handle).await?; - let project = pdb.add_project(&path).await.unwrap(); + let project = pdb.add_project(&path).await?; update_tags( &app_handle, "projects", @@ -90,7 +99,7 @@ pub async fn projects_db_project_remove( #[tauri::command] pub async fn projects_db_project_list( app_handle: tauri::AppHandle, -) -> Result, String> { +) -> Result, String> { let pdb = ProjectsDb::get_or_init(&app_handle).await?; let projects = pdb.list_projects().await.unwrap(); Ok(projects) @@ -111,13 +120,27 @@ pub async fn projects_db_project_update_exclude( Ok(()) } +#[tauri::command] +pub async fn projects_db_project_bulk_update_missing_on( + app_handle: tauri::AppHandle, + paths: Vec, + missing_on: Option, +) -> Result<(), String> { + let pdb = ProjectsDb::get_or_init(&app_handle).await?; + pdb.bulk_update_missing_on(paths, missing_on) + .await + .map_err(|e| e.to_string())?; + invalidate_tags(&app_handle, "projects", "bulk_update"); + Ok(()) +} + #[tauri::command] pub async fn projects_db_project_scan( app: tauri::AppHandle, path: String, full_scan: Option, - filesize: Option, - modified: Option, + _filesize: Option, + _modified: Option, ) -> Result { let pdb = ProjectsDb::get_or_init(&app).await?; // let update = |images_scanned: i32, images_total: i32| { @@ -142,7 +165,7 @@ pub async fn projects_db_project_scan( match result { Ok((_id, total)) => { let project = pdb - .update_project(&path, filesize, modified) + .update_project(&path, _filesize, _modified) .await .map_err(|e| e.to_string())?; @@ -173,7 +196,7 @@ pub async fn projects_db_project_scan( Ok(total as i32) } Err(err) => { - eprintln!("Error scanning project {}: {}", path, err); + log::error!("Error scanning project {}: {}", path, err); Err(err.to_string()) } } @@ -190,9 +213,11 @@ pub async fn projects_db_image_list( take: Option, skip: Option, count: Option, + show_video: Option, + show_image: Option, ) -> Result { let projects_db = ProjectsDb::get_or_init(&app).await?; - let opts = super::projects_db::ListImagesOptions { + let opts = ListImagesOptions { project_ids, search, filters, @@ -201,11 +226,22 @@ pub async fn projects_db_image_list( take, skip, count, + show_video, + show_image, }; Ok(projects_db.list_images(opts).await.unwrap()) } +#[tauri::command] +pub async fn projects_db_get_clip( + app_handle: tauri::AppHandle, + image_id: i64, +) -> Result, String> { + let projects_db = ProjectsDb::get_or_init(&app_handle).await?; + projects_db.get_clip(image_id).await +} + #[tauri::command] pub async fn projects_db_image_rebuild_fts(app: tauri::AppHandle) -> Result<(), String> { let projects_db = ProjectsDb::get_or_init(&app).await?; @@ -216,7 +252,7 @@ pub async fn projects_db_image_rebuild_fts(app: tauri::AppHandle) -> Result<(), #[tauri::command] pub async fn projects_db_watch_folder_list( app: tauri::AppHandle, -) -> Result, String> { +) -> Result, String> { let projects_db = ProjectsDb::get_or_init(&app).await?; Ok(projects_db.list_watch_folders().await.unwrap()) } @@ -225,12 +261,11 @@ pub async fn projects_db_watch_folder_list( pub async fn projects_db_watch_folder_add( app: tauri::AppHandle, path: String, - item_type: entity::enums::ItemType, recursive: bool, -) -> Result { +) -> Result { let projects_db = ProjectsDb::get_or_init(&app).await?; let result = projects_db - .add_watch_folder(&path, item_type, recursive) + .add_watch_folder(&path, recursive) .await .unwrap(); @@ -253,10 +288,10 @@ pub async fn projects_db_watch_folder_remove( #[tauri::command] pub async fn projects_db_watch_folder_update( app: tauri::AppHandle, - id: i32, + id: i64, recursive: Option, last_updated: Option, -) -> Result { +) -> Result { let projects_db = ProjectsDb::get_or_init(&app).await?; let result = projects_db .update_watch_folder(id, recursive, last_updated) @@ -301,10 +336,10 @@ pub async fn projects_db_list_models( pub async fn dt_project_get_tensor_history( project_file: String, index: u32, - count: u32, + count: usize, ) -> Result, String> { let project = DTProject::get(&project_file).await.unwrap(); - match project.get_histories(index as i64, count as i64).await { + match project.get_histories(index as i64, count).await { Ok(history) => Ok(history), Err(_e) => Ok(Vec::new()), } @@ -313,7 +348,7 @@ pub async fn dt_project_get_tensor_history( #[tauri::command] pub async fn dt_project_get_text_history( project_file: String, -) -> Result, String> { +) -> Result, String> { let project = DTProject::get(&project_file).await.unwrap(); Ok(project.get_text_history().await.unwrap()) } @@ -355,7 +390,7 @@ pub async fn dt_project_get_tensor_size( project_id: Option, project_path: Option, tensor_id: String, -) -> Result { +) -> Result { let project = get_project(app, project_path, project_id).await.unwrap(); let tensor = project.get_tensor_size(&tensor_id).await.unwrap(); Ok(tensor) diff --git a/src-tauri/src/projects_db/dt_project.rs b/src-tauri/src/projects_db/dt_project.rs index d1e842e..5308502 100644 --- a/src-tauri/src/projects_db/dt_project.rs +++ b/src-tauri/src/projects_db/dt_project.rs @@ -1,23 +1,32 @@ use crate::projects_db::{ - tensor_history::TensorHistoryNode, TensorHistoryImport, TextHistory, TextHistoryNode, + dtos::{ + project::DTProjectInfo, + tensor::{ + TensorHistoryClip, TensorHistoryExtra, TensorHistoryImport, TensorHistoryNode, + TensorNodeGrouper, TensorRaw, TensorSize, + }, + text::TextHistoryNode, + }, + tensor_history_tensor_data::TensorHistoryTensorData, + TextHistory, }; use moka::future::Cache; use once_cell::sync::Lazy; use serde::Serialize; -use sqlx::{query, sqlite::SqliteRow, Error, Row, SqlitePool}; -use std::{ - collections::HashSet, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, - }, +use sqlx::{query, query_as, sqlite::SqliteRow, Error, Row, SqlitePool}; +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, }; use tokio::sync::OnceCell; static PROJECT_CACHE: Lazy>> = Lazy::new(|| { Cache::builder() .max_capacity(16) - .time_to_idle(std::time::Duration::from_secs(300)) // 10 min idle timeout + // caching database connections for 3 seconds, so images can be loaded in bulk + // from separate requests. Closing them early to avoid locks, in case project + // is renamed in DT + .time_to_idle(std::time::Duration::from_secs(3)) .build() }); @@ -121,10 +130,30 @@ impl DTProject { } } + pub async fn get_fingerprint(&self) -> Result { + self.check_table(&DTProjectTable::Thumbs).await?; + + let row = query( + "SELECT + group_concat(rowid || \"-\" || __pk0, \":\") AS fingerprint + FROM ( + SELECT rowid, __pk0 + FROM thumbnailhistorynode + ORDER BY rowid ASC + LIMIT 5 + )", + ) + .fetch_one(&self.pool) + .await?; + + let fingerprint: String = row.get(0); + Ok(fingerprint.trim_end_matches(':').to_string()) + } + pub async fn get_histories( &self, first_id: i64, - count: i64, + count: usize, ) -> Result, Error> { match self.check_table(&DTProjectTable::TensorHistory).await { Ok(_) => {} @@ -137,18 +166,18 @@ impl DTProject { // full_query_where selects: rowid, lineage, logical_time, p, and then the content IDs. // It does NOT select f86. // We need to add f86 to the selection. + let result: Vec = + query_as(&full_query_where("thn.rowid >= ?1 AND thn.rowid < ?2")) + .bind(first_id) + .bind(first_id + count as i64) + .fetch_all(&self.pool) + .await?; - let query_str = import_query(self.has_moodboard.load(Ordering::Relaxed)); + let grouper = TensorNodeGrouper::new(&result); - let items: Vec = query(&query_str) - .bind(first_id) - .bind(first_id + count) - .map(|row: SqliteRow| self.map_import(row)) - .fetch_all(&self.pool) - .await?; + let mut items: Vec = grouper.collect(); - let mut items = items; - for item in items.iter_mut() { + for item in &mut items { if item.prompt.is_empty() && item.negative_prompt.is_empty() { let history = self .text_history @@ -156,11 +185,12 @@ impl DTProject { let nodes = self.get_text_history().await?; Ok::(TextHistory::new(nodes)) }) - .await?; + .await + .unwrap(); if let Some(prompts) = history.get_edit(item.text_lineage, item.text_edits) { - item.prompt = prompts.positive; - item.negative_prompt = prompts.negative; + item.prompt = prompts.positive.clone(); + item.negative_prompt = prompts.negative.clone(); } } } @@ -171,24 +201,21 @@ impl DTProject { fn map_import(&self, row: SqliteRow) -> TensorHistoryImport { let row_id: i64 = row.get(0); let p: &[u8] = row.get(1); - // let image_id: i64 = row.get(2); + let tensor_id: String = row.get(2); // These are booleans from the query (MAX(val) > 0) - let has_mask: bool = row.get(2); - let has_depth: bool = row.get(3); - let has_scribble: bool = row.get(4); - let has_pose: bool = row.get(5); - let has_color: bool = row.get(6); - let has_custom: bool = row.get(7); + let has_mask: bool = row.get(3); + let has_depth: bool = row.get(4); + let has_scribble: bool = row.get(5); + let has_pose: bool = row.get(6); + let has_color: bool = row.get(7); + let has_custom: bool = row.get(8); let has_shuffle: bool = row.get(8); - // We aren't using has_mask in TensorHistoryImport yet, but it's part of the query. - // TensorHistoryImport::new expects the boolean flags. - TensorHistoryImport::new( p, row_id, - // image_id, + tensor_id, has_depth, has_pose, has_color, @@ -294,43 +321,6 @@ impl DTProject { }) } - /* - pub async fn batch_thumbs(&self, thumb_ids: &[i64]) -> Result>, Error> { - self.check_table(&DTProjectTable::Thumbs).await?; - - if thumb_ids.is_empty() { - return Ok(HashMap::new()); - } - - // Build (?, ?, ?, ...) - let placeholders = std::iter::repeat("?") - .take(thumb_ids.len()) - .collect::>() - .join(", "); - - let sql = format!( - "SELECT __pk0, p FROM thumbnailhistoryhalfnode WHERE __pk0 IN ({})", - placeholders - ); - - let mut q = query(&sql); - for id in thumb_ids { - q = q.bind(id); - } - - let rows = q.fetch_all(&self.pool).await?; - - let mut out = HashMap::with_capacity(rows.len()); - for row in rows { - let id: i64 = row.get(0); - let data: Vec = row.get(1); - out.insert(id, extract_jpeg_slice(&data).unwrap()); - } - - Ok(out) - } - */ - pub async fn get_thumb_half(&self, thumb_id: i64) -> Result, Error> { self.check_table(&DTProjectTable::Thumbs).await?; let result = query("SELECT p FROM thumbnailhistoryhalfnode WHERE __pk0 = ?1") @@ -351,14 +341,38 @@ impl DTProject { Ok(thumbnail) } + pub async fn get_histories_from_clip( + &self, + node_id: i64, + ) -> Result, Error> { + self.check_table(&DTProjectTable::TensorHistory).await?; + + let history = self.get_history_full(node_id).await?; + let num_frames = history.history.num_frames; + + let items: Vec = query(CLIP_QUERY) + .bind(node_id) + .bind(node_id + num_frames as i64) + .map(|row: SqliteRow| self.map_clip(row)) + .fetch_all(&self.pool) + .await?; + + Ok(items) + } + + fn map_clip(self: &DTProject, row: SqliteRow) -> TensorHistoryClip { + TensorHistoryClip::new(row.get(0), row.get(1), row.get(2)).unwrap() + } + pub async fn get_history_full(&self, row_id: i64) -> Result { self.check_table(&DTProjectTable::TensorHistory).await?; - let mut item: TensorHistoryExtra = query(&full_query_where("thn.rowid == ?1")) + let result: Vec = query_as(&full_query_where("thn.rowid == ?1")) .bind(row_id) - .map(|row: SqliteRow| self.map_full(row)) - .fetch_one(&self.pool) + .fetch_all(&self.pool) .await?; + let mut item = TensorHistoryExtra::from((result, self.path.clone())); + item.moodboard_ids = self .get_shuffle_ids(item.lineage, item.logical_time) .await?; @@ -457,10 +471,12 @@ impl DTProject { pub async fn find_predecessor_candidates( &self, - row_id: i64, - lineage: i64, - logical_time: i64, + _row_id: i64, + _lineage: i64, + _logical_time: i64, ) -> Result, Error> { + Ok(Vec::new()) + /* self.check_table(&DTProjectTable::TensorHistory).await?; let q = &full_query_where("thn.__pk1 == ?1 AND thn.rowid < ?2"); let candidates = query(q) @@ -522,6 +538,7 @@ impl DTProject { } Ok(result) + */ } pub async fn get_text_history(&self) -> Result, Error> { @@ -562,6 +579,7 @@ fn import_query(has_moodboard: bool) -> String { thn.rowid, thn.p AS data_blob, + MAX('tensor_history_' || NULLIF(td.f20, 0)) AS tensor_id, MAX(td.f22) > 0 AS has_mask, MAX(td.f24) > 0 AS has_depth, MAX(td.f26) > 0 AS has_scribble, @@ -578,6 +596,7 @@ fn import_query(has_moodboard: bool) -> String { td.rowid, td.__pk0, td.__pk1, + f20.f20 AS f20, f22.f22 AS f22, f24.f24 AS f24, f26.f26 AS f26, @@ -585,6 +604,7 @@ fn import_query(has_moodboard: bool) -> String { f30.f30 AS f30, f32.f32 AS f32 FROM tensordata AS td + LEFT JOIN tensordata__f20 AS f20 ON f20.rowid = td.rowid LEFT JOIN tensordata__f22 AS f22 ON f22.rowid = td.rowid LEFT JOIN tensordata__f24 AS f24 ON f24.rowid = td.rowid LEFT JOIN tensordata__f26 AS f26 ON f26.rowid = td.rowid @@ -605,96 +625,49 @@ fn import_query(has_moodboard: bool) -> String { ) } -pub struct DTProjectInfo { - pub _path: String, - pub _history_count: i64, - pub history_max_id: i64, -} - -#[derive(Debug, Serialize, Clone)] -pub struct TensorHistoryExtra { - pub row_id: i64, - pub lineage: i64, - pub logical_time: i64, - pub tensor_id: Option, - pub mask_id: Option, - pub depth_map_id: Option, - pub scribble_id: Option, - pub pose_id: Option, - pub color_palette_id: Option, - pub custom_id: Option, - pub moodboard_ids: Vec, - pub history: TensorHistoryNode, - pub project_path: String, -} - -#[derive(Debug, Serialize, Clone)] -pub struct TensorRaw { - pub name: String, - pub tensor_type: i64, - pub data_type: i32, - pub format: i32, - pub width: i32, - pub height: i32, - pub channels: i32, - pub dim: Vec, - pub data: Vec, -} - -#[derive(Debug, Serialize, Clone)] -pub struct TensorSize { - pub width: i32, - pub height: i32, - pub channels: i32, -} +const CLIP_QUERY: &str = " + WITH td_ranked AS ( + SELECT + td.*, + ROW_NUMBER() OVER ( + PARTITION BY td.__pk0, td.__pk1 + ORDER BY td.__pk2 DESC -- prefer pk2 = 1 + ) AS rn + FROM tensordata AS td + ) + SELECT + thn.rowid, + thn.p AS data_blob, + 'tensor_history_' || td_f20.f20 AS tensor_id + FROM tensorhistorynode AS thn + LEFT JOIN td_ranked AS td + ON thn.__pk0 = td.__pk0 + AND thn.__pk1 = td.__pk1 + AND td.rn = 1 -- pick the preferred row per pk0/pk1 + LEFT JOIN tensordata__f20 AS td_f20 + ON td.rowid = td_f20.rowid + WHERE thn.rowid >= ?1 + AND thn.rowid < ?2 + ORDER BY thn.rowid; + "; fn full_query_where(where_expr: &str) -> String { format!( " SELECT thn.rowid, - thn.__pk0 AS lineage, - thn.__pk1 AS logical_time, - thn.p AS data_blob, - - -- Indexed fields from tensordata with prefix & 0 → NULL - MAX('tensor_history_' || NULLIF(td.f20, 0)) AS tensor_id, - MAX('binary_mask_' || NULLIF(td.f22, 0)) AS mask_id, - MAX('depth_map_' || NULLIF(td.f24, 0)) AS depth_map_id, - MAX('scribble_' || NULLIF(td.f26, 0)) AS scribble_id, - MAX('pose_' || NULLIF(td.f28, 0)) AS_pose_id, - MAX('color_palette_' || NULLIF(td.f30, 0)) AS color_palette_id, - MAX('custom_' || NULLIF(td.f32, 0)) AS custom_id - + thn.__pk0 as lineage, + thn.__pk1 as logical_time, + td.__pk2 as td_index, + thn.p AS node_data, + td.p AS tensor_data FROM tensorhistorynode AS thn - - -- Join tensordata on the two primary keys - LEFT JOIN ( - SELECT - td.rowid, - td.__pk0, - td.__pk1, - f20.f20 AS f20, - f22.f22 AS f22, - f24.f24 AS f24, - f26.f26 AS f26, - f28.f28 AS f28, - f30.f30 AS f30, - f32.f32 AS f32 - FROM tensordata AS td - LEFT JOIN tensordata__f20 AS f20 ON f20.rowid = td.rowid - LEFT JOIN tensordata__f22 AS f22 ON f22.rowid = td.rowid - LEFT JOIN tensordata__f24 AS f24 ON f24.rowid = td.rowid - LEFT JOIN tensordata__f26 AS f26 ON f26.rowid = td.rowid - LEFT JOIN tensordata__f28 AS f28 ON f28.rowid = td.rowid - LEFT JOIN tensordata__f30 AS f30 ON f30.rowid = td.rowid - LEFT JOIN tensordata__f32 AS f32 ON f32.rowid = td.rowid - ) AS td - ON thn.__pk0 = td.__pk0 AND thn.__pk1 = td.__pk1 - - WHERE {} - GROUP BY thn.rowid, thn.__pk0, thn.__pk1 - ORDER BY thn.rowid + LEFT JOIN tensordata AS td + ON td.__pk0 = thn.__pk0 + AND td.__pk1 = thn.__pk1 + WHERE td.__pk2 IS NOT NULL + AND {} + ORDER BY thn.rowid, td.__pk2 ASC; ", where_expr ) @@ -704,3 +677,21 @@ pub enum ProjectRef { Path(String), Id(i64), } + +/* +SELECT + thn.rowid, + thn.__pk0 as lineage, + thn.__pk1 as logical_time, + td.__pk2 as td_index, + thn.p AS node_data, + td.p AS tensor_data +FROM tensorhistorynode AS thn +LEFT JOIN tensordata AS td + ON td.__pk0 = thn.__pk0 + AND td.__pk1 = thn.__pk1 +-- WHERE thn.rowid >= ?1 +-- AND thn.rowid < ?2 +ORDER BY thn.rowid, td.__pk2 DESC; + +*/ diff --git a/src-tauri/src/projects_db/dtm_dtproject.rs b/src-tauri/src/projects_db/dtm_dtproject.rs index fe7faf1..51d6214 100644 --- a/src-tauri/src/projects_db/dtm_dtproject.rs +++ b/src-tauri/src/projects_db/dtm_dtproject.rs @@ -11,6 +11,13 @@ use crate::projects_db::{ DTProject, ProjectsDb, }; +const MISSING_SVG: &str = r##" + + + + +"##; + // dtm://dtm_dtproject/thumbhalf/5/82988 // dtm://dtm_dtproject/{item type}/{project_id}/{item id} @@ -61,12 +68,18 @@ pub async fn dtm_dtproject_protocol(request: http::Request, responder: Uri let response = match handle_request(request).await { Ok(r) => r, Err(e) => { - eprintln!("DTM Protocol Error: {}", e); - Response::builder() - .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(e.into_bytes()) - .unwrap() + log::error!("DTM Protocol Error: {}", e); + // Response::builder() + // .status(StatusCode::INTERNAL_SERVER_ERROR) + // .body(e.into_bytes()) + // .unwrap() + Response::builder() + .status(StatusCode::OK) + .header("Content-Type", "image/svg+xml") + .body(MISSING_SVG.as_bytes().to_vec()) + .unwrap() } + }; responder.respond(response); @@ -140,7 +153,7 @@ async fn tensor( node: Option, scale: Option, invert: Option, - mask: Option, + _mask: Option, ) -> Result>, String> { let dtp = DTProject::get(project_file) .await diff --git a/src-tauri/src/projects_db/dtos/image.rs b/src-tauri/src/projects_db/dtos/image.rs new file mode 100644 index 0000000..e066fc4 --- /dev/null +++ b/src-tauri/src/projects_db/dtos/image.rs @@ -0,0 +1,58 @@ +use crate::projects_db::filters::ListImagesFilter; +use sea_orm::FromQueryResult; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize, Clone, Default)] +pub struct ListImagesOptions { + pub project_ids: Option>, + pub search: Option, + pub filters: Option>, + pub sort: Option, + pub direction: Option, + pub take: Option, + pub skip: Option, + pub count: Option, + pub show_video: Option, + pub show_image: Option, +} + +#[derive(Debug, Serialize)] +pub struct ListImagesResult { + pub counts: Option>, + pub images: Option>, + pub total: u64, +} + +#[derive(Debug, FromQueryResult, Serialize)] +pub struct ImageCount { + pub project_id: i64, + pub count: i64, +} + +#[derive(Debug, FromQueryResult, Serialize)] +pub struct ImageExtra { + pub id: i64, + pub project_id: i64, + pub model_id: Option, + pub model_file: Option, + pub prompt: String, + pub negative_prompt: String, + pub num_frames: Option, + pub preview_id: i64, + pub node_id: i64, + pub has_depth: bool, + pub has_pose: bool, + pub has_color: bool, + pub has_custom: bool, + pub has_scribble: bool, + pub has_shuffle: bool, + pub start_width: i32, + pub start_height: i32, + pub upscaler_scale_factor: Option, +} + +#[derive(Debug, Serialize)] +pub struct Paged { + pub items: Vec, + pub total: u64, +} diff --git a/src-tauri/src/projects_db/dtos/mod.rs b/src-tauri/src/projects_db/dtos/mod.rs new file mode 100644 index 0000000..0ff5cf0 --- /dev/null +++ b/src-tauri/src/projects_db/dtos/mod.rs @@ -0,0 +1,6 @@ +pub mod project; +pub mod image; +pub mod watch_folder; +pub mod model; +pub mod tensor; +pub mod text; \ No newline at end of file diff --git a/src-tauri/src/projects_db/dtos/model.rs b/src-tauri/src/projects_db/dtos/model.rs new file mode 100644 index 0000000..e796776 --- /dev/null +++ b/src-tauri/src/projects_db/dtos/model.rs @@ -0,0 +1,12 @@ +pub use entity::enums::ModelType; +use serde::Serialize; + +#[derive(Debug, Serialize, Clone)] +pub struct ModelExtra { + pub id: i64, + pub model_type: ModelType, + pub filename: String, + pub name: Option, + pub version: Option, + pub count: i64, +} diff --git a/src-tauri/src/projects_db/dtos/project.rs b/src-tauri/src/projects_db/dtos/project.rs new file mode 100644 index 0000000..d71f790 --- /dev/null +++ b/src-tauri/src/projects_db/dtos/project.rs @@ -0,0 +1,39 @@ +use entity::projects; +use sea_orm::FromQueryResult; +use serde::Serialize; + +#[derive(Debug, FromQueryResult, Serialize)] +pub struct ProjectExtra { + pub id: i64, + pub fingerprint: String, + pub path: String, + pub image_count: Option, + pub last_id: Option, + pub filesize: Option, + pub modified: Option, + pub missing_on: Option, + pub excluded: bool, +} + +#[derive(Debug, Serialize, Clone)] +pub struct DTProjectInfo { + pub _path: String, + pub _history_count: i64, + pub history_max_id: i64, +} + +impl From for ProjectExtra { + fn from(m: projects::Model) -> Self { + Self { + id: m.id, + fingerprint: m.fingerprint, + path: m.path, + image_count: None, + last_id: None, + filesize: m.filesize, + modified: m.modified, + missing_on: m.missing_on, + excluded: m.excluded, + } + } +} diff --git a/src-tauri/src/projects_db/dtos/tensor.rs b/src-tauri/src/projects_db/dtos/tensor.rs new file mode 100644 index 0000000..685fe55 --- /dev/null +++ b/src-tauri/src/projects_db/dtos/tensor.rs @@ -0,0 +1,388 @@ +use crate::projects_db::{ + fbs::{root_as_tensor_data, TensorData}, + tensor_history_mod::{Control, LoRA}, + tensor_history_tensor_data::TensorHistoryTensorData, +}; +use chrono::NaiveDateTime; + +#[derive(serde::Serialize, Debug, Clone)] +pub struct ModelAndWeight { + pub model: String, + pub weight: f32, +} + +#[derive(serde::Serialize, Debug)] +pub struct TensorHistoryImport { + pub lineage: i64, + pub logical_time: i64, + pub tensor_id: String, + pub width: u16, + pub height: u16, + pub seed: u32, + pub steps: u32, + pub guidance_scale: f32, + pub strength: f32, + pub model: String, + pub wall_clock: Option, + pub sampler: i8, + pub hires_fix: bool, + pub upscaler: Option, + pub upscaler_scale_factor: u8, + pub generated: bool, + pub controls: Vec, + pub loras: Vec, + pub preview_id: i64, + pub refiner_model: Option, + pub refiner_start: f32, + pub shift: f32, + pub tiled_decoding: bool, + pub tiled_diffusion: bool, + pub resolution_dependent_shift: bool, + pub tea_cache: bool, + pub prompt: String, + pub negative_prompt: String, + pub clip_id: i64, + pub index_in_a_clip: i32, + pub num_frames: Option, + pub cfg_zero_star: bool, + pub row_id: i64, + pub has_depth: bool, + pub has_pose: bool, + pub has_color: bool, + pub has_custom: bool, + pub has_scribble: bool, + pub has_shuffle: bool, + pub has_mask: bool, + pub text_edits: i64, + pub text_lineage: i64, +} + +impl From<&TensorHistoryTensorData> for TensorHistoryImport { + fn from(row: &TensorHistoryTensorData) -> Self { + let row_id = row.node_id; + + let node_data = &row.node_data; + let tensor_data = root_as_tensor_data(&row.tensor_data).unwrap(); + + let mut history = TensorHistoryImport::new( + node_data, + row_id, + "".to_string(), + false, + false, + false, + false, + false, + false, + false, + ) + .unwrap(); + + update_history_import_flags(&mut history, &tensor_data); + + history + } +} + +fn update_history_import_flags(history: &mut TensorHistoryImport, tensor_data: &TensorData) { + if tensor_data.tensor_id() > 0 { + history.tensor_id = format!("tensor_history_{}", tensor_data.tensor_id()); + } + if tensor_data.mask_id() > 0 { + history.has_mask = true; + } + if tensor_data.depth_map_id() > 0 { + history.has_depth = true; + } + if tensor_data.scribble_id() > 0 { + history.has_scribble = true; + } + if tensor_data.pose_id() > 0 { + history.has_pose = true; + } + if tensor_data.color_palette_id() > 0 { + history.has_color = true; + } + if tensor_data.custom_id() > 0 { + history.has_custom = true; + } +} + +pub struct TensorNodeGrouper<'a> { + index: usize, + // data: &[TensorHistoryTensorData], + current_row: Option<&'a TensorHistoryTensorData>, + current_item: Option, + rows_iter: std::slice::Iter<'a, TensorHistoryTensorData>, +} + +impl Iterator for TensorNodeGrouper<'_> { + type Item = TensorHistoryImport; + fn next(&mut self) -> Option { + loop { + // if we don't have a row, pop one off + let row = self.current_row.or_else(|| self.rows_iter.next()); + + // when no rows are left, return the item (or none) + if row.is_none() { + return self.current_item.take(); + } + let row = row.unwrap(); + + // if we don't have an item, make one + let item = self.current_item.take(); + let mut item = item.unwrap_or_else(|| TensorHistoryImport::from(row)); + + // if the row doesn't match, clear the item return it + if row.node_id != item.row_id { + self.current_row = Some(row); + return Some(item); + } + + // otherwise, the row matches the item, update the item and clear the row + update_history_import_flags(&mut item, &root_as_tensor_data(&row.tensor_data).unwrap()); + self.current_row = None; + + // hold onto before looping + self.current_item = Some(item); + } + } +} + +impl<'a> TensorNodeGrouper<'a> { + pub fn new(data: &'a [TensorHistoryTensorData]) -> Self { + Self { + index: 0, + rows_iter: data.iter(), + current_row: None, + current_item: None, + } + } +} + +#[derive(serde::Serialize, Debug, Clone)] +pub struct TensorHistoryNode { + pub lineage: i64, + pub logical_time: i64, + pub start_width: u16, + pub start_height: u16, + pub seed: u32, + pub steps: u32, + pub guidance_scale: f32, + pub strength: f32, + pub model: Option, + pub tensor_id: i64, + pub mask_id: i64, + pub wall_clock: Option, + pub text_edits: i64, + pub text_lineage: i64, + pub batch_size: u32, + pub sampler: i8, + pub hires_fix: bool, + pub hires_fix_start_width: u16, + pub hires_fix_start_height: u16, + pub hires_fix_strength: f32, + pub upscaler: Option, + pub scale_factor: u16, + pub depth_map_id: i64, + pub generated: bool, + pub image_guidance_scale: f32, + pub seed_mode: i8, + pub clip_skip: u32, + pub controls: Option>, + pub scribble_id: i64, + pub pose_id: i64, + pub loras: Option>, + pub color_palette_id: i64, + pub mask_blur: f32, + pub custom_id: i64, + pub face_restoration: Option, + pub clip_weight: f32, + pub negative_prompt_for_image_prior: bool, + pub image_prior_steps: u32, + pub data_stored: i32, + pub preview_id: i64, + pub content_offset_x: i32, + pub content_offset_y: i32, + pub scale_factor_by_120: i32, + pub refiner_model: Option, + pub original_image_height: u32, + pub original_image_width: u32, + pub crop_top: i32, + pub crop_left: i32, + pub target_image_height: u32, + pub target_image_width: u32, + pub aesthetic_score: f32, + pub negative_aesthetic_score: f32, + pub zero_negative_prompt: bool, + pub refiner_start: f32, + pub negative_original_image_height: u32, + pub negative_original_image_width: u32, + pub shuffle_data_stored: i32, + pub fps_id: u32, + pub motion_bucket_id: u32, + pub cond_aug: f32, + pub start_frame_cfg: f32, + pub num_frames: u32, + pub mask_blur_outset: i32, + pub sharpness: f32, + pub shift: f32, + pub stage_2_steps: u32, + pub stage_2_cfg: f32, + pub stage_2_shift: f32, + pub tiled_decoding: bool, + pub decoding_tile_width: u16, + pub decoding_tile_height: u16, + pub decoding_tile_overlap: u16, + pub stochastic_sampling_gamma: f32, + pub preserve_original_after_inpaint: bool, + pub tiled_diffusion: bool, + pub diffusion_tile_width: u16, + pub diffusion_tile_height: u16, + pub diffusion_tile_overlap: u16, + pub upscaler_scale_factor: u8, + pub script_session_id: u64, + pub t5_text_encoder: bool, + pub separate_clip_l: bool, + pub clip_l_text: Option, + pub separate_open_clip_g: bool, + pub open_clip_g_text: Option, + pub speed_up_with_guidance_embed: bool, + pub guidance_embed: f32, + pub resolution_dependent_shift: bool, + pub tea_cache_start: i32, + pub tea_cache_end: i32, + pub tea_cache_threshold: f32, + pub tea_cache: bool, + pub separate_t5: bool, + pub t5_text: Option, + pub tea_cache_max_skip_steps: i32, + pub text_prompt: Option, + pub negative_text_prompt: Option, + pub clip_id: i64, + pub index_in_a_clip: i32, + pub causal_inference_enabled: bool, + pub causal_inference: i32, + pub causal_inference_pad: i32, + pub cfg_zero_star: bool, + pub cfg_zero_init_steps: i32, + pub generation_time: f64, + pub reason: i32, +} + +#[derive(serde::Serialize, Debug, Clone)] +pub struct TensorHistoryExtra { + pub row_id: i64, + pub lineage: i64, + pub logical_time: i64, + pub tensor_id: Option, + pub mask_id: Option, + pub depth_map_id: Option, + pub scribble_id: Option, + pub pose_id: Option, + pub color_palette_id: Option, + pub custom_id: Option, + pub moodboard_ids: Vec, + pub history: TensorHistoryNode, + pub project_path: String, +} + +impl From<(Vec, String)> for TensorHistoryExtra { + fn from((rows, project_path): (Vec, String)) -> Self { + assert!(!rows.is_empty(), "must have at least one row"); + + let node_id = rows[0].node_id; + let lineage = rows[0].lineage; + let logical_time = rows[0].logical_time; + + // Take the node data from the first row (they're all the same) + let node_data = &rows[0].node_data; + let history = TensorHistoryNode::try_from(node_data.as_ref()).unwrap(); + + // Initialize optional fields + let mut tensor_id: Option = None; + let mut mask_id: Option = None; + let mut depth_map_id: Option = None; + let mut scribble_id: Option = None; + let mut pose_id: Option = None; + let mut color_palette_id: Option = None; + let mut custom_id: Option = None; + let moodboard_ids: Vec = Vec::new(); + + // Iterate all tensor rows + for row in rows { + let tensor_fb = root_as_tensor_data(&row.tensor_data).unwrap(); + + if tensor_fb.tensor_id() > 0 { + tensor_id = Some(format!("tensor_history_{}", tensor_fb.tensor_id())); + } + if tensor_fb.mask_id() > 0 { + mask_id = Some(format!("binary_mask_{}", tensor_fb.mask_id())); + } + if tensor_fb.depth_map_id() > 0 { + depth_map_id = Some(format!("depth_map_{}", tensor_fb.depth_map_id())); + } + if tensor_fb.scribble_id() > 0 { + scribble_id = Some(format!("scribble_{}", tensor_fb.scribble_id())); + } + if tensor_fb.pose_id() > 0 { + pose_id = Some(format!("pose_{}", tensor_fb.pose_id())); + } + if tensor_fb.color_palette_id() > 0 { + color_palette_id = Some(format!("color_palette_{}", tensor_fb.color_palette_id())); + } + if tensor_fb.custom_id() > 0 { + custom_id = Some(format!("custom_{}", tensor_fb.custom_id())); + } + + // if let Some(mb_ids) = tensor_fb.() { + // moodboard_ids.extend(mb_ids.iter().map(|s| s.to_string())); + // } + } + + Self { + row_id: node_id, + lineage, + logical_time, + tensor_id, + mask_id, + depth_map_id, + scribble_id, + pose_id, + color_palette_id, + custom_id, + moodboard_ids, + history, + project_path, + } + } +} + +#[derive(serde::Serialize, Debug, Clone)] +pub struct TensorRaw { + pub name: String, + pub tensor_type: i64, + pub data_type: i32, + pub format: i32, + pub width: i32, + pub height: i32, + pub channels: i32, + pub dim: Vec, + pub data: Vec, +} + +#[derive(serde::Serialize, Debug, Clone)] +pub struct TensorSize { + pub width: i32, + pub height: i32, + pub channels: i32, +} + +#[derive(serde::Serialize, Debug, Clone)] +pub struct TensorHistoryClip { + pub tensor_id: String, + pub preview_id: i64, + pub clip_id: i64, + pub index_in_a_clip: i32, + pub row_id: i64, +} diff --git a/src-tauri/src/projects_db/dtos/text.rs b/src-tauri/src/projects_db/dtos/text.rs new file mode 100644 index 0000000..1267622 --- /dev/null +++ b/src-tauri/src/projects_db/dtos/text.rs @@ -0,0 +1,30 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)] +pub enum TextType { + PositiveText, + NegativeText, +} + +#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Default)] +pub struct TextRange { + pub location: i32, + pub length: i32, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub struct TextModification { + pub modification_type: TextType, + pub range: TextRange, + pub text: String, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub struct TextHistoryNode { + pub lineage: i64, + pub logical_time: i64, + pub start_edits: i64, + pub start_positive_text: String, + pub start_negative_text: String, + pub modifications: Vec, +} diff --git a/src-tauri/src/projects_db/dtos/watch_folder.rs b/src-tauri/src/projects_db/dtos/watch_folder.rs new file mode 100644 index 0000000..228705f --- /dev/null +++ b/src-tauri/src/projects_db/dtos/watch_folder.rs @@ -0,0 +1,21 @@ +use entity::watch_folders; +use serde::Serialize; + +#[derive(Debug, Serialize, Clone)] +pub struct WatchFolderDTO { + pub id: i64, + pub path: String, + pub recursive: Option, + pub last_updated: Option, +} + +impl From for WatchFolderDTO { + fn from(m: watch_folders::Model) -> Self { + Self { + id: m.id, + path: m.path, + recursive: m.recursive, + last_updated: m.last_updated, + } + } +} diff --git a/src-tauri/src/projects_db/fbs/mod.rs b/src-tauri/src/projects_db/fbs/mod.rs index 89b62fe..bafa6cc 100644 --- a/src-tauri/src/projects_db/fbs/mod.rs +++ b/src-tauri/src/projects_db/fbs/mod.rs @@ -15,3 +15,7 @@ mod text_modification_generated; pub use self::text_modification_generated::*; mod text_history_node_generated; pub use self::text_history_node_generated::*; +mod tensor_history_generated; +pub use self::tensor_history_generated::*; +mod tensor_data_generated; +pub use self::tensor_data_generated::*; diff --git a/src-tauri/src/projects_db/fbs/tensor_history_generated.rs b/src-tauri/src/projects_db/fbs/tensor_history_generated.rs new file mode 100644 index 0000000..cb9945b --- /dev/null +++ b/src-tauri/src/projects_db/fbs/tensor_history_generated.rs @@ -0,0 +1,3052 @@ +// automatically generated by the FlatBuffers compiler, do not modify + + +// @generated + +use core::mem; +use core::cmp::Ordering; + +extern crate flatbuffers; +use self::flatbuffers::{EndianScalar, Follow}; + +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MIN_SAMPLER_TYPE: i8 = 0; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MAX_SAMPLER_TYPE: i8 = 18; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +#[allow(non_camel_case_types)] +pub const ENUM_VALUES_SAMPLER_TYPE: [SamplerType; 19] = [ + SamplerType::DPMPP2MKarras, + SamplerType::EulerA, + SamplerType::DDIM, + SamplerType::PLMS, + SamplerType::DPMPPSDEKarras, + SamplerType::UniPC, + SamplerType::LCM, + SamplerType::EulerASubstep, + SamplerType::DPMPPSDESubstep, + SamplerType::TCD, + SamplerType::EulerATrailing, + SamplerType::DPMPPSDETrailing, + SamplerType::DPMPP2MAYS, + SamplerType::EulerAAYS, + SamplerType::DPMPPSDEAYS, + SamplerType::DPMPP2MTrailing, + SamplerType::DDIMTrailing, + SamplerType::UniPCTrailing, + SamplerType::UniPCAYS, +]; + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +#[repr(transparent)] +pub struct SamplerType(pub i8); +#[allow(non_upper_case_globals)] +impl SamplerType { + pub const DPMPP2MKarras: Self = Self(0); + pub const EulerA: Self = Self(1); + pub const DDIM: Self = Self(2); + pub const PLMS: Self = Self(3); + pub const DPMPPSDEKarras: Self = Self(4); + pub const UniPC: Self = Self(5); + pub const LCM: Self = Self(6); + pub const EulerASubstep: Self = Self(7); + pub const DPMPPSDESubstep: Self = Self(8); + pub const TCD: Self = Self(9); + pub const EulerATrailing: Self = Self(10); + pub const DPMPPSDETrailing: Self = Self(11); + pub const DPMPP2MAYS: Self = Self(12); + pub const EulerAAYS: Self = Self(13); + pub const DPMPPSDEAYS: Self = Self(14); + pub const DPMPP2MTrailing: Self = Self(15); + pub const DDIMTrailing: Self = Self(16); + pub const UniPCTrailing: Self = Self(17); + pub const UniPCAYS: Self = Self(18); + + pub const ENUM_MIN: i8 = 0; + pub const ENUM_MAX: i8 = 18; + pub const ENUM_VALUES: &'static [Self] = &[ + Self::DPMPP2MKarras, + Self::EulerA, + Self::DDIM, + Self::PLMS, + Self::DPMPPSDEKarras, + Self::UniPC, + Self::LCM, + Self::EulerASubstep, + Self::DPMPPSDESubstep, + Self::TCD, + Self::EulerATrailing, + Self::DPMPPSDETrailing, + Self::DPMPP2MAYS, + Self::EulerAAYS, + Self::DPMPPSDEAYS, + Self::DPMPP2MTrailing, + Self::DDIMTrailing, + Self::UniPCTrailing, + Self::UniPCAYS, + ]; + /// Returns the variant's name or "" if unknown. + pub fn variant_name(self) -> Option<&'static str> { + match self { + Self::DPMPP2MKarras => Some("DPMPP2MKarras"), + Self::EulerA => Some("EulerA"), + Self::DDIM => Some("DDIM"), + Self::PLMS => Some("PLMS"), + Self::DPMPPSDEKarras => Some("DPMPPSDEKarras"), + Self::UniPC => Some("UniPC"), + Self::LCM => Some("LCM"), + Self::EulerASubstep => Some("EulerASubstep"), + Self::DPMPPSDESubstep => Some("DPMPPSDESubstep"), + Self::TCD => Some("TCD"), + Self::EulerATrailing => Some("EulerATrailing"), + Self::DPMPPSDETrailing => Some("DPMPPSDETrailing"), + Self::DPMPP2MAYS => Some("DPMPP2MAYS"), + Self::EulerAAYS => Some("EulerAAYS"), + Self::DPMPPSDEAYS => Some("DPMPPSDEAYS"), + Self::DPMPP2MTrailing => Some("DPMPP2MTrailing"), + Self::DDIMTrailing => Some("DDIMTrailing"), + Self::UniPCTrailing => Some("UniPCTrailing"), + Self::UniPCAYS => Some("UniPCAYS"), + _ => None, + } + } +} +impl core::fmt::Debug for SamplerType { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + if let Some(name) = self.variant_name() { + f.write_str(name) + } else { + f.write_fmt(format_args!("", self.0)) + } + } +} +impl<'a> flatbuffers::Follow<'a> for SamplerType { + type Inner = Self; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = unsafe { flatbuffers::read_scalar_at::(buf, loc) }; + Self(b) + } +} + +impl flatbuffers::Push for SamplerType { + type Output = SamplerType; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + unsafe { flatbuffers::emplace_scalar::(dst, self.0); } + } +} + +impl flatbuffers::EndianScalar for SamplerType { + type Scalar = i8; + #[inline] + fn to_little_endian(self) -> i8 { + self.0.to_le() + } + #[inline] + #[allow(clippy::wrong_self_convention)] + fn from_little_endian(v: i8) -> Self { + let b = i8::from_le(v); + Self(b) + } +} + +impl<'a> flatbuffers::Verifiable for SamplerType { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + i8::run_verifier(v, pos) + } +} + +impl flatbuffers::SimpleToVerifyInSlice for SamplerType {} +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MIN_SEED_MODE: i8 = 0; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MAX_SEED_MODE: i8 = 3; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +#[allow(non_camel_case_types)] +pub const ENUM_VALUES_SEED_MODE: [SeedMode; 4] = [ + SeedMode::Legacy, + SeedMode::TorchCpuCompatible, + SeedMode::ScaleAlike, + SeedMode::NvidiaGpuCompatible, +]; + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +#[repr(transparent)] +pub struct SeedMode(pub i8); +#[allow(non_upper_case_globals)] +impl SeedMode { + pub const Legacy: Self = Self(0); + pub const TorchCpuCompatible: Self = Self(1); + pub const ScaleAlike: Self = Self(2); + pub const NvidiaGpuCompatible: Self = Self(3); + + pub const ENUM_MIN: i8 = 0; + pub const ENUM_MAX: i8 = 3; + pub const ENUM_VALUES: &'static [Self] = &[ + Self::Legacy, + Self::TorchCpuCompatible, + Self::ScaleAlike, + Self::NvidiaGpuCompatible, + ]; + /// Returns the variant's name or "" if unknown. + pub fn variant_name(self) -> Option<&'static str> { + match self { + Self::Legacy => Some("Legacy"), + Self::TorchCpuCompatible => Some("TorchCpuCompatible"), + Self::ScaleAlike => Some("ScaleAlike"), + Self::NvidiaGpuCompatible => Some("NvidiaGpuCompatible"), + _ => None, + } + } +} +impl core::fmt::Debug for SeedMode { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + if let Some(name) = self.variant_name() { + f.write_str(name) + } else { + f.write_fmt(format_args!("", self.0)) + } + } +} +impl<'a> flatbuffers::Follow<'a> for SeedMode { + type Inner = Self; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = unsafe { flatbuffers::read_scalar_at::(buf, loc) }; + Self(b) + } +} + +impl flatbuffers::Push for SeedMode { + type Output = SeedMode; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + unsafe { flatbuffers::emplace_scalar::(dst, self.0); } + } +} + +impl flatbuffers::EndianScalar for SeedMode { + type Scalar = i8; + #[inline] + fn to_little_endian(self) -> i8 { + self.0.to_le() + } + #[inline] + #[allow(clippy::wrong_self_convention)] + fn from_little_endian(v: i8) -> Self { + let b = i8::from_le(v); + Self(b) + } +} + +impl<'a> flatbuffers::Verifiable for SeedMode { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + i8::run_verifier(v, pos) + } +} + +impl flatbuffers::SimpleToVerifyInSlice for SeedMode {} +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MIN_CONTROL_MODE: i8 = 0; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MAX_CONTROL_MODE: i8 = 2; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +#[allow(non_camel_case_types)] +pub const ENUM_VALUES_CONTROL_MODE: [ControlMode; 3] = [ + ControlMode::Balanced, + ControlMode::Prompt, + ControlMode::Control, +]; + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +#[repr(transparent)] +pub struct ControlMode(pub i8); +#[allow(non_upper_case_globals)] +impl ControlMode { + pub const Balanced: Self = Self(0); + pub const Prompt: Self = Self(1); + pub const Control: Self = Self(2); + + pub const ENUM_MIN: i8 = 0; + pub const ENUM_MAX: i8 = 2; + pub const ENUM_VALUES: &'static [Self] = &[ + Self::Balanced, + Self::Prompt, + Self::Control, + ]; + /// Returns the variant's name or "" if unknown. + pub fn variant_name(self) -> Option<&'static str> { + match self { + Self::Balanced => Some("Balanced"), + Self::Prompt => Some("Prompt"), + Self::Control => Some("Control"), + _ => None, + } + } +} +impl core::fmt::Debug for ControlMode { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + if let Some(name) = self.variant_name() { + f.write_str(name) + } else { + f.write_fmt(format_args!("", self.0)) + } + } +} +impl<'a> flatbuffers::Follow<'a> for ControlMode { + type Inner = Self; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = unsafe { flatbuffers::read_scalar_at::(buf, loc) }; + Self(b) + } +} + +impl flatbuffers::Push for ControlMode { + type Output = ControlMode; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + unsafe { flatbuffers::emplace_scalar::(dst, self.0); } + } +} + +impl flatbuffers::EndianScalar for ControlMode { + type Scalar = i8; + #[inline] + fn to_little_endian(self) -> i8 { + self.0.to_le() + } + #[inline] + #[allow(clippy::wrong_self_convention)] + fn from_little_endian(v: i8) -> Self { + let b = i8::from_le(v); + Self(b) + } +} + +impl<'a> flatbuffers::Verifiable for ControlMode { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + i8::run_verifier(v, pos) + } +} + +impl flatbuffers::SimpleToVerifyInSlice for ControlMode {} +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MIN_CONTROL_INPUT_TYPE: i8 = 0; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MAX_CONTROL_INPUT_TYPE: i8 = 18; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +#[allow(non_camel_case_types)] +pub const ENUM_VALUES_CONTROL_INPUT_TYPE: [ControlInputType; 19] = [ + ControlInputType::Unspecified, + ControlInputType::Custom, + ControlInputType::Depth, + ControlInputType::Canny, + ControlInputType::Scribble, + ControlInputType::Pose, + ControlInputType::Normalbae, + ControlInputType::Color, + ControlInputType::Lineart, + ControlInputType::Softedge, + ControlInputType::Seg, + ControlInputType::Inpaint, + ControlInputType::Ip2p, + ControlInputType::Shuffle, + ControlInputType::Mlsd, + ControlInputType::Tile, + ControlInputType::Blur, + ControlInputType::Lowquality, + ControlInputType::Gray, +]; + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +#[repr(transparent)] +pub struct ControlInputType(pub i8); +#[allow(non_upper_case_globals)] +impl ControlInputType { + pub const Unspecified: Self = Self(0); + pub const Custom: Self = Self(1); + pub const Depth: Self = Self(2); + pub const Canny: Self = Self(3); + pub const Scribble: Self = Self(4); + pub const Pose: Self = Self(5); + pub const Normalbae: Self = Self(6); + pub const Color: Self = Self(7); + pub const Lineart: Self = Self(8); + pub const Softedge: Self = Self(9); + pub const Seg: Self = Self(10); + pub const Inpaint: Self = Self(11); + pub const Ip2p: Self = Self(12); + pub const Shuffle: Self = Self(13); + pub const Mlsd: Self = Self(14); + pub const Tile: Self = Self(15); + pub const Blur: Self = Self(16); + pub const Lowquality: Self = Self(17); + pub const Gray: Self = Self(18); + + pub const ENUM_MIN: i8 = 0; + pub const ENUM_MAX: i8 = 18; + pub const ENUM_VALUES: &'static [Self] = &[ + Self::Unspecified, + Self::Custom, + Self::Depth, + Self::Canny, + Self::Scribble, + Self::Pose, + Self::Normalbae, + Self::Color, + Self::Lineart, + Self::Softedge, + Self::Seg, + Self::Inpaint, + Self::Ip2p, + Self::Shuffle, + Self::Mlsd, + Self::Tile, + Self::Blur, + Self::Lowquality, + Self::Gray, + ]; + /// Returns the variant's name or "" if unknown. + pub fn variant_name(self) -> Option<&'static str> { + match self { + Self::Unspecified => Some("Unspecified"), + Self::Custom => Some("Custom"), + Self::Depth => Some("Depth"), + Self::Canny => Some("Canny"), + Self::Scribble => Some("Scribble"), + Self::Pose => Some("Pose"), + Self::Normalbae => Some("Normalbae"), + Self::Color => Some("Color"), + Self::Lineart => Some("Lineart"), + Self::Softedge => Some("Softedge"), + Self::Seg => Some("Seg"), + Self::Inpaint => Some("Inpaint"), + Self::Ip2p => Some("Ip2p"), + Self::Shuffle => Some("Shuffle"), + Self::Mlsd => Some("Mlsd"), + Self::Tile => Some("Tile"), + Self::Blur => Some("Blur"), + Self::Lowquality => Some("Lowquality"), + Self::Gray => Some("Gray"), + _ => None, + } + } +} +impl core::fmt::Debug for ControlInputType { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + if let Some(name) = self.variant_name() { + f.write_str(name) + } else { + f.write_fmt(format_args!("", self.0)) + } + } +} +impl<'a> flatbuffers::Follow<'a> for ControlInputType { + type Inner = Self; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = unsafe { flatbuffers::read_scalar_at::(buf, loc) }; + Self(b) + } +} + +impl flatbuffers::Push for ControlInputType { + type Output = ControlInputType; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + unsafe { flatbuffers::emplace_scalar::(dst, self.0); } + } +} + +impl flatbuffers::EndianScalar for ControlInputType { + type Scalar = i8; + #[inline] + fn to_little_endian(self) -> i8 { + self.0.to_le() + } + #[inline] + #[allow(clippy::wrong_self_convention)] + fn from_little_endian(v: i8) -> Self { + let b = i8::from_le(v); + Self(b) + } +} + +impl<'a> flatbuffers::Verifiable for ControlInputType { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + i8::run_verifier(v, pos) + } +} + +impl flatbuffers::SimpleToVerifyInSlice for ControlInputType {} +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MIN_LO_RAMODE: i8 = 0; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MAX_LO_RAMODE: i8 = 2; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +#[allow(non_camel_case_types)] +pub const ENUM_VALUES_LO_RAMODE: [LoRAMode; 3] = [ + LoRAMode::All, + LoRAMode::Base, + LoRAMode::Refiner, +]; + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +#[repr(transparent)] +pub struct LoRAMode(pub i8); +#[allow(non_upper_case_globals)] +impl LoRAMode { + pub const All: Self = Self(0); + pub const Base: Self = Self(1); + pub const Refiner: Self = Self(2); + + pub const ENUM_MIN: i8 = 0; + pub const ENUM_MAX: i8 = 2; + pub const ENUM_VALUES: &'static [Self] = &[ + Self::All, + Self::Base, + Self::Refiner, + ]; + /// Returns the variant's name or "" if unknown. + pub fn variant_name(self) -> Option<&'static str> { + match self { + Self::All => Some("All"), + Self::Base => Some("Base"), + Self::Refiner => Some("Refiner"), + _ => None, + } + } +} +impl core::fmt::Debug for LoRAMode { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + if let Some(name) = self.variant_name() { + f.write_str(name) + } else { + f.write_fmt(format_args!("", self.0)) + } + } +} +impl<'a> flatbuffers::Follow<'a> for LoRAMode { + type Inner = Self; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = unsafe { flatbuffers::read_scalar_at::(buf, loc) }; + Self(b) + } +} + +impl flatbuffers::Push for LoRAMode { + type Output = LoRAMode; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + unsafe { flatbuffers::emplace_scalar::(dst, self.0); } + } +} + +impl flatbuffers::EndianScalar for LoRAMode { + type Scalar = i8; + #[inline] + fn to_little_endian(self) -> i8 { + self.0.to_le() + } + #[inline] + #[allow(clippy::wrong_self_convention)] + fn from_little_endian(v: i8) -> Self { + let b = i8::from_le(v); + Self(b) + } +} + +impl<'a> flatbuffers::Verifiable for LoRAMode { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + i8::run_verifier(v, pos) + } +} + +impl flatbuffers::SimpleToVerifyInSlice for LoRAMode {} +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MIN_REASON: i32 = 0; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MAX_REASON: i32 = 8; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +#[allow(non_camel_case_types)] +pub const ENUM_VALUES_REASON: [Reason; 9] = [ + Reason::Other, + Reason::Generate, + Reason::Imported, + Reason::Draw, + Reason::Mask, + Reason::Scribble, + Reason::Moodboard, + Reason::DepthMap, + Reason::Clear, +]; + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +#[repr(transparent)] +pub struct Reason(pub i32); +#[allow(non_upper_case_globals)] +impl Reason { + pub const Other: Self = Self(0); + pub const Generate: Self = Self(1); + pub const Imported: Self = Self(2); + pub const Draw: Self = Self(3); + pub const Mask: Self = Self(4); + pub const Scribble: Self = Self(5); + pub const Moodboard: Self = Self(6); + pub const DepthMap: Self = Self(7); + pub const Clear: Self = Self(8); + + pub const ENUM_MIN: i32 = 0; + pub const ENUM_MAX: i32 = 8; + pub const ENUM_VALUES: &'static [Self] = &[ + Self::Other, + Self::Generate, + Self::Imported, + Self::Draw, + Self::Mask, + Self::Scribble, + Self::Moodboard, + Self::DepthMap, + Self::Clear, + ]; + /// Returns the variant's name or "" if unknown. + pub fn variant_name(self) -> Option<&'static str> { + match self { + Self::Other => Some("Other"), + Self::Generate => Some("Generate"), + Self::Imported => Some("Imported"), + Self::Draw => Some("Draw"), + Self::Mask => Some("Mask"), + Self::Scribble => Some("Scribble"), + Self::Moodboard => Some("Moodboard"), + Self::DepthMap => Some("DepthMap"), + Self::Clear => Some("Clear"), + _ => None, + } + } +} +impl core::fmt::Debug for Reason { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + if let Some(name) = self.variant_name() { + f.write_str(name) + } else { + f.write_fmt(format_args!("", self.0)) + } + } +} +impl<'a> flatbuffers::Follow<'a> for Reason { + type Inner = Self; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = unsafe { flatbuffers::read_scalar_at::(buf, loc) }; + Self(b) + } +} + +impl flatbuffers::Push for Reason { + type Output = Reason; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + unsafe { flatbuffers::emplace_scalar::(dst, self.0); } + } +} + +impl flatbuffers::EndianScalar for Reason { + type Scalar = i32; + #[inline] + fn to_little_endian(self) -> i32 { + self.0.to_le() + } + #[inline] + #[allow(clippy::wrong_self_convention)] + fn from_little_endian(v: i32) -> Self { + let b = i32::from_le(v); + Self(b) + } +} + +impl<'a> flatbuffers::Verifiable for Reason { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + i32::run_verifier(v, pos) + } +} + +impl flatbuffers::SimpleToVerifyInSlice for Reason {} +pub enum ControlOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct Control<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for Control<'a> { + type Inner = Control<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: unsafe { flatbuffers::Table::new(buf, loc) } } + } +} + +impl<'a> Control<'a> { + pub const VT_FILE: flatbuffers::VOffsetT = 4; + pub const VT_WEIGHT: flatbuffers::VOffsetT = 6; + pub const VT_GUIDANCE_START: flatbuffers::VOffsetT = 8; + pub const VT_GUIDANCE_END: flatbuffers::VOffsetT = 10; + pub const VT_NO_PROMPT: flatbuffers::VOffsetT = 12; + pub const VT_GLOBAL_AVERAGE_POOLING: flatbuffers::VOffsetT = 14; + pub const VT_DOWN_SAMPLING_RATE: flatbuffers::VOffsetT = 16; + pub const VT_CONTROL_MODE: flatbuffers::VOffsetT = 18; + pub const VT_TARGET_BLOCKS: flatbuffers::VOffsetT = 20; + pub const VT_INPUT_OVERRIDE: flatbuffers::VOffsetT = 22; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + Control { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + args: &'args ControlArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = ControlBuilder::new(_fbb); + if let Some(x) = args.target_blocks { builder.add_target_blocks(x); } + builder.add_down_sampling_rate(args.down_sampling_rate); + builder.add_guidance_end(args.guidance_end); + builder.add_guidance_start(args.guidance_start); + builder.add_weight(args.weight); + if let Some(x) = args.file { builder.add_file(x); } + builder.add_input_override(args.input_override); + builder.add_control_mode(args.control_mode); + builder.add_global_average_pooling(args.global_average_pooling); + builder.add_no_prompt(args.no_prompt); + builder.finish() + } + + + #[inline] + pub fn file(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(Control::VT_FILE, None)} + } + #[inline] + pub fn weight(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Control::VT_WEIGHT, Some(1.0)).unwrap()} + } + #[inline] + pub fn guidance_start(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Control::VT_GUIDANCE_START, Some(0.0)).unwrap()} + } + #[inline] + pub fn guidance_end(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Control::VT_GUIDANCE_END, Some(1.0)).unwrap()} + } + #[inline] + pub fn no_prompt(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Control::VT_NO_PROMPT, Some(false)).unwrap()} + } + #[inline] + pub fn global_average_pooling(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Control::VT_GLOBAL_AVERAGE_POOLING, Some(true)).unwrap()} + } + #[inline] + pub fn down_sampling_rate(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Control::VT_DOWN_SAMPLING_RATE, Some(1.0)).unwrap()} + } + #[inline] + pub fn control_mode(&self) -> ControlMode { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Control::VT_CONTROL_MODE, Some(ControlMode::Balanced)).unwrap()} + } + #[inline] + pub fn target_blocks(&self) -> Option>> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>>(Control::VT_TARGET_BLOCKS, None)} + } + #[inline] + pub fn input_override(&self) -> ControlInputType { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Control::VT_INPUT_OVERRIDE, Some(ControlInputType::Unspecified)).unwrap()} + } +} + +impl flatbuffers::Verifiable for Control<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::>("file", Self::VT_FILE, false)? + .visit_field::("weight", Self::VT_WEIGHT, false)? + .visit_field::("guidance_start", Self::VT_GUIDANCE_START, false)? + .visit_field::("guidance_end", Self::VT_GUIDANCE_END, false)? + .visit_field::("no_prompt", Self::VT_NO_PROMPT, false)? + .visit_field::("global_average_pooling", Self::VT_GLOBAL_AVERAGE_POOLING, false)? + .visit_field::("down_sampling_rate", Self::VT_DOWN_SAMPLING_RATE, false)? + .visit_field::("control_mode", Self::VT_CONTROL_MODE, false)? + .visit_field::>>>("target_blocks", Self::VT_TARGET_BLOCKS, false)? + .visit_field::("input_override", Self::VT_INPUT_OVERRIDE, false)? + .finish(); + Ok(()) + } +} +pub struct ControlArgs<'a> { + pub file: Option>, + pub weight: f32, + pub guidance_start: f32, + pub guidance_end: f32, + pub no_prompt: bool, + pub global_average_pooling: bool, + pub down_sampling_rate: f32, + pub control_mode: ControlMode, + pub target_blocks: Option>>>, + pub input_override: ControlInputType, +} +impl<'a> Default for ControlArgs<'a> { + #[inline] + fn default() -> Self { + ControlArgs { + file: None, + weight: 1.0, + guidance_start: 0.0, + guidance_end: 1.0, + no_prompt: false, + global_average_pooling: true, + down_sampling_rate: 1.0, + control_mode: ControlMode::Balanced, + target_blocks: None, + input_override: ControlInputType::Unspecified, + } + } +} + +pub struct ControlBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> ControlBuilder<'a, 'b, A> { + #[inline] + pub fn add_file(&mut self, file: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(Control::VT_FILE, file); + } + #[inline] + pub fn add_weight(&mut self, weight: f32) { + self.fbb_.push_slot::(Control::VT_WEIGHT, weight, 1.0); + } + #[inline] + pub fn add_guidance_start(&mut self, guidance_start: f32) { + self.fbb_.push_slot::(Control::VT_GUIDANCE_START, guidance_start, 0.0); + } + #[inline] + pub fn add_guidance_end(&mut self, guidance_end: f32) { + self.fbb_.push_slot::(Control::VT_GUIDANCE_END, guidance_end, 1.0); + } + #[inline] + pub fn add_no_prompt(&mut self, no_prompt: bool) { + self.fbb_.push_slot::(Control::VT_NO_PROMPT, no_prompt, false); + } + #[inline] + pub fn add_global_average_pooling(&mut self, global_average_pooling: bool) { + self.fbb_.push_slot::(Control::VT_GLOBAL_AVERAGE_POOLING, global_average_pooling, true); + } + #[inline] + pub fn add_down_sampling_rate(&mut self, down_sampling_rate: f32) { + self.fbb_.push_slot::(Control::VT_DOWN_SAMPLING_RATE, down_sampling_rate, 1.0); + } + #[inline] + pub fn add_control_mode(&mut self, control_mode: ControlMode) { + self.fbb_.push_slot::(Control::VT_CONTROL_MODE, control_mode, ControlMode::Balanced); + } + #[inline] + pub fn add_target_blocks(&mut self, target_blocks: flatbuffers::WIPOffset>>) { + self.fbb_.push_slot_always::>(Control::VT_TARGET_BLOCKS, target_blocks); + } + #[inline] + pub fn add_input_override(&mut self, input_override: ControlInputType) { + self.fbb_.push_slot::(Control::VT_INPUT_OVERRIDE, input_override, ControlInputType::Unspecified); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> ControlBuilder<'a, 'b, A> { + let start = _fbb.start_table(); + ControlBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for Control<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("Control"); + ds.field("file", &self.file()); + ds.field("weight", &self.weight()); + ds.field("guidance_start", &self.guidance_start()); + ds.field("guidance_end", &self.guidance_end()); + ds.field("no_prompt", &self.no_prompt()); + ds.field("global_average_pooling", &self.global_average_pooling()); + ds.field("down_sampling_rate", &self.down_sampling_rate()); + ds.field("control_mode", &self.control_mode()); + ds.field("target_blocks", &self.target_blocks()); + ds.field("input_override", &self.input_override()); + ds.finish() + } +} +pub enum LoRAOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct LoRA<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for LoRA<'a> { + type Inner = LoRA<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: unsafe { flatbuffers::Table::new(buf, loc) } } + } +} + +impl<'a> LoRA<'a> { + pub const VT_FILE: flatbuffers::VOffsetT = 4; + pub const VT_WEIGHT: flatbuffers::VOffsetT = 6; + pub const VT_MODE: flatbuffers::VOffsetT = 8; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + LoRA { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + args: &'args LoRAArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = LoRABuilder::new(_fbb); + builder.add_weight(args.weight); + if let Some(x) = args.file { builder.add_file(x); } + builder.add_mode(args.mode); + builder.finish() + } + + + #[inline] + pub fn file(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(LoRA::VT_FILE, None)} + } + #[inline] + pub fn weight(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(LoRA::VT_WEIGHT, Some(0.6)).unwrap()} + } + #[inline] + pub fn mode(&self) -> LoRAMode { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(LoRA::VT_MODE, Some(LoRAMode::All)).unwrap()} + } +} + +impl flatbuffers::Verifiable for LoRA<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::>("file", Self::VT_FILE, false)? + .visit_field::("weight", Self::VT_WEIGHT, false)? + .visit_field::("mode", Self::VT_MODE, false)? + .finish(); + Ok(()) + } +} +pub struct LoRAArgs<'a> { + pub file: Option>, + pub weight: f32, + pub mode: LoRAMode, +} +impl<'a> Default for LoRAArgs<'a> { + #[inline] + fn default() -> Self { + LoRAArgs { + file: None, + weight: 0.6, + mode: LoRAMode::All, + } + } +} + +pub struct LoRABuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> LoRABuilder<'a, 'b, A> { + #[inline] + pub fn add_file(&mut self, file: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(LoRA::VT_FILE, file); + } + #[inline] + pub fn add_weight(&mut self, weight: f32) { + self.fbb_.push_slot::(LoRA::VT_WEIGHT, weight, 0.6); + } + #[inline] + pub fn add_mode(&mut self, mode: LoRAMode) { + self.fbb_.push_slot::(LoRA::VT_MODE, mode, LoRAMode::All); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> LoRABuilder<'a, 'b, A> { + let start = _fbb.start_table(); + LoRABuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for LoRA<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("LoRA"); + ds.field("file", &self.file()); + ds.field("weight", &self.weight()); + ds.field("mode", &self.mode()); + ds.finish() + } +} +pub enum TensorHistoryNodeOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct TensorHistoryNode<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for TensorHistoryNode<'a> { + type Inner = TensorHistoryNode<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: unsafe { flatbuffers::Table::new(buf, loc) } } + } +} + +impl<'a> TensorHistoryNode<'a> { + pub const VT_LINEAGE: flatbuffers::VOffsetT = 4; + pub const VT_LOGICAL_TIME: flatbuffers::VOffsetT = 6; + pub const VT_START_WIDTH: flatbuffers::VOffsetT = 8; + pub const VT_START_HEIGHT: flatbuffers::VOffsetT = 10; + pub const VT_SEED: flatbuffers::VOffsetT = 12; + pub const VT_STEPS: flatbuffers::VOffsetT = 14; + pub const VT_GUIDANCE_SCALE: flatbuffers::VOffsetT = 16; + pub const VT_STRENGTH: flatbuffers::VOffsetT = 18; + pub const VT_MODEL: flatbuffers::VOffsetT = 20; + pub const VT_TENSOR_ID: flatbuffers::VOffsetT = 22; + pub const VT_MASK_ID: flatbuffers::VOffsetT = 24; + pub const VT_WALL_CLOCK: flatbuffers::VOffsetT = 26; + pub const VT_TEXT_EDITS: flatbuffers::VOffsetT = 28; + pub const VT_TEXT_LINEAGE: flatbuffers::VOffsetT = 30; + pub const VT_BATCH_SIZE: flatbuffers::VOffsetT = 32; + pub const VT_SAMPLER: flatbuffers::VOffsetT = 34; + pub const VT_HIRES_FIX: flatbuffers::VOffsetT = 36; + pub const VT_HIRES_FIX_START_WIDTH: flatbuffers::VOffsetT = 38; + pub const VT_HIRES_FIX_START_HEIGHT: flatbuffers::VOffsetT = 40; + pub const VT_HIRES_FIX_STRENGTH: flatbuffers::VOffsetT = 42; + pub const VT_UPSCALER: flatbuffers::VOffsetT = 44; + pub const VT_SCALE_FACTOR: flatbuffers::VOffsetT = 46; + pub const VT_DEPTH_MAP_ID: flatbuffers::VOffsetT = 48; + pub const VT_GENERATED: flatbuffers::VOffsetT = 50; + pub const VT_IMAGE_GUIDANCE_SCALE: flatbuffers::VOffsetT = 52; + pub const VT_SEED_MODE: flatbuffers::VOffsetT = 54; + pub const VT_CLIP_SKIP: flatbuffers::VOffsetT = 56; + pub const VT_CONTROLS: flatbuffers::VOffsetT = 58; + pub const VT_SCRIBBLE_ID: flatbuffers::VOffsetT = 60; + pub const VT_POSE_ID: flatbuffers::VOffsetT = 62; + pub const VT_LORAS: flatbuffers::VOffsetT = 64; + pub const VT_COLOR_PALETTE_ID: flatbuffers::VOffsetT = 66; + pub const VT_MASK_BLUR: flatbuffers::VOffsetT = 68; + pub const VT_CUSTOM_ID: flatbuffers::VOffsetT = 70; + pub const VT_FACE_RESTORATION: flatbuffers::VOffsetT = 72; + pub const VT_CLIP_WEIGHT: flatbuffers::VOffsetT = 78; + pub const VT_NEGATIVE_PROMPT_FOR_IMAGE_PRIOR: flatbuffers::VOffsetT = 80; + pub const VT_IMAGE_PRIOR_STEPS: flatbuffers::VOffsetT = 82; + pub const VT_DATA_STORED: flatbuffers::VOffsetT = 84; + pub const VT_PREVIEW_ID: flatbuffers::VOffsetT = 86; + pub const VT_CONTENT_OFFSET_X: flatbuffers::VOffsetT = 88; + pub const VT_CONTENT_OFFSET_Y: flatbuffers::VOffsetT = 90; + pub const VT_SCALE_FACTOR_BY_120: flatbuffers::VOffsetT = 92; + pub const VT_REFINER_MODEL: flatbuffers::VOffsetT = 94; + pub const VT_ORIGINAL_IMAGE_HEIGHT: flatbuffers::VOffsetT = 96; + pub const VT_ORIGINAL_IMAGE_WIDTH: flatbuffers::VOffsetT = 98; + pub const VT_CROP_TOP: flatbuffers::VOffsetT = 100; + pub const VT_CROP_LEFT: flatbuffers::VOffsetT = 102; + pub const VT_TARGET_IMAGE_HEIGHT: flatbuffers::VOffsetT = 104; + pub const VT_TARGET_IMAGE_WIDTH: flatbuffers::VOffsetT = 106; + pub const VT_AESTHETIC_SCORE: flatbuffers::VOffsetT = 108; + pub const VT_NEGATIVE_AESTHETIC_SCORE: flatbuffers::VOffsetT = 110; + pub const VT_ZERO_NEGATIVE_PROMPT: flatbuffers::VOffsetT = 112; + pub const VT_REFINER_START: flatbuffers::VOffsetT = 114; + pub const VT_NEGATIVE_ORIGINAL_IMAGE_HEIGHT: flatbuffers::VOffsetT = 116; + pub const VT_NEGATIVE_ORIGINAL_IMAGE_WIDTH: flatbuffers::VOffsetT = 118; + pub const VT_SHUFFLE_DATA_STORED: flatbuffers::VOffsetT = 120; + pub const VT_FPS_ID: flatbuffers::VOffsetT = 122; + pub const VT_MOTION_BUCKET_ID: flatbuffers::VOffsetT = 124; + pub const VT_COND_AUG: flatbuffers::VOffsetT = 126; + pub const VT_START_FRAME_CFG: flatbuffers::VOffsetT = 128; + pub const VT_NUM_FRAMES: flatbuffers::VOffsetT = 130; + pub const VT_MASK_BLUR_OUTSET: flatbuffers::VOffsetT = 132; + pub const VT_SHARPNESS: flatbuffers::VOffsetT = 134; + pub const VT_SHIFT: flatbuffers::VOffsetT = 136; + pub const VT_STAGE_2_STEPS: flatbuffers::VOffsetT = 138; + pub const VT_STAGE_2_CFG: flatbuffers::VOffsetT = 140; + pub const VT_STAGE_2_SHIFT: flatbuffers::VOffsetT = 142; + pub const VT_TILED_DECODING: flatbuffers::VOffsetT = 144; + pub const VT_DECODING_TILE_WIDTH: flatbuffers::VOffsetT = 146; + pub const VT_DECODING_TILE_HEIGHT: flatbuffers::VOffsetT = 148; + pub const VT_DECODING_TILE_OVERLAP: flatbuffers::VOffsetT = 150; + pub const VT_STOCHASTIC_SAMPLING_GAMMA: flatbuffers::VOffsetT = 152; + pub const VT_PRESERVE_ORIGINAL_AFTER_INPAINT: flatbuffers::VOffsetT = 154; + pub const VT_TILED_DIFFUSION: flatbuffers::VOffsetT = 156; + pub const VT_DIFFUSION_TILE_WIDTH: flatbuffers::VOffsetT = 158; + pub const VT_DIFFUSION_TILE_HEIGHT: flatbuffers::VOffsetT = 160; + pub const VT_DIFFUSION_TILE_OVERLAP: flatbuffers::VOffsetT = 162; + pub const VT_UPSCALER_SCALE_FACTOR: flatbuffers::VOffsetT = 164; + pub const VT_SCRIPT_SESSION_ID: flatbuffers::VOffsetT = 166; + pub const VT_T5_TEXT_ENCODER: flatbuffers::VOffsetT = 168; + pub const VT_SEPARATE_CLIP_L: flatbuffers::VOffsetT = 170; + pub const VT_CLIP_L_TEXT: flatbuffers::VOffsetT = 172; + pub const VT_SEPARATE_OPEN_CLIP_G: flatbuffers::VOffsetT = 174; + pub const VT_OPEN_CLIP_G_TEXT: flatbuffers::VOffsetT = 176; + pub const VT_SPEED_UP_WITH_GUIDANCE_EMBED: flatbuffers::VOffsetT = 178; + pub const VT_GUIDANCE_EMBED: flatbuffers::VOffsetT = 180; + pub const VT_RESOLUTION_DEPENDENT_SHIFT: flatbuffers::VOffsetT = 182; + pub const VT_PROFILE_DATA: flatbuffers::VOffsetT = 184; + pub const VT_TEA_CACHE_START: flatbuffers::VOffsetT = 186; + pub const VT_TEA_CACHE_END: flatbuffers::VOffsetT = 188; + pub const VT_TEA_CACHE_THRESHOLD: flatbuffers::VOffsetT = 190; + pub const VT_TEA_CACHE: flatbuffers::VOffsetT = 192; + pub const VT_SEPARATE_T5: flatbuffers::VOffsetT = 194; + pub const VT_T5_TEXT: flatbuffers::VOffsetT = 196; + pub const VT_TEA_CACHE_MAX_SKIP_STEPS: flatbuffers::VOffsetT = 198; + pub const VT_TEXT_PROMPT: flatbuffers::VOffsetT = 200; + pub const VT_NEGATIVE_TEXT_PROMPT: flatbuffers::VOffsetT = 202; + pub const VT_CLIP_ID: flatbuffers::VOffsetT = 204; + pub const VT_INDEX_IN_A_CLIP: flatbuffers::VOffsetT = 206; + pub const VT_CAUSAL_INFERENCE_ENABLED: flatbuffers::VOffsetT = 208; + pub const VT_CAUSAL_INFERENCE: flatbuffers::VOffsetT = 210; + pub const VT_CAUSAL_INFERENCE_PAD: flatbuffers::VOffsetT = 212; + pub const VT_CFG_ZERO_STAR: flatbuffers::VOffsetT = 214; + pub const VT_CFG_ZERO_INIT_STEPS: flatbuffers::VOffsetT = 216; + pub const VT_GENERATION_TIME: flatbuffers::VOffsetT = 218; + pub const VT_REASON: flatbuffers::VOffsetT = 220; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + TensorHistoryNode { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + args: &'args TensorHistoryNodeArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = TensorHistoryNodeBuilder::new(_fbb); + builder.add_generation_time(args.generation_time); + builder.add_clip_id(args.clip_id); + builder.add_script_session_id(args.script_session_id); + builder.add_preview_id(args.preview_id); + builder.add_custom_id(args.custom_id); + builder.add_color_palette_id(args.color_palette_id); + builder.add_pose_id(args.pose_id); + builder.add_scribble_id(args.scribble_id); + builder.add_depth_map_id(args.depth_map_id); + builder.add_text_lineage(args.text_lineage); + builder.add_text_edits(args.text_edits); + builder.add_wall_clock(args.wall_clock); + builder.add_mask_id(args.mask_id); + builder.add_tensor_id(args.tensor_id); + builder.add_logical_time(args.logical_time); + builder.add_lineage(args.lineage); + builder.add_reason(args.reason); + builder.add_cfg_zero_init_steps(args.cfg_zero_init_steps); + builder.add_causal_inference_pad(args.causal_inference_pad); + builder.add_causal_inference(args.causal_inference); + builder.add_index_in_a_clip(args.index_in_a_clip); + if let Some(x) = args.negative_text_prompt { builder.add_negative_text_prompt(x); } + if let Some(x) = args.text_prompt { builder.add_text_prompt(x); } + builder.add_tea_cache_max_skip_steps(args.tea_cache_max_skip_steps); + if let Some(x) = args.t5_text { builder.add_t5_text(x); } + builder.add_tea_cache_threshold(args.tea_cache_threshold); + builder.add_tea_cache_end(args.tea_cache_end); + builder.add_tea_cache_start(args.tea_cache_start); + if let Some(x) = args.profile_data { builder.add_profile_data(x); } + builder.add_guidance_embed(args.guidance_embed); + if let Some(x) = args.open_clip_g_text { builder.add_open_clip_g_text(x); } + if let Some(x) = args.clip_l_text { builder.add_clip_l_text(x); } + builder.add_stochastic_sampling_gamma(args.stochastic_sampling_gamma); + builder.add_stage_2_shift(args.stage_2_shift); + builder.add_stage_2_cfg(args.stage_2_cfg); + builder.add_stage_2_steps(args.stage_2_steps); + builder.add_shift(args.shift); + builder.add_sharpness(args.sharpness); + builder.add_mask_blur_outset(args.mask_blur_outset); + builder.add_num_frames(args.num_frames); + builder.add_start_frame_cfg(args.start_frame_cfg); + builder.add_cond_aug(args.cond_aug); + builder.add_motion_bucket_id(args.motion_bucket_id); + builder.add_fps_id(args.fps_id); + builder.add_shuffle_data_stored(args.shuffle_data_stored); + builder.add_negative_original_image_width(args.negative_original_image_width); + builder.add_negative_original_image_height(args.negative_original_image_height); + builder.add_refiner_start(args.refiner_start); + builder.add_negative_aesthetic_score(args.negative_aesthetic_score); + builder.add_aesthetic_score(args.aesthetic_score); + builder.add_target_image_width(args.target_image_width); + builder.add_target_image_height(args.target_image_height); + builder.add_crop_left(args.crop_left); + builder.add_crop_top(args.crop_top); + builder.add_original_image_width(args.original_image_width); + builder.add_original_image_height(args.original_image_height); + if let Some(x) = args.refiner_model { builder.add_refiner_model(x); } + builder.add_scale_factor_by_120(args.scale_factor_by_120); + builder.add_content_offset_y(args.content_offset_y); + builder.add_content_offset_x(args.content_offset_x); + builder.add_data_stored(args.data_stored); + builder.add_image_prior_steps(args.image_prior_steps); + builder.add_clip_weight(args.clip_weight); + if let Some(x) = args.face_restoration { builder.add_face_restoration(x); } + builder.add_mask_blur(args.mask_blur); + if let Some(x) = args.loras { builder.add_loras(x); } + if let Some(x) = args.controls { builder.add_controls(x); } + builder.add_clip_skip(args.clip_skip); + builder.add_image_guidance_scale(args.image_guidance_scale); + if let Some(x) = args.upscaler { builder.add_upscaler(x); } + builder.add_hires_fix_strength(args.hires_fix_strength); + builder.add_batch_size(args.batch_size); + if let Some(x) = args.model { builder.add_model(x); } + builder.add_strength(args.strength); + builder.add_guidance_scale(args.guidance_scale); + builder.add_steps(args.steps); + builder.add_seed(args.seed); + builder.add_diffusion_tile_overlap(args.diffusion_tile_overlap); + builder.add_diffusion_tile_height(args.diffusion_tile_height); + builder.add_diffusion_tile_width(args.diffusion_tile_width); + builder.add_decoding_tile_overlap(args.decoding_tile_overlap); + builder.add_decoding_tile_height(args.decoding_tile_height); + builder.add_decoding_tile_width(args.decoding_tile_width); + builder.add_scale_factor(args.scale_factor); + builder.add_hires_fix_start_height(args.hires_fix_start_height); + builder.add_hires_fix_start_width(args.hires_fix_start_width); + builder.add_start_height(args.start_height); + builder.add_start_width(args.start_width); + builder.add_cfg_zero_star(args.cfg_zero_star); + builder.add_causal_inference_enabled(args.causal_inference_enabled); + builder.add_separate_t5(args.separate_t5); + builder.add_tea_cache(args.tea_cache); + builder.add_resolution_dependent_shift(args.resolution_dependent_shift); + builder.add_speed_up_with_guidance_embed(args.speed_up_with_guidance_embed); + builder.add_separate_open_clip_g(args.separate_open_clip_g); + builder.add_separate_clip_l(args.separate_clip_l); + builder.add_t5_text_encoder(args.t5_text_encoder); + builder.add_upscaler_scale_factor(args.upscaler_scale_factor); + builder.add_tiled_diffusion(args.tiled_diffusion); + builder.add_preserve_original_after_inpaint(args.preserve_original_after_inpaint); + builder.add_tiled_decoding(args.tiled_decoding); + builder.add_zero_negative_prompt(args.zero_negative_prompt); + builder.add_negative_prompt_for_image_prior(args.negative_prompt_for_image_prior); + builder.add_seed_mode(args.seed_mode); + builder.add_generated(args.generated); + builder.add_hires_fix(args.hires_fix); + builder.add_sampler(args.sampler); + builder.finish() + } + + + #[inline] + pub fn lineage(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_LINEAGE, Some(0)).unwrap()} + } + #[inline] + pub fn logical_time(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_LOGICAL_TIME, Some(0)).unwrap()} + } + #[inline] + pub fn start_width(&self) -> u16 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_START_WIDTH, Some(0)).unwrap()} + } + #[inline] + pub fn start_height(&self) -> u16 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_START_HEIGHT, Some(0)).unwrap()} + } + #[inline] + pub fn seed(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_SEED, Some(0)).unwrap()} + } + #[inline] + pub fn steps(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_STEPS, Some(0)).unwrap()} + } + #[inline] + pub fn guidance_scale(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_GUIDANCE_SCALE, Some(0.0)).unwrap()} + } + #[inline] + pub fn strength(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_STRENGTH, Some(0.0)).unwrap()} + } + #[inline] + pub fn model(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(TensorHistoryNode::VT_MODEL, None)} + } + #[inline] + pub fn tensor_id(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_TENSOR_ID, Some(0)).unwrap()} + } + #[inline] + pub fn mask_id(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_MASK_ID, Some(0)).unwrap()} + } + #[inline] + pub fn wall_clock(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_WALL_CLOCK, Some(0)).unwrap()} + } + #[inline] + pub fn text_edits(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_TEXT_EDITS, Some(-1)).unwrap()} + } + #[inline] + pub fn text_lineage(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_TEXT_LINEAGE, Some(-1)).unwrap()} + } + #[inline] + pub fn batch_size(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_BATCH_SIZE, Some(1)).unwrap()} + } + #[inline] + pub fn sampler(&self) -> SamplerType { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_SAMPLER, Some(SamplerType::DPMPP2MKarras)).unwrap()} + } + #[inline] + pub fn hires_fix(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_HIRES_FIX, Some(false)).unwrap()} + } + #[inline] + pub fn hires_fix_start_width(&self) -> u16 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_HIRES_FIX_START_WIDTH, Some(0)).unwrap()} + } + #[inline] + pub fn hires_fix_start_height(&self) -> u16 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_HIRES_FIX_START_HEIGHT, Some(0)).unwrap()} + } + #[inline] + pub fn hires_fix_strength(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_HIRES_FIX_STRENGTH, Some(0.7)).unwrap()} + } + #[inline] + pub fn upscaler(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(TensorHistoryNode::VT_UPSCALER, None)} + } + #[inline] + pub fn scale_factor(&self) -> u16 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_SCALE_FACTOR, Some(1)).unwrap()} + } + #[inline] + pub fn depth_map_id(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_DEPTH_MAP_ID, Some(0)).unwrap()} + } + #[inline] + pub fn generated(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_GENERATED, Some(true)).unwrap()} + } + #[inline] + pub fn image_guidance_scale(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_IMAGE_GUIDANCE_SCALE, Some(1.5)).unwrap()} + } + #[inline] + pub fn seed_mode(&self) -> SeedMode { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_SEED_MODE, Some(SeedMode::Legacy)).unwrap()} + } + #[inline] + pub fn clip_skip(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_CLIP_SKIP, Some(1)).unwrap()} + } + #[inline] + pub fn controls(&self) -> Option>>> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>>(TensorHistoryNode::VT_CONTROLS, None)} + } + #[inline] + pub fn scribble_id(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_SCRIBBLE_ID, Some(0)).unwrap()} + } + #[inline] + pub fn pose_id(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_POSE_ID, Some(0)).unwrap()} + } + #[inline] + pub fn loras(&self) -> Option>>> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>>(TensorHistoryNode::VT_LORAS, None)} + } + #[inline] + pub fn color_palette_id(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_COLOR_PALETTE_ID, Some(0)).unwrap()} + } + #[inline] + pub fn mask_blur(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_MASK_BLUR, Some(0.0)).unwrap()} + } + #[inline] + pub fn custom_id(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_CUSTOM_ID, Some(0)).unwrap()} + } + #[inline] + pub fn face_restoration(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(TensorHistoryNode::VT_FACE_RESTORATION, None)} + } + #[inline] + pub fn clip_weight(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_CLIP_WEIGHT, Some(1.0)).unwrap()} + } + #[inline] + pub fn negative_prompt_for_image_prior(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_NEGATIVE_PROMPT_FOR_IMAGE_PRIOR, Some(true)).unwrap()} + } + #[inline] + pub fn image_prior_steps(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_IMAGE_PRIOR_STEPS, Some(5)).unwrap()} + } + #[inline] + pub fn data_stored(&self) -> i32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_DATA_STORED, Some(0)).unwrap()} + } + #[inline] + pub fn preview_id(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_PREVIEW_ID, Some(0)).unwrap()} + } + #[inline] + pub fn content_offset_x(&self) -> i32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_CONTENT_OFFSET_X, Some(0)).unwrap()} + } + #[inline] + pub fn content_offset_y(&self) -> i32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_CONTENT_OFFSET_Y, Some(0)).unwrap()} + } + #[inline] + pub fn scale_factor_by_120(&self) -> i32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_SCALE_FACTOR_BY_120, Some(120)).unwrap()} + } + #[inline] + pub fn refiner_model(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(TensorHistoryNode::VT_REFINER_MODEL, None)} + } + #[inline] + pub fn original_image_height(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_ORIGINAL_IMAGE_HEIGHT, Some(0)).unwrap()} + } + #[inline] + pub fn original_image_width(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_ORIGINAL_IMAGE_WIDTH, Some(0)).unwrap()} + } + #[inline] + pub fn crop_top(&self) -> i32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_CROP_TOP, Some(0)).unwrap()} + } + #[inline] + pub fn crop_left(&self) -> i32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_CROP_LEFT, Some(0)).unwrap()} + } + #[inline] + pub fn target_image_height(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_TARGET_IMAGE_HEIGHT, Some(0)).unwrap()} + } + #[inline] + pub fn target_image_width(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_TARGET_IMAGE_WIDTH, Some(0)).unwrap()} + } + #[inline] + pub fn aesthetic_score(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_AESTHETIC_SCORE, Some(0.0)).unwrap()} + } + #[inline] + pub fn negative_aesthetic_score(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_NEGATIVE_AESTHETIC_SCORE, Some(0.0)).unwrap()} + } + #[inline] + pub fn zero_negative_prompt(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_ZERO_NEGATIVE_PROMPT, Some(false)).unwrap()} + } + #[inline] + pub fn refiner_start(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_REFINER_START, Some(0.0)).unwrap()} + } + #[inline] + pub fn negative_original_image_height(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_NEGATIVE_ORIGINAL_IMAGE_HEIGHT, Some(0)).unwrap()} + } + #[inline] + pub fn negative_original_image_width(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_NEGATIVE_ORIGINAL_IMAGE_WIDTH, Some(0)).unwrap()} + } + #[inline] + pub fn shuffle_data_stored(&self) -> i32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_SHUFFLE_DATA_STORED, Some(0)).unwrap()} + } + #[inline] + pub fn fps_id(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_FPS_ID, Some(5)).unwrap()} + } + #[inline] + pub fn motion_bucket_id(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_MOTION_BUCKET_ID, Some(127)).unwrap()} + } + #[inline] + pub fn cond_aug(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_COND_AUG, Some(0.02)).unwrap()} + } + #[inline] + pub fn start_frame_cfg(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_START_FRAME_CFG, Some(1.0)).unwrap()} + } + #[inline] + pub fn num_frames(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_NUM_FRAMES, Some(14)).unwrap()} + } + #[inline] + pub fn mask_blur_outset(&self) -> i32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_MASK_BLUR_OUTSET, Some(0)).unwrap()} + } + #[inline] + pub fn sharpness(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_SHARPNESS, Some(0.0)).unwrap()} + } + #[inline] + pub fn shift(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_SHIFT, Some(1.0)).unwrap()} + } + #[inline] + pub fn stage_2_steps(&self) -> u32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_STAGE_2_STEPS, Some(10)).unwrap()} + } + #[inline] + pub fn stage_2_cfg(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_STAGE_2_CFG, Some(1.0)).unwrap()} + } + #[inline] + pub fn stage_2_shift(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_STAGE_2_SHIFT, Some(1.0)).unwrap()} + } + #[inline] + pub fn tiled_decoding(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_TILED_DECODING, Some(false)).unwrap()} + } + #[inline] + pub fn decoding_tile_width(&self) -> u16 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_DECODING_TILE_WIDTH, Some(10)).unwrap()} + } + #[inline] + pub fn decoding_tile_height(&self) -> u16 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_DECODING_TILE_HEIGHT, Some(10)).unwrap()} + } + #[inline] + pub fn decoding_tile_overlap(&self) -> u16 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_DECODING_TILE_OVERLAP, Some(2)).unwrap()} + } + #[inline] + pub fn stochastic_sampling_gamma(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_STOCHASTIC_SAMPLING_GAMMA, Some(0.3)).unwrap()} + } + #[inline] + pub fn preserve_original_after_inpaint(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_PRESERVE_ORIGINAL_AFTER_INPAINT, Some(true)).unwrap()} + } + #[inline] + pub fn tiled_diffusion(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_TILED_DIFFUSION, Some(false)).unwrap()} + } + #[inline] + pub fn diffusion_tile_width(&self) -> u16 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_DIFFUSION_TILE_WIDTH, Some(16)).unwrap()} + } + #[inline] + pub fn diffusion_tile_height(&self) -> u16 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_DIFFUSION_TILE_HEIGHT, Some(16)).unwrap()} + } + #[inline] + pub fn diffusion_tile_overlap(&self) -> u16 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_DIFFUSION_TILE_OVERLAP, Some(2)).unwrap()} + } + #[inline] + pub fn upscaler_scale_factor(&self) -> u8 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_UPSCALER_SCALE_FACTOR, Some(0)).unwrap()} + } + #[inline] + pub fn script_session_id(&self) -> u64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_SCRIPT_SESSION_ID, Some(0)).unwrap()} + } + #[inline] + pub fn t5_text_encoder(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_T5_TEXT_ENCODER, Some(true)).unwrap()} + } + #[inline] + pub fn separate_clip_l(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_SEPARATE_CLIP_L, Some(false)).unwrap()} + } + #[inline] + pub fn clip_l_text(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(TensorHistoryNode::VT_CLIP_L_TEXT, None)} + } + #[inline] + pub fn separate_open_clip_g(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_SEPARATE_OPEN_CLIP_G, Some(false)).unwrap()} + } + #[inline] + pub fn open_clip_g_text(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(TensorHistoryNode::VT_OPEN_CLIP_G_TEXT, None)} + } + #[inline] + pub fn speed_up_with_guidance_embed(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_SPEED_UP_WITH_GUIDANCE_EMBED, Some(true)).unwrap()} + } + #[inline] + pub fn guidance_embed(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_GUIDANCE_EMBED, Some(3.5)).unwrap()} + } + #[inline] + pub fn resolution_dependent_shift(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_RESOLUTION_DEPENDENT_SHIFT, Some(true)).unwrap()} + } + #[inline] + pub fn profile_data(&self) -> Option> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(TensorHistoryNode::VT_PROFILE_DATA, None)} + } + #[inline] + pub fn tea_cache_start(&self) -> i32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_TEA_CACHE_START, Some(5)).unwrap()} + } + #[inline] + pub fn tea_cache_end(&self) -> i32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_TEA_CACHE_END, Some(-1)).unwrap()} + } + #[inline] + pub fn tea_cache_threshold(&self) -> f32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_TEA_CACHE_THRESHOLD, Some(0.06)).unwrap()} + } + #[inline] + pub fn tea_cache(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_TEA_CACHE, Some(false)).unwrap()} + } + #[inline] + pub fn separate_t5(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_SEPARATE_T5, Some(false)).unwrap()} + } + #[inline] + pub fn t5_text(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(TensorHistoryNode::VT_T5_TEXT, None)} + } + #[inline] + pub fn tea_cache_max_skip_steps(&self) -> i32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_TEA_CACHE_MAX_SKIP_STEPS, Some(3)).unwrap()} + } + #[inline] + pub fn text_prompt(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(TensorHistoryNode::VT_TEXT_PROMPT, None)} + } + #[inline] + pub fn negative_text_prompt(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(TensorHistoryNode::VT_NEGATIVE_TEXT_PROMPT, None)} + } + #[inline] + pub fn clip_id(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_CLIP_ID, Some(-1)).unwrap()} + } + #[inline] + pub fn index_in_a_clip(&self) -> i32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_INDEX_IN_A_CLIP, Some(0)).unwrap()} + } + #[inline] + pub fn causal_inference_enabled(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_CAUSAL_INFERENCE_ENABLED, Some(false)).unwrap()} + } + #[inline] + pub fn causal_inference(&self) -> i32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_CAUSAL_INFERENCE, Some(3)).unwrap()} + } + #[inline] + pub fn causal_inference_pad(&self) -> i32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_CAUSAL_INFERENCE_PAD, Some(0)).unwrap()} + } + #[inline] + pub fn cfg_zero_star(&self) -> bool { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_CFG_ZERO_STAR, Some(false)).unwrap()} + } + #[inline] + pub fn cfg_zero_init_steps(&self) -> i32 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_CFG_ZERO_INIT_STEPS, Some(0)).unwrap()} + } + #[inline] + pub fn generation_time(&self) -> f64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_GENERATION_TIME, Some(0.0)).unwrap()} + } + #[inline] + pub fn reason(&self) -> Reason { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TensorHistoryNode::VT_REASON, Some(Reason::Other)).unwrap()} + } +} + +impl flatbuffers::Verifiable for TensorHistoryNode<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::("lineage", Self::VT_LINEAGE, false)? + .visit_field::("logical_time", Self::VT_LOGICAL_TIME, false)? + .visit_field::("start_width", Self::VT_START_WIDTH, false)? + .visit_field::("start_height", Self::VT_START_HEIGHT, false)? + .visit_field::("seed", Self::VT_SEED, false)? + .visit_field::("steps", Self::VT_STEPS, false)? + .visit_field::("guidance_scale", Self::VT_GUIDANCE_SCALE, false)? + .visit_field::("strength", Self::VT_STRENGTH, false)? + .visit_field::>("model", Self::VT_MODEL, false)? + .visit_field::("tensor_id", Self::VT_TENSOR_ID, false)? + .visit_field::("mask_id", Self::VT_MASK_ID, false)? + .visit_field::("wall_clock", Self::VT_WALL_CLOCK, false)? + .visit_field::("text_edits", Self::VT_TEXT_EDITS, false)? + .visit_field::("text_lineage", Self::VT_TEXT_LINEAGE, false)? + .visit_field::("batch_size", Self::VT_BATCH_SIZE, false)? + .visit_field::("sampler", Self::VT_SAMPLER, false)? + .visit_field::("hires_fix", Self::VT_HIRES_FIX, false)? + .visit_field::("hires_fix_start_width", Self::VT_HIRES_FIX_START_WIDTH, false)? + .visit_field::("hires_fix_start_height", Self::VT_HIRES_FIX_START_HEIGHT, false)? + .visit_field::("hires_fix_strength", Self::VT_HIRES_FIX_STRENGTH, false)? + .visit_field::>("upscaler", Self::VT_UPSCALER, false)? + .visit_field::("scale_factor", Self::VT_SCALE_FACTOR, false)? + .visit_field::("depth_map_id", Self::VT_DEPTH_MAP_ID, false)? + .visit_field::("generated", Self::VT_GENERATED, false)? + .visit_field::("image_guidance_scale", Self::VT_IMAGE_GUIDANCE_SCALE, false)? + .visit_field::("seed_mode", Self::VT_SEED_MODE, false)? + .visit_field::("clip_skip", Self::VT_CLIP_SKIP, false)? + .visit_field::>>>("controls", Self::VT_CONTROLS, false)? + .visit_field::("scribble_id", Self::VT_SCRIBBLE_ID, false)? + .visit_field::("pose_id", Self::VT_POSE_ID, false)? + .visit_field::>>>("loras", Self::VT_LORAS, false)? + .visit_field::("color_palette_id", Self::VT_COLOR_PALETTE_ID, false)? + .visit_field::("mask_blur", Self::VT_MASK_BLUR, false)? + .visit_field::("custom_id", Self::VT_CUSTOM_ID, false)? + .visit_field::>("face_restoration", Self::VT_FACE_RESTORATION, false)? + .visit_field::("clip_weight", Self::VT_CLIP_WEIGHT, false)? + .visit_field::("negative_prompt_for_image_prior", Self::VT_NEGATIVE_PROMPT_FOR_IMAGE_PRIOR, false)? + .visit_field::("image_prior_steps", Self::VT_IMAGE_PRIOR_STEPS, false)? + .visit_field::("data_stored", Self::VT_DATA_STORED, false)? + .visit_field::("preview_id", Self::VT_PREVIEW_ID, false)? + .visit_field::("content_offset_x", Self::VT_CONTENT_OFFSET_X, false)? + .visit_field::("content_offset_y", Self::VT_CONTENT_OFFSET_Y, false)? + .visit_field::("scale_factor_by_120", Self::VT_SCALE_FACTOR_BY_120, false)? + .visit_field::>("refiner_model", Self::VT_REFINER_MODEL, false)? + .visit_field::("original_image_height", Self::VT_ORIGINAL_IMAGE_HEIGHT, false)? + .visit_field::("original_image_width", Self::VT_ORIGINAL_IMAGE_WIDTH, false)? + .visit_field::("crop_top", Self::VT_CROP_TOP, false)? + .visit_field::("crop_left", Self::VT_CROP_LEFT, false)? + .visit_field::("target_image_height", Self::VT_TARGET_IMAGE_HEIGHT, false)? + .visit_field::("target_image_width", Self::VT_TARGET_IMAGE_WIDTH, false)? + .visit_field::("aesthetic_score", Self::VT_AESTHETIC_SCORE, false)? + .visit_field::("negative_aesthetic_score", Self::VT_NEGATIVE_AESTHETIC_SCORE, false)? + .visit_field::("zero_negative_prompt", Self::VT_ZERO_NEGATIVE_PROMPT, false)? + .visit_field::("refiner_start", Self::VT_REFINER_START, false)? + .visit_field::("negative_original_image_height", Self::VT_NEGATIVE_ORIGINAL_IMAGE_HEIGHT, false)? + .visit_field::("negative_original_image_width", Self::VT_NEGATIVE_ORIGINAL_IMAGE_WIDTH, false)? + .visit_field::("shuffle_data_stored", Self::VT_SHUFFLE_DATA_STORED, false)? + .visit_field::("fps_id", Self::VT_FPS_ID, false)? + .visit_field::("motion_bucket_id", Self::VT_MOTION_BUCKET_ID, false)? + .visit_field::("cond_aug", Self::VT_COND_AUG, false)? + .visit_field::("start_frame_cfg", Self::VT_START_FRAME_CFG, false)? + .visit_field::("num_frames", Self::VT_NUM_FRAMES, false)? + .visit_field::("mask_blur_outset", Self::VT_MASK_BLUR_OUTSET, false)? + .visit_field::("sharpness", Self::VT_SHARPNESS, false)? + .visit_field::("shift", Self::VT_SHIFT, false)? + .visit_field::("stage_2_steps", Self::VT_STAGE_2_STEPS, false)? + .visit_field::("stage_2_cfg", Self::VT_STAGE_2_CFG, false)? + .visit_field::("stage_2_shift", Self::VT_STAGE_2_SHIFT, false)? + .visit_field::("tiled_decoding", Self::VT_TILED_DECODING, false)? + .visit_field::("decoding_tile_width", Self::VT_DECODING_TILE_WIDTH, false)? + .visit_field::("decoding_tile_height", Self::VT_DECODING_TILE_HEIGHT, false)? + .visit_field::("decoding_tile_overlap", Self::VT_DECODING_TILE_OVERLAP, false)? + .visit_field::("stochastic_sampling_gamma", Self::VT_STOCHASTIC_SAMPLING_GAMMA, false)? + .visit_field::("preserve_original_after_inpaint", Self::VT_PRESERVE_ORIGINAL_AFTER_INPAINT, false)? + .visit_field::("tiled_diffusion", Self::VT_TILED_DIFFUSION, false)? + .visit_field::("diffusion_tile_width", Self::VT_DIFFUSION_TILE_WIDTH, false)? + .visit_field::("diffusion_tile_height", Self::VT_DIFFUSION_TILE_HEIGHT, false)? + .visit_field::("diffusion_tile_overlap", Self::VT_DIFFUSION_TILE_OVERLAP, false)? + .visit_field::("upscaler_scale_factor", Self::VT_UPSCALER_SCALE_FACTOR, false)? + .visit_field::("script_session_id", Self::VT_SCRIPT_SESSION_ID, false)? + .visit_field::("t5_text_encoder", Self::VT_T5_TEXT_ENCODER, false)? + .visit_field::("separate_clip_l", Self::VT_SEPARATE_CLIP_L, false)? + .visit_field::>("clip_l_text", Self::VT_CLIP_L_TEXT, false)? + .visit_field::("separate_open_clip_g", Self::VT_SEPARATE_OPEN_CLIP_G, false)? + .visit_field::>("open_clip_g_text", Self::VT_OPEN_CLIP_G_TEXT, false)? + .visit_field::("speed_up_with_guidance_embed", Self::VT_SPEED_UP_WITH_GUIDANCE_EMBED, false)? + .visit_field::("guidance_embed", Self::VT_GUIDANCE_EMBED, false)? + .visit_field::("resolution_dependent_shift", Self::VT_RESOLUTION_DEPENDENT_SHIFT, false)? + .visit_field::>>("profile_data", Self::VT_PROFILE_DATA, false)? + .visit_field::("tea_cache_start", Self::VT_TEA_CACHE_START, false)? + .visit_field::("tea_cache_end", Self::VT_TEA_CACHE_END, false)? + .visit_field::("tea_cache_threshold", Self::VT_TEA_CACHE_THRESHOLD, false)? + .visit_field::("tea_cache", Self::VT_TEA_CACHE, false)? + .visit_field::("separate_t5", Self::VT_SEPARATE_T5, false)? + .visit_field::>("t5_text", Self::VT_T5_TEXT, false)? + .visit_field::("tea_cache_max_skip_steps", Self::VT_TEA_CACHE_MAX_SKIP_STEPS, false)? + .visit_field::>("text_prompt", Self::VT_TEXT_PROMPT, false)? + .visit_field::>("negative_text_prompt", Self::VT_NEGATIVE_TEXT_PROMPT, false)? + .visit_field::("clip_id", Self::VT_CLIP_ID, false)? + .visit_field::("index_in_a_clip", Self::VT_INDEX_IN_A_CLIP, false)? + .visit_field::("causal_inference_enabled", Self::VT_CAUSAL_INFERENCE_ENABLED, false)? + .visit_field::("causal_inference", Self::VT_CAUSAL_INFERENCE, false)? + .visit_field::("causal_inference_pad", Self::VT_CAUSAL_INFERENCE_PAD, false)? + .visit_field::("cfg_zero_star", Self::VT_CFG_ZERO_STAR, false)? + .visit_field::("cfg_zero_init_steps", Self::VT_CFG_ZERO_INIT_STEPS, false)? + .visit_field::("generation_time", Self::VT_GENERATION_TIME, false)? + .visit_field::("reason", Self::VT_REASON, false)? + .finish(); + Ok(()) + } +} +pub struct TensorHistoryNodeArgs<'a> { + pub lineage: i64, + pub logical_time: i64, + pub start_width: u16, + pub start_height: u16, + pub seed: u32, + pub steps: u32, + pub guidance_scale: f32, + pub strength: f32, + pub model: Option>, + pub tensor_id: i64, + pub mask_id: i64, + pub wall_clock: i64, + pub text_edits: i64, + pub text_lineage: i64, + pub batch_size: u32, + pub sampler: SamplerType, + pub hires_fix: bool, + pub hires_fix_start_width: u16, + pub hires_fix_start_height: u16, + pub hires_fix_strength: f32, + pub upscaler: Option>, + pub scale_factor: u16, + pub depth_map_id: i64, + pub generated: bool, + pub image_guidance_scale: f32, + pub seed_mode: SeedMode, + pub clip_skip: u32, + pub controls: Option>>>>, + pub scribble_id: i64, + pub pose_id: i64, + pub loras: Option>>>>, + pub color_palette_id: i64, + pub mask_blur: f32, + pub custom_id: i64, + pub face_restoration: Option>, + pub clip_weight: f32, + pub negative_prompt_for_image_prior: bool, + pub image_prior_steps: u32, + pub data_stored: i32, + pub preview_id: i64, + pub content_offset_x: i32, + pub content_offset_y: i32, + pub scale_factor_by_120: i32, + pub refiner_model: Option>, + pub original_image_height: u32, + pub original_image_width: u32, + pub crop_top: i32, + pub crop_left: i32, + pub target_image_height: u32, + pub target_image_width: u32, + pub aesthetic_score: f32, + pub negative_aesthetic_score: f32, + pub zero_negative_prompt: bool, + pub refiner_start: f32, + pub negative_original_image_height: u32, + pub negative_original_image_width: u32, + pub shuffle_data_stored: i32, + pub fps_id: u32, + pub motion_bucket_id: u32, + pub cond_aug: f32, + pub start_frame_cfg: f32, + pub num_frames: u32, + pub mask_blur_outset: i32, + pub sharpness: f32, + pub shift: f32, + pub stage_2_steps: u32, + pub stage_2_cfg: f32, + pub stage_2_shift: f32, + pub tiled_decoding: bool, + pub decoding_tile_width: u16, + pub decoding_tile_height: u16, + pub decoding_tile_overlap: u16, + pub stochastic_sampling_gamma: f32, + pub preserve_original_after_inpaint: bool, + pub tiled_diffusion: bool, + pub diffusion_tile_width: u16, + pub diffusion_tile_height: u16, + pub diffusion_tile_overlap: u16, + pub upscaler_scale_factor: u8, + pub script_session_id: u64, + pub t5_text_encoder: bool, + pub separate_clip_l: bool, + pub clip_l_text: Option>, + pub separate_open_clip_g: bool, + pub open_clip_g_text: Option>, + pub speed_up_with_guidance_embed: bool, + pub guidance_embed: f32, + pub resolution_dependent_shift: bool, + pub profile_data: Option>>, + pub tea_cache_start: i32, + pub tea_cache_end: i32, + pub tea_cache_threshold: f32, + pub tea_cache: bool, + pub separate_t5: bool, + pub t5_text: Option>, + pub tea_cache_max_skip_steps: i32, + pub text_prompt: Option>, + pub negative_text_prompt: Option>, + pub clip_id: i64, + pub index_in_a_clip: i32, + pub causal_inference_enabled: bool, + pub causal_inference: i32, + pub causal_inference_pad: i32, + pub cfg_zero_star: bool, + pub cfg_zero_init_steps: i32, + pub generation_time: f64, + pub reason: Reason, +} +impl<'a> Default for TensorHistoryNodeArgs<'a> { + #[inline] + fn default() -> Self { + TensorHistoryNodeArgs { + lineage: 0, + logical_time: 0, + start_width: 0, + start_height: 0, + seed: 0, + steps: 0, + guidance_scale: 0.0, + strength: 0.0, + model: None, + tensor_id: 0, + mask_id: 0, + wall_clock: 0, + text_edits: -1, + text_lineage: -1, + batch_size: 1, + sampler: SamplerType::DPMPP2MKarras, + hires_fix: false, + hires_fix_start_width: 0, + hires_fix_start_height: 0, + hires_fix_strength: 0.7, + upscaler: None, + scale_factor: 1, + depth_map_id: 0, + generated: true, + image_guidance_scale: 1.5, + seed_mode: SeedMode::Legacy, + clip_skip: 1, + controls: None, + scribble_id: 0, + pose_id: 0, + loras: None, + color_palette_id: 0, + mask_blur: 0.0, + custom_id: 0, + face_restoration: None, + clip_weight: 1.0, + negative_prompt_for_image_prior: true, + image_prior_steps: 5, + data_stored: 0, + preview_id: 0, + content_offset_x: 0, + content_offset_y: 0, + scale_factor_by_120: 120, + refiner_model: None, + original_image_height: 0, + original_image_width: 0, + crop_top: 0, + crop_left: 0, + target_image_height: 0, + target_image_width: 0, + aesthetic_score: 0.0, + negative_aesthetic_score: 0.0, + zero_negative_prompt: false, + refiner_start: 0.0, + negative_original_image_height: 0, + negative_original_image_width: 0, + shuffle_data_stored: 0, + fps_id: 5, + motion_bucket_id: 127, + cond_aug: 0.02, + start_frame_cfg: 1.0, + num_frames: 14, + mask_blur_outset: 0, + sharpness: 0.0, + shift: 1.0, + stage_2_steps: 10, + stage_2_cfg: 1.0, + stage_2_shift: 1.0, + tiled_decoding: false, + decoding_tile_width: 10, + decoding_tile_height: 10, + decoding_tile_overlap: 2, + stochastic_sampling_gamma: 0.3, + preserve_original_after_inpaint: true, + tiled_diffusion: false, + diffusion_tile_width: 16, + diffusion_tile_height: 16, + diffusion_tile_overlap: 2, + upscaler_scale_factor: 0, + script_session_id: 0, + t5_text_encoder: true, + separate_clip_l: false, + clip_l_text: None, + separate_open_clip_g: false, + open_clip_g_text: None, + speed_up_with_guidance_embed: true, + guidance_embed: 3.5, + resolution_dependent_shift: true, + profile_data: None, + tea_cache_start: 5, + tea_cache_end: -1, + tea_cache_threshold: 0.06, + tea_cache: false, + separate_t5: false, + t5_text: None, + tea_cache_max_skip_steps: 3, + text_prompt: None, + negative_text_prompt: None, + clip_id: -1, + index_in_a_clip: 0, + causal_inference_enabled: false, + causal_inference: 3, + causal_inference_pad: 0, + cfg_zero_star: false, + cfg_zero_init_steps: 0, + generation_time: 0.0, + reason: Reason::Other, + } + } +} + +pub struct TensorHistoryNodeBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> TensorHistoryNodeBuilder<'a, 'b, A> { + #[inline] + pub fn add_lineage(&mut self, lineage: i64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_LINEAGE, lineage, 0); + } + #[inline] + pub fn add_logical_time(&mut self, logical_time: i64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_LOGICAL_TIME, logical_time, 0); + } + #[inline] + pub fn add_start_width(&mut self, start_width: u16) { + self.fbb_.push_slot::(TensorHistoryNode::VT_START_WIDTH, start_width, 0); + } + #[inline] + pub fn add_start_height(&mut self, start_height: u16) { + self.fbb_.push_slot::(TensorHistoryNode::VT_START_HEIGHT, start_height, 0); + } + #[inline] + pub fn add_seed(&mut self, seed: u32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_SEED, seed, 0); + } + #[inline] + pub fn add_steps(&mut self, steps: u32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_STEPS, steps, 0); + } + #[inline] + pub fn add_guidance_scale(&mut self, guidance_scale: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_GUIDANCE_SCALE, guidance_scale, 0.0); + } + #[inline] + pub fn add_strength(&mut self, strength: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_STRENGTH, strength, 0.0); + } + #[inline] + pub fn add_model(&mut self, model: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(TensorHistoryNode::VT_MODEL, model); + } + #[inline] + pub fn add_tensor_id(&mut self, tensor_id: i64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_TENSOR_ID, tensor_id, 0); + } + #[inline] + pub fn add_mask_id(&mut self, mask_id: i64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_MASK_ID, mask_id, 0); + } + #[inline] + pub fn add_wall_clock(&mut self, wall_clock: i64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_WALL_CLOCK, wall_clock, 0); + } + #[inline] + pub fn add_text_edits(&mut self, text_edits: i64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_TEXT_EDITS, text_edits, -1); + } + #[inline] + pub fn add_text_lineage(&mut self, text_lineage: i64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_TEXT_LINEAGE, text_lineage, -1); + } + #[inline] + pub fn add_batch_size(&mut self, batch_size: u32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_BATCH_SIZE, batch_size, 1); + } + #[inline] + pub fn add_sampler(&mut self, sampler: SamplerType) { + self.fbb_.push_slot::(TensorHistoryNode::VT_SAMPLER, sampler, SamplerType::DPMPP2MKarras); + } + #[inline] + pub fn add_hires_fix(&mut self, hires_fix: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_HIRES_FIX, hires_fix, false); + } + #[inline] + pub fn add_hires_fix_start_width(&mut self, hires_fix_start_width: u16) { + self.fbb_.push_slot::(TensorHistoryNode::VT_HIRES_FIX_START_WIDTH, hires_fix_start_width, 0); + } + #[inline] + pub fn add_hires_fix_start_height(&mut self, hires_fix_start_height: u16) { + self.fbb_.push_slot::(TensorHistoryNode::VT_HIRES_FIX_START_HEIGHT, hires_fix_start_height, 0); + } + #[inline] + pub fn add_hires_fix_strength(&mut self, hires_fix_strength: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_HIRES_FIX_STRENGTH, hires_fix_strength, 0.7); + } + #[inline] + pub fn add_upscaler(&mut self, upscaler: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(TensorHistoryNode::VT_UPSCALER, upscaler); + } + #[inline] + pub fn add_scale_factor(&mut self, scale_factor: u16) { + self.fbb_.push_slot::(TensorHistoryNode::VT_SCALE_FACTOR, scale_factor, 1); + } + #[inline] + pub fn add_depth_map_id(&mut self, depth_map_id: i64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_DEPTH_MAP_ID, depth_map_id, 0); + } + #[inline] + pub fn add_generated(&mut self, generated: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_GENERATED, generated, true); + } + #[inline] + pub fn add_image_guidance_scale(&mut self, image_guidance_scale: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_IMAGE_GUIDANCE_SCALE, image_guidance_scale, 1.5); + } + #[inline] + pub fn add_seed_mode(&mut self, seed_mode: SeedMode) { + self.fbb_.push_slot::(TensorHistoryNode::VT_SEED_MODE, seed_mode, SeedMode::Legacy); + } + #[inline] + pub fn add_clip_skip(&mut self, clip_skip: u32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_CLIP_SKIP, clip_skip, 1); + } + #[inline] + pub fn add_controls(&mut self, controls: flatbuffers::WIPOffset>>>) { + self.fbb_.push_slot_always::>(TensorHistoryNode::VT_CONTROLS, controls); + } + #[inline] + pub fn add_scribble_id(&mut self, scribble_id: i64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_SCRIBBLE_ID, scribble_id, 0); + } + #[inline] + pub fn add_pose_id(&mut self, pose_id: i64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_POSE_ID, pose_id, 0); + } + #[inline] + pub fn add_loras(&mut self, loras: flatbuffers::WIPOffset>>>) { + self.fbb_.push_slot_always::>(TensorHistoryNode::VT_LORAS, loras); + } + #[inline] + pub fn add_color_palette_id(&mut self, color_palette_id: i64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_COLOR_PALETTE_ID, color_palette_id, 0); + } + #[inline] + pub fn add_mask_blur(&mut self, mask_blur: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_MASK_BLUR, mask_blur, 0.0); + } + #[inline] + pub fn add_custom_id(&mut self, custom_id: i64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_CUSTOM_ID, custom_id, 0); + } + #[inline] + pub fn add_face_restoration(&mut self, face_restoration: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(TensorHistoryNode::VT_FACE_RESTORATION, face_restoration); + } + #[inline] + pub fn add_clip_weight(&mut self, clip_weight: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_CLIP_WEIGHT, clip_weight, 1.0); + } + #[inline] + pub fn add_negative_prompt_for_image_prior(&mut self, negative_prompt_for_image_prior: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_NEGATIVE_PROMPT_FOR_IMAGE_PRIOR, negative_prompt_for_image_prior, true); + } + #[inline] + pub fn add_image_prior_steps(&mut self, image_prior_steps: u32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_IMAGE_PRIOR_STEPS, image_prior_steps, 5); + } + #[inline] + pub fn add_data_stored(&mut self, data_stored: i32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_DATA_STORED, data_stored, 0); + } + #[inline] + pub fn add_preview_id(&mut self, preview_id: i64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_PREVIEW_ID, preview_id, 0); + } + #[inline] + pub fn add_content_offset_x(&mut self, content_offset_x: i32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_CONTENT_OFFSET_X, content_offset_x, 0); + } + #[inline] + pub fn add_content_offset_y(&mut self, content_offset_y: i32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_CONTENT_OFFSET_Y, content_offset_y, 0); + } + #[inline] + pub fn add_scale_factor_by_120(&mut self, scale_factor_by_120: i32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_SCALE_FACTOR_BY_120, scale_factor_by_120, 120); + } + #[inline] + pub fn add_refiner_model(&mut self, refiner_model: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(TensorHistoryNode::VT_REFINER_MODEL, refiner_model); + } + #[inline] + pub fn add_original_image_height(&mut self, original_image_height: u32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_ORIGINAL_IMAGE_HEIGHT, original_image_height, 0); + } + #[inline] + pub fn add_original_image_width(&mut self, original_image_width: u32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_ORIGINAL_IMAGE_WIDTH, original_image_width, 0); + } + #[inline] + pub fn add_crop_top(&mut self, crop_top: i32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_CROP_TOP, crop_top, 0); + } + #[inline] + pub fn add_crop_left(&mut self, crop_left: i32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_CROP_LEFT, crop_left, 0); + } + #[inline] + pub fn add_target_image_height(&mut self, target_image_height: u32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_TARGET_IMAGE_HEIGHT, target_image_height, 0); + } + #[inline] + pub fn add_target_image_width(&mut self, target_image_width: u32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_TARGET_IMAGE_WIDTH, target_image_width, 0); + } + #[inline] + pub fn add_aesthetic_score(&mut self, aesthetic_score: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_AESTHETIC_SCORE, aesthetic_score, 0.0); + } + #[inline] + pub fn add_negative_aesthetic_score(&mut self, negative_aesthetic_score: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_NEGATIVE_AESTHETIC_SCORE, negative_aesthetic_score, 0.0); + } + #[inline] + pub fn add_zero_negative_prompt(&mut self, zero_negative_prompt: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_ZERO_NEGATIVE_PROMPT, zero_negative_prompt, false); + } + #[inline] + pub fn add_refiner_start(&mut self, refiner_start: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_REFINER_START, refiner_start, 0.0); + } + #[inline] + pub fn add_negative_original_image_height(&mut self, negative_original_image_height: u32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_NEGATIVE_ORIGINAL_IMAGE_HEIGHT, negative_original_image_height, 0); + } + #[inline] + pub fn add_negative_original_image_width(&mut self, negative_original_image_width: u32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_NEGATIVE_ORIGINAL_IMAGE_WIDTH, negative_original_image_width, 0); + } + #[inline] + pub fn add_shuffle_data_stored(&mut self, shuffle_data_stored: i32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_SHUFFLE_DATA_STORED, shuffle_data_stored, 0); + } + #[inline] + pub fn add_fps_id(&mut self, fps_id: u32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_FPS_ID, fps_id, 5); + } + #[inline] + pub fn add_motion_bucket_id(&mut self, motion_bucket_id: u32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_MOTION_BUCKET_ID, motion_bucket_id, 127); + } + #[inline] + pub fn add_cond_aug(&mut self, cond_aug: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_COND_AUG, cond_aug, 0.02); + } + #[inline] + pub fn add_start_frame_cfg(&mut self, start_frame_cfg: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_START_FRAME_CFG, start_frame_cfg, 1.0); + } + #[inline] + pub fn add_num_frames(&mut self, num_frames: u32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_NUM_FRAMES, num_frames, 14); + } + #[inline] + pub fn add_mask_blur_outset(&mut self, mask_blur_outset: i32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_MASK_BLUR_OUTSET, mask_blur_outset, 0); + } + #[inline] + pub fn add_sharpness(&mut self, sharpness: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_SHARPNESS, sharpness, 0.0); + } + #[inline] + pub fn add_shift(&mut self, shift: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_SHIFT, shift, 1.0); + } + #[inline] + pub fn add_stage_2_steps(&mut self, stage_2_steps: u32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_STAGE_2_STEPS, stage_2_steps, 10); + } + #[inline] + pub fn add_stage_2_cfg(&mut self, stage_2_cfg: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_STAGE_2_CFG, stage_2_cfg, 1.0); + } + #[inline] + pub fn add_stage_2_shift(&mut self, stage_2_shift: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_STAGE_2_SHIFT, stage_2_shift, 1.0); + } + #[inline] + pub fn add_tiled_decoding(&mut self, tiled_decoding: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_TILED_DECODING, tiled_decoding, false); + } + #[inline] + pub fn add_decoding_tile_width(&mut self, decoding_tile_width: u16) { + self.fbb_.push_slot::(TensorHistoryNode::VT_DECODING_TILE_WIDTH, decoding_tile_width, 10); + } + #[inline] + pub fn add_decoding_tile_height(&mut self, decoding_tile_height: u16) { + self.fbb_.push_slot::(TensorHistoryNode::VT_DECODING_TILE_HEIGHT, decoding_tile_height, 10); + } + #[inline] + pub fn add_decoding_tile_overlap(&mut self, decoding_tile_overlap: u16) { + self.fbb_.push_slot::(TensorHistoryNode::VT_DECODING_TILE_OVERLAP, decoding_tile_overlap, 2); + } + #[inline] + pub fn add_stochastic_sampling_gamma(&mut self, stochastic_sampling_gamma: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_STOCHASTIC_SAMPLING_GAMMA, stochastic_sampling_gamma, 0.3); + } + #[inline] + pub fn add_preserve_original_after_inpaint(&mut self, preserve_original_after_inpaint: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_PRESERVE_ORIGINAL_AFTER_INPAINT, preserve_original_after_inpaint, true); + } + #[inline] + pub fn add_tiled_diffusion(&mut self, tiled_diffusion: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_TILED_DIFFUSION, tiled_diffusion, false); + } + #[inline] + pub fn add_diffusion_tile_width(&mut self, diffusion_tile_width: u16) { + self.fbb_.push_slot::(TensorHistoryNode::VT_DIFFUSION_TILE_WIDTH, diffusion_tile_width, 16); + } + #[inline] + pub fn add_diffusion_tile_height(&mut self, diffusion_tile_height: u16) { + self.fbb_.push_slot::(TensorHistoryNode::VT_DIFFUSION_TILE_HEIGHT, diffusion_tile_height, 16); + } + #[inline] + pub fn add_diffusion_tile_overlap(&mut self, diffusion_tile_overlap: u16) { + self.fbb_.push_slot::(TensorHistoryNode::VT_DIFFUSION_TILE_OVERLAP, diffusion_tile_overlap, 2); + } + #[inline] + pub fn add_upscaler_scale_factor(&mut self, upscaler_scale_factor: u8) { + self.fbb_.push_slot::(TensorHistoryNode::VT_UPSCALER_SCALE_FACTOR, upscaler_scale_factor, 0); + } + #[inline] + pub fn add_script_session_id(&mut self, script_session_id: u64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_SCRIPT_SESSION_ID, script_session_id, 0); + } + #[inline] + pub fn add_t5_text_encoder(&mut self, t5_text_encoder: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_T5_TEXT_ENCODER, t5_text_encoder, true); + } + #[inline] + pub fn add_separate_clip_l(&mut self, separate_clip_l: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_SEPARATE_CLIP_L, separate_clip_l, false); + } + #[inline] + pub fn add_clip_l_text(&mut self, clip_l_text: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(TensorHistoryNode::VT_CLIP_L_TEXT, clip_l_text); + } + #[inline] + pub fn add_separate_open_clip_g(&mut self, separate_open_clip_g: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_SEPARATE_OPEN_CLIP_G, separate_open_clip_g, false); + } + #[inline] + pub fn add_open_clip_g_text(&mut self, open_clip_g_text: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(TensorHistoryNode::VT_OPEN_CLIP_G_TEXT, open_clip_g_text); + } + #[inline] + pub fn add_speed_up_with_guidance_embed(&mut self, speed_up_with_guidance_embed: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_SPEED_UP_WITH_GUIDANCE_EMBED, speed_up_with_guidance_embed, true); + } + #[inline] + pub fn add_guidance_embed(&mut self, guidance_embed: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_GUIDANCE_EMBED, guidance_embed, 3.5); + } + #[inline] + pub fn add_resolution_dependent_shift(&mut self, resolution_dependent_shift: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_RESOLUTION_DEPENDENT_SHIFT, resolution_dependent_shift, true); + } + #[inline] + pub fn add_profile_data(&mut self, profile_data: flatbuffers::WIPOffset>) { + self.fbb_.push_slot_always::>(TensorHistoryNode::VT_PROFILE_DATA, profile_data); + } + #[inline] + pub fn add_tea_cache_start(&mut self, tea_cache_start: i32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_TEA_CACHE_START, tea_cache_start, 5); + } + #[inline] + pub fn add_tea_cache_end(&mut self, tea_cache_end: i32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_TEA_CACHE_END, tea_cache_end, -1); + } + #[inline] + pub fn add_tea_cache_threshold(&mut self, tea_cache_threshold: f32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_TEA_CACHE_THRESHOLD, tea_cache_threshold, 0.06); + } + #[inline] + pub fn add_tea_cache(&mut self, tea_cache: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_TEA_CACHE, tea_cache, false); + } + #[inline] + pub fn add_separate_t5(&mut self, separate_t5: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_SEPARATE_T5, separate_t5, false); + } + #[inline] + pub fn add_t5_text(&mut self, t5_text: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(TensorHistoryNode::VT_T5_TEXT, t5_text); + } + #[inline] + pub fn add_tea_cache_max_skip_steps(&mut self, tea_cache_max_skip_steps: i32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_TEA_CACHE_MAX_SKIP_STEPS, tea_cache_max_skip_steps, 3); + } + #[inline] + pub fn add_text_prompt(&mut self, text_prompt: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(TensorHistoryNode::VT_TEXT_PROMPT, text_prompt); + } + #[inline] + pub fn add_negative_text_prompt(&mut self, negative_text_prompt: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(TensorHistoryNode::VT_NEGATIVE_TEXT_PROMPT, negative_text_prompt); + } + #[inline] + pub fn add_clip_id(&mut self, clip_id: i64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_CLIP_ID, clip_id, -1); + } + #[inline] + pub fn add_index_in_a_clip(&mut self, index_in_a_clip: i32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_INDEX_IN_A_CLIP, index_in_a_clip, 0); + } + #[inline] + pub fn add_causal_inference_enabled(&mut self, causal_inference_enabled: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_CAUSAL_INFERENCE_ENABLED, causal_inference_enabled, false); + } + #[inline] + pub fn add_causal_inference(&mut self, causal_inference: i32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_CAUSAL_INFERENCE, causal_inference, 3); + } + #[inline] + pub fn add_causal_inference_pad(&mut self, causal_inference_pad: i32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_CAUSAL_INFERENCE_PAD, causal_inference_pad, 0); + } + #[inline] + pub fn add_cfg_zero_star(&mut self, cfg_zero_star: bool) { + self.fbb_.push_slot::(TensorHistoryNode::VT_CFG_ZERO_STAR, cfg_zero_star, false); + } + #[inline] + pub fn add_cfg_zero_init_steps(&mut self, cfg_zero_init_steps: i32) { + self.fbb_.push_slot::(TensorHistoryNode::VT_CFG_ZERO_INIT_STEPS, cfg_zero_init_steps, 0); + } + #[inline] + pub fn add_generation_time(&mut self, generation_time: f64) { + self.fbb_.push_slot::(TensorHistoryNode::VT_GENERATION_TIME, generation_time, 0.0); + } + #[inline] + pub fn add_reason(&mut self, reason: Reason) { + self.fbb_.push_slot::(TensorHistoryNode::VT_REASON, reason, Reason::Other); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> TensorHistoryNodeBuilder<'a, 'b, A> { + let start = _fbb.start_table(); + TensorHistoryNodeBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for TensorHistoryNode<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("TensorHistoryNode"); + ds.field("lineage", &self.lineage()); + ds.field("logical_time", &self.logical_time()); + ds.field("start_width", &self.start_width()); + ds.field("start_height", &self.start_height()); + ds.field("seed", &self.seed()); + ds.field("steps", &self.steps()); + ds.field("guidance_scale", &self.guidance_scale()); + ds.field("strength", &self.strength()); + ds.field("model", &self.model()); + ds.field("tensor_id", &self.tensor_id()); + ds.field("mask_id", &self.mask_id()); + ds.field("wall_clock", &self.wall_clock()); + ds.field("text_edits", &self.text_edits()); + ds.field("text_lineage", &self.text_lineage()); + ds.field("batch_size", &self.batch_size()); + ds.field("sampler", &self.sampler()); + ds.field("hires_fix", &self.hires_fix()); + ds.field("hires_fix_start_width", &self.hires_fix_start_width()); + ds.field("hires_fix_start_height", &self.hires_fix_start_height()); + ds.field("hires_fix_strength", &self.hires_fix_strength()); + ds.field("upscaler", &self.upscaler()); + ds.field("scale_factor", &self.scale_factor()); + ds.field("depth_map_id", &self.depth_map_id()); + ds.field("generated", &self.generated()); + ds.field("image_guidance_scale", &self.image_guidance_scale()); + ds.field("seed_mode", &self.seed_mode()); + ds.field("clip_skip", &self.clip_skip()); + ds.field("controls", &self.controls()); + ds.field("scribble_id", &self.scribble_id()); + ds.field("pose_id", &self.pose_id()); + ds.field("loras", &self.loras()); + ds.field("color_palette_id", &self.color_palette_id()); + ds.field("mask_blur", &self.mask_blur()); + ds.field("custom_id", &self.custom_id()); + ds.field("face_restoration", &self.face_restoration()); + ds.field("clip_weight", &self.clip_weight()); + ds.field("negative_prompt_for_image_prior", &self.negative_prompt_for_image_prior()); + ds.field("image_prior_steps", &self.image_prior_steps()); + ds.field("data_stored", &self.data_stored()); + ds.field("preview_id", &self.preview_id()); + ds.field("content_offset_x", &self.content_offset_x()); + ds.field("content_offset_y", &self.content_offset_y()); + ds.field("scale_factor_by_120", &self.scale_factor_by_120()); + ds.field("refiner_model", &self.refiner_model()); + ds.field("original_image_height", &self.original_image_height()); + ds.field("original_image_width", &self.original_image_width()); + ds.field("crop_top", &self.crop_top()); + ds.field("crop_left", &self.crop_left()); + ds.field("target_image_height", &self.target_image_height()); + ds.field("target_image_width", &self.target_image_width()); + ds.field("aesthetic_score", &self.aesthetic_score()); + ds.field("negative_aesthetic_score", &self.negative_aesthetic_score()); + ds.field("zero_negative_prompt", &self.zero_negative_prompt()); + ds.field("refiner_start", &self.refiner_start()); + ds.field("negative_original_image_height", &self.negative_original_image_height()); + ds.field("negative_original_image_width", &self.negative_original_image_width()); + ds.field("shuffle_data_stored", &self.shuffle_data_stored()); + ds.field("fps_id", &self.fps_id()); + ds.field("motion_bucket_id", &self.motion_bucket_id()); + ds.field("cond_aug", &self.cond_aug()); + ds.field("start_frame_cfg", &self.start_frame_cfg()); + ds.field("num_frames", &self.num_frames()); + ds.field("mask_blur_outset", &self.mask_blur_outset()); + ds.field("sharpness", &self.sharpness()); + ds.field("shift", &self.shift()); + ds.field("stage_2_steps", &self.stage_2_steps()); + ds.field("stage_2_cfg", &self.stage_2_cfg()); + ds.field("stage_2_shift", &self.stage_2_shift()); + ds.field("tiled_decoding", &self.tiled_decoding()); + ds.field("decoding_tile_width", &self.decoding_tile_width()); + ds.field("decoding_tile_height", &self.decoding_tile_height()); + ds.field("decoding_tile_overlap", &self.decoding_tile_overlap()); + ds.field("stochastic_sampling_gamma", &self.stochastic_sampling_gamma()); + ds.field("preserve_original_after_inpaint", &self.preserve_original_after_inpaint()); + ds.field("tiled_diffusion", &self.tiled_diffusion()); + ds.field("diffusion_tile_width", &self.diffusion_tile_width()); + ds.field("diffusion_tile_height", &self.diffusion_tile_height()); + ds.field("diffusion_tile_overlap", &self.diffusion_tile_overlap()); + ds.field("upscaler_scale_factor", &self.upscaler_scale_factor()); + ds.field("script_session_id", &self.script_session_id()); + ds.field("t5_text_encoder", &self.t5_text_encoder()); + ds.field("separate_clip_l", &self.separate_clip_l()); + ds.field("clip_l_text", &self.clip_l_text()); + ds.field("separate_open_clip_g", &self.separate_open_clip_g()); + ds.field("open_clip_g_text", &self.open_clip_g_text()); + ds.field("speed_up_with_guidance_embed", &self.speed_up_with_guidance_embed()); + ds.field("guidance_embed", &self.guidance_embed()); + ds.field("resolution_dependent_shift", &self.resolution_dependent_shift()); + ds.field("profile_data", &self.profile_data()); + ds.field("tea_cache_start", &self.tea_cache_start()); + ds.field("tea_cache_end", &self.tea_cache_end()); + ds.field("tea_cache_threshold", &self.tea_cache_threshold()); + ds.field("tea_cache", &self.tea_cache()); + ds.field("separate_t5", &self.separate_t5()); + ds.field("t5_text", &self.t5_text()); + ds.field("tea_cache_max_skip_steps", &self.tea_cache_max_skip_steps()); + ds.field("text_prompt", &self.text_prompt()); + ds.field("negative_text_prompt", &self.negative_text_prompt()); + ds.field("clip_id", &self.clip_id()); + ds.field("index_in_a_clip", &self.index_in_a_clip()); + ds.field("causal_inference_enabled", &self.causal_inference_enabled()); + ds.field("causal_inference", &self.causal_inference()); + ds.field("causal_inference_pad", &self.causal_inference_pad()); + ds.field("cfg_zero_star", &self.cfg_zero_star()); + ds.field("cfg_zero_init_steps", &self.cfg_zero_init_steps()); + ds.field("generation_time", &self.generation_time()); + ds.field("reason", &self.reason()); + ds.finish() + } +} +#[inline] +/// Verifies that a buffer of bytes contains a `TensorHistoryNode` +/// and returns it. +/// Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `root_as_tensor_history_node_unchecked`. +pub fn root_as_tensor_history_node(buf: &[u8]) -> Result { + flatbuffers::root::(buf) +} +#[inline] +/// Verifies that a buffer of bytes contains a size prefixed +/// `TensorHistoryNode` and returns it. +/// Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `size_prefixed_root_as_tensor_history_node_unchecked`. +pub fn size_prefixed_root_as_tensor_history_node(buf: &[u8]) -> Result { + flatbuffers::size_prefixed_root::(buf) +} +#[inline] +/// Verifies, with the given options, that a buffer of bytes +/// contains a `TensorHistoryNode` and returns it. +/// Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `root_as_tensor_history_node_unchecked`. +pub fn root_as_tensor_history_node_with_opts<'b, 'o>( + opts: &'o flatbuffers::VerifierOptions, + buf: &'b [u8], +) -> Result, flatbuffers::InvalidFlatbuffer> { + flatbuffers::root_with_opts::>(opts, buf) +} +#[inline] +/// Verifies, with the given verifier options, that a buffer of +/// bytes contains a size prefixed `TensorHistoryNode` and returns +/// it. Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `root_as_tensor_history_node_unchecked`. +pub fn size_prefixed_root_as_tensor_history_node_with_opts<'b, 'o>( + opts: &'o flatbuffers::VerifierOptions, + buf: &'b [u8], +) -> Result, flatbuffers::InvalidFlatbuffer> { + flatbuffers::size_prefixed_root_with_opts::>(opts, buf) +} +#[inline] +/// Assumes, without verification, that a buffer of bytes contains a TensorHistoryNode and returns it. +/// # Safety +/// Callers must trust the given bytes do indeed contain a valid `TensorHistoryNode`. +pub unsafe fn root_as_tensor_history_node_unchecked(buf: &[u8]) -> TensorHistoryNode { + unsafe { flatbuffers::root_unchecked::(buf) } +} +#[inline] +/// Assumes, without verification, that a buffer of bytes contains a size prefixed TensorHistoryNode and returns it. +/// # Safety +/// Callers must trust the given bytes do indeed contain a valid size prefixed `TensorHistoryNode`. +pub unsafe fn size_prefixed_root_as_tensor_history_node_unchecked(buf: &[u8]) -> TensorHistoryNode { + unsafe { flatbuffers::size_prefixed_root_unchecked::(buf) } +} +#[inline] +pub fn finish_tensor_history_node_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( + fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + root: flatbuffers::WIPOffset>) { + fbb.finish(root, None); +} + +#[inline] +pub fn finish_size_prefixed_tensor_history_node_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, root: flatbuffers::WIPOffset>) { + fbb.finish_size_prefixed(root, None); +} diff --git a/src-tauri/src/projects_db/fbs/text_history_generated.rs b/src-tauri/src/projects_db/fbs/text_history_generated.rs new file mode 100644 index 0000000..ead88cb --- /dev/null +++ b/src-tauri/src/projects_db/fbs/text_history_generated.rs @@ -0,0 +1,608 @@ +// automatically generated by the FlatBuffers compiler, do not modify + + +// @generated + +use core::mem; +use core::cmp::Ordering; + +extern crate flatbuffers; +use self::flatbuffers::{EndianScalar, Follow}; + +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MIN_TEXT_TYPE: i8 = 0; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +pub const ENUM_MAX_TEXT_TYPE: i8 = 1; +#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")] +#[allow(non_camel_case_types)] +pub const ENUM_VALUES_TEXT_TYPE: [TextType; 2] = [ + TextType::PositiveText, + TextType::NegativeText, +]; + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +#[repr(transparent)] +pub struct TextType(pub i8); +#[allow(non_upper_case_globals)] +impl TextType { + pub const PositiveText: Self = Self(0); + pub const NegativeText: Self = Self(1); + + pub const ENUM_MIN: i8 = 0; + pub const ENUM_MAX: i8 = 1; + pub const ENUM_VALUES: &'static [Self] = &[ + Self::PositiveText, + Self::NegativeText, + ]; + /// Returns the variant's name or "" if unknown. + pub fn variant_name(self) -> Option<&'static str> { + match self { + Self::PositiveText => Some("PositiveText"), + Self::NegativeText => Some("NegativeText"), + _ => None, + } + } +} +impl core::fmt::Debug for TextType { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + if let Some(name) = self.variant_name() { + f.write_str(name) + } else { + f.write_fmt(format_args!("", self.0)) + } + } +} +impl<'a> flatbuffers::Follow<'a> for TextType { + type Inner = Self; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = unsafe { flatbuffers::read_scalar_at::(buf, loc) }; + Self(b) + } +} + +impl flatbuffers::Push for TextType { + type Output = TextType; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + unsafe { flatbuffers::emplace_scalar::(dst, self.0); } + } +} + +impl flatbuffers::EndianScalar for TextType { + type Scalar = i8; + #[inline] + fn to_little_endian(self) -> i8 { + self.0.to_le() + } + #[inline] + #[allow(clippy::wrong_self_convention)] + fn from_little_endian(v: i8) -> Self { + let b = i8::from_le(v); + Self(b) + } +} + +impl<'a> flatbuffers::Verifiable for TextType { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + i8::run_verifier(v, pos) + } +} + +impl flatbuffers::SimpleToVerifyInSlice for TextType {} +// struct TextRange, aligned to 4 +#[repr(transparent)] +#[derive(Clone, Copy, PartialEq)] +pub struct TextRange(pub [u8; 8]); +impl Default for TextRange { + fn default() -> Self { + Self([0; 8]) + } +} +impl core::fmt::Debug for TextRange { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("TextRange") + .field("location", &self.location()) + .field("length", &self.length()) + .finish() + } +} + +impl flatbuffers::SimpleToVerifyInSlice for TextRange {} +impl<'a> flatbuffers::Follow<'a> for TextRange { + type Inner = &'a TextRange; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + unsafe { <&'a TextRange>::follow(buf, loc) } + } +} +impl<'a> flatbuffers::Follow<'a> for &'a TextRange { + type Inner = &'a TextRange; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + unsafe { flatbuffers::follow_cast_ref::(buf, loc) } + } +} +impl<'b> flatbuffers::Push for TextRange { + type Output = TextRange; + #[inline] + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + let src = unsafe { ::core::slice::from_raw_parts(self as *const TextRange as *const u8, ::size()) }; + dst.copy_from_slice(src); + } + #[inline] + fn alignment() -> flatbuffers::PushAlignment { + flatbuffers::PushAlignment::new(4) + } +} + +impl<'a> flatbuffers::Verifiable for TextRange { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.in_buffer::(pos) + } +} + +impl<'a> TextRange { + #[allow(clippy::too_many_arguments)] + pub fn new( + location: i32, + length: i32, + ) -> Self { + let mut s = Self([0; 8]); + s.set_location(location); + s.set_length(length); + s + } + + pub fn location(&self) -> i32 { + let mut mem = core::mem::MaybeUninit::<::Scalar>::uninit(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid value in this slot + EndianScalar::from_little_endian(unsafe { + core::ptr::copy_nonoverlapping( + self.0[0..].as_ptr(), + mem.as_mut_ptr() as *mut u8, + core::mem::size_of::<::Scalar>(), + ); + mem.assume_init() + }) + } + + pub fn set_location(&mut self, x: i32) { + let x_le = x.to_little_endian(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid value in this slot + unsafe { + core::ptr::copy_nonoverlapping( + &x_le as *const _ as *const u8, + self.0[0..].as_mut_ptr(), + core::mem::size_of::<::Scalar>(), + ); + } + } + + pub fn length(&self) -> i32 { + let mut mem = core::mem::MaybeUninit::<::Scalar>::uninit(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid value in this slot + EndianScalar::from_little_endian(unsafe { + core::ptr::copy_nonoverlapping( + self.0[4..].as_ptr(), + mem.as_mut_ptr() as *mut u8, + core::mem::size_of::<::Scalar>(), + ); + mem.assume_init() + }) + } + + pub fn set_length(&mut self, x: i32) { + let x_le = x.to_little_endian(); + // Safety: + // Created from a valid Table for this object + // Which contains a valid value in this slot + unsafe { + core::ptr::copy_nonoverlapping( + &x_le as *const _ as *const u8, + self.0[4..].as_mut_ptr(), + core::mem::size_of::<::Scalar>(), + ); + } + } + +} + +pub enum TextModificationOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct TextModification<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for TextModification<'a> { + type Inner = TextModification<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: unsafe { flatbuffers::Table::new(buf, loc) } } + } +} + +impl<'a> TextModification<'a> { + pub const VT_TYPE_: flatbuffers::VOffsetT = 4; + pub const VT_RANGE: flatbuffers::VOffsetT = 6; + pub const VT_TEXT: flatbuffers::VOffsetT = 8; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + TextModification { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + args: &'args TextModificationArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = TextModificationBuilder::new(_fbb); + if let Some(x) = args.text { builder.add_text(x); } + if let Some(x) = args.range { builder.add_range(x); } + builder.add_type_(args.type_); + builder.finish() + } + + + #[inline] + pub fn type_(&self) -> TextType { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TextModification::VT_TYPE_, Some(TextType::PositiveText)).unwrap()} + } + #[inline] + pub fn range(&self) -> Option<&'a TextRange> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TextModification::VT_RANGE, None)} + } + #[inline] + pub fn text(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(TextModification::VT_TEXT, None)} + } +} + +impl flatbuffers::Verifiable for TextModification<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::("type_", Self::VT_TYPE_, false)? + .visit_field::("range", Self::VT_RANGE, false)? + .visit_field::>("text", Self::VT_TEXT, false)? + .finish(); + Ok(()) + } +} +pub struct TextModificationArgs<'a> { + pub type_: TextType, + pub range: Option<&'a TextRange>, + pub text: Option>, +} +impl<'a> Default for TextModificationArgs<'a> { + #[inline] + fn default() -> Self { + TextModificationArgs { + type_: TextType::PositiveText, + range: None, + text: None, + } + } +} + +pub struct TextModificationBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> TextModificationBuilder<'a, 'b, A> { + #[inline] + pub fn add_type_(&mut self, type_: TextType) { + self.fbb_.push_slot::(TextModification::VT_TYPE_, type_, TextType::PositiveText); + } + #[inline] + pub fn add_range(&mut self, range: &TextRange) { + self.fbb_.push_slot_always::<&TextRange>(TextModification::VT_RANGE, range); + } + #[inline] + pub fn add_text(&mut self, text: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(TextModification::VT_TEXT, text); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> TextModificationBuilder<'a, 'b, A> { + let start = _fbb.start_table(); + TextModificationBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for TextModification<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("TextModification"); + ds.field("type_", &self.type_()); + ds.field("range", &self.range()); + ds.field("text", &self.text()); + ds.finish() + } +} +pub enum TextHistoryNodeOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct TextHistoryNode<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for TextHistoryNode<'a> { + type Inner = TextHistoryNode<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: unsafe { flatbuffers::Table::new(buf, loc) } } + } +} + +impl<'a> TextHistoryNode<'a> { + pub const VT_LINEAGE: flatbuffers::VOffsetT = 4; + pub const VT_LOGICAL_TIME: flatbuffers::VOffsetT = 6; + pub const VT_START_EDITS: flatbuffers::VOffsetT = 8; + pub const VT_START_POSITIVE_TEXT: flatbuffers::VOffsetT = 10; + pub const VT_START_NEGATIVE_TEXT: flatbuffers::VOffsetT = 12; + pub const VT_MODIFICATIONS: flatbuffers::VOffsetT = 14; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + TextHistoryNode { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + args: &'args TextHistoryNodeArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = TextHistoryNodeBuilder::new(_fbb); + builder.add_start_edits(args.start_edits); + builder.add_logical_time(args.logical_time); + builder.add_lineage(args.lineage); + if let Some(x) = args.modifications { builder.add_modifications(x); } + if let Some(x) = args.start_negative_text { builder.add_start_negative_text(x); } + if let Some(x) = args.start_positive_text { builder.add_start_positive_text(x); } + builder.finish() + } + + + #[inline] + pub fn lineage(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TextHistoryNode::VT_LINEAGE, Some(0)).unwrap()} + } + #[inline] + pub fn logical_time(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TextHistoryNode::VT_LOGICAL_TIME, Some(0)).unwrap()} + } + #[inline] + pub fn start_edits(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(TextHistoryNode::VT_START_EDITS, Some(0)).unwrap()} + } + #[inline] + pub fn start_positive_text(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(TextHistoryNode::VT_START_POSITIVE_TEXT, None)} + } + #[inline] + pub fn start_negative_text(&self) -> Option<&'a str> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(TextHistoryNode::VT_START_NEGATIVE_TEXT, None)} + } + #[inline] + pub fn modifications(&self) -> Option>>> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>>(TextHistoryNode::VT_MODIFICATIONS, None)} + } +} + +impl flatbuffers::Verifiable for TextHistoryNode<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::("lineage", Self::VT_LINEAGE, false)? + .visit_field::("logical_time", Self::VT_LOGICAL_TIME, false)? + .visit_field::("start_edits", Self::VT_START_EDITS, false)? + .visit_field::>("start_positive_text", Self::VT_START_POSITIVE_TEXT, false)? + .visit_field::>("start_negative_text", Self::VT_START_NEGATIVE_TEXT, false)? + .visit_field::>>>("modifications", Self::VT_MODIFICATIONS, false)? + .finish(); + Ok(()) + } +} +pub struct TextHistoryNodeArgs<'a> { + pub lineage: i64, + pub logical_time: i64, + pub start_edits: i64, + pub start_positive_text: Option>, + pub start_negative_text: Option>, + pub modifications: Option>>>>, +} +impl<'a> Default for TextHistoryNodeArgs<'a> { + #[inline] + fn default() -> Self { + TextHistoryNodeArgs { + lineage: 0, + logical_time: 0, + start_edits: 0, + start_positive_text: None, + start_negative_text: None, + modifications: None, + } + } +} + +pub struct TextHistoryNodeBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> TextHistoryNodeBuilder<'a, 'b, A> { + #[inline] + pub fn add_lineage(&mut self, lineage: i64) { + self.fbb_.push_slot::(TextHistoryNode::VT_LINEAGE, lineage, 0); + } + #[inline] + pub fn add_logical_time(&mut self, logical_time: i64) { + self.fbb_.push_slot::(TextHistoryNode::VT_LOGICAL_TIME, logical_time, 0); + } + #[inline] + pub fn add_start_edits(&mut self, start_edits: i64) { + self.fbb_.push_slot::(TextHistoryNode::VT_START_EDITS, start_edits, 0); + } + #[inline] + pub fn add_start_positive_text(&mut self, start_positive_text: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(TextHistoryNode::VT_START_POSITIVE_TEXT, start_positive_text); + } + #[inline] + pub fn add_start_negative_text(&mut self, start_negative_text: flatbuffers::WIPOffset<&'b str>) { + self.fbb_.push_slot_always::>(TextHistoryNode::VT_START_NEGATIVE_TEXT, start_negative_text); + } + #[inline] + pub fn add_modifications(&mut self, modifications: flatbuffers::WIPOffset>>>) { + self.fbb_.push_slot_always::>(TextHistoryNode::VT_MODIFICATIONS, modifications); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> TextHistoryNodeBuilder<'a, 'b, A> { + let start = _fbb.start_table(); + TextHistoryNodeBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for TextHistoryNode<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("TextHistoryNode"); + ds.field("lineage", &self.lineage()); + ds.field("logical_time", &self.logical_time()); + ds.field("start_edits", &self.start_edits()); + ds.field("start_positive_text", &self.start_positive_text()); + ds.field("start_negative_text", &self.start_negative_text()); + ds.field("modifications", &self.modifications()); + ds.finish() + } +} +#[inline] +/// Verifies that a buffer of bytes contains a `TextHistoryNode` +/// and returns it. +/// Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `root_as_text_history_node_unchecked`. +pub fn root_as_text_history_node(buf: &[u8]) -> Result { + flatbuffers::root::(buf) +} +#[inline] +/// Verifies that a buffer of bytes contains a size prefixed +/// `TextHistoryNode` and returns it. +/// Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `size_prefixed_root_as_text_history_node_unchecked`. +pub fn size_prefixed_root_as_text_history_node(buf: &[u8]) -> Result { + flatbuffers::size_prefixed_root::(buf) +} +#[inline] +/// Verifies, with the given options, that a buffer of bytes +/// contains a `TextHistoryNode` and returns it. +/// Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `root_as_text_history_node_unchecked`. +pub fn root_as_text_history_node_with_opts<'b, 'o>( + opts: &'o flatbuffers::VerifierOptions, + buf: &'b [u8], +) -> Result, flatbuffers::InvalidFlatbuffer> { + flatbuffers::root_with_opts::>(opts, buf) +} +#[inline] +/// Verifies, with the given verifier options, that a buffer of +/// bytes contains a size prefixed `TextHistoryNode` and returns +/// it. Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `root_as_text_history_node_unchecked`. +pub fn size_prefixed_root_as_text_history_node_with_opts<'b, 'o>( + opts: &'o flatbuffers::VerifierOptions, + buf: &'b [u8], +) -> Result, flatbuffers::InvalidFlatbuffer> { + flatbuffers::size_prefixed_root_with_opts::>(opts, buf) +} +#[inline] +/// Assumes, without verification, that a buffer of bytes contains a TextHistoryNode and returns it. +/// # Safety +/// Callers must trust the given bytes do indeed contain a valid `TextHistoryNode`. +pub unsafe fn root_as_text_history_node_unchecked(buf: &[u8]) -> TextHistoryNode { + unsafe { flatbuffers::root_unchecked::(buf) } +} +#[inline] +/// Assumes, without verification, that a buffer of bytes contains a size prefixed TextHistoryNode and returns it. +/// # Safety +/// Callers must trust the given bytes do indeed contain a valid size prefixed `TextHistoryNode`. +pub unsafe fn size_prefixed_root_as_text_history_node_unchecked(buf: &[u8]) -> TextHistoryNode { + unsafe { flatbuffers::size_prefixed_root_unchecked::(buf) } +} +#[inline] +pub fn finish_text_history_node_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( + fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, + root: flatbuffers::WIPOffset>) { + fbb.finish(root, None); +} + +#[inline] +pub fn finish_size_prefixed_text_history_node_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, root: flatbuffers::WIPOffset>) { + fbb.finish_size_prefixed(root, None); +} diff --git a/src-tauri/src/projects_db/metadata.rs b/src-tauri/src/projects_db/metadata.rs index 9926d43..6453fb5 100644 --- a/src-tauri/src/projects_db/metadata.rs +++ b/src-tauri/src/projects_db/metadata.rs @@ -2,7 +2,7 @@ use num_enum::TryFromPrimitive; use serde::{Deserialize, Serialize, Serializer}; use serde_json::{json, Value}; -use crate::projects_db::tensor_history::TensorHistoryNode; +use crate::projects_db::dtos::tensor::TensorHistoryNode; /// represents the draw things metadata as it is stored in image metadata. /// contains mostly data from TensorHistoryNode #[derive(Debug, Serialize, Deserialize)] diff --git a/src-tauri/src/projects_db/mod.rs b/src-tauri/src/projects_db/mod.rs index 7085162..bf1260e 100644 --- a/src-tauri/src/projects_db/mod.rs +++ b/src-tauri/src/projects_db/mod.rs @@ -4,25 +4,28 @@ mod projects_db; pub use projects_db::ProjectsDb; mod tensor_history; -pub use tensor_history::TensorHistoryImport; - pub mod tensor_history_generated; pub mod commands; mod dtm_dtproject; -pub use dtm_dtproject::dtm_dtproject_protocol; +pub use dtm_dtproject::{dtm_dtproject_protocol, extract_jpeg_slice}; mod tensor_history_mod; mod tensors; +pub use tensors::decode_tensor; mod metadata; mod text_history; -pub use text_history::{TextHistory, TextHistoryNode, TextModification, TextRange, TextType}; +pub use text_history::TextHistory; pub mod fbs; mod filters; mod search; + +pub mod dtos; + +mod tensor_history_tensor_data; diff --git a/src-tauri/src/projects_db/projects_db.rs b/src-tauri/src/projects_db/projects_db.rs index a275b69..91fd19a 100644 --- a/src-tauri/src/projects_db/projects_db.rs +++ b/src-tauri/src/projects_db/projects_db.rs @@ -7,36 +7,58 @@ use migration::{Migrator, MigratorTrait}; use sea_orm::{ sea_query::{Expr, OnConflict}, ActiveModelTrait, ColumnTrait, ConnectionTrait, Database, DatabaseConnection, DbErr, - EntityTrait, ExprTrait, FromQueryResult, JoinType, Order, PaginatorTrait, QueryFilter, - QueryOrder, QuerySelect, QueryTrait, RelationTrait, Set, + EntityTrait, ExprTrait, JoinType, Order, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect, + QueryTrait, RelationTrait, Set, +}; +use serde::Deserialize; +use std::{ + collections::{HashMap, HashSet}, + fs, }; -use serde::{Deserialize, Serialize}; -use std::collections::{HashMap, HashSet}; use tauri::Manager; use tokio::sync::OnceCell; use crate::projects_db::{ dt_project::{self, ProjectRef}, - filters::ListImagesFilter, + dtos::{ + image::{ImageCount, ImageExtra, ListImagesOptions, ListImagesResult, Paged}, + model::ModelExtra, + project::ProjectExtra, + tensor::{TensorHistoryClip, TensorHistoryImport}, + watch_folder::WatchFolderDTO, + }, search::{self, process_prompt}, - DTProject, TensorHistoryImport, + DTProject, }; static CELL: OnceCell = OnceCell::const_new(); +static SCAN_BATCH_SIZE: u32 = 500; #[derive(Clone, Debug)] pub struct ProjectsDb { - db: DatabaseConnection, + pub db: DatabaseConnection, } fn get_path(app_handle: &tauri::AppHandle) -> String { let app_data_dir = app_handle.path().app_data_dir().unwrap(); - let project_db_path = app_data_dir.join("projects2.db"); + if !app_data_dir.exists() { + std::fs::create_dir_all(&app_data_dir).expect("Failed to create app data dir"); + } + let project_db_path = app_data_dir.join("projects3.db"); format!("sqlite://{}?mode=rwc", project_db_path.to_str().unwrap()) } +fn check_old_path(app_handle: &tauri::AppHandle) { + let app_data_dir = app_handle.path().app_data_dir().unwrap(); + let old_path = app_data_dir.join("projects2.db"); + if old_path.exists() { + fs::remove_file(old_path).unwrap_or_default(); + } +} + impl ProjectsDb { pub async fn get_or_init(app_handle: &tauri::AppHandle) -> Result<&'static ProjectsDb, String> { + check_old_path(app_handle); CELL.get_or_try_init(|| async { ProjectsDb::new(&get_path(app_handle)) .await @@ -60,9 +82,13 @@ impl ProjectsDb { Ok(count as u32) } - pub async fn add_project(&self, path: &str) -> Result { + pub async fn add_project(&self, path: &str) -> Result { + let dt_project = DTProject::get(path).await?; + let fingerprint = dt_project.get_fingerprint().await?; + let project = projects::ActiveModel { path: Set(path.to_string()), + fingerprint: Set(fingerprint), ..Default::default() }; @@ -85,7 +111,7 @@ impl ProjectsDb { let project = projects::Entity::find_by_path(path).one(&self.db).await?; if project.is_none() { - println!("No project found for path: {}", path); + log::debug!("remove project: No project found for path: {}", path); return Ok(None); } let project = project.unwrap(); @@ -95,7 +121,7 @@ impl ProjectsDb { .await?; if delete_result.rows_affected == 0 { - println!("project couldn't be deleted: {}", path); + log::debug!("remove project: project couldn't be deleted: {}", path); } Ok(Some(project.id)) @@ -165,7 +191,7 @@ impl ProjectsDb { path: &str, filesize: Option, modified: Option, - ) -> Result { + ) -> Result { // Fetch existing project let mut project: projects::ActiveModel = projects::Entity::find() .filter(projects::Column::Path.eq(path)) @@ -184,7 +210,7 @@ impl ProjectsDb { } // Save changes - let updated: projects::Model = project.update(&self.db).await?; + let updated: ProjectExtra = project.update(&self.db).await?.into(); Ok(updated) } @@ -199,23 +225,29 @@ impl ProjectsDb { let end = dt_project_info.history_max_id; let project = self.get_project_by_path(path).await?; + if project.excluded { + return Ok((project.id, 0)); + } + let start = match full_scan { true => 0, false => project.last_id.or(Some(-1)).unwrap(), }; - for batch_start in (start..end).step_by(250) { - let histories = dt_project.get_histories(batch_start, 250).await?; + for batch_start in (start..end).step_by(SCAN_BATCH_SIZE as usize) { + let histories = dt_project + .get_histories(batch_start, SCAN_BATCH_SIZE as usize) + .await?; let histories_filtered: Vec = histories .into_iter() .filter(|h| full_scan || (h.index_in_a_clip == 0 && h.generated)) .collect(); - let _preview_ids = histories_filtered - .iter() - .map(|h| h.preview_id) - .collect::>(); + // let _preview_ids = histories_filtered + // .iter() + // .map(|h| h.preview_id) + // .collect::>(); // let preview_thumbs: HashMap> = match preview_ids.len() { // 0 => HashMap::new(), // _ => dt_project.batch_thumbs(&preview_ids).await?, @@ -272,9 +304,9 @@ impl ProjectsDb { self.rebuild_images_fts().await?; - match total { - ListImagesResult::Counts(_) => panic!("Unexpected result"), - ListImagesResult::Images(images) => Ok((project.id, images.total)), + match total.images { + Some(_) => Ok((project.id, total.total)), + None => panic!("Unexpected result"), } } @@ -338,6 +370,7 @@ impl ProjectsDb { preview_id: Set(h.preview_id), thumbnail_half: Set(preview_thumb), clip_id: Set(h.clip_id), + num_frames: Set(h.num_frames.and_then(|n| Some(n as i16))), prompt: Set(h.prompt.trim().to_string()), negative_prompt: Set(h.negative_prompt.trim().to_string()), prompt_search: Set(process_prompt(&h.prompt)), @@ -355,6 +388,13 @@ impl ProjectsDb { tiled_diffusion: Set(h.tiled_diffusion), tea_cache: Set(h.tea_cache), cfg_zero_star: Set(h.cfg_zero_star), + upscaler_scale_factor: Set(match h.upscaler { + Some(_) => Some(match h.upscaler_scale_factor { + 2 => 2, + _ => 4, + }), + None => None, + }), wall_clock: Set(h.wall_clock.unwrap_or_default().and_utc()), // Handle missing wall_clock has_mask: Set(h.has_mask), has_depth: Set(h.has_depth), @@ -492,10 +532,15 @@ impl ProjectsDb { pub async fn list_images(&self, opts: ListImagesOptions) -> Result { // print!("ListImagesOptions: {:#?}\n", opts); + let direction = match opts.direction.as_deref() { + Some("asc") => Order::Asc, + _ => Order::Desc, + }; + let mut query = images::Entity::find() .join(JoinType::LeftJoin, images::Relation::Models.def()) .column_as(entity::models::Column::Filename, "model_file") - .order_by(images::Column::WallClock, Order::Desc); + .order_by(images::Column::WallClock, direction); if let Some(project_ids) = &opts.project_ids { if !project_ids.is_empty() { @@ -556,6 +601,24 @@ impl ProjectsDb { } } + // Apply show_image / show_video filters + let show_image = opts.show_image.unwrap_or(true); + let show_video = opts.show_video.unwrap_or(true); + + if !show_image && !show_video { + return Ok(ListImagesResult { + counts: None, + images: Some(vec![]), + total: 0, + }); + } + + if show_image && !show_video { + query = query.filter(images::Column::NumFrames.is_null()); + } else if !show_image && show_video { + query = query.filter(images::Column::NumFrames.is_not_null()); + } + if Some(true) == opts.count { let project_counts = query .select_only() @@ -566,15 +629,23 @@ impl ProjectsDb { .all(&self.db) .await?; - return Ok(ListImagesResult::Counts( - project_counts - .into_iter() - .map(|p| ImageCount { + let mut total: u64 = 0; + let counts = project_counts + .into_iter() + .map(|p| { + total += p.count as u64; + ImageCount { project_id: p.project_id, count: p.count, - }) - .collect(), - )); + } + }) + .collect(); + + return Ok(ListImagesResult { + counts: Some(counts), + images: None, + total, + }); } if let Some(skip) = opts.skip { @@ -586,24 +657,23 @@ impl ProjectsDb { } let _stmt = query.clone().build(self.db.get_database_backend()); - // println!("Query: {:#?}", stmt); - let count = query.clone().count(&self.db).await?; let result = query.into_model::().all(&self.db).await?; - Ok(ListImagesResult::Images(Paged { - items: result, + Ok(ListImagesResult { + images: Some(result), total: count, - })) + counts: None, + }) } - pub async fn list_watch_folders(&self) -> Result, DbErr> { - let folder = entity::watch_folders::Entity::find() - .into_model() + pub async fn list_watch_folders(&self) -> Result, DbErr> { + let folders = entity::watch_folders::Entity::find() + .order_by_asc(entity::watch_folders::Column::Path) .all(&self.db) .await?; - Ok(folder) + Ok(folders.into_iter().map(|f| f.into()).collect()) } // pub async fn get_project_folder( @@ -624,28 +694,17 @@ impl ProjectsDb { pub async fn add_watch_folder( &self, path: &str, - item_type: entity::enums::ItemType, recursive: bool, - ) -> Result { - let folder = entity::watch_folders::ActiveModel { + ) -> Result { + let model = entity::watch_folders::ActiveModel { path: Set(path.to_string()), - item_type: Set(item_type), recursive: Set(Some(recursive)), ..Default::default() - }; - let folder = entity::watch_folders::Entity::insert(folder) - .on_conflict( - OnConflict::columns([ - entity::watch_folders::Column::Path, - entity::watch_folders::Column::ItemType, - ]) - .value(entity::watch_folders::Column::Path, path) - .to_owned(), - ) - .exec_with_returning(&self.db) - .await?; + } + .insert(&self.db) + .await?; - Ok(folder) + Ok(model.into()) } pub async fn remove_watch_folders(&self, ids: Vec) -> Result<(), DbErr> { @@ -663,23 +722,27 @@ impl ProjectsDb { pub async fn update_watch_folder( &self, - id: i32, + id: i64, recursive: Option, last_updated: Option, - ) -> Result { - let folder = entity::watch_folders::Entity::find_by_id(id) - .one(&self.db) - .await?; - let mut folder: entity::watch_folders::ActiveModel = folder.unwrap().into(); - if let Some(recursive) = recursive { - folder.recursive = Set(Some(recursive)); + ) -> Result { + let mut model: entity::watch_folders::ActiveModel = + entity::watch_folders::Entity::find_by_id(id as i64) + .one(&self.db) + .await? + .unwrap() + .into(); + + if let Some(r) = recursive { + model.recursive = Set(Some(r)); } - if let Some(last_updated) = last_updated { - folder.last_updated = Set(Some(last_updated)); + + if let Some(lu) = last_updated { + model.last_updated = Set(Some(lu)); } - let folder: entity::watch_folders::Model = folder.update(&self.db).await?; - Ok(folder) + let model = model.update(&self.db).await?; + Ok(model.into()) } pub async fn update_exclude(&self, project_id: i32, exclude: bool) -> Result<(), DbErr> { @@ -697,19 +760,50 @@ impl ProjectsDb { project.update(&self.db).await?; if exclude { - println!("Excluding project {}", project_id); + log::debug!("Excluding project {}", project_id); // Remove all images associated with this project // Cascade delete will handle image_controls and image_loras let result = images::Entity::delete_many() .filter(images::Column::ProjectId.eq(project_id)) .exec(&self.db) .await?; - println!("Deleted {} images", result.rows_affected); + log::debug!("Deleted {} images", result.rows_affected); } Ok(()) } + pub async fn bulk_update_missing_on( + &self, + paths: Vec, + missing_on: Option, + ) -> Result<(), DbErr> { + if paths.is_empty() { + return Ok(()); + } + + // Look up project IDs from paths + let projects = projects::Entity::find() + .filter(projects::Column::Path.is_in(paths)) + .select_only() + .column(projects::Column::Id) + .into_tuple::() + .all(&self.db) + .await?; + + if projects.is_empty() { + return Ok(()); + } + + projects::Entity::update_many() + .col_expr(projects::Column::MissingOn, Expr::value(missing_on)) + .filter(projects::Column::Id.is_in(projects)) + .exec(&self.db) + .await?; + + Ok(()) + } + pub async fn rebuild_images_fts(&self) -> Result<(), sea_orm::DbErr> { self.db .execute_unprepared("INSERT INTO images_fts(images_fts) VALUES('rebuild')") @@ -736,6 +830,28 @@ impl ProjectsDb { Ok(dt_project::DTProject::get(&project_path).await.unwrap()) } + pub async fn get_clip(&self, image_id: i64) -> Result, String> { + let result: Option<(String, i64)> = images::Entity::find_by_id(image_id) + .join(JoinType::InnerJoin, images::Relation::Projects.def()) + .select_only() + .column(entity::projects::Column::Path) + .column(images::Column::NodeId) + .into_tuple() + .one(&self.db) + .await + .map_err(|e| e.to_string())?; + + let (project_path, node_id) = result.ok_or("Image or Project not found")?; + + let dt_project = DTProject::get(&project_path) + .await + .map_err(|e| e.to_string())?; + dt_project + .get_histories_from_clip(node_id) + .await + .map_err(|e| e.to_string()) + } + pub async fn update_models( &self, mut models: HashMap, @@ -937,61 +1053,6 @@ impl ProjectsDb { } } -#[derive(Debug, FromQueryResult, Serialize)] -pub struct ImageCount { - pub project_id: i64, - pub count: i64, -} - -#[derive(Debug, Serialize)] -pub enum ListImagesResult { - Counts(Vec), - Images(Paged), -} - -#[derive(Debug, Serialize, Clone)] -pub struct ModelExtra { - pub id: i64, - pub model_type: ModelType, - pub filename: String, - pub name: Option, - pub version: Option, - pub count: i64, -} - -#[derive(Debug, Serialize, Clone, Default)] -pub struct ListImagesOptions { - pub project_ids: Option>, - pub search: Option, - pub filters: Option>, - pub sort: Option, - pub direction: Option, - pub take: Option, - pub skip: Option, - pub count: Option, -} - -#[derive(Debug, FromQueryResult, Serialize)] -pub struct ProjectExtra { - pub id: i64, - pub path: String, - pub image_count: i64, - pub last_id: Option, - pub filesize: Option, - pub modified: Option, - pub excluded: bool, -} - -// #[derive(Serialize, Clone)] -// pub struct ScanProgress { -// pub projects_scanned: i32, -// pub projects_total: i32, -// pub project_final: i32, -// pub project_path: String, -// pub images_scanned: i32, -// pub images_total: i32, -// } - #[derive(Debug)] pub enum MixedError { SeaOrm(DbErr), @@ -1053,32 +1114,6 @@ impl From for String { } } -#[derive(Debug, FromQueryResult, Serialize)] -pub struct ImageExtra { - pub id: i64, - pub project_id: i64, - pub model_id: Option, - pub model_file: Option, - pub prompt: String, - pub negative_prompt: String, - pub preview_id: i64, - pub node_id: i64, - pub has_depth: bool, - pub has_pose: bool, - pub has_color: bool, - pub has_custom: bool, - pub has_scribble: bool, - pub has_shuffle: bool, - pub start_width: i32, - pub start_height: i32, -} - -#[derive(Debug, Serialize)] -pub struct Paged { - pub items: Vec, - pub total: u64, -} - type ModelTypeAndFile = (String, ModelType); struct NodeModelWeight { pub node_id: i64, diff --git a/src-tauri/src/projects_db/search.rs b/src-tauri/src/projects_db/search.rs index 9864b35..a29ecec 100644 --- a/src-tauri/src/projects_db/search.rs +++ b/src-tauri/src/projects_db/search.rs @@ -44,9 +44,6 @@ pub fn add_search(mut query: Select, search_text: &str) -> Selec remainder = process_prompt(&remainder); let terms: Vec<&str> = remainder.split_whitespace().collect(); - println!("terms: {:#?}", terms); - println!("phrases: {:#?}", phrases); - if !terms.is_empty() { let fts_query = terms.join(" OR "); diff --git a/src-tauri/src/projects_db/tensor_history.rs b/src-tauri/src/projects_db/tensor_history.rs index a3a2e5c..39bddcb 100644 --- a/src-tauri/src/projects_db/tensor_history.rs +++ b/src-tauri/src/projects_db/tensor_history.rs @@ -1,137 +1,17 @@ use chrono::{DateTime, NaiveDateTime}; // use entity::enums::Sampler; // Unused import -// use tauri::Emitter; // Unused import use super::tensor_history_mod::{Control, LoRA}; -// use crate::projects_db::{ListImagesResult, ModelExtra, ProjectExtra}; // Unused import +use crate::projects_db::dtos::tensor::{ + ModelAndWeight, TensorHistoryClip, TensorHistoryImport, TensorHistoryNode, +}; use crate::projects_db::tensor_history_generated::root_as_tensor_history_node; -#[derive(serde::Serialize, Debug, Clone)] -pub struct ModelAndWeight { - pub model: String, - pub weight: f32, -} - -#[derive(serde::Serialize, Debug)] -pub struct TensorHistoryImport { - pub lineage: i64, - pub logical_time: i64, - pub width: u16, - pub height: u16, - pub seed: u32, - pub steps: u32, - pub guidance_scale: f32, - pub strength: f32, - pub model: String, - pub wall_clock: Option, - pub sampler: i8, - pub hires_fix: bool, - pub upscaler: Option, - pub generated: bool, - pub controls: Vec, - pub loras: Vec, - pub preview_id: i64, - pub refiner_model: Option, - pub refiner_start: f32, - pub shift: f32, - pub tiled_decoding: bool, - pub tiled_diffusion: bool, - pub resolution_dependent_shift: bool, - pub tea_cache: bool, - pub prompt: String, - pub negative_prompt: String, - pub clip_id: i64, - pub index_in_a_clip: i32, - pub cfg_zero_star: bool, - // pub image_id: i64, - pub row_id: i64, - pub has_depth: bool, - pub has_pose: bool, - pub has_color: bool, - pub has_custom: bool, - pub has_scribble: bool, - pub has_shuffle: bool, - pub has_mask: bool, - // pub tensor_id: i64, - pub text_edits: i64, - pub text_lineage: i64, - // pub batch_size: u32, - // pub hires_fix_start_width: u16, - // pub hires_fix_start_height: u16, - // pub hires_fix_strength: f32, - // pub scale_factor: u16, - // pub image_guidance_scale: f32, - // pub seed_mode: String, - // pub clip_skip: u32, - // pub mask_blur: f32, - // pub face_restoration: Option, - // pub decode_with_attention: bool, - // pub hires_fix_decode_with_attention: bool, - // pub clip_weight: f32, - // pub negative_prompt_for_image_prior: bool, - // pub image_prior_steps: u32, - // pub data_stored: i32, - // pub content_offset_x: i32, - // pub content_offset_y: i32, - // pub scale_factor_by_120: i32, - // pub original_image_height: u32, - // pub original_image_width: u32, - // pub crop_top: i32, - // pub crop_left: i32, - // pub target_image_height: u32, - // pub target_image_width: u32, - // pub aesthetic_score: f32, - // pub negative_aesthetic_score: f32, - // pub zero_negative_prompt: bool, - // pub negative_original_image_height: u32, - // pub negative_original_image_width: u32, - // pub shuffle_data_stored: i32, - // pub fps_id: u32, - // pub motion_bucket_id: u32, - // pub cond_aug: f32, - // pub start_frame_cfg: f32, - // pub num_frames: u32, - // pub mask_blur_outset: i32, - // pub sharpness: f32, - // pub stage_2_steps: u32, - // pub stage_2_cfg: f32, - // pub stage_2_shift: f32, - // pub decoding_tile_width: u16, - // pub decoding_tile_height: u16, - // pub decoding_tile_overlap: u16, - // pub stochastic_sampling_gamma: f32, - // pub preserve_original_after_inpaint: bool, - // pub diffusion_tile_width: u16, - // pub diffusion_tile_height: u16, - // pub diffusion_tile_overlap: u16, - // pub upscaler_scale_factor: u8, - // pub script_session_id: u64, - // pub t5_text_encoder: bool, - // pub separate_clip_l: bool, - // pub clip_l_text: Option, - // pub separate_open_clip_g: bool, - // pub open_clip_g_text: Option, - // pub speed_up_with_guidance_embed: bool, - // pub guidance_embed: f32, - // pub profile_data: Vec, - // pub tea_cache_start: i32, - // pub tea_cache_end: i32, - // pub tea_cache_threshold: f32, - // pub separate_t5: bool, - // pub t5_text: Option, - // pub tea_cache_max_skip_steps: i32, - // pub causal_inference_enabled: bool, - // pub causal_inference: i32, - // pub causal_inference_pad: i32, - // pub cfg_zero_init_steps: i32, - // pub generation_time: f64, - // pub reason: i32, -} - impl TensorHistoryImport { pub fn new( blob: &[u8], row_id: i64, + tensor_id: String, has_depth: bool, has_pose: bool, has_color: bool, @@ -174,6 +54,7 @@ impl TensorHistoryImport { model: node.model().unwrap_or("").trim().to_string(), lineage: node.lineage(), preview_id: node.preview_id(), + tensor_id, row_id, controls, loras, @@ -183,6 +64,10 @@ impl TensorHistoryImport { wall_clock: wall_clock_to_datetime(node.wall_clock()), cfg_zero_star: node.cfg_zero_star(), clip_id: node.clip_id(), + num_frames: match node.clip_id() >= 0 { + true => Some(node.num_frames()), + false => None, + }, guidance_scale: node.guidance_scale(), hires_fix: node.hires_fix(), height: node.start_height(), @@ -201,6 +86,7 @@ impl TensorHistoryImport { width: node.start_width(), tea_cache: node.tea_cache(), upscaler: node.upscaler().and_then(|v| Some(v.trim().to_string())), + upscaler_scale_factor: node.upscaler_scale_factor(), has_depth, has_pose, has_color, @@ -219,116 +105,6 @@ impl TensorHistoryImport { * values are exactly as they are when stored in the project files, * with the exception of profile data which is not implemented */ -#[derive(serde::Serialize, Debug, Clone)] -pub struct TensorHistoryNode { - pub lineage: i64, - pub logical_time: i64, - pub start_width: u16, // - pub start_height: u16, // - pub seed: u32, // - pub steps: u32, // - pub guidance_scale: f32, // - pub strength: f32, // - pub model: Option, - pub tensor_id: i64, - pub mask_id: i64, - pub wall_clock: Option, - pub text_edits: i64, - pub text_lineage: i64, - pub batch_size: u32, - pub sampler: i8, // - pub hires_fix: bool, // - pub hires_fix_start_width: u16, // - pub hires_fix_start_height: u16, // - pub hires_fix_strength: f32, // - pub upscaler: Option, // - pub scale_factor: u16, - pub depth_map_id: i64, - pub generated: bool, - pub image_guidance_scale: f32, // - pub seed_mode: i8, - pub clip_skip: u32, - pub controls: Option>, - pub scribble_id: i64, - pub pose_id: i64, - pub loras: Option>, - pub color_palette_id: i64, - pub mask_blur: f32, - pub custom_id: i64, - pub face_restoration: Option, - pub clip_weight: f32, - pub negative_prompt_for_image_prior: bool, - pub image_prior_steps: u32, - pub data_stored: i32, - pub preview_id: i64, - pub content_offset_x: i32, - pub content_offset_y: i32, - pub scale_factor_by_120: i32, - pub refiner_model: Option, - pub original_image_height: u32, - pub original_image_width: u32, - pub crop_top: i32, - pub crop_left: i32, - pub target_image_height: u32, - pub target_image_width: u32, - pub aesthetic_score: f32, - pub negative_aesthetic_score: f32, - pub zero_negative_prompt: bool, - pub refiner_start: f32, - pub negative_original_image_height: u32, - pub negative_original_image_width: u32, - pub shuffle_data_stored: i32, - pub fps_id: u32, - pub motion_bucket_id: u32, - pub cond_aug: f32, - pub start_frame_cfg: f32, - pub num_frames: u32, - pub mask_blur_outset: i32, - pub sharpness: f32, - pub shift: f32, // - pub stage_2_steps: u32, - pub stage_2_cfg: f32, - pub stage_2_shift: f32, - pub tiled_decoding: bool, // - pub decoding_tile_width: u16, - pub decoding_tile_height: u16, - pub decoding_tile_overlap: u16, - pub stochastic_sampling_gamma: f32, - pub preserve_original_after_inpaint: bool, - pub tiled_diffusion: bool, // - pub diffusion_tile_width: u16, - pub diffusion_tile_height: u16, - pub diffusion_tile_overlap: u16, - pub upscaler_scale_factor: u8, - pub script_session_id: u64, - pub t5_text_encoder: bool, - pub separate_clip_l: bool, - pub clip_l_text: Option, - pub separate_open_clip_g: bool, - pub open_clip_g_text: Option, - pub speed_up_with_guidance_embed: bool, - pub guidance_embed: f32, // - pub resolution_dependent_shift: bool, // - // pub profile_data: Option>>, - pub tea_cache_start: i32, - pub tea_cache_end: i32, - pub tea_cache_threshold: f32, - pub tea_cache: bool, // - pub separate_t5: bool, - pub t5_text: Option, - pub tea_cache_max_skip_steps: i32, - pub text_prompt: Option, - pub negative_text_prompt: Option, - pub clip_id: i64, - pub index_in_a_clip: i32, - pub causal_inference_enabled: bool, - pub causal_inference: i32, - pub causal_inference_pad: i32, - pub cfg_zero_star: bool, - pub cfg_zero_init_steps: i32, - pub generation_time: f64, - pub reason: i32, -} impl TryFrom<&[u8]> for TensorHistoryNode { type Error = flatbuffers::InvalidFlatbuffer; @@ -471,3 +247,17 @@ fn wall_clock_to_datetime(value: i64) -> Option { None } } + +impl TensorHistoryClip { + pub fn new(row_id: i64, blob: &[u8], tensor_id: String) -> Result { + let node = root_as_tensor_history_node(blob) + .map_err(|e| format!("flatbuffers parse error: {:?}", e))?; + Ok(Self { + tensor_id, + preview_id: node.preview_id(), + clip_id: node.clip_id(), + index_in_a_clip: node.index_in_a_clip(), + row_id, + }) + } +} diff --git a/src-tauri/src/projects_db/tensor_history_tensor_data.rs b/src-tauri/src/projects_db/tensor_history_tensor_data.rs new file mode 100644 index 0000000..be1730e --- /dev/null +++ b/src-tauri/src/projects_db/tensor_history_tensor_data.rs @@ -0,0 +1,33 @@ +use anyhow::Result; +use sqlx::{sqlite::SqliteRow, FromRow, Row}; + +#[derive(Debug)] +pub struct TensorHistoryTensorData { + pub node_id: i64, + pub lineage: i64, + pub logical_time: i64, + pub td_index: i64, + pub node_data: Vec, + pub tensor_data: Vec, +} + +impl<'r> FromRow<'r, SqliteRow> for TensorHistoryTensorData { + fn from_row(row: &SqliteRow) -> Result { + let node_id: i64 = row.try_get("rowid")?; + let lineage: i64 = row.try_get("lineage")?; + let logical_time: i64 = row.try_get("logical_time")?; + let td_index: i64 = row.try_get("td_index")?; + + let node_data: Vec = row.try_get("node_data")?; + let tensor_data: Vec = row.try_get("tensor_data")?; + + Ok(Self { + node_id, + lineage, + logical_time, + td_index, + node_data, + tensor_data, + }) + } +} diff --git a/src-tauri/src/projects_db/tensors.rs b/src-tauri/src/projects_db/tensors.rs index 2e34cf9..d799b14 100644 --- a/src-tauri/src/projects_db/tensors.rs +++ b/src-tauri/src/projects_db/tensors.rs @@ -5,13 +5,13 @@ use fpzip_sys::*; use image::GrayImage; use png::{BitDepth, ColorType, Encoder}; + use std::ffi::c_void; use std::io::Cursor; use std::io::Read; -use crate::projects_db::dt_project::TensorRaw; +use crate::projects_db::dtos::tensor::{TensorRaw, TensorHistoryNode}; use crate::projects_db::metadata::DrawThingsMetadata; -use crate::projects_db::tensor_history::TensorHistoryNode; // const HEADER_SIZE: usize = 68; // const FPZIP_MAGIC: u32 = 1012247; diff --git a/src-tauri/src/projects_db/text_history.rs b/src-tauri/src/projects_db/text_history.rs index 26a4997..5ac268b 100644 --- a/src-tauri/src/projects_db/text_history.rs +++ b/src-tauri/src/projects_db/text_history.rs @@ -1,12 +1,8 @@ use super::fbs; -use serde::{Deserialize, Serialize}; +use crate::projects_db::dtos::text::{TextType, TextRange, TextModification, TextHistoryNode}; +use serde::Serialize; use std::sync::Mutex; -#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)] -pub enum TextType { - PositiveText, - NegativeText, -} impl From for TextType { fn from(fb: fbs::TextType) -> Self { @@ -18,11 +14,6 @@ impl From for TextType { } } -#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Default)] -pub struct TextRange { - pub location: i32, - pub length: i32, -} impl From<&fbs::TextRange> for TextRange { fn from(fb: &fbs::TextRange) -> Self { @@ -33,12 +24,6 @@ impl From<&fbs::TextRange> for TextRange { } } -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] -pub struct TextModification { - pub modification_type: TextType, - pub range: TextRange, - pub text: String, -} impl TryFrom> for TextModification { type Error = flatbuffers::InvalidFlatbuffer; @@ -52,15 +37,6 @@ impl TryFrom> for TextModification { } } -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] -pub struct TextHistoryNode { - pub lineage: i64, - pub logical_time: i64, - pub start_edits: i64, - pub start_positive_text: String, - pub start_negative_text: String, - pub modifications: Vec, -} impl TryFrom<&[u8]> for TextHistoryNode { type Error = flatbuffers::InvalidFlatbuffer; diff --git a/src-tauri/src/projects_db/text_history_sample.json b/src-tauri/src/projects_db/text_history_sample.json new file mode 100644 index 0000000..dab13c3 --- /dev/null +++ b/src-tauri/src/projects_db/text_history_sample.json @@ -0,0 +1,2836 @@ +[ + { + "lineage": 2, + "logical_time": 0, + "start_edits": 0, + "start_positive_text": "", + "start_negative_text": "", + "modifications": [ + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 0 + }, + "text": "war in space, lasers, spacestation in space, people, futuristic, planet outside window, unreal engine, octane render, bokeh, vray, houdini render, quixel megascans, arnold render, 8k uhd, raytracing, cgi, lumen reflections, cgsociety, ultra realistic, 100mm, film photography, dslr, cinema4d, studio quality, film grain, trending on artstation, trending on cgsociety" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 366 + }, + "text": "3d fluffy llama, closeup cute and adorable, cute big circular reflective eyes, long fuzzy fur, pixar render, unreal engine cinematic smooth, intricate detail, cinematic" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 168 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 0 + }, + "text": "O" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 2, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 3, + "length": 0 + }, + "text": "g" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 4, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 5, + "length": 0 + }, + "text": "n" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 7, + "length": 0 + }, + "text": "l" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 8, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": "m" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 0 + }, + "text": "g" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 14 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 0 + }, + "text": "T" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 2, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 3, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 4, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 5, + "length": 0 + }, + "text": "f" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 0 + }, + "text": "y" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 7, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 8, + "length": 0 + }, + "text": "n" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 0 + }, + "text": "g" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 0 + }, + "text": "d" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": "n" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 0 + }, + "text": "o" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 15, + "length": 0 + }, + "text": "s" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 16, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "u" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 18, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 19 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 0 + }, + "text": "n" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 2, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 3, + "length": 0 + }, + "text": "u" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 4, + "length": 0 + }, + "text": "g" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 5, + "length": 0 + }, + "text": "l" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 0 + }, + "text": "y" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 7, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 8, + "length": 0 + }, + "text": "t" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 0 + }, + "text": "u" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 0 + }, + "text": "k" + } + ] + }, + { + "lineage": 2, + "logical_time": 1, + "start_edits": 50, + "start_positive_text": "an ugly turke", + "start_negative_text": "", + "modifications": [ + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": "y" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 15, + "length": 0 + }, + "text": "(" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 16, + "length": 0 + }, + "text": "#" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "1" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 18, + "length": 0 + }, + "text": ")" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "2" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 13 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 0 + }, + "text": "s" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 0 + }, + "text": "w" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 2, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 3, + "length": 0 + }, + "text": "m" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 4, + "length": 0 + }, + "text": "p" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 5, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 0 + }, + "text": "c" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 7, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 8, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": "u" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": "t" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 0 + }, + "text": "u" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "3" + } + ] + }, + { + "lineage": 5, + "logical_time": 1, + "start_edits": 50, + "start_positive_text": "an ugly turke", + "start_negative_text": "", + "modifications": [ + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": "y" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 15, + "length": 0 + }, + "text": "(" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 16, + "length": 0 + }, + "text": "#" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "1" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 18, + "length": 0 + }, + "text": ")" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "2" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 3, + "length": 12 + }, + "text": "b" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 4, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 5, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 0 + }, + "text": "u" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 7, + "length": 0 + }, + "text": "t" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 8, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 0 + }, + "text": "f" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": "u" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 0 + }, + "text": "l" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 15, + "length": 0 + }, + "text": "g" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 16, + "length": 0 + }, + "text": "l" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 18, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 21, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 21, + "length": 0 + }, + "text": "3" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 2, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 0 + }, + "text": " " + } + ] + }, + { + "lineage": 3, + "logical_time": 1, + "start_edits": 50, + "start_positive_text": "an ugly turke", + "start_negative_text": "", + "modifications": [ + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": "y" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 15, + "length": 0 + }, + "text": "(" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 16, + "length": 0 + }, + "text": "#" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "1" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 18, + "length": 0 + }, + "text": ")" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "2" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 13 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 0 + }, + "text": "s" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 0 + }, + "text": "w" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 2, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 3, + "length": 0 + }, + "text": "m" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 4, + "length": 0 + }, + "text": "p" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 5, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 0 + }, + "text": "c" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 7, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 8, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": "u" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": "t" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 0 + }, + "text": "u" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "3" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "4" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 15 + }, + "text": "h" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 2, + "length": 0 + }, + "text": "p" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 3, + "length": 0 + }, + "text": "p" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 4, + "length": 0 + }, + "text": "y" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 5, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 0 + }, + "text": "d" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 7, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 8, + "length": 0 + }, + "text": "n" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 0 + }, + "text": "o" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": "s" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 0 + }, + "text": "u" + } + ] + }, + { + "lineage": 3, + "logical_time": 2, + "start_edits": 100, + "start_positive_text": "happy dinosaur(#4)", + "start_negative_text": "", + "modifications": [ + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 0 + }, + "text": " " + } + ] + }, + { + "lineage": 4, + "logical_time": 1, + "start_edits": 50, + "start_positive_text": "an ugly turke", + "start_negative_text": "", + "modifications": [ + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": "y" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 15, + "length": 0 + }, + "text": "(" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 16, + "length": 0 + }, + "text": "#" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "1" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 18, + "length": 0 + }, + "text": ")" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 19 + }, + "text": "m" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 2, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 3, + "length": 0 + }, + "text": "t" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 4, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 5, + "length": 0 + }, + "text": "m" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 0 + }, + "text": "o" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 7, + "length": 0 + }, + "text": "n" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 8, + "length": 0 + }, + "text": "s" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 0 + }, + "text": "t" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": "(" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 0 + }, + "text": "#" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 15, + "length": 0 + }, + "text": "2" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 16, + "length": 0 + }, + "text": ")" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 15, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 0 + }, + "text": "#" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 15, + "length": 0 + }, + "text": "7" + } + ] + }, + { + "lineage": 6, + "logical_time": 1, + "start_edits": 50, + "start_positive_text": "an ugly turke", + "start_negative_text": "", + "modifications": [ + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": "y" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 15, + "length": 0 + }, + "text": "(" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 16, + "length": 0 + }, + "text": "#" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "1" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 18, + "length": 0 + }, + "text": ")" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "2" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 3, + "length": 12 + }, + "text": "b" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 4, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 5, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 0 + }, + "text": "u" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 7, + "length": 0 + }, + "text": "t" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 8, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 0 + }, + "text": "f" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": "u" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 0 + }, + "text": "l" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 15, + "length": 0 + }, + "text": "g" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 16, + "length": 0 + }, + "text": "l" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 18, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 21, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 21, + "length": 0 + }, + "text": "3" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 2, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 2, + "length": 9 + }, + "text": "s" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 3, + "length": 0 + }, + "text": "c" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 4, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 5, + "length": 0 + }, + "text": "l" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 7, + "length": 0 + }, + "text": "y" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 2 + }, + "text": "f" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 0 + }, + "text": "s" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 0 + }, + "text": "h" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 3 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 16, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 16, + "length": 0 + }, + "text": "5" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 7, + "length": 0 + }, + "text": "d" + } + ] + }, + { + "lineage": 7, + "logical_time": 1, + "start_edits": 50, + "start_positive_text": "an ugly turke", + "start_negative_text": "", + "modifications": [ + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": "y" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 15, + "length": 0 + }, + "text": "(" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 16, + "length": 0 + }, + "text": "#" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "1" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 18, + "length": 0 + }, + "text": ")" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "2" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "3" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 15 + }, + "text": "b" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 2, + "length": 0 + }, + "text": "g" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 3, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 4, + "length": 0 + }, + "text": "t" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 5, + "length": 0 + }, + "text": "o" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 0 + }, + "text": "n" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 7, + "length": 0 + }, + "text": "g" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 8, + "length": 0 + }, + "text": "u" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": " " + } + ] + }, + { + "lineage": 8, + "logical_time": 0, + "start_edits": 0, + "start_positive_text": "", + "start_negative_text": "", + "modifications": [ + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 0 + }, + "text": "war in space, lasers, spacestation in space, people, futuristic, planet outside window, unreal engine, octane render, bokeh, vray, houdini render, quixel megascans, arnold render, 8k uhd, raytracing, cgi, lumen reflections, cgsociety, ultra realistic, 100mm, film photography, dslr, cinema4d, studio quality, film grain, trending on artstation, trending on cgsociety" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 366 + }, + "text": "3d fluffy llama, closeup cute and adorable, cute big circular reflective eyes, long fuzzy fur, pixar render, unreal engine cinematic smooth, intricate detail, cinematic" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 168 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 0 + }, + "text": "O" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 2, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 3, + "length": 0 + }, + "text": "g" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 4, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 5, + "length": 0 + }, + "text": "n" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 7, + "length": 0 + }, + "text": "l" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 8, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": "m" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 0 + }, + "text": "g" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 14 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 0 + }, + "text": "T" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 2, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 3, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 4, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 5, + "length": 0 + }, + "text": "f" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 0 + }, + "text": "y" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 7, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 8, + "length": 0 + }, + "text": "n" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 0 + }, + "text": "g" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 0 + }, + "text": "d" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": "n" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 0 + }, + "text": "o" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 15, + "length": 0 + }, + "text": "s" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 16, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "u" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 18, + "length": 0 + }, + "text": "r" + }, + { + "modification_type": "NegativeText", + "range": { + "location": 0, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 18, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 16, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 15, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 1 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 13 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 0, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 1, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 2, + "length": 0 + }, + "text": "b" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 3, + "length": 0 + }, + "text": "r" + } + ] + }, + { + "lineage": 8, + "logical_time": 1, + "start_edits": 50, + "start_positive_text": "a bro", + "start_negative_text": " ", + "modifications": [ + { + "modification_type": "PositiveText", + "range": { + "location": 5, + "length": 0 + }, + "text": "w" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 6, + "length": 0 + }, + "text": "n" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 7, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 8, + "length": 0 + }, + "text": "f" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 9, + "length": 0 + }, + "text": "u" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 10, + "length": 0 + }, + "text": "z" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 11, + "length": 0 + }, + "text": "z" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 12, + "length": 0 + }, + "text": "y" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 13, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 14, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 15, + "length": 0 + }, + "text": "l" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 16, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 17, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 18, + "length": 0 + }, + "text": "n" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 19, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 20, + "length": 0 + }, + "text": "w" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 21, + "length": 0 + }, + "text": "i" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 22, + "length": 0 + }, + "text": "t" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 23, + "length": 0 + }, + "text": "h" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 24, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 25, + "length": 0 + }, + "text": "o" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 26, + "length": 0 + }, + "text": "n" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 27, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 28, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 29, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 30, + "length": 0 + }, + "text": "y" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 31, + "length": 0 + }, + "text": "e" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 24, + "length": 8 + }, + "text": "" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 24, + "length": 0 + }, + "text": "o" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 25, + "length": 0 + }, + "text": "u" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 26, + "length": 0 + }, + "text": "t" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 27, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 28, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 29, + "length": 0 + }, + "text": " " + }, + { + "modification_type": "PositiveText", + "range": { + "location": 30, + "length": 0 + }, + "text": "f" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 31, + "length": 0 + }, + "text": "a" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 32, + "length": 0 + }, + "text": "c" + }, + { + "modification_type": "PositiveText", + "range": { + "location": 33, + "length": 0 + }, + "text": "e" + } + ] + } +] \ No newline at end of file diff --git a/src-tauri/src/swift/FolderPicker.swift b/src-tauri/src/swift/FolderPicker.swift new file mode 100644 index 0000000..bfb1576 --- /dev/null +++ b/src-tauri/src/swift/FolderPicker.swift @@ -0,0 +1,116 @@ +import Cocoa +import Foundation + +@_cdecl("open_dt_folder_picker") +public func open_dt_folder_picker(defaultPath: UnsafePointer?) -> UnsafeMutablePointer? { + var resultString: UnsafeMutablePointer? = nil + + DispatchQueue.main.sync { + let openPanel = NSOpenPanel() + openPanel.canChooseDirectories = true + openPanel.canChooseFiles = false + openPanel.allowsMultipleSelection = false + openPanel.prompt = "Select Documents folder" + + // Suggest the standard path or the provided default + if let defaultPath = defaultPath, + let pathString = String(validatingUTF8: defaultPath) { + openPanel.directoryURL = URL(fileURLWithPath: pathString) + } else { + let homeDir = FileManager.default.homeDirectoryForCurrentUser + let suggestion = homeDir.appendingPathComponent("Library/Containers/com.liuliu.draw-things/Data/Documents") + openPanel.directoryURL = suggestion + } + + if openPanel.runModal() == .OK { + if let url = openPanel.url { + do { + let bookmarkData = try url.bookmarkData( + options: .withSecurityScope, + includingResourceValuesForKeys: nil, + relativeTo: nil + ) + + let base64String = bookmarkData.base64EncodedString() + let path = url.path + let result = "\(path)|\(base64String)" + resultString = strdup(result) + } catch { + print("Failed to create bookmark: \(error)") + } + } + } + } + + return resultString +} + +@_cdecl("free_string_ptr") +public func free_string_ptr(ptr: UnsafeMutablePointer?) { + guard let ptr = ptr else { return } + free(ptr) +} + +class BookmarkManager { + static let shared = BookmarkManager() + var activeBookmarks: [String: URL] = [:] +} + +@_cdecl("start_accessing_security_scoped_resource") +public func start_accessing_security_scoped_resource(bookmarkBase64: UnsafePointer?) -> UnsafeMutablePointer? { + guard let bookmarkBase64 = bookmarkBase64, + let base64String = String(validatingUTF8: bookmarkBase64), + let data = Data(base64Encoded: base64String) else { + return nil + } + + // Check if we are already accessing this bookmark (via simple string key lookup) + // In a robust implementation, we might resolve first to check equality, but string key is sufficient for this simple cache. + if let existingUrl = BookmarkManager.shared.activeBookmarks[base64String] { + return strdup(existingUrl.path) + } + + do { + var isStale = false + let url = try URL(resolvingBookmarkData: data, + options: .withSecurityScope, + relativeTo: nil, + bookmarkDataIsStale: &isStale) + + if isStale { + print("Bookmark is stale") + // In some cases we might want to re-save it, but for now we just proceed. + } + + if url.startAccessingSecurityScopedResource() { + BookmarkManager.shared.activeBookmarks[base64String] = url + return strdup(url.path) + } else { + print("Failed to start accessing security scoped resource") + return nil + } + } catch { + print("Error resolving bookmark: \(error)") + return nil + } +} + +@_cdecl("stop_accessing_security_scoped_resource") +public func stop_accessing_security_scoped_resource(bookmarkBase64: UnsafePointer?) { + guard let bookmarkBase64 = bookmarkBase64, + let base64String = String(validatingUTF8: bookmarkBase64) else { + return + } + + if let url = BookmarkManager.shared.activeBookmarks.removeValue(forKey: base64String) { + url.stopAccessingSecurityScopedResource() + } +} + +@_cdecl("stop_all_security_scoped_resources") +public func stop_all_security_scoped_resources() { + for (_, url) in BookmarkManager.shared.activeBookmarks { + url.stopAccessingSecurityScopedResource() + } + BookmarkManager.shared.activeBookmarks.removeAll() +} diff --git a/src-tauri/src/vid.rs b/src-tauri/src/vid.rs new file mode 100644 index 0000000..015c20c --- /dev/null +++ b/src-tauri/src/vid.rs @@ -0,0 +1,708 @@ +use regex::Regex; +use sea_orm::{EntityTrait, JoinType, QuerySelect, RelationTrait}; +use serde::{Deserialize, Serialize}; +use std::io::{BufRead, BufReader}; +use std::process::{Command, Stdio}; +use std::{fs, path::PathBuf}; +use tauri::{Emitter, Manager}; + +use crate::projects_db::{decode_tensor, DTProject, ProjectsDb}; + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FramesExportOpts { + pub image_id: i64, + pub output_dir: String, + pub use_tensor: bool, + pub filename_pattern: String, + pub clip_number: Option, + pub start_frame: Option, +} + +#[tauri::command] +pub async fn save_all_clip_frames( + app: tauri::AppHandle, + opts: FramesExportOpts, +) -> Result<(usize, String), String> { + let projects_db = ProjectsDb::get_or_init(&app).await?; + + let result: Option<(String, i64, i64)> = entity::images::Entity::find_by_id(opts.image_id) + .join( + JoinType::InnerJoin, + entity::images::Relation::Projects.def(), + ) + .select_only() + .column(entity::projects::Column::Path) + .column(entity::images::Column::NodeId) + .column(entity::images::Column::ProjectId) + .into_tuple() + .one(&projects_db.db) + .await + .map_err(|e| e.to_string())?; + + let (project_path, node_id, _project_db_id) = result.ok_or("Image or Project not found")?; + + // 2. Fetch Clip Frames + let dt_project = DTProject::get(&project_path) + .await + .map_err(|e| e.to_string())?; + let frames = dt_project + .get_histories_from_clip(node_id) + .await + .map_err(|e| e.to_string())?; + + if frames.is_empty() { + return Err("No frames found for this clip".to_string()); + } + + let output_dir = PathBuf::from(&opts.output_dir); + fs::create_dir_all(&output_dir).map_err(|e| e.to_string())?; + + let mut name_gen = NameGen::new(NameOpts { + pattern: opts.filename_pattern, + clip_number: opts.clip_number, + first: opts.start_frame, + count: frames.len() as u32, + }); + + let total = frames.len(); + match opts.use_tensor { + true => { + for (i, frame) in frames.iter().enumerate() { + let name = name_gen.next().unwrap(); + let tensor = dt_project + .get_tensor_raw(&frame.tensor_id) + .await + .map_err(|e| e.to_string())?; + let png = decode_tensor(tensor, true, None, None).map_err(|e| e.to_string())?; + let file_path = output_dir.join(name); + fs::write(&file_path, png).map_err(|e| e.to_string())?; + + let _ = app.emit( + "export_frames_progress", + ExportProgress { + current: i + 1, + total, + msg: "Extracting frames...".to_string(), + }, + ); + } + } + false => { + for (i, frame) in frames.iter().enumerate() { + let name = name_gen.next().unwrap(); + let thumb_data = dt_project + .get_thumb(frame.preview_id) + .await + .map_err(|e| e.to_string())?; + + let thumb_data = crate::projects_db::extract_jpeg_slice(&thumb_data) + .ok_or("Failed to extract JPEG slice".to_string())?; + + let file_path = output_dir.join(name); + fs::write(&file_path, thumb_data).map_err(|e| e.to_string())?; + + let _ = app.emit( + "export_frames_progress", + ExportProgress { + current: i + 1, + total, + msg: "Extracting frames...".to_string(), + }, + ); + } + } + } + + let _ = app.emit( + "export_frames_progress", + ExportProgress { + current: total, + total, + msg: "Done".to_string(), + }, + ); + + Ok((total, output_dir.to_str().unwrap().to_string())) +} + +#[derive(Clone, Serialize, Debug)] +#[serde(rename_all = "camelCase")] +struct ExportProgress { + current: usize, + total: usize, + msg: String, +} + +#[derive(Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct VideoExportOpts { + image_id: i64, + output_file: String, + use_tensor: bool, + fps: u8, + out_fps: Option, + width: Option, + height: Option, +} + +#[tauri::command] +pub async fn create_video_from_frames( + app: tauri::AppHandle, + opts: VideoExportOpts, +) -> Result { + // ------------------------------------------------- + // Prepare temp dir + // ------------------------------------------------- + let app_data_dir = app.path().app_data_dir().unwrap(); + let ffmpeg_path = app_data_dir.join("bin").join("ffmpeg"); + let temp_dir = app_data_dir.join("temp_video_frames"); + + if !ffmpeg_path.exists() { + return Err("ffmpeg not found".to_string()); + } + + if temp_dir.exists() { + fs::remove_dir_all(&temp_dir).map_err(|e| e.to_string())?; + } + fs::create_dir_all(&temp_dir).map_err(|e| e.to_string())?; + + // ------------------------------------------------- + // Ensure output directory exists + // ------------------------------------------------- + let output_file = PathBuf::from(&opts.output_file); + + if let Some(parent) = output_file.parent() { + fs::create_dir_all(parent).map_err(|e| e.to_string())?; + } + + let extension = if opts.use_tensor { "png" } else { "jpg" }; + + // ------------------------------------------------- + // Export frames first + // ------------------------------------------------- + let (frame_count, _) = save_all_clip_frames( + app.clone(), + FramesExportOpts { + image_id: opts.image_id, + output_dir: temp_dir.to_str().unwrap().to_string(), + use_tensor: opts.use_tensor, + filename_pattern: format!("frame_####.{}", extension), + clip_number: None, + start_frame: None, + }, + ) + .await?; + + let out_fps = opts.out_fps.unwrap_or(opts.fps); + let interpolate = out_fps != opts.fps; + + let total_frames = match interpolate { + true => frame_count as f64 / opts.fps as f64 * out_fps as f64, + false => frame_count as f64, + }; + + let _ = app.emit( + "export_video_progress", + ExportProgress { + current: 0, + total: 100, + msg: "Encoding video…".to_string(), + }, + ); + + // ------------------------------------------------- + // Optional scale filter + // ------------------------------------------------- + let interp = if interpolate { + format!(",minterpolate=fps={out_fps}:mi_mode=mci:mc_mode=aobmc:me_mode=bidir:vsbmc=1") + } else { + "".to_string() + }; + + let vf_arg = if let (Some(w), Some(h)) = (opts.width, opts.height) { + if w > 0 && h > 0 { + Some(format!( + "scale={w}:{h}:force_original_aspect_ratio=decrease:force_divisible_by=2,\ + pad={w}:{h}:(ow-iw)/2:(oh-ih)/2{interp}" + )) + } else { + None + } + } else { + None + }; + + // ------------------------------------------------- + // Build ffmpeg command + // ------------------------------------------------- + let mut cmd = Command::new(ffmpeg_path); + + cmd.args([ + "-y", + "-framerate", + &opts.fps.to_string(), + "-i", + temp_dir + .join(format!("frame_%04d.{}", extension)) + .to_str() + .unwrap(), + "-progress", + "pipe:1", + "-nostats", + "-stats_period", + "0.2", + ]); + + if let Some(vf) = &vf_arg { + cmd.args(["-vf", vf]); + } + + cmd.args([ + "-color_range", + "pc", + "-colorspace", + "bt709", + "-color_primaries", + "bt709", + "-color_trc", + "bt709", + ]); + + cmd.args([ + "-c:v", + "libx264", + "-pix_fmt", + "yuv420p", + "-preset", + "medium", + "-crf", + "18", + output_file.to_str().unwrap(), + ]); + + cmd.stdout(Stdio::piped()); + + // ------------------------------------------------- + // Spawn and read progress + // ------------------------------------------------- + let mut child = cmd.spawn().map_err(|e| e.to_string())?; + + let stdout = child.stdout.take().unwrap(); + let reader = BufReader::new(stdout); + + for line in reader.lines() { + let line = line.map_err(|e| e.to_string())?; + + // frame=### + if let Some(f) = line.strip_prefix("frame=") { + if let Ok(frame) = f.trim().parse::() { + let pct = (frame / total_frames).clamp(0.0, 1.0); + let percent = (pct * 100.0).round() as usize; + + let _ = app.emit( + "export_video_progress", + ExportProgress { + current: percent, + total: 100, + msg: format!("Encoding… {}%", percent), + }, + ); + } + } + } + + // ------------------------------------------------- + // Wait for finish + // ------------------------------------------------- + let status = child.wait().map_err(|e| e.to_string())?; + + if !status.success() { + return Err("FFmpeg failed to generate video".to_string()); + } + + let _ = app.emit( + "export_video_progress", + ExportProgress { + current: 100, + total: 100, + msg: "Done".to_string(), + }, + ); + + Ok(output_file.to_string_lossy().to_string()) +} + +/// returns the highest existing clip id and frame number for the given pattern +/// -1 indicates no matches +pub fn check_files(dir: &str, pattern: &str) -> Result<(i32, i32), String> { + log::debug!("checking {} for {}", dir, pattern); + let matcher = get_matcher(pattern); + + let mut max_clip: i32 = -1; + let mut max_frame: i32 = -1; + + let entries = fs::read_dir(dir).map_err(|e| e.to_string())?; + + for entry in entries { + if let Ok(entry) = entry { + let name = entry.file_name().to_string_lossy().into_owned(); + let caps = matcher.captures(&name); + if let Some(caps) = caps { + if let Some(clip) = caps.name("clip") { + if let Ok(clip) = clip.as_str().parse::() { + if clip > max_clip { + max_clip = clip; + } + } + } + if let Some(frame) = caps.name("frame") { + if let Ok(frame) = frame.as_str().parse::() { + if frame > max_frame { + max_frame = frame; + } + } + } + } + } + } + Ok((max_clip, max_frame)) +} + +/// takes a filename pattern and returns a regex that matches the pattern +/// ### will be replaced with capture group \d+ for frame number +/// %% will be replaced with capture group \d+ for clip number +pub fn get_matcher(filename_pattern: &str) -> Regex { + let mut pattern = regex::escape(filename_pattern); + pattern = format!("^{}$", pattern); + let matcher_frame: Regex = Regex::new(r"(\\#)+").unwrap(); + let matcher_clip: Regex = Regex::new(r"%+").unwrap(); + let pattern = matcher_frame.replace_all(&pattern, "(?P\\d+)"); + let pattern = matcher_clip.replace_all(&pattern, "(?P\\d+)"); + Regex::new(&pattern).unwrap() +} + +#[derive(Clone, Serialize, Deserialize, Debug, Default)] +#[serde(rename_all = "camelCase")] +pub struct CheckPatternResult { + valid: bool, + invalid_reason: Option, + output_dir_dne: bool, + first_safe_index: u32, + clip_id: u32, + examples: Vec, +} + +#[tauri::command] +pub fn check_pattern( + pattern: String, + dir: String, + num_frames: u32, +) -> Result { + let mut result = CheckPatternResult { + valid: false, + clip_id: 1, + first_safe_index: 0, + ..Default::default() + }; + + if !is_valid_filename(&pattern) { + result.invalid_reason = Some("Invalid characters in filename pattern".to_string()); + return Ok(result); + } + + let matcher_frame: Regex = Regex::new(r"#+").unwrap(); + let matcher_clip: Regex = Regex::new(r"%+").unwrap(); + + let mut frame_iter = matcher_frame.find_iter(&pattern); + let mut clip_iter = matcher_clip.find_iter(&pattern); + + let frame_token = frame_iter.next(); + if frame_token.is_none() || frame_iter.next().is_some() { + result.invalid_reason = Some( + "Filename pattern must have one frame token (one or more #'s in a row)".to_string(), + ); + return Ok(result); + } + + let clip_token = clip_iter.next(); + if clip_iter.next().is_some() { + result.invalid_reason = Some( + "Filename pattern can only have at most one clip token (one or more %'s in a row)" + .to_string(), + ); + return Ok(result); + } + + result.valid = true; + + match PathBuf::from(&dir).exists() { + false => result.output_dir_dne = true, + true => { + let (max_clip, max_frame) = check_files(&dir, &pattern).unwrap(); + result.clip_id = (max_clip.max(0) + 1) as u32; + result.first_safe_index = match clip_token.is_some() { + true => 1, + false => (max_frame.max(-1) + 1) as u32, + }; + } + } + + let mut name_gen = NameGen::new(NameOpts { + pattern: pattern.clone(), + clip_number: Some(result.clip_id), + first: Some(result.first_safe_index), + count: num_frames, + }); + let first = name_gen.next().unwrap_or_default(); + let second = name_gen.next().unwrap_or_default(); + let last = name_gen.last().unwrap_or_default(); + result.examples = [first, second, "...".to_string(), last].to_vec(); + Ok(result) +} + +#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct NameOpts { + pattern: String, + clip_number: Option, + first: Option, + count: u32, +} + +#[derive(Clone)] +struct NameGen { + prefix: String, + suffix: String, + pad: u8, + index: i64, + first: i64, + count: i64, +} + +impl NameGen { + pub fn new(opts: NameOpts) -> Self { + let mut pattern = opts.pattern; + + // 1. Replace Clip Number if present + if let Some(clip) = opts.clip_number { + let matcher_clip: Regex = Regex::new(r"%+").unwrap(); + if let Some(mat) = matcher_clip.find(&pattern) { + let pad = mat.len(); + let clip_str = format!("{:0width$}", clip, width = pad); + pattern = matcher_clip.replace(&pattern, clip_str).to_string(); + } + } + + // 2. Parse Frame Number Pattern + let matcher_frame: Regex = Regex::new(r"#+").unwrap(); + let (prefix, suffix, pad) = if let Some(mat) = matcher_frame.find(&pattern) { + let prefix = pattern[..mat.start()].to_string(); + let suffix = pattern[mat.end()..].to_string(); + let pad = mat.len() as u8; + (prefix, suffix, pad) + } else { + // Fallback if no frame pattern found (though logic usually implies there should be one for iteration) + // If no ###, we might just append numbers? Or maybe we assume prefix is everything? + // Per requirements: "prefix should be everything before #, suffix is everything after" + // If no #, then it's effectively a static name? But this is an iterator. + // Let's assume valid pattern has #. If not, behave safely. + (pattern.clone(), "".to_string(), 0) + }; + + Self { + prefix, + suffix, + pad, + index: opts.first.unwrap_or(0) as i64 - 1, + first: opts.first.unwrap_or(0) as i64, + count: opts.count as i64, + } + } + + pub fn copy(&self) -> Self { + let mut copy = self.clone(); + copy.index = self.first as i64 - 1; + copy + } +} + +impl Iterator for NameGen { + type Item = String; + + fn next(&mut self) -> Option { + self.index += 1; + if self.index >= self.first + self.count { + return None; + } + Some(format!( + "{}{:0width$}{}", + self.prefix, + self.index, + self.suffix, + width = self.pad as usize + )) + } +} + +fn is_valid_filename(pattern: &str) -> bool { + if pattern.is_empty() { + return false; + } + + if pattern.chars().any(|c| { + c.is_control() || matches!(c, '<' | '>' | ':' | '"' | '|' | '?' | '*' | '/' | '\\') + }) { + return false; + } + + // forbid "." or ".." + if pattern == "." || pattern == ".." { + return false; + } + + // forbid trailing dot or space (Windows) + if pattern.ends_with('.') || pattern.ends_with(' ') { + return false; + } + + true +} + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::Once; + use std::sync::OnceLock; + static PATH: OnceLock = OnceLock::new(); + static FILES_INIT: Once = Once::new(); + fn initialize_files() { + FILES_INIT.call_once(|| { + // create and set the test directory + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + path.push("test_data"); + PATH.set(path).unwrap(); + fs::create_dir_all(&PATH.get().unwrap()).unwrap(); + + // create test files + fs::write(PATH.get().unwrap().join("clip_001_frame_0001.png"), "").unwrap(); + fs::write(PATH.get().unwrap().join("clip_001_frame_0002.png"), "").unwrap(); + fs::write(PATH.get().unwrap().join("clip_002_frame_0001.png"), "").unwrap(); + fs::write(PATH.get().unwrap().join("image_003.png"), "").unwrap(); + // this is to make sure patterns are being escaped + fs::write(PATH.get().unwrap().join("image_004Xpng"), "").unwrap(); + }); + } + + #[test] + fn test_is_valid_filename() { + assert!(is_valid_filename("clip_001_frame_0001.png")); + assert!(is_valid_filename("image-###.png")); + assert!(is_valid_filename("test 01.png")); + assert!(is_valid_filename("a.png")); + assert!(is_valid_filename("###.png")); + assert!(is_valid_filename("clip_%%%_frame_###.jpg")); + + assert!(!is_valid_filename("")); + assert!(!is_valid_filename("dir/file.png")); + assert!(!is_valid_filename("dir\\file.png")); + assert!(!is_valid_filename("clip<01>.png")); + assert!(!is_valid_filename("clip:01.png")); + assert!(!is_valid_filename("clip\"01.png")); + assert!(!is_valid_filename("clip|01.png")); + assert!(!is_valid_filename("clip?01.png")); + assert!(!is_valid_filename("clip*01.png")); + assert!(!is_valid_filename("clip_\n.png")); + assert!(!is_valid_filename("clip_\t.png")); + assert!(!is_valid_filename(".")); + assert!(!is_valid_filename("..")); + assert!(!is_valid_filename("clip.png.")); + assert!(!is_valid_filename("clip.png ")); + } + + #[test] + fn test_check_files() { + initialize_files(); + let path = PATH.get().unwrap(); + + // this pattern should return clip = 2, frame = 2 + // because those are the highest values matching the pattern + // clip_002_frame_0001.png and clip_001_frame_0002.png exist + assert_eq!( + check_files(&path.to_str().unwrap(), "clip_%%_frame_###.png").unwrap(), + (2, 2) + ); + + // this pattern should return clip = -1, frame = 3 + // clip is -1 because there is no clip in the pattern + // frame is 3 because image_003.png exists + assert_eq!( + check_files(&path.to_str().unwrap(), "image_###.png").unwrap(), + (-1, 3) + ); + } + + #[test] + fn test_check_pattern() { + initialize_files(); + let path = PATH.get().unwrap().to_str().unwrap(); + let result1 = + check_pattern("clip_%%_frame_###.png".to_string(), path.to_string(), 1).unwrap(); + assert!(result1.valid); + assert_eq!(result1.clip_id, 3); // next available clip number + assert_eq!(result1.first_safe_index, 1); // frame always starts at 1 if clip is in pattern + + let result2 = check_pattern("image_###.png".to_string(), path.to_string(), 1).unwrap(); + assert!(result2.valid); + assert_eq!(result2.clip_id, 1); // clip will always be 1 if not in pattern + assert_eq!(result2.first_safe_index, 4); // next available frame number + + // pattern has two frames + let result4 = + check_pattern("clip_%%_frame_##_###.png".to_string(), path.to_string(), 1).unwrap(); + assert!(!result4.valid); + // pattern has no frames + let result5 = check_pattern("clip_%%.png".to_string(), path.to_string(), 1).unwrap(); + assert!(!result5.valid); + + // illegal filename + let result6 = + check_pattern("clip_%%\\frame_###.png".to_string(), path.to_string(), 1).unwrap(); + assert!(!result6.valid); + } + + #[test] + fn test_name_gen() { + let mut name_gen = NameGen::new(NameOpts { + pattern: "frame_####.png".to_string(), + clip_number: Some(1), + first: Some(1), + count: 2, + }); + assert_eq!(name_gen.next(), Some("frame_0001.png".to_string())); + assert_eq!(name_gen.next(), Some("frame_0002.png".to_string())); + + let mut name_gen2 = name_gen.copy(); + assert_eq!(name_gen2.next(), Some("frame_0001.png".to_string())); + + assert_eq!(name_gen.next(), None); + + assert_eq!(name_gen2.next(), Some("frame_0002.png".to_string())); + assert_eq!(name_gen2.next(), None); + } + + #[test] + fn test_name_gen_clip() { + let mut name_gen = NameGen::new(NameOpts { + pattern: "clip_%%%_frame_###.png".to_string(), + clip_number: Some(5), + first: Some(10), + count: 2, + }); + // clip 5 padded to 3 digits -> 005 + // frame 10 padded to 3 digits -> 010 + assert_eq!(name_gen.next(), Some("clip_005_frame_010.png".to_string())); + assert_eq!(name_gen.next(), Some("clip_005_frame_011.png".to_string())); + assert_eq!(name_gen.next(), None); + } +} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index a997e1e..98f5b0d 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "DTM", - "version": "0.2.1", + "version": "0.3.0", "identifier": "com.kcjer.dtm", "build": { "beforeDevCommand": "vite", diff --git a/src/App.tsx b/src/App.tsx index 01eddc3..affac0f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,7 +5,7 @@ import { lazy, type PropsWithChildren, Suspense, useEffect, useRef } from "react import { ErrorBoundary } from "react-error-boundary" import { useSnapshot } from "valtio" import { CheckRoot, Sidebar, Tooltip } from "@/components" -import { FaMinus, FaMoon, FaPlus } from "@/components/icons" +import { FaMinus, FaMoon, FaPlus } from "@/components/icons/icons" import { Preview, useIsPreviewActive } from "@/components/preview" import { themeHelpers } from "@/theme/helpers" import { toggleColorMode, useColorMode } from "./components/ui/color-mode" @@ -14,7 +14,7 @@ import AppStore from "./hooks/appState" import { Loading } from "./main" import "./menu" import UpgradeButton from "./metadata/toolbar/UpgradeButton" -import { viewDescription } from "./views" +import { viewDescription, views } from "./views" // import Onboard from "./Onboard" @@ -46,7 +46,7 @@ function App() { }} > - + {viewDescription.map((item) => ( import("./metadata/Metadata")), - mini: lazy(() => import("./Mini")), - vid: lazy(() => import("./vid/Vid")), - library: lazy(() => import("./library/Library")), - projects: lazy(() => import("./dtProjects/DTProjects")), - scratch: lazy(() => import("./scratch/Reactive")), -} function getView(view: string) { if (isView(view)) return views[view] diff --git a/src/commands/bookmarks.ts b/src/commands/bookmarks.ts new file mode 100644 index 0000000..c3b77b6 --- /dev/null +++ b/src/commands/bookmarks.ts @@ -0,0 +1,38 @@ +import { invoke } from "@tauri-apps/api/core"; + +export interface PickFolderResult { + path: string; + bookmark: string; +} + +/** + * Opens a native folder picker on macOS to select the Draw Things Documents folder. + * Returns both the selected folder's path and a base64-encoded security-scoped bookmark. + * + * @param defaultPath Optional path to suggest in the picker. + * @returns A PickFolderResult containing path and bookmark, or null if cancelled. + */ +export async function pickDrawThingsFolder(defaultPath?: string): Promise { + return await invoke("pick_draw_things_folder", { defaultPath }); +} + +/** + * Resolves a security-scoped bookmark and starts accessing the resource. + * Returns the local file path to the resource. + * The internal cache ensures stopAccessing... is called only when the app exits. + * + * @param bookmark The base64-encoded bookmark string to resolve. + * @returns The resolved local path. + */ +export async function resolveBookmark(bookmark: string): Promise { + return await invoke("resolve_bookmark", { bookmark }); +} + +/** + * Manually stops accessing a security-scoped bookmark and removes it from the bookmark manager. + * + * @param bookmark The base64-encoded bookmark string to release. + */ +export async function stopAccessingBookmark(bookmark: string): Promise { + return await invoke("stop_accessing_bookmark", { bookmark }); +} diff --git a/src/commands/index.ts b/src/commands/index.ts index 4836163..62a0b3f 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -1 +1,3 @@ -export * from './projects' \ No newline at end of file +export * from './projects' +export * from './vid' +export * from './bookmarks' \ No newline at end of file diff --git a/src/commands/projects.ts b/src/commands/projects.ts index 0b4b2c8..e103d0f 100644 --- a/src/commands/projects.ts +++ b/src/commands/projects.ts @@ -1,414 +1,398 @@ import { invoke } from "@tauri-apps/api/core" import type { ProjectState } from "@/dtProjects/state/projects" +import type { + ImageExtra, + ListImagesResult, + ProjectExtra, + TensorHistoryClip, +} from "@/generated/types" import type { DrawThingsConfig, DrawThingsConfigGrouped } from "@/types" import type { ImagesSource as ListImagesOpts } from "../dtProjects/types" -// -------------------- -// Type definitions -// -------------------- - -export type ProjectExtra = { - id: number - path: string - image_count: number - last_id?: number - filesize: number - modified: number - excluded: boolean -} - -export type ImageExtra = { - id: number - project_id: number - model_id?: number - model_file?: string - prompt?: string - negative_prompt?: string - preview_id: number - node_id: number - has_depth: boolean - has_pose: boolean - has_color: boolean - has_custom: boolean - has_scribble: boolean - has_shuffle: boolean - start_width: number - start_height: number - } +export type { ImageExtra, ListImagesResult, ProjectExtra } export type Control = { - file?: string - weight: number - guidance_start: number - guidance_end: number - no_prompt: boolean - global_average_pooling: boolean - down_sampling_rate: number - control_mode: string - target_blocks?: string[] - input_override: string + file?: string + weight: number + guidance_start: number + guidance_end: number + no_prompt: boolean + global_average_pooling: boolean + down_sampling_rate: number + control_mode: string + target_blocks?: string[] + input_override: string } export type LoRA = { - file?: string - weight: number - mode: string + file?: string + weight: number + mode: string } -export type TensorHistoryNode = { - lineage: number - logical_time: number - start_width: number - start_height: number - seed: number - steps: number - guidance_scale: number - strength: number - model?: string - tensor_id: number - mask_id: number - wall_clock?: string - text_edits: number - text_lineage: number - batch_size: number - sampler: number - hires_fix: boolean - hires_fix_start_width: number - hires_fix_start_height: number - hires_fix_strength: number - upscaler?: string - scale_factor: number - depth_map_id: number - generated: boolean - image_guidance_scale: number - seed_mode: number - clip_skip: number - controls?: Control[] - scribble_id: number - pose_id: number - loras?: LoRA[] - color_palette_id: number - mask_blur: number - custom_id: number - face_restoration?: string - clip_weight: number - negative_prompt_for_image_prior: boolean - image_prior_steps: number - data_stored: number - preview_id: number - content_offset_x: number - content_offset_y: number - scale_factor_by_120: number - refiner_model?: string - original_image_height: number - original_image_width: number - crop_top: number - crop_left: number - target_image_height: number - target_image_width: number - aesthetic_score: number - negative_aesthetic_score: number - zero_negative_prompt: boolean - refiner_start: number - negative_original_image_height: number - negative_original_image_width: number - shuffle_data_stored: number - fps_id: number - motion_bucket_id: number - cond_aug: number - start_frame_cfg: number - num_frames: number - mask_blur_outset: number - sharpness: number - shift: number - stage_2_steps: number - stage_2_cfg: number - stage_2_shift: number - tiled_decoding: boolean - decoding_tile_width: number - decoding_tile_height: number - decoding_tile_overlap: number - stochastic_sampling_gamma: number - preserve_original_after_inpaint: boolean - tiled_diffusion: boolean - diffusion_tile_width: number - diffusion_tile_height: number - diffusion_tile_overlap: number - upscaler_scale_factor: number - script_session_id: number - t5_text_encoder: boolean - separate_clip_l: boolean - clip_l_text?: string - separate_open_clip_g: boolean - open_clip_g_text?: string - speed_up_with_guidance_embed: boolean - guidance_embed: number - resolution_dependent_shift: boolean - tea_cache_start: number - tea_cache_end: number - tea_cache_threshold: number - tea_cache: boolean - separate_t5: boolean - t5_text?: string - tea_cache_max_skip_steps: number - text_prompt?: string - negative_text_prompt?: string - clip_id: number - index_in_a_clip: number - causal_inference_enabled: boolean - causal_inference: number - causal_inference_pad: number - cfg_zero_star: boolean - cfg_zero_init_steps: number - generation_time: number - reason: number +export type XTensorHistoryNode = { + lineage: number + logical_time: number + start_width: number + start_height: number + seed: number + steps: number + guidance_scale: number + strength: number + model?: string + tensor_id: number + mask_id: number + wall_clock?: string + text_edits: number + text_lineage: number + batch_size: number + sampler: number + hires_fix: boolean + hires_fix_start_width: number + hires_fix_start_height: number + hires_fix_strength: number + upscaler?: string + scale_factor: number + depth_map_id: number + generated: boolean + image_guidance_scale: number + seed_mode: number + clip_skip: number + controls?: Control[] + scribble_id: number + pose_id: number + loras?: LoRA[] + color_palette_id: number + mask_blur: number + custom_id: number + face_restoration?: string + clip_weight: number + negative_prompt_for_image_prior: boolean + image_prior_steps: number + data_stored: number + preview_id: number + content_offset_x: number + content_offset_y: number + scale_factor_by_120: number + refiner_model?: string + original_image_height: number + original_image_width: number + crop_top: number + crop_left: number + target_image_height: number + target_image_width: number + aesthetic_score: number + negative_aesthetic_score: number + zero_negative_prompt: boolean + refiner_start: number + negative_original_image_height: number + negative_original_image_width: number + shuffle_data_stored: number + fps_id: number + motion_bucket_id: number + cond_aug: number + start_frame_cfg: number + num_frames: number + mask_blur_outset: number + sharpness: number + shift: number + stage_2_steps: number + stage_2_cfg: number + stage_2_shift: number + tiled_decoding: boolean + decoding_tile_width: number + decoding_tile_height: number + decoding_tile_overlap: number + stochastic_sampling_gamma: number + preserve_original_after_inpaint: boolean + tiled_diffusion: boolean + diffusion_tile_width: number + diffusion_tile_height: number + diffusion_tile_overlap: number + upscaler_scale_factor: number + script_session_id: number + t5_text_encoder: boolean + separate_clip_l: boolean + clip_l_text?: string + separate_open_clip_g: boolean + open_clip_g_text?: string + speed_up_with_guidance_embed: boolean + guidance_embed: number + resolution_dependent_shift: boolean + tea_cache_start: number + tea_cache_end: number + tea_cache_threshold: number + tea_cache: boolean + separate_t5: boolean + t5_text?: string + tea_cache_max_skip_steps: number + text_prompt?: string + negative_text_prompt?: string + clip_id: number + index_in_a_clip: number + causal_inference_enabled: boolean + causal_inference: number + causal_inference_pad: number + cfg_zero_star: boolean + cfg_zero_init_steps: number + generation_time: number + reason: number } export type TensorHistoryExtra = { - row_id: number - lineage: number - logical_time: number - tensor_id?: string - mask_id?: string - depth_map_id?: string - scribble_id?: string - pose_id?: string - color_palette_id?: string - custom_id?: string - moodboard_ids: string[] - history: TensorHistoryNode - project_path: string + row_id: number + lineage: number + logical_time: number + tensor_id?: string + mask_id?: string + depth_map_id?: string + scribble_id?: string + pose_id?: string + color_palette_id?: string + custom_id?: string + moodboard_ids: string[] + history: XTensorHistoryNode + project_path: string } export type DTImageFull = { - id: number - prompt?: string - negativePrompt?: string - model?: Model - project: ProjectState - config: DrawThingsConfig - groupedConfig: DrawThingsConfigGrouped - node: TensorHistoryNode - images?: { - tensorId?: string - previewId?: number - maskId?: string - depthMapId?: string - scribbleId?: string - poseId?: string - colorPaletteId?: string - customId?: string - moodboardIds?: string[] - } + id: number + prompt?: string + negativePrompt?: string + model?: Model + project: ProjectState + config: DrawThingsConfig + groupedConfig: DrawThingsConfigGrouped + clipId: number + numFrames: number + node: XTensorHistoryNode + images?: { + tensorId?: string + previewId?: number + maskId?: string + depthMapId?: string + scribbleId?: string + poseId?: string + colorPaletteId?: string + customId?: string + moodboardIds?: string[] + } } export type ScanProgress = { - projects_scanned: number - projects_total: number - project_path: string - images_scanned: number - images_total: number + projects_scanned: number + projects_total: number + project_path: string + images_scanned: number + images_total: number } export type TensorRaw = { - tensor_type: number - data_type: number - format: number - width: number - height: number - channels: number - dim: ArrayBuffer - data: ArrayBuffer + tensor_type: number + data_type: number + format: number + width: number + height: number + channels: number + dim: ArrayBuffer + data: ArrayBuffer } export type ListImagesOptions = { - projectIds?: number[] - nodeId?: number - sort?: string - direction?: string - model?: number[] - control?: number[] - lora?: number[] - search?: string - take?: number - skip?: number + projectIds?: number[] + nodeId?: number + sort?: string + direction?: string + model?: number[] + control?: number[] + lora?: number[] + search?: string + take?: number + skip?: number } export type WatchFolder = { - id: number - path: string - recursive: boolean - item_type: "Projects" | "ModelInfo" - last_updated?: number | null - } + id: number + path: string + recursive: boolean + last_updated?: number | null +} // -------------------- // Command wrappers // -------------------- export const pdb = { - // #unused - getImageCount: async (): Promise => invoke("projects_db_image_count"), - - addProject: async (path: string): Promise => - invoke("projects_db_project_add", { path }), - - removeProject: async (path: string): Promise => - invoke("projects_db_project_remove", { path }), - - listProjects: async (): Promise => invoke("projects_db_project_list"), - - scanProject: async ( - path: string, - fullScan = false, - filesize?: number, - modified?: number, - ): Promise => - invoke("projects_db_project_scan", { path, fullScan, filesize, modified }), - - updateExclude: async (id: number, exclude: boolean): Promise => - invoke("projects_db_project_update_exclude", { id, exclude }), - - listImages: async ( - source: MaybeReadonly, - skip: number, - take: number, - ): Promise<{ items: ImageExtra[]; total: number }> => { - const result: Record = await invoke("projects_db_image_list", { - ...source, - skip, - take, - }) - if ("Images" in result) return result.Images as { items: ImageExtra[]; total: number } - else return { items: [], total: 0 } - }, - - /** - * ignores projectIds, returns count of image matches in each project. - */ - listImagesCount: async (source: MaybeReadonly) => { - const opts = { ...source, projectIds: undefined, count: true } - const result: Record = await invoke("projects_db_image_list", opts) - if ("Counts" in result) { - const counts = result.Counts as { project_id: number; count: number }[] - const total = counts.reduce((acc, item) => acc + item.count, 0) - return { counts, total } - } else return { counts: [], total: 0 } - }, - - rebuildIndex: async (): Promise => invoke("projects_db_image_rebuild_fts"), - - watchFolders: { - listAll: async (): Promise => invoke("projects_db_watch_folder_list"), - - add: async ( - path: string, - itemType: "Projects" | "ModelInfo", - recursive: boolean, - ): Promise => - invoke("projects_db_watch_folder_add", { path, itemType, recursive }), - - remove: async (ids: number[] | number): Promise => - invoke("projects_db_watch_folder_remove", { ids: Array.isArray(ids) ? ids : [ids] }), - - update: async ( - id: number, - recursive?: boolean, - lastUpdated?: number, - ): Promise => - invoke("projects_db_watch_folder_update", { id, recursive, lastUpdated }), - }, - - scanModelInfo: async (filePath: string, modelType: ModelType): Promise => - invoke("projects_db_scan_model_info", { filePath, modelType }), - - listModels: async (modelType?: ModelType): Promise => - invoke("projects_db_list_models", { modelType }), + // #unused + getImageCount: async (): Promise => invoke("projects_db_image_count"), + + addProject: async (path: string): Promise => { + try { + return await invoke("projects_db_project_add", { path }) + } + catch (e) { + if (e === "error communicating with database: Table not found") return undefined + console.error(e) + return undefined + } + }, + + removeProject: async (path: string): Promise => + invoke("projects_db_project_remove", { path }), + + listProjects: async (): Promise => invoke("projects_db_project_list"), + + scanProject: async ( + path: string, + fullScan = false, + filesize?: number, + modified?: number, + ): Promise => + invoke("projects_db_project_scan", { path, fullScan, filesize, modified }), + + updateExclude: async (id: number, exclude: boolean): Promise => + invoke("projects_db_project_update_exclude", { id, exclude }), + + updateMissingOn: async (paths: string[], missingOn: number | null): Promise => + invoke("projects_db_project_bulk_update_missing_on", { paths, missingOn }), + + listImages: async ( + source: MaybeReadonly, + skip: number, + take: number, + ): Promise => { + const result: ListImagesResult = await invoke("projects_db_image_list", { + ...source, + skip, + take, + }) + return result + }, + + getClip: async (imageId: number): Promise => + invoke("projects_db_get_clip", { imageId }), + + /** + * ignores projectIds, returns count of image matches in each project. + */ + listImagesCount: async (source: MaybeReadonly) => { + const opts = { ...source, projectIds: undefined, count: true } + const result: ListImagesResult = await invoke("projects_db_image_list", opts) + return result + }, + + rebuildIndex: async (): Promise => invoke("projects_db_image_rebuild_fts"), + + watchFolders: { + listAll: async (): Promise => invoke("projects_db_watch_folder_list"), + + add: async ( + path: string, + recursive: boolean, + ): Promise => + invoke("projects_db_watch_folder_add", { path, recursive }), + + remove: async (ids: number[] | number): Promise => + invoke("projects_db_watch_folder_remove", { ids: Array.isArray(ids) ? ids : [ids] }), + + update: async ( + id: number, + recursive?: boolean, + lastUpdated?: number, + ): Promise => + invoke("projects_db_watch_folder_update", { id, recursive, lastUpdated }), + }, + + scanModelInfo: async (filePath: string, modelType: ModelType): Promise => + invoke("projects_db_scan_model_info", { filePath, modelType }), + + listModels: async (modelType?: ModelType): Promise => + invoke("projects_db_list_models", { modelType }), } export type ModelType = "Model" | "Lora" | "Cnet" | "Upscaler" export type Model = { - id: number - model_type: ModelType - filename: string - name?: string - version?: string - count?: number + id: number + model_type: ModelType + filename: string + name?: string + version?: string + count?: number } export type ModelInfo = { - file: string - name: string - version: string - model_type: ModelType + file: string + name: string + version: string + model_type: ModelType } export type TensorSize = { - width: number - height: number - channels: number + width: number + height: number + channels: number } export const dtProject = { - // #unused - getTensorHistory: async ( - project_file: string, - index: number, - count: number, - ): Promise[]> => - invoke("dt_project_get_tensor_history", { project_file, index, count }), - - // #unused - getThumbHalf: async (project_file: string, thumb_id: number): Promise => - invoke("dt_project_get_thumb_half", { project_file, thumb_id }), - - getHistoryFull: async (projectFile: string, rowId: number): Promise => - invoke("dt_project_get_history_full", { projectFile, rowId }), - - // #unused - getTensorRaw: async ( - projectFile: string, - projectId: number, - tensorId: string, - ): Promise => - invoke("dt_project_get_tensor_raw", { projectFile, projectId, tensorId }), - - getTensorSize: async (project: string | number, tensorId: string): Promise => { - const opts = { - tensorId, - projectId: typeof project === "string" ? undefined : project, - projectFile: typeof project === "string" ? project : undefined, - } - return invoke("dt_project_get_tensor_size", opts) - }, - - decodeTensor: async ( - project: string | number, - tensorId: string, - asPng: boolean, - nodeId?: number, - ): Promise> => { - const opts = { - tensorId, - projectId: typeof project === "string" ? undefined : project, - projectFile: typeof project === "string" ? project : undefined, - asPng, - nodeId, - } - return new Uint8Array(await invoke("dt_project_decode_tensor", opts)) - }, - - getPredecessorCandidates: async ( - projectFile: string, - rowId: number, - lineage: number, - logicalTime: number, - ): Promise => - invoke("dt_project_find_predecessor_candidates", { - projectFile, - rowId, - lineage, - logicalTime, - }), + // #unused + getTensorHistory: async ( + project_file: string, + index: number, + count: number, + ): Promise[]> => + invoke("dt_project_get_tensor_history", { project_file, index, count }), + + // #unused + getThumbHalf: async (project_file: string, thumb_id: number): Promise => + invoke("dt_project_get_thumb_half", { project_file, thumb_id }), + + getHistoryFull: async (projectFile: string, rowId: number): Promise => + invoke("dt_project_get_history_full", { projectFile, rowId }), + + // #unused + getTensorRaw: async ( + projectFile: string, + projectId: number, + tensorId: string, + ): Promise => + invoke("dt_project_get_tensor_raw", { projectFile, projectId, tensorId }), + + getTensorSize: async (project: string | number, tensorId: string): Promise => { + const opts = { + tensorId, + projectId: typeof project === "string" ? undefined : project, + projectFile: typeof project === "string" ? project : undefined, + } + return invoke("dt_project_get_tensor_size", opts) + }, + + decodeTensor: async ( + project: string | number, + tensorId: string, + asPng: boolean, + nodeId?: number, + ): Promise> => { + const opts = { + tensorId, + projectId: typeof project === "string" ? undefined : project, + projectFile: typeof project === "string" ? project : undefined, + asPng, + nodeId, + } + return new Uint8Array(await invoke("dt_project_decode_tensor", opts)) + }, + + getPredecessorCandidates: async ( + projectFile: string, + rowId: number, + lineage: number, + logicalTime: number, + ): Promise => + invoke("dt_project_find_predecessor_candidates", { + projectFile, + rowId, + lineage, + logicalTime, + }), } diff --git a/src/commands/urls.ts b/src/commands/urls.ts index 0759b12..bbb72b0 100644 --- a/src/commands/urls.ts +++ b/src/commands/urls.ts @@ -1,20 +1,33 @@ import type { ImageExtra } from "./projects" +function thumb(image: ImageExtra): string +function thumb(projectId: number, previewId: number): string +function thumb(arg: ImageExtra | number, previewId?: number): string { + if (typeof arg === "number") return `dtm://dtproject/thumb/${arg}/${previewId}` + return `dtm://dtproject/thumb/${arg.project_id}/${arg.preview_id}` +} + +function thumbHalf(image: ImageExtra): string +function thumbHalf(projectId: number, previewId: number): string +function thumbHalf(arg: ImageExtra | number, previewId?: number): string { + if (typeof arg === "number") return `dtm://dtproject/thumbhalf/${arg}/${previewId}` + return `dtm://dtproject/thumbhalf/${arg.project_id}/${arg.preview_id}` +} + const urls = { - thumb: (image: ImageExtra) => `dtm://dtproject/thumb/${image.project_id}/${image.preview_id}`, - thumbHalf: (image: ImageExtra) => - `dtm://dtproject/thumbhalf/${image.project_id}/${image.preview_id}`, - tensor: ( - projectId: number, - name: string, - opts?: { nodeId?: number | null; size?: number | null; invert?: boolean }, - ) => { - const url = new URL(`dtm://dtproject/tensor/${projectId}/${name}`) - if (opts?.nodeId) url.searchParams.set("node", opts.nodeId.toString()) - if (opts?.size) url.searchParams.set("s", opts.size.toString()) - if (opts?.invert) url.searchParams.set("mask", "invert") - return url.toString() - }, + thumb, + thumbHalf, + tensor: ( + projectId: number, + name: string, + opts?: { nodeId?: number | null; size?: number | null; invert?: boolean }, + ) => { + const url = new URL(`dtm://dtproject/tensor/${projectId}/${name}`) + if (opts?.nodeId) url.searchParams.set("node", opts.nodeId.toString()) + if (opts?.size) url.searchParams.set("s", opts.size.toString()) + if (opts?.invert) url.searchParams.set("mask", "invert") + return url.toString() + }, } export default urls diff --git a/src/commands/vid.ts b/src/commands/vid.ts new file mode 100644 index 0000000..ce1e9c7 --- /dev/null +++ b/src/commands/vid.ts @@ -0,0 +1,63 @@ +import { invoke } from "@tauri-apps/api/core" + +export interface FramesExportOpts { + imageId: number + outputDir: string + useTensor: boolean + filenamePattern: string + clipNumber?: number + startFrame?: number +} + +export interface VideoExportOpts { + imageId: number + outputFile: string + useTensor: boolean + fps: number + width?: number + height?: number +} + +export interface NameOpts { + pattern: string + clipNumber?: number + first?: number + count: number +} + +export interface CheckPatternResult { + valid: boolean + invalidReason?: string + outputDirDne: boolean + firstSafeIndex: number + clipId: number + examples: string[] +} + +export async function ffmpegCheck(): Promise { + return await invoke("ffmpeg_check") +} + +export async function ffmpegDownload(): Promise { + return await invoke("ffmpeg_download") +} + +export async function ffmpegCall(args: string[]): Promise { + return await invoke("ffmpeg_call", { args }) +} + +export async function saveAllClipFrames(opts: FramesExportOpts): Promise { + return await invoke("save_all_clip_frames", { opts }) +} + +export async function createVideoFromFrames(opts: VideoExportOpts): Promise { + return await invoke("create_video_from_frames", { opts }) +} + +export async function checkPattern( + pattern: string, + dir: string, + numFrames: number, +): Promise { + return await invoke("check_pattern", { pattern, dir, numFrames }) +} diff --git a/src/components/DataItem.tsx b/src/components/DataItem.tsx index f062ff0..7a4e78b 100644 --- a/src/components/DataItem.tsx +++ b/src/components/DataItem.tsx @@ -287,7 +287,8 @@ const templates = { const { image } = useDTImage() const upscaler = image?.groupedConfig?.upscaler - const scale = upscaler?.value && upscaler?.scaleFactor ? `(x${upscaler.scaleFactor})` : "" + let scale = "" + if (upscaler?.value) scale = upscaler.scaleFactor === 2 ? "(x2)" : "(x4)" if (!value?.width || !value?.height) return null return ( @@ -346,6 +347,7 @@ const templates = { }, NumFrames: (props: DataItemTemplateProps<"numFrames">) => { const { value, ...rest } = props + if (!value) return null return }, @@ -389,9 +391,12 @@ const templates = { }, Refiner: (props: DataItemTemplateProps<"refiner">) => { const { value, ...rest } = props + const { refiner } = useDTImage() if (!value?.model) return null + + const name = refiner?.name || value.model const start = value.start !== undefined ? ` (${(value.start * 100).toFixed(1)}%)` : "" - return + return }, Shift: (props: DataItemTemplateProps<"shift">) => { const { value, ...rest } = props diff --git a/src/components/FloatIndicator.tsx b/src/components/FloatIndicator.tsx index 30870c3..f120366 100644 --- a/src/components/FloatIndicator.tsx +++ b/src/components/FloatIndicator.tsx @@ -2,7 +2,7 @@ import { IconButton } from "@/components" import { chakra, HStack } from "@chakra-ui/react" import { AnimatePresence, motion } from "motion/react" import { createContext, use, useEffect, useMemo, useState, type ComponentProps } from "react" -import { FiX } from "@/components/icons" +import { FiX } from "@/components/icons/icons" import { useDTP } from "../dtProjects/state/context" const dur = 0.2 diff --git a/src/components/FrameCountIndicator.tsx b/src/components/FrameCountIndicator.tsx new file mode 100644 index 0000000..286d456 --- /dev/null +++ b/src/components/FrameCountIndicator.tsx @@ -0,0 +1,87 @@ +import { Box, chakra } from "@chakra-ui/react" +import { Fragment } from "react/jsx-runtime" + +const topEdge = 35 +const bottomEdge = 165 +const width = 220 +const height = 200 +const THICKNESS = 15 + +interface FrameCountIndicatorProps extends ChakraProps { + count?: React.ReactNode + bgColor?: string + thickness?: number +} + +function FrameCountIndicator(props: FrameCountIndicatorProps) { + const { count, bgColor, thickness = THICKNESS, ...restProps } = props + const margin = thickness / 2 + 5 + + return ( + + + + + + + {Array.from({ length: 4 }).map((_, i) => ( + + + + + ))} + + {count} + + + + ) +} + +export default FrameCountIndicator diff --git a/src/components/IconButton.tsx b/src/components/IconButton.tsx new file mode 100644 index 0000000..41c1523 --- /dev/null +++ b/src/components/IconButton.tsx @@ -0,0 +1,242 @@ +import { chakra } from "@chakra-ui/react" +import type { ComponentProps, ReactNode } from "react" +import { Tooltip } from "." + +// from the chakra ui button recipe +// https://github.com/chakra-ui/chakra-ui/blob/main/packages/react/src/theme/recipes/button.ts + +const Base = chakra("button", { + base: { + color: "fg.3", + aspectRatio: "1", + bgColor: "transparent", + display: "inline-flex", + appearance: "none", + alignItems: "center", + justifyContent: "center", + userSelect: "none", + position: "relative", + borderRadius: "l2", + whiteSpace: "nowrap", + verticalAlign: "middle", + borderWidth: "1px", + borderColor: "transparent", + overflow: "visible", + cursor: "button", + flexShrink: "0", + outline: "0", + lineHeight: "1.2", + isolation: "isolate", + fontWeight: "medium", + transitionProperty: "common", + transitionDuration: "moderate", + focusVisibleRing: "outside", + transformOrigin: "center center", + _disabled: { + layerStyle: "disabled", + cursor: "default", + }, + _icon: {}, + }, + + variants: { + variant: { + inset: { + bgColor: "bg.1", + border: "1px solid {gray/30}", + color: "fg.1", + paddingBlock: 0.5, + height: "unset", + paddingInline: 1, + // border: "1px solid", + // borderColor: "transparent", + borderRadius: "md", + margin: 0, + marginInline: "-0.5px", + _hover: { + color: "fg.1", + scale: "1", + "& *": { + scale: 1.05, + }, + }, + "& *": { + transformOrigin: "center center", + }, + }, + simple: { + _hover: { + scale: 1.1, + }, + }, + toggle: { + paddingBlock: 0.5, + height: "unset", + paddingInline: 1, + border: "1px solid", + borderColor: "transparent", + borderRadius: 0, + margin: 0, + marginInline: "-0.5px", + _hover: { + scale: "1", + "& *": { + scale: 1.05, + }, + }, + "& *": { + transformOrigin: "center center", + }, + "&:first-of-type": { + borderTopLeftRadius: "md", + borderBottomLeftRadius: "md", + marginLeft: 0, + }, + "&:last-of-type": { + borderTopRightRadius: "md", + borderBottomRightRadius: "md", + marginRight: 0, + }, + }, + }, + toggled: { + true: { + bgColor: "bg.2", + border: "1px solid {gray/30}", + color: "fg.1", + _hover: { + color: "fg.1", + }, + // boxShadow: "0px 0px 5px 0px #c958286d inset" + }, + false: { + color: "fg.3/70", + bgColor: "bg.deep", + border: "1px solid {gray/30}", + _hover: { + color: "fg.3", + }, + }, + }, + size: { + min: { + h: "min-content", + minH: 0, + w: "min-content", + minW: 0, + textStyle: "xs", + _icon: { + width: "5", + height: "5", + }, + }, + "2xs": { + h: "6", + minW: "6", + textStyle: "xs", + px: "2", + gap: "1", + _icon: { + width: "3.5", + height: "3.5", + gap: "1.5", + }, + }, + xs: { + h: "8", + minW: "8", + textStyle: "xs", + px: "2.5", + gap: "1", + _icon: { + width: "4", + height: "4", + }, + }, + sm: { + h: "8", + minW: "8", + px: "0", + textStyle: "sm", + gap: "2", + _icon: { + width: "5", + height: "5", + }, + }, + md: { + h: "10", + minW: "10", + textStyle: "sm", + px: "4", + gap: "2", + _icon: { + width: "6", + height: "6", + }, + }, + lg: { + h: "11", + minW: "11", + textStyle: "md", + px: "5", + gap: "3", + _icon: { + width: "5", + height: "5", + }, + }, + xl: { + h: "12", + minW: "12", + textStyle: "md", + px: "5", + gap: "2.5", + _icon: { + width: "5", + height: "5", + }, + }, + "2xl": { + h: "16", + minW: "16", + textStyle: "lg", + px: "7", + gap: "3", + _icon: { + width: "6", + height: "6", + }, + }, + }, + }, + + defaultVariants: { + variant: "simple", + size: "sm", + }, +}) + +export interface IconButtonProps extends ComponentProps { + tip?: ReactNode + tipTitle?: string + tipText?: string +} + +const IconButton = (props: IconButtonProps) => { + const { tip, tipTitle, tipText, children, ...rest } = props + + const button = {children} + + if (tip || tipTitle || tipText) { + return ( + + {button} + + ) + } + + return button +} + +export default IconButton diff --git a/src/components/IconToggle.tsx b/src/components/IconToggle.tsx new file mode 100644 index 0000000..08f57a3 --- /dev/null +++ b/src/components/IconToggle.tsx @@ -0,0 +1,109 @@ +import { HStack } from "@chakra-ui/react" +import { type ComponentProps, createContext, type ReactNode, use, useCallback } from "react" +import { IconButton, Tooltip } from "." + +const IconToggleContext = createContext({ + value: {} as Record, + onClick: (_option: string) => {}, +}) + +interface IconToggleProps extends Omit { + children: ReactNode + value: Record + onChange: (value: Record) => void + mode?: "toggle" | "requireOne" | "zeroOrOne" +} + +function IconToggle(props: IconToggleProps) { + const { children, value, mode, onChange, ...restProps } = props + + const onClick = useCallback( + (option: string) => { + const entries = { ...value } + const totalOptions = Object.keys(entries).length + const totalSelected = Object.values(entries).filter((v) => v).length + + if (mode === "requireOne") { + // if clicking the selected option, and can switch if there are two + if (entries[option] && totalOptions === 2 && totalSelected === 1) { + Object.keys(entries).forEach((key) => { + entries[key] = !entries[key] + }) + } + // otherwise, select the clicked option and disable the others + else { + Object.keys(entries).forEach((key) => { + entries[key] = false + }) + entries[option] = true + } + } + // max one can be selected + else if (mode === "zeroOrOne") { + const optionValue = entries[option] + for (const key in entries) { + entries[key] = false + } + entries[option] = !optionValue + } + // otherwise just toggle + else entries[option] = !entries[option] + onChange(entries) + }, + [value, onChange, mode], + ) + + const cv = { value, onClick } + + return ( + + + {children} + + + ) +} + +interface TriggerProps extends ComponentProps { + option: string +} + +function Trigger(props: TriggerProps) { + const { children, option, ...restProps } = props + + const { value, onClick } = use(IconToggleContext) + + // useEffect(() => { + // if (!(option in context.entries)) { + // context.entries[option] = initialValue ?? false + // } + // return () => { + // delete context.entries[option] + // } + // }, [option, initialValue, context]) + + return ( + { + onClick(option) + }} + {...restProps} + > + {children} + + ) +} + +IconToggle.Trigger = Trigger + +export default IconToggle diff --git a/src/components/PanelList.tsx b/src/components/PanelList.tsx index 534a09d..4a85ef7 100644 --- a/src/components/PanelList.tsx +++ b/src/components/PanelList.tsx @@ -1,12 +1,11 @@ import { HStack, Spacer } from "@chakra-ui/react" -import { motion, useSpring } from "motion/react" import { type ComponentType, useEffect, useMemo, useRef } from "react" -import type { IconType } from "@/components/icons" -import { PiInfo } from "@/components/icons" import { proxy, type Snapshot, useSnapshot } from "valtio" +import type { IconType } from "@/components/icons/icons" +import { PiInfo } from "@/components/icons/icons" import { type Selectable, useSelectableGroup } from "@/hooks/useSelectableV" import { IconButton, PaneListContainer, PanelListItem, PanelSectionHeader, Tooltip } from "." -import { PanelListScrollContent, PanelSection, PaneListScrollContainer } from "./common" +import { PaneListScrollContainer, PanelListScrollContent, PanelSection } from "./common" interface PanelListComponentProps extends ChakraProps { emptyListText?: string | boolean @@ -26,6 +25,7 @@ export type PanelListCommandItem = PanelListCommand | "s export interface PanelListCommand { id: string + ariaLabel?: string icon?: IconType | ComponentType getIcon?: (selected: Snapshot, context?: C) => IconType | ComponentType requiresSelection?: boolean @@ -93,8 +93,8 @@ function PanelList(props: PanelListComponen emptyListTextProp === false ? null : typeof emptyListTextProp === "string" - ? emptyListTextProp - : "(No items)" + ? emptyListTextProp + : "(No items)" return ( @@ -111,14 +111,14 @@ function PanelList(props: PanelListComponen { - // if (!wrapperRef.current || !contentRef.current) return - // const max = - // contentRef.current?.clientHeight - wrapperRef.current?.clientHeight - // scrollY.current = Math.max(0, Math.min(max, scrollY.current + e.deltaY)) - // scrollYMv.set(-scrollY.current) - // }} + // overflowY="clip" + // onWheel={(e) => { + // if (!wrapperRef.current || !contentRef.current) return + // const max = + // contentRef.current?.clientHeight - wrapperRef.current?.clientHeight + // scrollY.current = Math.max(0, Math.min(max, scrollY.current + e.deltaY)) + // scrollYMv.set(-scrollY.current) + // }} > {children} @@ -161,6 +161,7 @@ function PanelList(props: PanelListComponen return ( command.onClick(selectedItems, commandContext)} diff --git a/src/components/Progress.tsx b/src/components/Progress.tsx new file mode 100644 index 0000000..eae1bbf --- /dev/null +++ b/src/components/Progress.tsx @@ -0,0 +1,32 @@ +import { Box, Progress as ChakraProgress, HStack, Spacer } from "@chakra-ui/react" +import { forwardRef } from "react" + +export interface ProgressProps extends ChakraProgress.RootProps { + showValueText?: boolean + valueText?: React.ReactNode + labelA?: React.ReactNode + labelB?: React.ReactNode +} + +const Progress = forwardRef(function Progress(props, ref) { + const { showValueText, valueText, labelA, labelB, ...rest } = props + return ( + + {labelA && ( + + + {labelA} + + {labelB} + + + )} + + + + {showValueText && {valueText}} + + ) +}) + +export default Progress diff --git a/src/components/sliderWithInput.tsx b/src/components/SliderWithInput.tsx similarity index 100% rename from src/components/sliderWithInput.tsx rename to src/components/SliderWithInput.tsx diff --git a/src/components/Tooltip.tsx b/src/components/Tooltip.tsx index 295512a..3c9189d 100644 --- a/src/components/Tooltip.tsx +++ b/src/components/Tooltip.tsx @@ -3,45 +3,47 @@ import type { PropsWithChildren } from "react" import { Tooltip } from "./ui/tooltip" interface TooltipProps extends TooltipContentProps { - /** if present, tiptitle and tiptext will be ignored */ - tip?: React.ReactNode - tipTitle?: string - tipText?: string + /** if present, tiptitle and tiptext will be ignored */ + tip?: React.ReactNode + tipTitle?: string + tipText?: string + contentProps?: TooltipContentProps } function TooltipComponent(props: PropsWithChildren) { - const { tip, tipTitle, tipText, children, ...rest } = props + const { tip, tipTitle, tipText, children, contentProps, ...rest } = props - const Content = tip ?? ( - - - {tipTitle} - - - {tipText} - - - ) + const Content = tip ?? ( + + + {tipTitle} + + + {tipText} + + + ) - return ( - - {children} - - ) + return ( + + {children} + + ) } export default TooltipComponent diff --git a/src/components/common.tsx b/src/components/common.tsx index 7fb7799..6f76412 100644 --- a/src/components/common.tsx +++ b/src/components/common.tsx @@ -29,19 +29,32 @@ export const CheckRoot = chakra( { base: { display: "flex", - bgImage: "url(check_light.png)", - bgSize: "50px 50px", - bgColor: "#000000", + // bgImage: "url(check_light.png)", + // bgSize: "50px 50px", + // bgColor: "#000000", + bgColor: "transparent", width: "100%", height: "100%", overscrollBehavior: "none none", position: "relative", borderRadius: "md", + zIndex: 0, + _before: { + content: '""', + bgImage: "url(check_light.png)", + position: "absolute", + width: "100%", + height: "100%", + bgSize: "50px 50px", + inset: 0, + pointerEvents: "none", + zIndex: -2, + }, }, variants: { dark: { true: { - _before: { + _after: { content: '""', bgImage: "url(check_dark.png)", position: "absolute", @@ -51,10 +64,11 @@ export const CheckRoot = chakra( inset: 0, animation: "fadeIn 0.2s ease forwards", pointerEvents: "none", + zIndex: -1, }, }, false: { - _before: { + _after: { content: '""', bgImage: "url(check_dark.png)", position: "absolute", @@ -64,6 +78,7 @@ export const CheckRoot = chakra( inset: 0, animation: "fadeOut 0.2s ease forwards", pointerEvents: "none", + zIndex: -1, }, }, }, @@ -101,7 +116,7 @@ export const PaneListScrollContainer = chakra( height: "100%", width: "100%", paddingY: "1px", - gap: 0.5, + gap: 0, display: "flex", justifyContent: "flex-start", alignItems: "stretch", @@ -149,8 +164,11 @@ export const PanelListItem = chakra( paddingX: 2, paddingY: 1, borderRadius: "sm", - boxShadow: "0px 0px 18px -8px #00000022", - border: "2px solid #00000000", + // boxShadow: "0px 0px 18px -8px #00000022", + border: "1px solid", + margin: "0px", + borderColor: "#00000033", + // borderColor: "fg.3/30", transition: "all 0.2s ease-out", _focusVisible: { outline: "2px inset {colors.blue.400/70} !important", @@ -174,7 +192,7 @@ export const PanelListItem = chakra( _hover: { bgColor: "color-mix(in srgb, {colors.bg.3} 50%, {colors.blue.500} 50%)", }, - borderBlock: "2px groove #00000033", + borderBlock: "1px solid #00000033", }, }, hoverScale: { @@ -194,11 +212,12 @@ export const PanelButton = chakra( { base: { bgColor: "bg.3", - margin: 1, + margin: 0, color: "fg.2", height: "min-content", paddingY: 2, fontWeight: "500", + boxShadow: "0px 1px 5px -3px #00000055", }, variants: { tone: { @@ -210,10 +229,31 @@ export const PanelButton = chakra( boxShadow: "0px 1px 5px -3px #00000055", }, }, + success: { + color: "bg.0", + fontWeight: "600", + bgColor: "success.1", // "color-mix(in srgb, {colors.bg.1} 70%, {colors.green.500} 30%)", + border: "2px solid {colors.success.1}", + _hover: { + bgColor: "success.1/90", + // bgColor: "color-mix(in srgb, {colors.bg.1} 20%, {colors.highlight} 80%)", + border: "2px solid {colors.success.1}", + boxShadow: "0px 1px 5px -3px #00000055", + }, + }, none: { _hover: { - border: "1px solid {colors.fg.2/20}", - bgColor: "bg.2", + // border: "1px solid {colors.fg.2/20}", + boxShadow: "0px 0px 4px -2px #00000088", + bgColor: "bg.0", + }, + }, + selected: { + color: "white", + fontWeight: "600", + bgColor: "highlight.1", + _hover: { + bgColor: "highlight", }, }, }, @@ -227,9 +267,9 @@ export const PanelSection = chakra("div", { base: { display: "flex", flexDirection: "column", - padding: 1, + padding: 0.5, boxShadow: "0px 2px 8px -3px #00000022, 0px 0px 10px -5px #00000022", - borderRadius: "xl", + borderRadius: "lg", border: "1px solid {gray/20}", overflowY: "clip", overflowX: "clip", @@ -237,6 +277,27 @@ export const PanelSection = chakra("div", { justifyContent: "flex-start", gap: 0, bgColor: "bg.1", - color: "fg.1" + color: "fg.1", + }, +}) + +export const LinkButton = chakra("button", { + base: { + color: "info", + fontWeight: "600", + _hover: { + textDecoration: "underline", + }, + cursor: "pointer", + }, + variants: { + show: { + true: { + display: "inline", + }, + false: { + display: "none", + }, + }, }, }) diff --git a/src/components/iconButton.tsx b/src/components/iconButton.tsx deleted file mode 100644 index 4218211..0000000 --- a/src/components/iconButton.tsx +++ /dev/null @@ -1,168 +0,0 @@ -import { chakra, type HTMLChakraProps, type RecipeProps } from "@chakra-ui/react" -import type { ReactNode } from "react" -import { Tooltip } from "." - -// from the chakra ui button recipe -// https://github.com/chakra-ui/chakra-ui/blob/main/packages/react/src/theme/recipes/button.ts - -const Base = chakra("button", { - base: { - color: "fg.3", - backgroundColor: "transparent", - aspectRatio: "1", - bgColor: "transparent", - display: "inline-flex", - appearance: "none", - alignItems: "center", - justifyContent: "center", - userSelect: "none", - position: "relative", - borderRadius: "l2", - whiteSpace: "nowrap", - verticalAlign: "middle", - borderWidth: "1px", - borderColor: "transparent", - cursor: "button", - flexShrink: "0", - outline: "0", - lineHeight: "1.2", - isolation: "isolate", - fontWeight: "medium", - transitionProperty: "common", - transitionDuration: "moderate", - focusVisibleRing: "outside", - _hover: { - scale: "1.2", - color: "fg.1", - }, - _disabled: { - layerStyle: "disabled", - cursor: "default", - }, - _icon: { - flexShrink: "0", - }, - }, - - variants: { - size: { - min: { - h: "min-content", - minH: 0, - w: "min-content", - minW: 0, - textStyle: "xs", - _icon: { - width: "5", - height: "5", - }, - }, - "2xs": { - h: "6", - minW: "6", - textStyle: "xs", - px: "2", - gap: "1", - _icon: { - width: "3.5", - height: "3.5", - gap: "1.5", - }, - }, - xs: { - h: "8", - minW: "8", - textStyle: "xs", - px: "2.5", - gap: "1", - _icon: { - width: "4", - height: "4", - }, - }, - sm: { - h: "8", - minW: "8", - px: "0", - textStyle: "sm", - gap: "2", - _icon: { - width: "5", - height: "5", - }, - }, - md: { - h: "10", - minW: "10", - textStyle: "sm", - px: "4", - gap: "2", - _icon: { - width: "6", - height: "6", - }, - }, - lg: { - h: "11", - minW: "11", - textStyle: "md", - px: "5", - gap: "3", - _icon: { - width: "5", - height: "5", - }, - }, - xl: { - h: "12", - minW: "12", - textStyle: "md", - px: "5", - gap: "2.5", - _icon: { - width: "5", - height: "5", - }, - }, - "2xl": { - h: "16", - minW: "16", - textStyle: "lg", - px: "7", - gap: "3", - _icon: { - width: "6", - height: "6", - }, - }, - }, - }, - - defaultVariants: { - size: "sm", - }, -}) - -export interface IconButtonProps extends HTMLChakraProps<"button", RecipeProps<"button">> { - tip?: ReactNode - tipTitle?: string - tipText?: string -} - -const IconButton = (props: IconButtonProps) => { - const { tip, tipTitle, tipText, children, ...rest } = props - - const button = {children} - - if (tip || tipTitle || tipText) { - return ( - - {button} - - ) - } - - return button -} - -export default IconButton diff --git a/src/components/icons.tsx b/src/components/icons.tsx deleted file mode 100644 index 9e28d48..0000000 --- a/src/components/icons.tsx +++ /dev/null @@ -1,10 +0,0 @@ -export type { IconType } from "react-icons/lib"; - -export { BiDetail } from "react-icons/bi"; -export { FaMinus, FaMoon, FaPlus } from "react-icons/fa6"; -export { FiClipboard, FiCopy, FiEye, FiEyeOff, FiFolder, FiList, FiRefreshCw, FiSave, FiX, FiXCircle } from "react-icons/fi"; -export { GoGear } from "react-icons/go"; -export { LuFolderTree, LuMoon, LuSun, LuX } from "react-icons/lu"; -export { MdBlock, MdImageSearch } from "react-icons/md"; -export { PiCoffee, PiInfo, PiListMagnifyingGlassBold } from "react-icons/pi"; -export { TbBrowser, TbSortAscending, TbSortAscending2, TbSortAscendingLetters, TbSortDescending2, TbSortDescendingNumbers } from "react-icons/tb"; diff --git a/src/components/icons/VideoFramesIcon.tsx b/src/components/icons/VideoFramesIcon.tsx new file mode 100644 index 0000000..f4aba03 --- /dev/null +++ b/src/components/icons/VideoFramesIcon.tsx @@ -0,0 +1,50 @@ +import { chakra } from "@chakra-ui/react" +import type { ComponentProps } from "react" + +function VideoFrameIcon(props: ComponentProps) { + return ( + + + + + + + + + + + + + + + + + + + + + ) +} + +export default VideoFrameIcon diff --git a/src/components/icons/icons.tsx b/src/components/icons/icons.tsx new file mode 100644 index 0000000..22c7476 --- /dev/null +++ b/src/components/icons/icons.tsx @@ -0,0 +1,37 @@ +export { BiDetail } from "react-icons/bi" +export { FaMinus, FaMoon, FaPlus, FaRegImages } from "react-icons/fa6" +export { + FiClipboard, + FiCopy, + FiEye, + FiEyeOff, + FiFolder, + FiList, + FiRefreshCw, + FiSave, + FiX, + FiXCircle, +} from "react-icons/fi" +export { GiNeedleDrill } from "react-icons/gi" +export { GoGear } from "react-icons/go" +export type { IconType } from "react-icons/lib" +export { LuFolderTree, LuMoon, LuSun, LuX } from "react-icons/lu" +export { MdBlock, MdImageSearch } from "react-icons/md" +export { + PiCoffee, + PiFilmStrip, + PiImage, + PiImages, + PiInfo, + PiListMagnifyingGlassBold, + PiPauseFill, + PiPlayFill, +} from "react-icons/pi" +export { + TbBrowser, + TbSortAscending, + TbSortAscending2, + TbSortAscendingLetters, + TbSortDescending2, + TbSortDescendingNumbers, +} from "react-icons/tb" diff --git a/src/components/index.ts b/src/components/index.ts index 1fc8648..689dd85 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -3,13 +3,12 @@ import DataItem from "./DataItem" import IconButton from "./IconButton" import MeasureGrid from "./measureGrid/MeasureGrid" import { useMeasureGrid } from "./measureGrid/useMeasureGrid" +import Progress from "./Progress" import * as Preview from "./preview" import SliderWithInput from "./SliderWithInput" import Sidebar from "./sidebar/Sidebar" import Tooltip from "./Tooltip" import VirtualizedList from "./virtualizedList/VirtualizedList" -// import Root from './FloatIndicator' -// export {Root as FloatIndicator} export const { CheckRoot, @@ -20,6 +19,7 @@ export const { PanelSectionHeader, PanelButton, PanelSection, + LinkButton, } = Common export { @@ -32,6 +32,5 @@ export { MeasureGrid, useMeasureGrid, DataItem, + Progress, } - -// doesn't exporting like this prevent code spiltting? Hmmm diff --git a/src/components/sidebar/Sidebar.tsx b/src/components/sidebar/Sidebar.tsx index 9d0d783..1bcf5d2 100644 --- a/src/components/sidebar/Sidebar.tsx +++ b/src/components/sidebar/Sidebar.tsx @@ -40,7 +40,7 @@ const Root = chakra( {}, ) -interface SidebarProps extends PropsWithChildren> {} +interface SidebarProps extends PropsWithChildren> { } function SidebarComponent(props: SidebarProps) { const { children, ...rest } = props const { isSidebarVisible } = useSnapshot(AppStore.store) @@ -48,6 +48,7 @@ function SidebarComponent(props: SidebarProps) { return ( + {/* */} + ) } diff --git a/src/dtProjects/jobs/models.ts b/src/dtProjects/jobs/models.ts new file mode 100644 index 0000000..64684c4 --- /dev/null +++ b/src/dtProjects/jobs/models.ts @@ -0,0 +1,91 @@ +import { path } from "@tauri-apps/api" +import { writeTextFile } from "@tauri-apps/plugin-fs" +import { pdb } from "@/commands" +import type { JobCallback } from "@/utils/container/queue" +import type { DTPJobSpec } from "../state/types" +import type { ListModelInfoFilesResult } from "../state/watchFolders" + +async function getRemoteCombinedModels(lastUpdated?: string) { + const res = await fetch("https://kcjerrell.github.io/dt-models/combined_models.json") + const data = await res.json() + + if (lastUpdated && lastUpdated >= data.lastUpdate) { + return null + } + + const check = (key: string) => key in data && Array.isArray(data[key]) + + const modelInfoFiles = [] as ListModelInfoFilesResult[] + + const models = [] + if (check("officialModels")) models.push(...data.officialModels) + if (check("communityModels")) models.push(...data.communityModels) + if (check("uncuratedModels")) models.push(...data.uncuratedModels) + if (models.length) { + const filePath = await path.join(await path.appDataDir(), "combined_models.json") + await writeTextFile(filePath, JSON.stringify(models, null, 2)) + modelInfoFiles.push({ path: filePath, modelType: "Model" }) + } + + const cnets = [] + if (check("officialCnets")) cnets.push(...data.officialCnets) + if (check("communityCnets")) cnets.push(...data.communityCnets) + if (cnets.length) { + const filePath = await path.join(await path.appDataDir(), "combined_cnets.json") + await writeTextFile(filePath, JSON.stringify(cnets, null, 2)) + modelInfoFiles.push({ path: filePath, modelType: "Cnet" }) + } + + const loras = [] + if (check("officialLoras")) loras.push(...data.officialLoras) + if (check("communityLoras")) loras.push(...data.communityLoras) + if (loras.length) { + const filePath = await path.join(await path.appDataDir(), "combined_loras.json") + await writeTextFile(filePath, JSON.stringify(loras, null, 2)) + modelInfoFiles.push({ path: filePath, modelType: "Lora" }) + } + + return [modelInfoFiles, data.lastUpdate] as [ListModelInfoFilesResult[], string] +} + +export function syncModelInfoJob( + modelInfoFiles: ListModelInfoFilesResult[], + callback?: JobCallback, +): DTPJobSpec<"models-scan"> { + return { + type: "models-scan", + label: `Syncing models from files: ${modelInfoFiles.map((m) => m.path.split("/").pop())}`, + callback, + data: modelInfoFiles, + execute: async (data) => { + for (const { path, modelType } of data) { + await pdb.scanModelInfo(path, modelType) + } + }, + } +} + +export function syncRemoteModelsJob(callback?: JobCallback): DTPJobSpec<"models-scan-remote"> { + return { + type: "models-scan-remote", + label: "Checking models from remote", + data: undefined, + callback, + execute: async (_, container) => { + const settings = container.getService("settings") + const lastUpdate = settings?.state?.models?.lastUpdated + + const update = await getRemoteCombinedModels(lastUpdate) + + if (!update) return undefined + + const [modelInfoFiles, newLastUpdate] = update + + const syncJob = syncModelInfoJob(modelInfoFiles, () => { + settings?.updateSetting("models", "lastUpdated", newLastUpdate) + }) + + return { jobs: [syncJob] } + }, + } +} diff --git a/src/dtProjects/settingsPanel/GrantAccess.tsx b/src/dtProjects/settingsPanel/GrantAccess.tsx new file mode 100644 index 0000000..efe866f --- /dev/null +++ b/src/dtProjects/settingsPanel/GrantAccess.tsx @@ -0,0 +1,46 @@ +import { Text } from "@chakra-ui/react" +import { pickDrawThingsFolder } from "@/commands" +import { PanelButton, PanelSection, PanelSectionHeader } from "@/components" +import { useDTP } from "../state/context" + +interface GrantAccessProps extends ChakraProps {} + +function GrantAccess(props: GrantAccessProps) { + const { ...restProps } = props + const { settings: storage, watchFolders } = useDTP() + + const storageSnap = storage.useSnap() + const hasBookmark = !!storageSnap.permissions.bookmark + + return ( + + + Draw Things Access + + + To view your Draw Things projects, DTM needs access to your Draw Things data folder. + After clicking the button, a file picker will open. Select the Documents folder. + + Note: DTM does not modify your projects. + { + const bookmark = await pickDrawThingsFolder(watchFolders.containerPath) + if (!bookmark) return + if (bookmark.path !== watchFolders.defaultProjectPath) { + alert( + `Please select the correct folder: ${watchFolders.defaultProjectPath}`, + ) + return + } + storage.updateSetting("permissions", "bookmark", bookmark.bookmark) + watchFolders.addDefaultDataFolder() + }} + > + Select folder + + + ) +} + +export default GrantAccess diff --git a/src/dtProjects/settingsPanel/ResetPermission.tsx b/src/dtProjects/settingsPanel/ResetPermission.tsx new file mode 100644 index 0000000..389766e --- /dev/null +++ b/src/dtProjects/settingsPanel/ResetPermission.tsx @@ -0,0 +1,43 @@ +import { Text, VStack } from "@chakra-ui/react" +import { relaunch } from "@tauri-apps/plugin-process" +import { PanelButton, PanelSection, PanelSectionHeader } from "@/components" +import { useDTP } from "../state/context" + +interface ResetPermissionProps extends ChakraProps {} + +function ResetPermission(props: ResetPermissionProps) { + const { ...restProps } = props + const { settings: storage } = useDTP() + + const storageSnap = storage.useSnap() + const hasBookmark = !!storageSnap.permissions.bookmark + + return ( + + Reset Permission + + + Permission has been granted to use Draw Thing's data. If this is no longer + working as expected, you can reset by clicking the button below. This will clear + the permissions and relaunch the app. + + { + storage.updateSetting("permissions", "bookmark", null) + setTimeout(() => relaunch(), 300) + }} + tone={"danger"} + > + Reset + + + + ) +} + +export default ResetPermission diff --git a/src/dtProjects/SettingsPanel.tsx b/src/dtProjects/settingsPanel/SettingsPanel.tsx similarity index 50% rename from src/dtProjects/SettingsPanel.tsx rename to src/dtProjects/settingsPanel/SettingsPanel.tsx index 883b718..3319691 100644 --- a/src/dtProjects/SettingsPanel.tsx +++ b/src/dtProjects/settingsPanel/SettingsPanel.tsx @@ -1,25 +1,24 @@ -import { Box, Button, Link, Text, VStack } from "@chakra-ui/react" +import { Box, HStack, Text, VStack } from "@chakra-ui/react" +import { openUrl } from "@tauri-apps/plugin-opener" import { useMemo } from "react" -import { PanelButton, PanelListItem, PanelSection, PanelSectionHeader } from "@/components" -import { FaMinus, FaPlus, FiList, LuFolderTree } from "@/components/icons" +import { IconButton, LinkButton, PanelListItem, PanelSection, PanelSectionHeader } from "@/components" +import { FaMinus, FaPlus, FiList, FiX, LuFolderTree } from "@/components/icons/icons" import PanelList, { type PanelListCommand } from "@/components/PanelList" import { Slider } from "@/components/ui/slider" import { useSelectable } from "@/hooks/useSelectableV" import { openAnd } from "@/utils/helpers" -import { ContentPanelPopup, type ContentPanelPopupProps } from "./imagesList/ContentPanelPopup" -import { useDTP } from "./state/context" -import type { WatchFolderState, WatchFoldersController } from "./state/watchFolders" -import { openUrl } from '@tauri-apps/plugin-opener' +import { ContentPanelPopup, type ContentPanelPopupProps } from "../imagesList/ContentPanelPopup" +import { useDTP } from "../state/context" +import type { WatchFolderState, WatchFoldersController } from "../state/watchFolders" +import GrantAccess from "./GrantAccess" +import ResetPermission from "./ResetPermission" -function useCommands( - folderType: "Projects" | "ModelInfo", - watchFolders: WatchFoldersController, -): PanelListCommand[] { - const ft = folderType === "Projects" ? "proj" : "modinfo" +function useCommands(watchFolders: WatchFoldersController): PanelListCommand[] { const commands = useMemo( () => [ { - id: `${ft}-toggle-recursive`, + id: `watch-toggle-recursive`, + ariaLabel: "toggle recursive", getIcon: (selected: readonly WatchFolderState[]) => selected[0]?.recursive ? FiList : LuFolderTree, requiresSelection: true, @@ -30,7 +29,8 @@ function useCommands( selected[0]?.recursive ? "Disable recursive" : "Enable recursive", }, { - id: `${ft}-remove-folders`, + id: `watch-remove-folders`, + ariaLabel: "remove folder", icon: FaMinus, requiresSelection: true, onClick: (selected: readonly WatchFolderState[]) => { @@ -39,18 +39,19 @@ function useCommands( tip: "Remove selected folders", }, { - id: `${ft}-add-folder`, + id: `watch-add-folder`, + ariaLabel: "add folder", icon: FaPlus, onClick: () => - openAnd((f) => watchFolders.addWatchFolder(f, folderType), { + openAnd((f) => watchFolders.addWatchFolder(f), { directory: true, multiple: false, - title: `Select ${folderType.toLowerCase()} folder`, + title: `Select watch folder`, }), tip: "Add folder", }, ], - [folderType, watchFolders, ft], + [watchFolders], ) return commands @@ -61,11 +62,9 @@ export function SettingsPanel(props: Omit 25rem)": { + "& div": { + left: "0", + right: "unset", + }, + }, + }} {...restProps} > - + - - Settings - - + + + Settings + + uiState.showSettings(false)} + > + + + + Consider this a preview version, some features are currently missing or incomplete, and there are likely some bugs here and there. Report any issues - or suggestions in - - or - . + + . + watchFolders.state.projectFolders} - header={"Project locations"} + itemsState={() => watchFolders.state.folders} + header={"Watch locations"} headerInfo={ - "Draw Things projects in these folders will be indexed and listed in the projects tab. \n\nFor most users, only the default folder will be needed. If you move your projects to external storage, you can include the locations here." + "Folders in these locations will be scanned for Draw Things projects and model info files. \n\nFor most users, only the default folders will be needed. If you use a custom model folder, include it here." } - commands={projectFolderCommands} + commands={folderCommands} keyFn={(item) => item.id} - clearSelection={modelInfoFolders.some((f) => f.selected)} > - {projectFolders.map((folder) => ( + {folders.map((folder) => ( ))} - {projectFolders.length === 0 && ( + {folders.length === 0 && ( - {!hasProjectDefault && ( - watchFolders.addDefaultWatchFolder("Projects")} - > - Add default location - - )} - - watchFolders.state.modelInfoFolders} - header={"Model info"} - headerInfo={ - "Model info files in these folders will be indexed to improve search and provide more useful context. \n\nIf you use the External Model Folder setting in Draw Things, add that folder here." - } - commands={modelInfoFolderCommands} - keyFn={(item) => item.id} - clearSelection={projectFolders.some((f) => f.selected)} - > - {modelInfoFolders.map((folder) => ( - - ))} - {modelInfoFolders.length === 0 && ( - - (no folders added) - - )} - - - {!hasModelInfoDefault && ( - watchFolders.addDefaultWatchFolder("ModelInfo")} - > - Add default locations - - )} - Thumbnail columns @@ -224,6 +191,7 @@ export function SettingsPanel(props: Omit + diff --git a/src/dtProjects/state/context.tsx b/src/dtProjects/state/context.tsx index 01b84aa..c34458d 100644 --- a/src/dtProjects/state/context.tsx +++ b/src/dtProjects/state/context.tsx @@ -1,18 +1,18 @@ -import { snapshot } from "valtio" -import { watch } from "valtio/utils" import { UIController } from "@/dtProjects/state/uiState" import { JobQueue } from "@/utils/container/queue" import { Container } from "../../utils/container/container" +import { syncRemoteModelsJob } from "../jobs/models" import DetailsService from "./details" import ImagesController from "./images" import ModelsController from "./models" import ProjectsController from "./projects" import ScannerService from "./scanner" import SearchController from "./search" +import SettingsController from "./settings" import type { DTPContainer, DTPEvents, DTProjectsJobs, DTPServices } from "./types" import WatchFoldersController from "./watchFolders" -let _container = createContainer() +let _container: Container | null = null function getContainer() { if (!_container || _container.isDisposed) { _container = createContainer() @@ -20,42 +20,42 @@ function getContainer() { return _container } -window.addEventListener("unload", () => { - if (document.hidden && _container && !_container.isDisposed) _container.dispose() -}) +// window.addEventListener("unload", () => { +// if (document.hidden && _container && !_container.isDisposed) _container.dispose() +// }) export function useDTP() { const container = getContainer() return container.services } -let _unwatch: () => void -async function _connectDevMode(controllers: DTPServices) { - if (_unwatch) _unwatch() +// let _unwatch: () => void +// async function _connectDevMode(controllers: DTPServices) { +// if (_unwatch) _unwatch() - let _devUpdate: ReturnType | null = null - if (import.meta.env.DEV) { - const devStore = await import("@/Dev.tsx") - _unwatch = watch((get) => { - if (_devUpdate) clearTimeout(_devUpdate) +// let _devUpdate: ReturnType | null = null +// if (import.meta.env.DEV) { +// const devStore = await import("@/Dev.tsx") +// _unwatch = watch((get) => { +// if (_devUpdate) clearTimeout(_devUpdate) - for (const value of Object.values(controllers)) { - if ("state" in value) get(value.state) - } +// for (const value of Object.values(controllers)) { +// if ("state" in value) get(value.state) +// } - _devUpdate = setTimeout(() => { - console.log("it's happening") - const update = {} as Record - update.jobs = controllers.jobs?.jobs - for (const [key, value] of Object.entries(controllers)) { - if ("state" in value) update[key] = snapshot(value.state) - } - devStore.updateDevState("projects", update) - _devUpdate = null - }, 200) - }) - } -} +// _devUpdate = setTimeout(() => { +// console.log("it's happening") +// const update = {} as Record +// update.jobs = controllers.jobs?.jobs +// for (const [key, value] of Object.entries(controllers)) { +// if ("state" in value) update[key] = snapshot(value.state) +// } +// devStore.updateDevState("projects", update) +// _devUpdate = null +// }, 200) +// }) +// } +// } function createContainer() { console.log("creating container") @@ -69,15 +69,18 @@ function createContainer() { const scanner = new ScannerService() const search = new SearchController() const details = new DetailsService(projects) + const settings = new SettingsController() search.onSearch = (text, filters) => { - images.setSearchFilter(text, filters) + images.buildImageSource({ text: text ?? "", filters: filters ?? [] }) } Promise.all([ projects.loadProjects(), models.refreshModels(), - watchFolders.loadWatchFolders(), + // watchFolders.loadWatchFolders(), + scanner.sync({}), + jobs.addJob(syncRemoteModelsJob()), ]) const controllers = { @@ -90,6 +93,7 @@ function createContainer() { images, details, jobs, + settings, } as DTPServices // connectDevMode(controllers) diff --git a/src/dtProjects/state/details.ts b/src/dtProjects/state/details.ts index da9da87..4c4d409 100644 --- a/src/dtProjects/state/details.ts +++ b/src/dtProjects/state/details.ts @@ -1,4 +1,5 @@ -import { type DTImageFull, dtProject, type ImageExtra } from "@/commands" +import { type DTImageFull, dtProject } from "@/commands" +import type { ImageExtra } from '@/generated/types' import { extractConfigFromTensorHistoryNode, groupConfigProperties } from "@/utils/config" import type ProjectsController from "./projects" import { DTPStateService } from "./types" @@ -31,6 +32,8 @@ class DetailsService extends DTPStateService { config: rawConfig, groupedConfig: config, node: history, + numFrames: item.num_frames ?? undefined, + clipId: history.clip_id, images: { tensorId: extra.tensor_id, previewId: history.preview_id, diff --git a/src/dtProjects/state/images.ts b/src/dtProjects/state/images.ts index 9ffaa56..0250175 100644 --- a/src/dtProjects/state/images.ts +++ b/src/dtProjects/state/images.ts @@ -1,11 +1,12 @@ -import { type ImageExtra, pdb } from "@/commands" +import { proxy, subscribe, useSnapshot } from "valtio" +import { pdb } from "@/commands" import { EmptyItemSource, type IItemSource, PagedItemSource, } from "@/components/virtualizedList/PagedItemSource" +import type { ImageExtra } from "@/generated/types" import type { ContainerEvent } from "@/utils/container/StateController" -import { proxy, useSnapshot } from "valtio" import type { ImagesSource } from "../types" import type { ProjectState, ProjectsControllerState } from "./projects" import type { BackendFilter } from "./search" @@ -46,14 +47,17 @@ class ImagesController extends DTPStateController { super("images") this.container.getFutureService("projects").then((projectsService) => { - this.watchProxy((get) => { - const p = get(projectsService.state.selectedProjects) - this.setSelectedProjects(p) + const unsubProjects = subscribe(projectsService.state.selectedProjects, () => { + this.buildImageSource() }) - this.watchProxy((get) => { + this.unwatchFns.push(unsubProjects) + + this.watchProxy(async (get) => { const p = get(projectsService.state.projects) const changed = updateProjectsCache(p, this.projectsCache) + if (changed.length > 0) { + await this.container.services.uiState.importLockPromise if (this.eventTimer) return clearTimeout(this.eventTimer) this.eventTimer = setTimeout(async () => { @@ -67,10 +71,15 @@ class ImagesController extends DTPStateController { this.watchProxy((get) => { const source = get(this.state.imageSource) - + console.log("imageSource", source) const getItems = async (skip: number, take: number) => { - const res = await pdb.listImages(source, skip, take) - return res.items + const s = { ...source } + if (s.showImage === false && s.showVideo === false) { + s.showImage = true + s.showVideo = true + } + const res = await pdb.listImages(s, skip, take) + return res.images } const getCount = async () => { await this.refreshImageCounts() @@ -92,6 +101,16 @@ class ImagesController extends DTPStateController { }) } + buildImageSource(search?: { text?: string; filters?: BackendFilter[] }) { + if (search) { + this.setSearchText(search.text) + this.setSearchFilters(search.filters) + } + + const selectedProjects = this.container.getService("projects")?.state.selectedProjects + if (selectedProjects) this.setSelectedProjects(selectedProjects) + } + projectsCache: Record = {} toggleSortDirection() { @@ -100,17 +119,20 @@ class ImagesController extends DTPStateController { else this.state.imageSource.direction = "asc" } - async setSearchFilter(searchText?: string, filter?: BackendFilter[]) { - this.state.imageSource.search = searchText - ?.replace(/\u201C|\u201D/g, '"') - .replace(/\u2018|\u2019/g, "'") - this.state.imageSource.filters = filter?.map((f) => ({ + async setSearchFilters(filters?: BackendFilter[]) { + this.state.imageSource.filters = filters?.map((f) => ({ target: f.target.toLowerCase(), operator: f.operator, value: f.value, })) } + async setSearchText(searchText?: string) { + this.state.imageSource.search = searchText + ?.replace(/\u201C|\u201D/g, '"') + .replace(/\u2018|\u2019/g, "'") + } + async setSelectedProjects(projects: ProjectState[]) { this.state.imageSource.projectIds = projects.map((p) => p.id) } @@ -126,7 +148,13 @@ class ImagesController extends DTPStateController { } async refreshImageCounts() { - const { total, counts } = await pdb.listImagesCount(this.state.imageSource) + const source = { ...this.state.imageSource } + console.log("refreshImageCounts", source) + if (source.showImage === false && source.showVideo === false) { + source.showImage = true + source.showVideo = true + } + const { total, counts } = await pdb.listImagesCount(source) const projectCounts = {} as Record for (const count of counts) { projectCounts[count.project_id] = count.count @@ -142,6 +170,14 @@ class ImagesController extends DTPStateController { this.state.totalImageCount = total } + setShowVideos(show: boolean) { + this.state.imageSource.showVideo = show + } + + setShowImages(show: boolean) { + this.state.imageSource.showImage = show + } + useItemSource() { const _id = useSnapshot(this.state).searchId return this.itemSource @@ -166,7 +202,7 @@ function updateProjectsCache( visited[project.id] = null if (cache[project.id] !== project.image_count) { projectsChanged.push(project.id) - cache[project.id] = project.image_count + cache[project.id] = project.image_count ?? 0 } } diff --git a/src/dtProjects/state/overview.md b/src/dtProjects/state/overview.md new file mode 100644 index 0000000..7dd1ae5 --- /dev/null +++ b/src/dtProjects/state/overview.md @@ -0,0 +1,53 @@ +# DTProjects tool +The DTProjects tool is focused on indexing, browsing, and searching through a library of Draw Things projects, which is not possible within Draw Things. Projects are included by adding watch folders - typically most users will only have one folder to include, although the intent is to support external/removable storage as well. + +All *generated* images are added to projects2.db, including their prompts, models, and various config properties. The resulting database is fairly small, even with 25k images it is only 15mb. + +It's also possible to save thumbnails in the db, which would be useful for removable storage, as you could still find/preview the project's content without the file being present. Even with thumbnails, the db is about 1GB for 25k images (the size of the combined projects is 100GB). + +Why am I writing this. Oh so I can clean up the state. + +--- + +The primary entry point for components is useDTP(), which returns an object with all the DTP services and state controllers. + +The controllers are initialized by the module, which lazily creates a container and the various services. Its life cycle is NOT managed by React and probably shouldn't be. + +My amateur implementation of DI is probably full of bad ideas, but it works. The abstraction is only partially implemented, and making it fully generic is low priority. The classes and interfaces involved... + +(Note: In the context of this project, services and controllers both have a specific domain (projects, models, images) or high level function (scanner, search). The difference between services and controllers is that controllers have a valtio state proxy that react components can consume via .useSnap(). DPTControllers is extended from DTPService, and the base classes offer connectivity via the container.) + +(Another note: The class design is a bit muddled. Container is generic, and should be a base class, but instead has some DTP specific stuff in it. That's fine for now, although when I move the the arranger or looper into this project, I will want to use the same patterns.) + +- Container + - DTPServices includes the types for all services/controllers + - Services must be initialized during the container's constructor by providing the servicesInit callback parameter. The DTPService base class will register itself automagically. + - The container subscribes to tauri events (this should be in a subclass) + - Has a poorly implemented 'tags' system for invalidating state. StateControllers can register for a tag type and handle invalidation/update events + - Is an EventEmitter, allowing services to emit and listen without dependency on each other + - Has a dispose method to clean up subscriptions and listeners, and to dispose all services + - Provides access to services by their registered name + - Also provides access to *future* services, in case a service wants to do something with another service before it's been created. That way, the order of initialization doesn't matter + - This was created when some services had callbacks or watch functions that other services consumed. I'm moving towards using events instead. + +So what's a service and state controller? + +The Service base class (which is actually DTPService currently, but doesn't have anything DTP specific, same with DPTStateController) .... + - Registers itself with the container when constructed + - Provides protected access to the container + - Has a dispose method that can be overridden + - Provides a watchProxy method subclasses use to have unwatch automatically handled when disposed + +The abstract StateController base class extends Service and adds... + - an abstract state property (given the nature of proxies there's not a straightforward way to require that this is actually a valtio proxy) + - useSnap() hook that returns the snapshot + - IMPORTANT: this is a React hook and follows the rules of react hooks. It must be called from a React component or hook, in a stable order. + - an empty handleTags method that can be overriden to use the tags system. (the tag should be provided in the constructor) + +That's it. + +Currently some services still have dependencies on other services. Trying to reorganize some of that so that... +- Interaction between different services and controllers can be debugged more easily +- (most) services can be tested in isolation without mocking + +I think it's natural for some services to have dependencies - for instance the scanner uses watchfolders, projects, and models. There's not really a way around that. \ No newline at end of file diff --git a/src/dtProjects/state/projects.ts b/src/dtProjects/state/projects.ts index 6b0e7e8..c368745 100644 --- a/src/dtProjects/state/projects.ts +++ b/src/dtProjects/state/projects.ts @@ -17,16 +17,40 @@ export type ProjectsControllerState = { selectedProjects: ProjectState[] showEmptyProjects: boolean projectsCount: number - projectsScanned: number } +const projectSort = ( + a: Selectable<{ + name: string + id: number + fingerprint: string + path: string + image_count: number | null + last_id: number | null + filesize: number | null + modified: number | null + missing_on: number | null + excluded: boolean + }>, + b: Selectable<{ + name: string + id: number + fingerprint: string + path: string + image_count: number | null + last_id: number | null + filesize: number | null + modified: number | null + missing_on: number | null + excluded: boolean + }>, +): number => a.name.toLowerCase().localeCompare(b.name.toLowerCase()) class ProjectsController extends DTPStateController { state = proxy({ projects: [], selectedProjects: [], showEmptyProjects: false, projectsCount: 0, - projectsScanned: 0, }) hasLoaded = false @@ -35,27 +59,54 @@ class ProjectsController extends DTPStateController { super("projects", "projects") } + protected formatTags( + tags: string, + data?: { removed?: number; added?: ProjectExtra; updated?: ProjectExtra; desc?: string }, + ): string { + if (data?.desc) return `invalidate tag: ${tags} - ${data.desc}` + if (data?.removed) return `update tag - removed project - id ${data.removed}` + if (data?.added) + return `update tag - added project - ${data.added.path.split("/").pop()} id ${data.added.id}` + if (data?.updated) + return `update tag - updated project - ${data.updated.path.split("/").pop()} id ${data.updated.id}` + return `update tag: ${tags} ${String(data)}` + } + protected handleTags( _tags: string, data: { removed?: number; added?: ProjectExtra; updated?: ProjectExtra }, ) { if (data.updated) { - const index = this.state.projects.findIndex((p) => p.id === data.updated?.id) - if (index !== -1) { - if (this.state.projects[index].filesize === 0) { - this.state.projectsScanned++ - } - this.state.projects[index].filesize = data.updated.filesize - this.state.projects[index].image_count = data.updated.image_count - this.state.projects[index].excluded = data.updated.excluded - this.state.projects[index].modified = data.updated.modified + this.updateProject(data.updated.id, data.updated) + } else if (data.added) { + // check if project is already listed + if (this.state.projects.some((p) => p.id === data.added?.id)) { + this.updateProject(data.added.id, data.added) + return true + } + this.state.projects.push( + makeSelectable({ ...data.added, name: data.added.path.split("/").pop() as string }), + ) + this.state.projects.sort(projectSort) + this.state.projectsCount++ + } else if (data.removed) { + const project = this.state.projects.find((p) => p.id === data.removed) + if (project) { + va.remove(this.state.projects, project) + this.state.projectsCount-- } - } else { - this.loadProjects() } + this.loadProjectsDebounced() return true } + updateProject(projectId: number, data: Partial) { + const project = this.state.projects.find((p) => p.id === projectId) + if (project) { + Object.assign(project, data) + } + } + private _onProjectsLoaded: ContainerEvent<"projectsLoaded"> = { on: (fn: (_: undefined) => void) => this.container.on("projectsLoaded", fn), once: (fn: (_: undefined) => void) => this.container.once("projectsLoaded", fn), @@ -70,15 +121,29 @@ class ProjectsController extends DTPStateController { va.set( this.state.projects, projects - .map((p) => makeSelectable({ ...p, name: p.path.split("/").pop() as string })) - .sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase())), + .map((p) => + makeSelectable( + { ...p, name: p.path.split("/").pop() as string }, + this.state.selectedProjects.some((sp) => sp.id === p.id), + ), + ) + .sort(projectSort), ) this.state.projectsCount = projects.length - this.state.projectsScanned = projects.filter((p) => p.filesize > 0).length this.hasLoaded = true this.container.emit("projectsLoaded") } + private loadProjectsTimeout: NodeJS.Timeout | null = null + async loadProjectsDebounced() { + if (this.loadProjectsTimeout) { + clearTimeout(this.loadProjectsTimeout) + } + this.loadProjectsTimeout = setTimeout(() => { + this.loadProjects() + }, 2000) + } + async removeProjects(projectFiles: string[]) { for (const projectFile of projectFiles) { await pdb.removeProject(projectFile) @@ -106,10 +171,11 @@ class ProjectsController extends DTPStateController { await pdb.updateExclude(project.id, exclude) projectState.excluded = exclude stateUpdate.push(projectState) + projectState.setSelected(false) } this.setSelectedProjects([]) - await this.container.getService("scanner").syncProjects(stateUpdate.map((p) => p.path)) - await this.loadProjects() + const scanner = this.container.getService("scanner") + await scanner.syncProjects(stateUpdate.map((p) => p.path)) } getProject(projectId?: number | null) { @@ -128,20 +194,18 @@ class ProjectsController extends DTPStateController { } setSelectedProjects(projects: ProjectState[]) { + for (const project of this.state.projects) { + project.setSelected(projects.some((p) => p.id === project.id)) + } va.set(this.state.selectedProjects, projects) } - useSelectedProjects() { - const snap = this.useSnap() - return snap.selectedProjects.map((p) => p.id) - } - useProjectsSummary() { const snap = this.useSnap() return { totalProjects: snap.projects.length, - totalImages: snap.projects.reduce((acc, p) => acc + p.image_count, 0), - totalSize: snap.projects.reduce((acc, p) => acc + p.filesize, 0), + totalImages: snap.projects.reduce((acc, p) => acc + (p.image_count ?? 0), 0), + totalSize: snap.projects.reduce((acc, p) => acc + (p.filesize ?? 0), 0), } } diff --git a/src/dtProjects/state/scanner.ts b/src/dtProjects/state/scanner.ts index 305b4ce..eee3a47 100644 --- a/src/dtProjects/state/scanner.ts +++ b/src/dtProjects/state/scanner.ts @@ -1,135 +1,58 @@ import { exists, stat } from "@tauri-apps/plugin-fs" -import { pdb } from "@/commands" +import { type ProjectExtra, pdb } from "@/commands" import type { JobCallback } from "@/utils/container/queue" +import { TMap } from "@/utils/TMap" +import { syncModelInfoJob } from "../jobs/models" +import { getRefreshModelsJob } from "./models" import { + type DTPContainer, type DTPJob, - type DTPJobSpec, DTPStateService, type ProjectFilesChangedPayload, + type SyncScope, type WatchFoldersChangedPayload, } from "./types" -import type { WatchFolderState } from "./watchFolders" -import { getRefreshModelsJob } from "./models" +import type { ListModelInfoFilesResult, ProjectFileStats, WatchFolderState } from "./watchFolders" class ScannerService extends DTPStateService { constructor() { super("scanner") - this.container.on("watchFoldersChanged", (e) => this.onWatchFoldersChanged(e)) - this.container.on("projectFilesChanged", async (e) => this.onProjectFilesChanged(e)) } async onWatchFoldersChanged(e: WatchFoldersChangedPayload) { const syncFolders = [e.added, e.changed].flat() as WatchFolderState[] - for (const folder of syncFolders) { - if (folder.item_type === "ModelInfo") { - const job = getModelInfoJob(folder.path) - this.container.getService("jobs").addJob(job) - } else if (folder.item_type === "Projects") { - const job = syncProjectFolderJob(folder.path) - this.container.getService("jobs").addJob(job) - } else throw new Error("Invalid item type") + if (syncFolders.length > 0) { + this.sync({ watchFolders: syncFolders }, () => { + console.log("sync finished?") + }) } if (e.removed.length > 0) { - this.syncProjectFolders(undefined, () => { - this.syncModelInfo() + this.sync({}, () => { + console.log("sync finished?") }) } } async onProjectFilesChanged(e: ProjectFilesChangedPayload) { - { - const jobs = [] - for (const projectFile of e.files) { - const stats = await getProjectStats(projectFile) - const project = this.container - .getService("projects") - .state.projects.find((p) => p.path === projectFile) - if (project?.excluded) continue - - if (!stats || stats === "dne") { - if (project) { - jobs.push( - getProjectJob(projectFile, { action: "remove", size: 0, mtime: 0 }), - ) - } - continue - } - - if (!project) { - jobs.push(getProjectJob(projectFile, { action: "add", ...stats })) - continue - } - - jobs.push(getProjectJob(projectFile, { action: "update", ...stats })) - } - this.container.getService("jobs").addJobs(jobs) - } + this.syncProjects(e.files) } - /** - * if watchfolder provided, the projects in that folder will be add/updated to the db. This won't - * remove any projects. - * If not provided, every project in the db and every project in the watchfolders will be checked. - * This may remove projects, if the project file is missing and thw watchfolder is still present - */ - syncProjectFolders(watchFolder?: string, callback?: JobCallback) { - if (watchFolder) { - const job = syncProjectFolderJob(watchFolder, () => { - callback?.() - }) - this.container.getService("jobs").addJob(job) - } else { - const job = syncProjectsJob(() => { - callback?.() - }) - this.container.getService("jobs").addJob(job) + sync(scope: SyncScope, callback?: JobCallback) { + console.log("starting sync job", scope) + const callbackWrapper = () => { + console.log("sync finished") + callback?.() } + const job = createSyncJob(scope, callbackWrapper) + this.container.getService("jobs").addJob(job) } async syncProjects(projectPaths: string[], callback?: JobCallback) { - const result: DTPJob[] = [] - const projects = this.container.getService("projects") - - for (const path of projectPaths) { - const stats = await getProjectStats(path) - const project = projects.state.projects.find((p) => p.path === path) - - if (!stats || stats === "dne") { - if (project) { - result.push(getProjectJob(path, { action: "remove", size: 0, mtime: 0 })) - } - continue - } - - if (!project) { - result.push(getProjectJob(path, { action: "add", ...stats })) - } - - if (project?.excluded) continue - - if (project?.filesize !== stats.size || project?.modified !== stats.mtime) { - result.push(getProjectJob(path, { action: "update", ...stats })) - } - } - - if (result.length > 0) { - this.container.getService("jobs").addJobs(result) - } - - callback?.() - } - - async syncModelInfo() { - const wf = this.container.getService("watchFolders") - - await wf.loadWatchFolders() - - for (const folder of wf.state.modelInfoFolders) { - const job = getModelInfoJob(folder.path) - this.container.getService("jobs").addJob(job) - } + const projectStats = await Promise.all(projectPaths.map((p) => getProjectStats(p))) + const projects = projectStats.filter((p) => !!p) as ProjectFileStats[] + this.sync({ projects }, callback) } override dispose() { @@ -140,8 +63,8 @@ class ScannerService extends DTPStateService { export default ScannerService async function getProjectStats(projectPath: string) { - if (!projectPath.endsWith(".sqlite3")) return null - if (!(await exists(projectPath))) return "dne" + if (!projectPath.endsWith(".sqlite3")) return undefined + if (!(await exists(projectPath))) return undefined const stats = await stat(projectPath) @@ -154,239 +77,210 @@ async function getProjectStats(projectPath: string) { } return { + path: projectPath, size: stats.size + walStats.size, - mtime: Math.max(stats.mtime?.getTime() || 0, walStats.mtime?.getTime() || 0), + modified: Math.max(stats.mtime?.getTime() || 0, walStats.mtime?.getTime() || 0), } } export type ProjectJobPayload = { - action: "add" | "update" | "remove" | "none" + action: "add" | "update" | "remove" | "none" | "mark-missing" project: string size: number mtime: number } -/** this job syncs all projects in the db with all watch folders */ -function syncProjectsJob(callback?: () => void): DTPJob { +function getSyncScopeLabel(scope: SyncScope) { + if (scope.watchFolders) { + const folders = scope.watchFolders.map((f) => f.path.split("/").pop()) + return `Sync for folders: ${folders.join(", ")}` + } + if (scope.projects) { + const projects = scope.projects.map((p) => p.path.split("/").pop()) + return `Sync for projects: ${projects.join(", ")}` + } + return "Full sync" +} + +function createSyncJob(scope: SyncScope, callback?: JobCallback): DTPJob { + const label = getSyncScopeLabel(scope) return { - type: "projects-sync", - data: undefined, - execute: async (_, container) => { - const wf = container.services.watchFolders - const p = container.services.projects - - type ProjectDesc = { - projectFile: string - size: number - mtime: number - status: "unknown" | "new" | "changed" | "missing" | "unchanged" - action: "none" | "remove" | "add" | "update" - isOrphaned?: boolean - } - let allProjects: Map - const cpd = (projectFile: string) => - ({ - projectFile, - size: -1, - mtime: -1, - status: "unknown", - action: "none", - }) as ProjectDesc - const getPd = (projectFile: string) => { - if (!allProjects.has(projectFile)) allProjects.set(projectFile, cpd(projectFile)) - const pd = allProjects.get(projectFile) - if (!pd) throw new Error("Project not found") - return pd - } + type: "data-sync", + label, + data: scope, + execute: getExecuteSync(callback), + } +} - await p.loadProjects() - allProjects = new Map(p.state.projects.map((p) => [p.path, cpd(p.path)])) - - // iterate over known projects (in the db already) - for (const project of p.state.projects) { - const projectStats = await getProjectStats(project.path) - const pd = getPd(project.path) - - if (!projectStats || projectStats === "dne") { - pd.status = "missing" - pd.size = 0 - pd.mtime = 0 - continue - } - - pd.size = projectStats.size - pd.mtime = projectStats.mtime - - if (project.filesize !== pd.size || project.modified !== pd.mtime) { - pd.status = "changed" - } else { - pd.status = "unchanged" - } - } +type ProjectSyncObject = { + file?: ProjectFileStats + entity?: ProjectExtra + isMissing: boolean + action: "add" | "remove" | "update" | "none" | "mark-missing" +} - await wf.loadWatchFolders() +function getSyncObject(opts: Partial): ProjectSyncObject { + return { + file: opts.file, + entity: opts.entity, + isMissing: opts.isMissing ?? false, + action: opts.action ?? "none", + } +} - // iterate over project files in each watch folder - for (const folder of wf.state.projectFolders) { - const folderProjects = await wf.listProjects(folder) - for (const project of folderProjects) { - const pd = getPd(project) - if (pd.status !== "unknown") continue +function getExecuteSync(callback?: JobCallback) { + async function executeSync(scope: SyncScope, container: DTPContainer) { + const wfs = container.services.watchFolders + const ps = container.services.projects - const projectStats = await getProjectStats(project) - if (projectStats && projectStats !== "dne") { - pd.status = "new" - pd.size = projectStats.size - pd.mtime = projectStats.mtime - } - } - } + const folderScoped = !!scope.watchFolders && scope.watchFolders.length > 0 + const projectScoped = !!scope.projects && scope.projects.length > 0 - // assign actions - for (const pd of allProjects.values()) { - if (pd.status === "new") pd.action = "add" - else if (pd.status === "changed") pd.action = "update" - - // check if project is orphaned - const folder = await wf.getFolderForProject(pd.projectFile) - if (!folder) { - pd.isOrphaned = true - pd.action = "remove" - } - - if (pd.status === "missing" && !pd.isOrphaned) { - // if project is missing, do nothing if folder is also missing - // keep this project in db to support removable storage - pd.action = "remove" - } - } + if (folderScoped && projectScoped) throw new Error("not supported at this time") - const jobs = [] as DTPJob[] + const watchFolders = + (await (async () => { + if (folderScoped) return scope.watchFolders + if (projectScoped) return [] + await wfs.loadWatchFolders(true) + return wfs.state.folders + })()) ?? [] - let jobsCreated = 0 - let jobsDone = 0 - const finishedCallback = () => { - jobsDone++ - if (jobsDone === jobsCreated) { - callback?.() - } - } + const modelFiles = [] as ListModelInfoFilesResult[] + const projectFiles = [] as ProjectFileStats[] - for (const pd of allProjects.values()) { - if (pd.action === "none") continue + for (const folder of watchFolders) { + const folderFiles = await wfs.listFiles(folder) + modelFiles.push(...folderFiles.models) + projectFiles.push(...folderFiles.projects) + } + if (projectScoped) { + projectFiles.push(...(scope.projects ?? [])) + } - const job = getProjectJob(pd.projectFile, pd, finishedCallback) + // gather ENTITIES + await ps.loadProjects() + const projectEntities = TMap.from(ps.state.projects, (p) => p.path) - if (job?.type === "project-add") { - jobs.unshift(job) - } else if (job?.type === "project-update") { - jobs.push(job) - } else if (job?.type === "project-remove") { - jobs.unshift(job) - } - } + if (folderScoped && watchFolders?.length) { + projectEntities.retain((path) => watchFolders.some((f) => path.startsWith(f.path))) + } else if (projectScoped && scope.projects?.length) { + const scopedProjects = new Set(scope.projects.map((p) => p.path)) + projectEntities.retain((path) => scopedProjects.has(path)) + } - jobsCreated = jobs.length + const syncs = [] as ProjectSyncObject[] - return { jobs } - }, - } -} + for (const projectFile of projectFiles) { + const project = getSyncObject({ + file: projectFile, + entity: projectEntities.take(projectFile.path), + }) + syncs.push(project) + } -function syncProjectFolderJob(watchFolder: string, callback?: () => void): DTPJob { - return { - type: "project-folder-scan", - data: watchFolder, - callback, - execute: async (_, container) => { - const wf = container.services.watchFolders - const p = container.services.projects - - await wf.loadWatchFolders() - const folder = wf.state.projectFolders.find((f) => f.path === watchFolder) - - if (!folder) return { jobs: [] } - - await p.loadProjects() - - const folderProjects = await wf.listProjects(folder) - const updProjects = {} as Record< - string, - { size: number; mtime: number; action: "add" | "update" } - > - - for (const path of folderProjects) { - const existingProject = p.state.projects.find((pj) => pj.path === path) - const stats = await getProjectStats(path) - - if (!stats || stats === "dne") continue - - if (existingProject) { - if ( - existingProject.filesize !== stats.size || - existingProject.modified !== stats.mtime - ) { - updProjects[path] = { ...stats, action: "update" } - } - } else { - updProjects[path] = { ...stats, action: "add" } - } + for (const projectEntity of projectEntities.values()) { + const project = getSyncObject({ + entity: projectEntity, + }) + // if a project is not covered by a watchfolder, we can stop searching for a file + const projectFolder = await wfs.getFolderForProject(projectEntity.path) + if (!projectFolder) { + syncs.push(project) + continue } - const jobs = [] as DTPJob[] + const projectStats = await getProjectStats(projectEntity.path) + if (projectStats) + project.file = { ...projectStats, watchFolderPath: projectFolder.path } + else project.isMissing = true + syncs.push(project) + } - let jobsCreated = 0 - let jobsDone = 0 - const finishedCallback = () => { - jobsDone++ - if (jobsDone === jobsCreated) { - callback?.() - } + // create jobs from the entity/file pairs + const jobs = [] as DTPJob[] + + for (const project of syncs) { + // file with no entity, add new project + if (project.file && !project.entity) project.action = "add" + // entity with no file, remove or mark missing + else if (!project.file && project.entity) { + const folder = await wfs.getFolderForProject(project.entity.path) + if (folder?.isMissing) project.action = "mark-missing" + else project.action = "remove" } - - for (const [project, data] of Object.entries(updProjects)) { - const job = getProjectJob( - project, - data as Omit, - finishedCallback, + // update if sizes or modified times are different + else if (project.file && project.entity && !project.entity.excluded) { + if ( + project.file.size !== project.entity.filesize || + project.file.modified !== project.entity.modified ) - if (job?.type === "project-update") jobs.push(job) - else if (job?.type === "project-add") jobs.unshift(job) + project.action = "update" } + } + + let jobsCreated = 0 + let jobsCompleted = 0 - jobsCreated = jobs.length + const jobCallback = () => { + jobsCompleted++ + if (jobsCompleted === jobsCreated) callback?.() + } + + // create jobs + for (const project of syncs) { + if (project.action === "none") continue + const projectPath = project.file?.path ?? project.entity?.path + if (!projectPath) continue + const job = getProjectJob(projectPath, project, jobCallback) + if (job) jobs.push(job) + } + + if (modelFiles.length > 0) { + jobs.push(syncModelInfoJob(modelFiles, jobCallback)) + } - return { jobs } - }, + jobsCreated = jobs.length + + return { jobs } } + + return executeSync } function getProjectJob( project: string, - data: Omit, + data: ProjectSyncObject, callback?: JobCallback, -): DTPJob { +): DTPJob | undefined { switch (data.action) { case "add": + if (!data.file) { + console.warn("can't create 'project-add' job without file stats") + return undefined + } return { type: "project-add", - data: [project], + data: [data.file], merge: "first", callback, - execute: async (data: string[], container) => { + execute: async (data: ProjectFileStats[], container) => { container.services.uiState.setImportLock(true) + const projects = [] as [ProjectFileStats, ProjectExtra][] + // there are two loops here because of the way the progress bar works + // the first loop creates the projects and gives the progress bar a total count + // the second loop scans each project and advances the progress bar for (const p of data) { try { - await pdb.addProject(p) + const project = await pdb.addProject(p.path) + if (project) projects.push([p, project]) } catch (e) { console.error(e) } } - for (const p of data) { + for (const [p, project] of projects) { try { - const stats = await getProjectStats(p) - if (!stats || stats === "dne") continue - await pdb.scanProject(p, false, stats.size, stats.mtime) + await pdb.scanProject(project.path, false, p.size, p.modified) } catch (e) { console.error(e) } @@ -396,9 +290,18 @@ function getProjectJob( }, } case "update": + if (!data.file) { + console.warn("can't create 'project-update' job without file stats") + return undefined + } return { type: "project-update", - data: { project, ...data }, + data: { + project, + mtime: data.file?.modified, + size: data.file?.size, + action: "update", + }, callback, execute: async (data: ProjectJobPayload, _container) => { await pdb.scanProject(project, false, data.size, data.mtime) @@ -407,33 +310,24 @@ function getProjectJob( case "remove": return { type: "project-remove", - data: { project, ...data }, + data: project, callback, - execute: async (_data: ProjectJobPayload, _container) => { + execute: async (_data: string, _container) => { await pdb.removeProject(project) }, } - default: - throw new Error() - } -} - -function getModelInfoJob(folder: string, callback?: JobCallback): DTPJobSpec<"models-scan"> { - return { - type: "models-scan", - callback, - data: folder, - execute: async (folder, container) => { - const wf = container.services.watchFolders - const folderState = wf.state.modelInfoFolders.find((f) => f.path === folder) - - if (!folderState) return - - const files = await wf.listModelInfoFiles(folderState) - - for (const file of files) { - await pdb.scanModelInfo(file.path, file.modelType) + case "mark-missing": + return { + type: "project-mark-missing", + data: [project], + merge: "first", + callback, + execute: async (data: string[], _container) => { + await pdb.updateMissingOn(data, null) + console.log("missing", data) + }, } - }, + default: + return undefined } } diff --git a/src/dtProjects/state/search.ts b/src/dtProjects/state/search.ts index 09a0d3d..96e9ccc 100644 --- a/src/dtProjects/state/search.ts +++ b/src/dtProjects/state/search.ts @@ -1,6 +1,7 @@ import { useMemo } from "react" import { proxy, useSnapshot } from "valtio" import type { Model } from "@/commands" +import type { MediaType, SamplerType } from '@/types' import { arrayIfOnly } from "@/utils/helpers" import { type FilterValueSelector, @@ -8,7 +9,6 @@ import { targetCollection, } from "../controlPane/filters/collections" import { DTPStateController } from "./types" -import { SamplerType } from '@/types' export type SearchControllerState = { searchInput: string @@ -42,7 +42,7 @@ export type BackendFilter = { } export type ContentType = "depth" | "pose" | "color" | "custom" | "scribble" | "shuffle" -export type FilterValue = number | ContentType[] | Model | SamplerType +export type FilterValue = number | ContentType[] | Model | SamplerType | MediaType /** * Handles state for building search queries. diff --git a/src/dtProjects/state/settings.ts b/src/dtProjects/state/settings.ts new file mode 100644 index 0000000..53ac9bb --- /dev/null +++ b/src/dtProjects/state/settings.ts @@ -0,0 +1,76 @@ +import { store } from "@tauri-store/valtio" +import { resolveBookmark, stopAccessingBookmark } from "@/commands" +import { DTPStateController } from "./types" + +type SettingsControllerState = { + export: { + framesFilenamePattern: string + framesOutputDir: string + framesSource: "preview" | "tensor" + videoSource: "preview" | "tensor" + videoFps: number + } + permissions: { + bookmark: string | null + } + models: { + lastUpdated: string + } +} + +const defaultState: SettingsControllerState = { + export: { + framesFilenamePattern: "clip_%%%_frame_###", + framesOutputDir: "", + framesSource: "preview", + videoSource: "preview", + videoFps: 16, + }, + permissions: { + bookmark: null, + }, + models: { + lastUpdated: new Date(0).toISOString(), + }, +} + +const settingsStore = store("dtp-settings", defaultState, { + autoStart: true, + saveOnChange: true, + saveStrategy: "immediate", + syncStrategy: "immediate", +}) + +class SettingsController extends DTPStateController { + state = settingsStore.state + + constructor() { + super("settings") + console.log("does bookmark exist?", !!this.state.permissions.bookmark) + } + + updateSetting< + G extends keyof SettingsControllerState, + K extends keyof SettingsControllerState[G], + >(group: G, key: K, value: SettingsControllerState[G][K]) { + this.state[group][key] = value + } + + async setBookmark(bookmark: string) { + await this.clearBookmark() + + this.state.permissions.bookmark = bookmark + await resolveBookmark(bookmark) + } + + async clearBookmark() { + const currentBookmark = this.state.permissions.bookmark + if (currentBookmark) { + await stopAccessingBookmark(currentBookmark) + } + + this.state.permissions.bookmark = null + } +} + +export default SettingsController diff --git a/src/dtProjects/state/types.ts b/src/dtProjects/state/types.ts index d2bf38d..fd3b1c8 100644 --- a/src/dtProjects/state/types.ts +++ b/src/dtProjects/state/types.ts @@ -9,8 +9,14 @@ import type ProjectsController from "./projects" import type ScannerService from "./scanner" import type { ProjectJobPayload } from "./scanner" import type SearchController from "./search" +import type SettingsController from "./settings" import type { UIController } from "./uiState" -import type { WatchFolderState, WatchFoldersController } from "./watchFolders" +import type { + ListModelInfoFilesResult, + ProjectFileStats, + WatchFolderState, + WatchFoldersController, +} from "./watchFolders" export type DTProjectsJobs = { "models-refresh": { @@ -18,11 +24,15 @@ export type DTProjectsJobs = { result: never } "models-scan": { - data: string + data: ListModelInfoFilesResult[] + result: never + } + "models-scan-remote": { + data: undefined result: never } "project-add": { - data: string[] + data: ProjectFileStats[] result: never } "project-update": { @@ -30,7 +40,7 @@ export type DTProjectsJobs = { result: never } "project-remove": { - data: ProjectJobPayload + data: string result: never } "project-folder-scan": { @@ -45,8 +55,21 @@ export type DTProjectsJobs = { data: string result: never } + "project-mark-missing": { + data: string[] + result: never + } + "data-sync": { + data: SyncScope + result: never + } } +export type SyncScope = + | { watchFolders?: never; projects?: ProjectFileStats[] } + | { watchFolders?: WatchFolderState[]; projects?: never } + | Record + export type DTPJob = JobUnion export type DTPJobSpec = JobSpec export type DTPJobResult = JobResult< @@ -91,4 +114,5 @@ export interface DTPServices { images: ImagesController details: DetailsService jobs: JobQueue + settings: SettingsController } diff --git a/src/dtProjects/state/uiState.ts b/src/dtProjects/state/uiState.ts index ec1b5f5..14d9441 100644 --- a/src/dtProjects/state/uiState.ts +++ b/src/dtProjects/state/uiState.ts @@ -1,6 +1,7 @@ import { proxy, ref, useSnapshot } from "valtio" -import { type DTImageFull, dtProject, type ImageExtra, type TensorHistoryExtra } from "@/commands" +import { type DTImageFull, dtProject, type TensorHistoryExtra } from "@/commands" import urls from "@/commands/urls" +import type { ImageExtra } from "@/generated/types" import { uint8ArrayToBase64 } from "@/utils/helpers" import { drawPose, pointsToPose, tensorToPoints } from "@/utils/pose" import type { ProjectState } from "./projects" @@ -94,8 +95,21 @@ export class UIController extends DTPStateController { this.state.isGridInert = inert ?? !this.state.isGridInert } + _importLockPromise = Promise.resolve() + _importLockResolver: (() => void) | null = null + get importLockPromise() { + return this._importLockPromise + } + /** show/hide the import lock */ setImportLock(lock: boolean) { this.state.importLock = lock + if (lock) { + this._importLockPromise = new Promise((resolve) => { + this._importLockResolver = resolve + }) + } else { + this._importLockResolver?.() + } } async showDetailsOverlay(item: ImageExtra) { diff --git a/src/dtProjects/state/watchFolders.ts b/src/dtProjects/state/watchFolders.ts index 4b26dbf..c2c3919 100644 --- a/src/dtProjects/state/watchFolders.ts +++ b/src/dtProjects/state/watchFolders.ts @@ -1,23 +1,23 @@ import { path } from "@tauri-apps/api" -import { exists, readDir, type UnwatchFn, watch, writeTextFile } from "@tauri-apps/plugin-fs" +import { + exists, + readDir, + stat, + type UnwatchFn, + type WatchEvent, + watch, +} from "@tauri-apps/plugin-fs" import { proxy } from "valtio" import { pdb, type WatchFolder } from "@/commands" import { makeSelectable, type Selectable } from "@/hooks/useSelectableV" import va from "@/utils/array" +import { DebounceMap } from "@/utils/DebounceMap" import { arrayIfOnly, compareItems } from "@/utils/helpers" -import { compileOfficialModels } from "@/utils/models" import { DTPStateController } from "./types" const home = await path.homeDir() -const _defaultProjectPath = await path.join( - home, - "/Library/Containers/com.liuliu.draw-things/Data/Documents", -) -const _defaultModelInfoPaths = [ - // await path.join(home, "/Library/Containers/com.liuliu.draw-things/Data/Library/Caches/net"), - await path.join(home, "/Library/Containers/com.liuliu.draw-things/Data/Documents/Models"), - "remote:official", -] +const _containerPath = await path.join(home, "Library/Containers/com.liuliu.draw-things/Data") +const _defaultDataFolder = await path.join(_containerPath, "Documents") const modelInfoFilenames = { "custom.json": "Model", @@ -30,10 +30,8 @@ const modelInfoFilenames = { } as Record export type WatchFoldersControllerState = { - projectFolders: WatchFolderState[] - modelInfoFolders: WatchFolderState[] - hasProjectDefault: boolean - hasModelInfoDefault: boolean + folders: WatchFolderState[] + hasDefaultDataFolder: boolean } export type WatchFolderState = Selectable< @@ -44,11 +42,25 @@ export type WatchFolderState = Selectable< } > -type ListModelInfoFilesResult = { +export type ListModelInfoFilesResult = { path: string modelType: "Model" | "Cnet" | "Lora" } +export type ProjectFileStats = { + path: string + size: number + modified: number + watchFolderPath?: string +} + +export type ListFilesResult = { + /// note that even though only the .sqlite file is given, the .sqlite-wal is included in size/modified + projects: ProjectFileStats[] + models: ListModelInfoFilesResult[] + isMissing?: boolean +} + /** * Manages watch folders for projects and model info. * Takes a handler for when a full scan is required. @@ -56,12 +68,13 @@ type ListModelInfoFilesResult = { */ export class WatchFoldersController extends DTPStateController { state = proxy({ - modelInfoFolders: [] as WatchFolderState[], - hasModelInfoDefault: false, - projectFolders: [] as WatchFolderState[], - hasProjectDefault: false, + folders: [] as WatchFolderState[], + hasDefaultDataFolder: false, }) + watchDisposers = new Map>() + watchCallbacks = new DebounceMap(1500) + constructor() { super("watchFolders", "watchfolders") } @@ -71,37 +84,24 @@ export class WatchFoldersController extends DTPStateController>() - - async loadWatchFolders() { - const prevFolders = [...this.state.modelInfoFolders, ...this.state.projectFolders] - - const res = (await pdb.watchFolders.listAll()) as WatchFolder[] + async loadWatchFolders(supressEvent = false) { + const res = await pdb.watchFolders.listAll() const folders = res.map((f) => makeSelectable(f as WatchFolderState)) for (const folder of folders) { - if (folder.path.startsWith("remote:")) continue + if (!this.state.hasDefaultDataFolder && folder.path === _defaultDataFolder) { + this.state.hasDefaultDataFolder = true + } folder.isMissing = !(await exists(folder.path)) } - va.set( - this.state.projectFolders, - folders.filter((f) => f.item_type === "Projects"), - ) - this.state.hasProjectDefault = folders.some((f) => f.path === _defaultProjectPath) - - va.set( - this.state.modelInfoFolders, - folders.filter((f) => f.item_type === "ModelInfo"), - ) - this.state.hasModelInfoDefault = _defaultModelInfoPaths.every((f) => - this.state.modelInfoFolders.some((mif) => mif.path === f), - ) + const prevFolders = [...this.state.folders] + va.set(this.state.folders, folders) const diff = compareItems(prevFolders, folders, (f) => f.id, { ignoreFunctions: true }) if (!diff.itemsChanged) return + // why stop and start watching changed? for (const folder of [...diff.removed, ...diff.changed]) { this.stopWatch(folder.path) } @@ -110,52 +110,115 @@ export class WatchFoldersController extends DTPStateController f.id)) + // it is not necessary to reload after removing - tags will invalidate + async removeWatchFolders(folder: WatchFolderState): Promise + async removeWatchFolders(folders: readonly WatchFolderState[]): Promise + async removeWatchFolders(arg: WatchFolderState | readonly WatchFolderState[]): Promise { + const folders = arrayIfOnly(arg) + await pdb.watchFolders.remove(folders.map((f) => f.id)) + if (folders.some((f) => f.path === _defaultDataFolder)) + this.state.hasDefaultDataFolder = false } async setRecursive(folder: WatchFolderState | readonly WatchFolderState[], value: boolean) { - const toUpdate = arrayIfOnly(folder) + // disallow changing recursive on default folder + const toUpdate = arrayIfOnly(folder).filter((f) => f.path !== _defaultDataFolder) for (const folder of toUpdate) { const updFolder = await pdb.watchFolders.update(folder.id, value) - const folders = - folder.item_type === "Projects" - ? this.state.projectFolders - : this.state.modelInfoFolders - - const idx = folders.findIndex((f) => f.id === folder.id) + // TODO: is this necessary? I don't think so... + const idx = this.state.folders.findIndex((f) => f.id === folder.id) if (idx !== -1) { - folders[idx].recursive = updFolder.recursive + this.state.folders[idx].recursive = updFolder.recursive } } } - async addDefaultWatchFolder(type: "Projects" | "ModelInfo") { - if (type === "Projects") await this.addWatchFolder(_defaultProjectPath, type) - else if (type === "ModelInfo") { - for (const f of _defaultModelInfoPaths) { - await this.addWatchFolder(f, type) + async addDefaultDataFolder() { + await this.addWatchFolder(_defaultDataFolder, true) + } + + async listFiles(folder: WatchFolderState): Promise { + const result: ListFilesResult = { + projects: [], + models: [], + isMissing: false, + } + + if (!exists(folder.path)) { + result.isMissing = true + return result + } + + const toCheck = [folder.path] + + async function readFolder(currentFolder: string) { + try { + const files = await readDir(currentFolder) + for (const file of files) { + const filePath = await path.join(currentFolder, file.name) + // add folders to list + if (file.isDirectory) { + toCheck.push(filePath) + } + // check project files - this also will check the -wal file + else if (file.name.endsWith(".sqlite3")) { + const fileStats = await stat(filePath) + if (!fileStats) continue + + const walPath = filePath + "-wal" + const walStats = (await exists(walPath)) ? await stat(walPath) : undefined + + const project: ProjectFileStats = { + path: filePath, + size: fileStats.size + (walStats?.size ?? 0), + modified: Math.max( + fileStats.mtime?.getTime() ?? 0, + walStats?.mtime?.getTime() ?? 0, + ), + watchFolderPath: currentFolder, + } + result.projects.push(project) + } + // check model files + else if (file.name.endsWith(".json") && file.name in modelInfoFilenames) { + result.models.push({ + path: filePath, + modelType: modelInfoFilenames[file.name], + }) + } + } + } catch (e) { + console.error(e) } + return result } + + while (toCheck.length > 0) { + const currentFolder = toCheck.shift() + if (!currentFolder) continue + await readFolder(currentFolder) + if (!folder.recursive) break + } + + return result } + // TODO: deprecate async listProjects(folder: WatchFolderState): Promise { - if (folder.item_type !== "Projects") return [] - try { if (!(await exists(folder.path))) { folder.isMissing = true @@ -173,9 +236,9 @@ export class WatchFoldersController extends DTPStateController { const folders = [] as WatchFolderState[] - for (const folder of this.state.projectFolders) { + for (const folder of this.state.folders) { const sep = await path.sep() const folderWithSep = folder.path.endsWith(sep) ? folder.path : folder.path + sep if (project.startsWith(folderWithSep)) { @@ -187,127 +250,32 @@ export class WatchFoldersController extends DTPStateController b.path.length - a.path.length) - return folders[0] - } - - async listModelInfoFiles(folder: WatchFolderState) { - if (folder.item_type !== "ModelInfo") return [] - if (folder.path.startsWith("remote")) return this.getRemoteCombinedModels(folder) - - try { - if (!(await exists(folder.path))) { - folder.isMissing = true - return [] - } - folder.isMissing = false - - const dirFiles = await readDir(folder.path) - const modelInfoFiles = [] as ListModelInfoFilesResult[] - for (const file of dirFiles) { - if (!file.isFile || !file.name.endsWith(".json")) continue - if (file.name in modelInfoFilenames) { - const infoPath = await path.join(folder.path, file.name) - modelInfoFiles.push({ - path: infoPath, - modelType: modelInfoFilenames[file.name], - }) - } - } - return modelInfoFiles - } catch (e) { - console.error(e) - return [] - } - } - - async getRemoteCombinedModels(folder: WatchFolderState) { - const res = await fetch("https://kcjerrell.github.io/dt-models/combined_models.json") - const data = await res.json() - if (folder.last_updated && folder.last_updated >= data.lastUpdate) { - return [] - } - const check = (key: string) => key in data && Array.isArray(data[key]) - - const modelInfoFiles = [] as ListModelInfoFilesResult[] - - const models = [] - if (check("officialModels")) models.push(...data.officialModels) - if (check("communityModels")) models.push(...data.communityModels) - if (check("uncuratedModels")) models.push(...data.uncuratedModels) - if (models.length) { - const filePath = await path.join(await path.appDataDir(), "combined_models.json") - await writeTextFile(filePath, JSON.stringify(models, null, 2)) - modelInfoFiles.push({ path: filePath, modelType: "Model" }) - } - - const cnets = [] - if (check("officialCnets")) cnets.push(...data.officialCnets) - if (check("communityCnets")) cnets.push(...data.communityCnets) - if (cnets.length) { - const filePath = await path.join(await path.appDataDir(), "combined_cnets.json") - await writeTextFile(filePath, JSON.stringify(cnets, null, 2)) - modelInfoFiles.push({ path: filePath, modelType: "Cnet" }) - } - - const loras = [] - if (check("officialLoras")) loras.push(...data.officialLoras) - if (check("communityLoras")) loras.push(...data.communityLoras) - if (loras.length) { - const filePath = await path.join(await path.appDataDir(), "combined_loras.json") - await writeTextFile(filePath, JSON.stringify(loras, null, 2)) - modelInfoFiles.push({ path: filePath, modelType: "Lora" }) - } - - await pdb.watchFolders.update(folder.id, undefined, data.lastUpdate) - - return modelInfoFiles - } - - async getRemoteModelInfoFiles() { - const filenames = ["Model", "ControlNet", "LoRA"] as const - const modelFiles = [] as ListModelInfoFilesResult[] - for (const filename of filenames) { - try { - const modelInfo = await compileOfficialModels(filename) - const modelInfoJson = JSON.stringify(modelInfo, null, 2) - const filePath = await path.join( - await path.appDataDir(), - `official_${filename.toLowerCase()}.json`, - ) - await writeTextFile(filePath, modelInfoJson) - modelFiles.push({ - path: filePath, - modelType: filename.replace("LoRA", "Lora").replace("ControlNet", "Cnet") as - | "Model" - | "Cnet" - | "Lora", - }) - } catch (e) { - console.error(e) - } - } - return modelFiles + return folders[0] ?? undefined } async startWatch(folder: WatchFolderState) { if (this.watchDisposers.has(folder.path)) throw new Error(`must stop watching folder first, ${folder.path}`) - // not currently watching for model info changes - if (folder.item_type === "ModelInfo") return - - // console.debug("starting watch", folder.path) + console.debug("starting watch", folder.path) const unwatch = watch( folder.path, async (e) => { + console.debug("watch event", e, shouldReact(e)) + if (!shouldReact(e)) return const projectFiles = e.paths .filter((p) => p.endsWith(".sqlite3") || p.endsWith(".sqlite3-wal")) .map((p) => p.replace(/-wal$/g, "")) if (projectFiles.length === 0) return const uniqueFiles = Array.from(new Set(projectFiles)) - this.container.emit("projectFilesChanged", { files: uniqueFiles }) + + for (const file of uniqueFiles) { + this.watchCallbacks.set(file, () => { + this.container.emit("projectFilesChanged", { files: [file] }) + }) + } }, - { delayMs: 2000, recursive: folder.recursive }, + { delayMs: 1500, recursive: folder.recursive }, ) this.watchDisposers.set(folder.path, unwatch) } @@ -322,6 +290,14 @@ export class WatchFoldersController extends DTPStateController { + return invoke("read_clipboard_types", { pasteboard }); +} + +export async function readClipboardStrings(types: string[], pasteboard: string | null): Promise> { + return invoke>("read_clipboard_strings", { types, pasteboard }); +} + +export async function readClipboardBinary(ty: string, pasteboard: string | null): Promise { + return invoke("read_clipboard_binary", { ty, pasteboard }); +} + +export async function writeClipboardBinary(ty: string, data: number[]): Promise { + return invoke("write_clipboard_binary", { ty, data }); +} + +export async function ffmpegCheck(): Promise { + return invoke("ffmpeg_check"); +} + +export async function ffmpegDownload(): Promise { + return invoke("ffmpeg_download"); +} + +export async function ffmpegCall(args: string[]): Promise { + return invoke("ffmpeg_call", { args }); +} + +export async function fetchImageFile(url: string): Promise { + return invoke("fetch_image_file", { url }); +} + +export async function showDevWindow(): Promise { + return invoke("show_dev_window"); +} + +export async function stemAll(): Promise { + return invoke("stem_all"); +} + +export async function createVideoFromFrames(imageId: number): Promise { + return invoke("create_video_from_frames", { imageId }); +} + +export async function projectsDbImageCount(): Promise { + return invoke("projects_db_image_count"); +} + +export async function projectsDbProjectAdd(path: string): Promise { + return invoke("projects_db_project_add", { path }); +} + +export async function projectsDbProjectRemove(path: string): Promise { + return invoke("projects_db_project_remove", { path }); +} + +export async function projectsDbProjectList(): Promise { + return invoke("projects_db_project_list"); +} + +export async function projectsDbProjectUpdateExclude(id: number, exclude: boolean): Promise { + return invoke("projects_db_project_update_exclude", { id, exclude }); +} + +export async function projectsDbProjectScan(path: string, fullScan: boolean | null, filesize: number | null, modified: number | null): Promise { + return invoke("projects_db_project_scan", { path, fullScan, filesize, modified }); +} + +export async function projectsDbImageList(projectIds: number[] | null, search: string | null, filters: ListImagesFilter[] | null, sort: string | null, direction: string | null, take: number | null, skip: number | null, count: boolean | null, showVideo: boolean | null, showImage: boolean | null): Promise { + return invoke("projects_db_image_list", { projectIds, search, filters, sort, direction, take, skip, count, showVideo, showImage }); +} + +export async function projectsDbGetClip(imageId: number): Promise { + return invoke("projects_db_get_clip", { imageId }); +} + +export async function projectsDbImageRebuildFts(): Promise { + return invoke("projects_db_image_rebuild_fts"); +} + +export async function projectsDbWatchFolderList(): Promise { + return invoke("projects_db_watch_folder_list"); +} + +export async function projectsDbWatchFolderAdd(path: string, itemType: entity::enums::ItemType, recursive: boolean): Promise { + return invoke("projects_db_watch_folder_add", { path, itemType, recursive }); +} + +export async function projectsDbWatchFolderRemove(ids: number[]): Promise { + return invoke("projects_db_watch_folder_remove", { ids }); +} + +export async function projectsDbWatchFolderUpdate(id: number, recursive: boolean | null, lastUpdated: number | null): Promise { + return invoke("projects_db_watch_folder_update", { id, recursive, lastUpdated }); +} + +export async function projectsDbScanModelInfo(filePath: string, modelType: entity::enums::ModelType): Promise { + return invoke("projects_db_scan_model_info", { filePath, modelType }); +} + +export async function projectsDbListModels(modelType: entity::enums::ModelType | null): Promise { + return invoke("projects_db_list_models", { modelType }); +} + +export async function dtProjectGetTensorHistory(projectFile: string, index: number, count: number): Promise { + return invoke("dt_project_get_tensor_history", { projectFile, index, count }); +} + +export async function dtProjectGetTextHistory(projectFile: string): Promise { + return invoke("dt_project_get_text_history", { projectFile }); +} + +export async function dtProjectGetThumbHalf(projectFile: string, thumbId: number): Promise { + return invoke("dt_project_get_thumb_half", { projectFile, thumbId }); +} + +export async function dtProjectGetHistoryFull(projectFile: string, rowId: number): Promise { + return invoke("dt_project_get_history_full", { projectFile, rowId }); +} + +export async function dtProjectGetTensorRaw(projectId: number | null, projectPath: string | null, tensorId: string): Promise { + return invoke("dt_project_get_tensor_raw", { projectId, projectPath, tensorId }); +} + +export async function dtProjectGetTensorSize(projectId: number | null, projectPath: string | null, tensorId: string): Promise { + return invoke("dt_project_get_tensor_size", { projectId, projectPath, tensorId }); +} + +export async function dtProjectDecodeTensor(projectId: number | null, projectFile: string | null, nodeId: number | null, tensorId: string, asPng: boolean): Promise { + return invoke("dt_project_decode_tensor", { projectId, projectFile, nodeId, tensorId, asPng }); +} + +export async function dtProjectFindPredecessorCandidates(projectFile: string, rowId: number, lineage: number, logicalTime: number): Promise { + return invoke("dt_project_find_predecessor_candidates", { projectFile, rowId, lineage, logicalTime }); +} + diff --git a/src/generated/types.ts b/src/generated/types.ts new file mode 100644 index 0000000..e518c3e --- /dev/null +++ b/src/generated/types.ts @@ -0,0 +1,325 @@ +// This file was auto-generated by tauri-ts-generator +// Do not edit this file manually + +export interface TensorSize { + width: number + height: number + channels: number +} + +export interface TensorRaw { + name: string + tensor_type: number + data_type: number + format: number + width: number + height: number + channels: number + dim: number[] + data: number[] +} + +export interface TensorHistoryExtra { + row_id: number + lineage: number + logical_time: number + tensor_id: string | null + mask_id: string | null + depth_map_id: string | null + scribble_id: string | null + pose_id: string | null + color_palette_id: string | null + custom_id: string | null + moodboard_ids: string[] + history: TensorHistoryNode + project_path: string +} + +export interface TensorHistoryNode { + lineage: number + logical_time: number + start_width: number + start_height: number + seed: number + steps: number + guidance_scale: number + strength: number + model: string | null + tensor_id: number + mask_id: number + wall_clock: string | null + text_edits: number + text_lineage: number + batch_size: number + sampler: number + hires_fix: boolean + hires_fix_start_width: number + hires_fix_start_height: number + hires_fix_strength: number + upscaler: string | null + scale_factor: number + depth_map_id: number + generated: boolean + image_guidance_scale: number + seed_mode: number + clip_skip: number + controls: Control[] | null + scribble_id: number + pose_id: number + loras: LoRA[] | null + color_palette_id: number + mask_blur: number + custom_id: number + face_restoration: string | null + clip_weight: number + negative_prompt_for_image_prior: boolean + image_prior_steps: number + data_stored: number + preview_id: number + content_offset_x: number + content_offset_y: number + scale_factor_by_120: number + refiner_model: string | null + original_image_height: number + original_image_width: number + crop_top: number + crop_left: number + target_image_height: number + target_image_width: number + aesthetic_score: number + negative_aesthetic_score: number + zero_negative_prompt: boolean + refiner_start: number + negative_original_image_height: number + negative_original_image_width: number + shuffle_data_stored: number + fps_id: number + motion_bucket_id: number + cond_aug: number + start_frame_cfg: number + num_frames: number + mask_blur_outset: number + sharpness: number + shift: number + stage_2_steps: number + stage_2_cfg: number + stage_2_shift: number + tiled_decoding: boolean + decoding_tile_width: number + decoding_tile_height: number + decoding_tile_overlap: number + stochastic_sampling_gamma: number + preserve_original_after_inpaint: boolean + tiled_diffusion: boolean + diffusion_tile_width: number + diffusion_tile_height: number + diffusion_tile_overlap: number + upscaler_scale_factor: number + script_session_id: number + t5_text_encoder: boolean + separate_clip_l: boolean + clip_l_text: string | null + separate_open_clip_g: boolean + open_clip_g_text: string | null + speed_up_with_guidance_embed: boolean + guidance_embed: number + resolution_dependent_shift: boolean + tea_cache_start: number + tea_cache_end: number + tea_cache_threshold: number + tea_cache: boolean + separate_t5: boolean + t5_text: string | null + tea_cache_max_skip_steps: number + text_prompt: string | null + negative_text_prompt: string | null + clip_id: number + index_in_a_clip: number + causal_inference_enabled: boolean + causal_inference: number + causal_inference_pad: number + cfg_zero_star: boolean + cfg_zero_init_steps: number + generation_time: number + reason: number +} + +export type LoRA = object + +export type Control = object + +export interface TextHistoryNode { + lineage: number + logical_time: number + start_edits: number + start_positive_text: string + start_negative_text: string + modifications: TextModification[] +} + +export interface TextModification { + modification_type: TextType + range: TextRange + text: string +} + +export interface TextRange { + location: number + length: number +} + +export interface TensorHistoryImport { + lineage: number + logical_time: number + tensor_id: string + width: number + height: number + seed: number + steps: number + guidance_scale: number + strength: number + model: string + wall_clock: string | null + sampler: number + hires_fix: boolean + upscaler: string | null + generated: boolean + controls: ModelAndWeight[] + loras: ModelAndWeight[] + preview_id: number + refiner_model: string | null + refiner_start: number + shift: number + tiled_decoding: boolean + tiled_diffusion: boolean + resolution_dependent_shift: boolean + tea_cache: boolean + prompt: string + negative_prompt: string + clip_id: number + index_in_a_clip: number + num_frames: number | null + cfg_zero_star: boolean + row_id: number + has_depth: boolean + has_pose: boolean + has_color: boolean + has_custom: boolean + has_scribble: boolean + has_shuffle: boolean + has_mask: boolean + text_edits: number + text_lineage: number +} + +export interface ModelAndWeight { + model: string + weight: number +} + +export interface ModelExtra { + id: number + model_type: string + filename: string + name: string | null + version: string | null + count: number +} + +export interface WatchFolderDTO { + id: number + path: string + recursive: boolean | null + item_type: string + last_updated: number | null +} + +export interface TensorHistoryClip { + tensor_id: string + preview_id: number + clip_id: number + index_in_a_clip: number + row_id: number +} + +export interface ListImagesResult { + counts: ImageCount[] | null + images: ImageExtra[] | null + total: number +} + +export interface ImageExtra { + id: number + project_id: number + model_id: number | null + model_file: string | null + prompt: string + negative_prompt: string + num_frames: number | null + preview_id: number + node_id: number + has_depth: boolean + has_pose: boolean + has_color: boolean + has_custom: boolean + has_scribble: boolean + has_shuffle: boolean + start_width: number + start_height: number + upscaler_scale_factor: number | null +} + +export interface ImageCount { + project_id: number + count: number +} + +export interface ListImagesFilter { + target: ListImagesFilterTarget + operator: ListImagesFilterOperator + value: ListImagesFilterValue +} + +export interface ProjectExtra { + id: number + fingerprint: string + path: string + image_count: number | null + last_id: number | null + filesize: number | null + modified: number | null + missing_on: number | null + excluded: boolean +} + +export type TextType = "PositiveText" | "NegativeText" + +export type ListImagesFilterValue = string[] | number[] + +export type ListImagesFilterOperator = + | "eq" + | "neq" + | "gt" + | "gte" + | "lt" + | "lte" + | "is" + | "isnot" + | "has" + | "hasall" + | "doesnothave" + +export type ListImagesFilterTarget = + | "model" + | "lora" + | "control" + | "sampler" + | "content" + | "seed" + | "steps" + | "width" + | "height" + | "textguidance" + | "shift" + +export type TextHistoryNodeDTO = TextHistoryNode diff --git a/src/hooks/appState.ts b/src/hooks/appState.ts index 766383c..a40bdf6 100644 --- a/src/hooks/appState.ts +++ b/src/hooks/appState.ts @@ -1,6 +1,6 @@ import { check } from "@tauri-apps/plugin-updater" +// import { check } from "@/mocks/tauri-updater" import { store } from "@tauri-store/valtio" -import { postMessage } from "@/context/Messages" import { getStoreName } from "@/utils/helpers" type ViewRequest = { @@ -86,37 +86,15 @@ async function downloadAndInstallUpdate() { if (!update || appState.updateStatus !== "found") return try { appState.updateStatus = "downloading" - postMessage({ - channel: "toolbar", - message: "Downloading update...", - uType: "update", - }) await update.download() appState.updateStatus = "installing" - postMessage({ - channel: "toolbar", - message: "Installing update...", - uType: "update", - }) await update.install() appState.updateStatus = "installed" - postMessage({ - channel: "toolbar", - message: "Update installed! Click the update button to restart", - duration: 3000, - uType: "update", - }) } catch (e) { console.error(e) appState.updateStatus = "error" - postMessage({ - channel: "toolbar", - message: "There was a problem installing the update. Click to retry.", - duration: 3000, - uType: "update", - }) } } diff --git a/src/hooks/useFfmpeg.tsx b/src/hooks/useFfmpeg.tsx new file mode 100644 index 0000000..2863b7d --- /dev/null +++ b/src/hooks/useFfmpeg.tsx @@ -0,0 +1,117 @@ +import { Box, FormatByte, Grid } from "@chakra-ui/react" +import { listen } from "@tauri-apps/api/event" +import { memo, useEffect } from "react" +import { ffmpegCheck, ffmpegDownload } from "@/commands" +import { PanelButton, PanelSection, Progress } from "@/components" +import { useProxyRef } from "./valtioHooks" + +type FfmpegStatus = "unknown" | "not-installed" | "installed" | "installing" | "error" +type FfmpegProgress = { + progress: number + total: number + received: number + msg: string +} + +export function useFfmpeg() { + const { state, snap } = useProxyRef(() => ({ + showComponent: false, + status: "unknown" as FfmpegStatus, + progressText: "", + progress: 0, + total: 0, + received: 0, + })) + + useEffect(() => { + ffmpegCheck().then((result) => { + state.status = result ? "installed" : "not-installed" + if (!result) state.showComponent = true + }) + }, [state]) + + const installFfmpeg = async () => { + const unlisten = await listen("ffmpeg_download_progress", (event) => { + // event msgs are progress, verifying, extracting, installing, done + // probably excessive + const msg = event.payload.msg + switch (msg) { + case "progress": + state.progress = event.payload.progress + state.total = event.payload.total + state.received = event.payload.received + break + case "verifying": + state.progressText = "Verifying..." + break + case "extracting": + state.progressText = "Extracting..." + break + case "installing": + state.progressText = "Installing..." + break + case "done": + state.progressText = "Done" + break + } + }) + state.status = "installing" + try { + state.progressText = "Downloading..." + await ffmpegDownload() + state.status = "installed" + } catch (e) { + state.status = "error" + state.progressText = `Something went wrong: ${e}` + } finally { + unlisten() + } + } + + const FfmpegComponent = memo((props: ChakraProps) => { + if (!snap.showComponent) return null + return ( + + + FFMPEG must be downloaded before video can be exported. + { + installFfmpeg() + }} + disabled={snap.status === "installing" || snap.status === "installed"} + > + { + { + "not-installed": "Install", + installing: "Installing...", + installed: "Done!", + error: "Retry", + unknown: "Install", + }[snap.status] + } + + {snap.total > 0 && ( + // + } + labelB={} + showValueText={true} + value={snap.progress * 100} + /> + )} + + + ) + }) + + return { status: snap.status, isReady: snap.status === "installed", FfmpegComponent } +} diff --git a/src/hooks/useGetContext.tsx b/src/hooks/useGetContext.tsx new file mode 100644 index 0000000..0e8155c --- /dev/null +++ b/src/hooks/useGetContext.tsx @@ -0,0 +1,21 @@ +import { useContext, useRef } from "react" + +/** + * This is a somewhat hacky solution to allow a component to access a context + * within a child component. The Extractor component should be placed as a child + * of the component you want to access the context from. Either provide the ref as + * an arg, or use the ref returned + */ +export function useGetContext(context: React.Context, ref?: React.RefObject) { + const contextRef = useRef(null) + + const Extractor = () => { + const ctx = useContext(context) + contextRef.current = ctx + if (ref) ref.current = ctx + + return null + } + + return { Extractor, contextRef } +} diff --git a/src/hooks/useRootElement.ts b/src/hooks/useRootElement.ts index 02f8809..9497d59 100644 --- a/src/hooks/useRootElement.ts +++ b/src/hooks/useRootElement.ts @@ -27,6 +27,10 @@ function getElement(id: keyof typeof rootElementIds, view?: string) { export function useRootElement(rootElement: RootElement) { const { currentView } = useSnapshot(AppStore.store) + if (process.env.NODE_ENV === "test") { + return document.getElementById("root") + } + const element = getElement(rootElement, currentView) if (!element) throw new Error(`Element ${rootElementIds[rootElement]} not found`) return element diff --git a/src/index.css b/src/index.css index 7b2db93..25d421b 100644 --- a/src/index.css +++ b/src/index.css @@ -8,14 +8,23 @@ .loading-text { color: #8e97a2; - font-size: 2rem; + font-size: 3rem; font-weight: 600; + font-family: -apple-system, BlinkMacSystemFont, sans-serif; +} + +:root.dark .loading-text { + color: #b9bfc5; } #root { background-color: #dbdddf; } +:root.dark #root { + background-color: #1a1a1d; +} + .error-container { width: 100%; height: 100%; diff --git a/src/main.tsx b/src/main.tsx index 6602baa..7abf89d 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -7,68 +7,69 @@ import { createRoot } from "react-dom/client" import { ColorModeProvider } from "./components/ui/color-mode" import AppStore from "./hooks/appState" import "./index.css" +import { HotkeysProvider } from "react-hotkeys-hook" import { themeHelpers } from "./theme/helpers" import { system } from "./theme/theme" -import { HotkeysProvider } from "react-hotkeys-hook" +// import "./utils/tauriLogger" +import App from './App' -window.toJSON = (object: unknown) => JSON.parse(JSON.stringify(object)) +function bootstrap() { + window.toJSON = (object: unknown) => JSON.parse(JSON.stringify(object)) -const hash = document.location?.hash?.slice(1) -if (hash === "mini") AppStore.setView("mini") -else if (hash === "vid") AppStore.setView("vid") + const hash = document.location?.hash?.slice(1) + if (hash === "mini") AppStore.setView("mini") + else if (hash === "vid") AppStore.setView("vid") -const RootComponent = lazy(() => { - if (hash === "dev") return import("./Dev") - else return import("./App") -}) + const RootComponent = App -themeHelpers.applySize() + themeHelpers.applySize() -if (import.meta.env.DEV) { - const _global = globalThis as unknown as { _devKeyPressHandler?: (e: KeyboardEvent) => void } - if (_global._devKeyPressHandler) { - window.removeEventListener("keypress", _global._devKeyPressHandler) - } - _global._devKeyPressHandler = async (e: KeyboardEvent) => { - if (e.key === "`") { - invoke("show_dev_window") - } - } - window.addEventListener("keypress", _global._devKeyPressHandler) -} + if (import.meta.env.DEV) { + const _global = globalThis as unknown as { _devKeyPressHandler?: (e: KeyboardEvent) => void } + if (_global._devKeyPressHandler) { + window.removeEventListener("keypress", _global._devKeyPressHandler) + } + _global._devKeyPressHandler = async (e: KeyboardEvent) => { + if (e.key === "`") { + invoke("show_dev_window") + } + } + window.addEventListener("keypress", _global._devKeyPressHandler) + } -// this ensures that the window appears even if an error is thrown in the initial render -if (hash !== "dev") { - setTimeout(() => { - getCurrentWindow().show() - }, 3000) -} + // this ensures that the window appears even if an error is thrown in the initial render + if (hash !== "dev") { + setTimeout(() => { + getCurrentWindow().show() + }, 3000) + } -const root = document.getElementById("root") -if (root) - createRoot(root).render( - - - - - - - - - , - ) + const root = document.getElementById("root") + if (root) + createRoot(root).render( + + + + + + + + + , + ) +} export function Loading() { - return ( - -
- Loading... -
-
- ) + return ( + +
Loading...
+
+ ) } + +bootstrap() diff --git a/src/menu.ts b/src/menu.ts index 23c7891..411f8ae 100644 --- a/src/menu.ts +++ b/src/menu.ts @@ -17,15 +17,11 @@ import AppStore from "./hooks/appState" import { themeHelpers } from "./theme/helpers" import { getLocalImage } from "./utils/clipboard" import { viewDescription } from "./views" +import { clearAll, clearCurrent, createImageItem, getMetadataStore } from './metadata/state/store' +import { loadImage2 } from './metadata/state/imageLoaders' const Separator = () => PredefinedMenuItem.new({ item: "Separator" }) -let _metadataStore = null as typeof import("./metadata/state/store") | null -async function getMetadataStore() { - if (!_metadataStore) _metadataStore = await import("./metadata/state/store") - return _metadataStore -} - const aboutApp: AboutMetadata = { name: "DTM", version: await getVersion(), @@ -110,7 +106,7 @@ const fileSubmenu = await Submenu.new({ if (imagePath == null) return const image = await getLocalImage(imagePath) if (image) - await (await getMetadataStore()).createImageItem( + await createImageItem( image, await pathLib.extname(imagePath), { @@ -124,7 +120,6 @@ const fileSubmenu = await Submenu.new({ text: "Open from pasteboard...", id: "file_openPasteboard", action: async () => { - const { loadImage2 } = await import("./metadata/state/imageLoaders") await loadImage2("general") }, }), @@ -133,21 +128,21 @@ const fileSubmenu = await Submenu.new({ text: "Close", id: "file_close", action: async () => { - await (await getMetadataStore()).clearCurrent() + await clearCurrent() }, }), await MenuItem.new({ text: "Close unpinned", id: "file_closeUnpinned", action: async () => { - await (await getMetadataStore()).clearAll(true) + await clearAll(true) }, }), await MenuItem.new({ text: "Close all", id: "file_closeAll", action: async () => { - await (await getMetadataStore()).clearAll(false) + await clearAll(false) }, }), ], diff --git a/src/metadata/components/CurrentImage.tsx b/src/metadata/components/CurrentImage.tsx index bfa5dc0..0396506 100644 --- a/src/metadata/components/CurrentImage.tsx +++ b/src/metadata/components/CurrentImage.tsx @@ -3,14 +3,14 @@ import { AnimatePresence, motion, } from "motion/react" import { useRef } from "react" import { useSnapshot } from "valtio" import { showPreview } from "@/components/preview" -import { MetadataStore } from "../state/store" +import { getMetadataStore } from "../state/store" interface CurrentImageProps extends ChakraProps {} function CurrentImage(props: CurrentImageProps) { const { ...restProps } = props - const snap = useSnapshot(MetadataStore) + const snap = useSnapshot(getMetadataStore()) const { currentImage } = snap const imgRef = useRef(null) diff --git a/src/metadata/components/CurrentImageZoomPan.tsx b/src/metadata/components/CurrentImageZoomPan.tsx index a8a1d94..9633055 100644 --- a/src/metadata/components/CurrentImageZoomPan.tsx +++ b/src/metadata/components/CurrentImageZoomPan.tsx @@ -1,18 +1,17 @@ // @ts-nocheck import { Box, chakra, Flex } from "@chakra-ui/react" -import { MetadataStore } from "../state/store" +import { getMetadataStore } from "../state/store" import { useSnapshot } from "valtio" import { motion, useMotionValue, useSpring } from 'motion/react' -import { showPreview } from '@/components/preview' -import { useEffect, useRef } from 'react' +import { useRef } from 'react' interface CurrentImageProps extends ChakraProps {} function CurrentImage(props: CurrentImageProps) { const { ...restProps } = props - const snap = useSnapshot(MetadataStore) + const snap = useSnapshot(getMetadataStore()) const { currentImage } = snap const zoomMv = useSpring(1, {bounce: 0, visualDuration: 0.2}) diff --git a/src/metadata/history/History.tsx b/src/metadata/history/History.tsx index 04a45dc..daba15e 100644 --- a/src/metadata/history/History.tsx +++ b/src/metadata/history/History.tsx @@ -3,7 +3,7 @@ import { motion, useMotionValue } from "motion/react" import { useCallback, useRef } from "react" import { useSnapshot } from "valtio" import type { ImageItem } from "../state/ImageItem" -import { MetadataStore, selectImage } from "../state/store" +import { getMetadataStore, selectImage } from "../state/store" import HistoryItem from "./HistoryItem" interface HistoryProps extends Omit {} @@ -11,7 +11,7 @@ interface HistoryProps extends Omit {} function History(props: HistoryProps) { const { ...restProps } = props - const snap = useSnapshot(MetadataStore) + const snap = useSnapshot(getMetadataStore()) const { images, currentImage } = snap const pinned = images.filter((i) => i.pin != null) as ImageItem[] diff --git a/src/metadata/history/HistoryItem.tsx b/src/metadata/history/HistoryItem.tsx index 74079de..a0a976c 100644 --- a/src/metadata/history/HistoryItem.tsx +++ b/src/metadata/history/HistoryItem.tsx @@ -1,10 +1,10 @@ import { type BoxProps, chakra } from "@chakra-ui/react" import { motion } from "motion/react" import { useEffect, useRef } from "react" -import type { MetadataStore } from "../state/store" +import type { getMetadataStore } from "../state/store" interface HistoryItemProps extends BoxProps { - image: ReadonlyState<(typeof MetadataStore)["images"][number]> + image: ReadonlyState["images"][number]> isSelected: boolean onSelect?: () => void isPinned?: boolean diff --git a/src/metadata/state/context.tsx b/src/metadata/state/context.tsx index 66dd64a..1eea8c5 100644 --- a/src/metadata/state/context.tsx +++ b/src/metadata/state/context.tsx @@ -1,10 +1,10 @@ -import { createContext, type PropsWithChildren } from "react" +import { createContext, useContext, type PropsWithChildren } from "react" import type { ImageSource } from "@/types" import type { ImageItem } from "./ImageItem" -import type { ExifType, ImageItemParam, MetadataStore } from "./store" +import type { ExifType, ImageItemParam, getMetadataStore } from "./store" export type MetadataStoreContextType = { - state: typeof MetadataStore + state: ReturnType selectImage(image?: ImageItemParam | null): void pinImage(image: ImageItemParam, value: number | boolean | null): void pinImage(useCurrent: true, value: number | boolean | null): void diff --git a/src/metadata/state/hooks.ts b/src/metadata/state/hooks.ts index 8c8ce1b..33a071c 100644 --- a/src/metadata/state/hooks.ts +++ b/src/metadata/state/hooks.ts @@ -1,10 +1,10 @@ import { useSnapshot } from 'valtio' import type { ImageItem } from './ImageItem' -import { MetadataStore } from './store' +import { getMetadataStore } from './store' + -const store = MetadataStore export function useCurrentImage(): ReadonlyState | undefined { - const snap = useSnapshot(store) + const snap = useSnapshot(getMetadataStore()) return snap.currentImage } \ No newline at end of file diff --git a/src/metadata/state/interop.ts b/src/metadata/state/interop.ts index 0bc0cf3..2468ad5 100644 --- a/src/metadata/state/interop.ts +++ b/src/metadata/state/interop.ts @@ -1,30 +1,22 @@ import AppStore from "@/hooks/appState" import type { ImageSource } from "@/types" import type { ImageItem } from "./ImageItem" - -let _metadataStore: typeof import("./store") -async function getStore() { - if (!_metadataStore) { - _metadataStore = await import("./store") - } - return _metadataStore -} +import { createImageItem, getMetadataStore, selectImage } from './store' export async function sendToMetadata( imageData: Uint8Array, type: string, source: ImageSource, ) { - const store = await getStore() - // check if the item already has been sent to the store - let imageItem = store.MetadataStore.images.find((im) => + const state = getMetadataStore() + let imageItem = state.images.find((im) => compareImageSource(im.source, source), ) as Nullable - imageItem ??= await store.createImageItem(imageData, type, source) + imageItem ??= await createImageItem(imageData, type, source) if (imageItem) { - store.selectImage(imageItem) + selectImage(imageItem) await AppStore.setView("metadata") } } diff --git a/src/metadata/state/store.ts b/src/metadata/state/store.ts index d798309..54fc4ab 100644 --- a/src/metadata/state/store.ts +++ b/src/metadata/state/store.ts @@ -1,4 +1,3 @@ -import { getCurrentWindow } from "@tauri-apps/api/window" import { readFile } from "@tauri-apps/plugin-fs" import { store } from "@tauri-store/valtio" import * as exifr from "exifr" @@ -16,57 +15,78 @@ export function bind(instance: T): T { for (const prop of props) { const method = instance[prop as keyof T] if (prop === "constructor" || typeof method !== "function") continue - ;(instance as Record)[prop] = (...args: unknown[]) => - method.apply(instance, args) + ; (instance as Record)[prop] = (...args: unknown[]) => + method.apply(instance, args) } return instance } -const metadataStore = store( - getStoreName("metadata"), - { - images: [] as ImageItem[], - currentIndex: null as number | null, - zoomPreview: false, - showHistory: false, - maxHistory: 10, - get currentImage(): ImageItem | undefined { - if (MetadataStore.currentIndex === null) return undefined - return MetadataStore.images[MetadataStore.currentIndex] + +function initStore() { + const storeInstance = store( + getStoreName("metadata"), + { + images: [] as ImageItem[], + currentIndex: null as number | null, + zoomPreview: false, + showHistory: false, + maxHistory: 10, + get currentImage(): ImageItem | undefined { + const s = getMetadataStore() + if (s.currentIndex === null) return undefined + return s.images[s.currentIndex] + }, }, - }, - { - filterKeys: ["currentImage", "currentIndex", "zoomPreview", "showHistory"], - filterKeysStrategy: "omit", - saveOnChange: true, - saveOnExit: true, - saveStrategy: "debounce", - syncStrategy: "throttle", - saveInterval: 60000, - syncInterval: 1000, - - hooks: { - beforeFrontendSync(state) { - if (typeof state !== "object" || state === null) return state - - if ("images" in state && Array.isArray(state.images)) { - state.images = state.images.map((im) => { - if (im instanceof ImageItem) return im - const newIm = bind(proxy(new ImageItem(im as ImageItemConstructorOpts))) - newIm.loadEntry() - newIm.loadExif() - return newIm - }) - } - - return state + { + autoStart: true, + filterKeys: ["currentImage", "currentIndex", "zoomPreview", "showHistory"], + filterKeysStrategy: "omit", + saveOnChange: true, + saveOnExit: true, + saveStrategy: "debounce", + syncStrategy: "throttle", + saveInterval: 60000, + syncInterval: 1000, + + hooks: { + beforeFrontendSync(state) { + if (typeof state !== "object" || state === null) return state + + if ("images" in state && Array.isArray(state.images)) { + state.images = state.images.map((im) => { + if (im instanceof ImageItem) return im + const newIm = bind(proxy(new ImageItem(im as ImageItemConstructorOpts))) + newIm.loadEntry() + newIm.loadExif() + return newIm + }) + } + + return state + }, }, }, - }, -) -export const MetadataStore = metadataStore.state -await metadataStore.start() + ) + window.addEventListener("unload", () => { + cleanUp() + getStore().stop() + }) + return storeInstance +} + +let metadataStore: ReturnType | undefined + +function getStore() { + if (!metadataStore) { + metadataStore = initStore() + } + return metadataStore! +} + +export function getMetadataStore() { + return getStore().state +} export type ImageItemParam = ReadonlyState | ImageItem | number | null @@ -78,17 +98,11 @@ export type ImageItemParam = ReadonlyState | ImageItem | number | nul // await window.destroy() // }) -window.addEventListener("unload", () => { - // unlisten.then((u) => u()) - cleanUp() - metadataStore.stop() -}) - async function cleanUp() { const clearHistory = AppStore.store.clearHistoryOnExit const clearPins = AppStore.store.clearPinsOnExit - const saveIds = MetadataStore.images + const saveIds = getMetadataStore().images .filter((im) => { if (im.pin != null && !clearPins) return true if (!clearHistory) return true @@ -96,28 +110,29 @@ async function cleanUp() { }) .map((im) => im.id) - MetadataStore.images = MetadataStore.images.filter((im) => saveIds.includes(im.id)) + getMetadataStore().images = getMetadataStore().images.filter((im) => saveIds.includes(im.id)) await syncImageStore() } async function syncImageStore() { - const ids = MetadataStore.images.map((im) => im.id) + const ids = getMetadataStore().images.map((im) => im.id) await ImageStore.sync(ids) } export function selectImage(image?: ImageItemParam | null) { + const state = getMetadataStore() if (image == null) { - MetadataStore.currentIndex = null + state.currentIndex = null } else if (typeof image === "number") { - if (image < 0 || image >= MetadataStore.images.length) return - MetadataStore.currentIndex = image + if (image < 0 || image >= state.images.length) return + state.currentIndex = image } else { - const index = MetadataStore.images.findIndex((im) => im.id === image?.id) + const index = state.images.findIndex((im) => im.id === image?.id) if (index === -1) return - MetadataStore.currentIndex = index + state.currentIndex = index } - if (MetadataStore.currentIndex === null) console.log("selected no image") - else console.debug("selected image", MetadataStore.images[MetadataStore.currentIndex].id) + if (state.currentIndex === null) console.log("selected no image") + else console.debug("selected image", state.images[state.currentIndex].id) } export function pinImage(image: ImageItemParam, value: number | boolean | null): void @@ -128,11 +143,11 @@ export function pinImage( ): void { let index = -1 if (typeof imageOrCurrent === "number") index = imageOrCurrent - else if (imageOrCurrent === true) index = MetadataStore.currentIndex ?? -1 - else index = MetadataStore.images.findIndex((im) => im.id === imageOrCurrent?.id) + else if (imageOrCurrent === true) index = getMetadataStore().currentIndex ?? -1 + else index = getMetadataStore().images.findIndex((im) => im.id === imageOrCurrent?.id) - if (index < 0 || index >= MetadataStore.images.length) return - const storeImage = MetadataStore.images[index] + if (index < 0 || index >= getMetadataStore().images.length) return + const storeImage = getMetadataStore().images[index] if (!storeImage) return const pinValue = @@ -143,7 +158,7 @@ export function pinImage( } function reconcilePins() { - const pins = MetadataStore.images + const pins = getMetadataStore().images .filter((im) => im.pin != null) .sort((a, b) => (a.pin ?? 0) - (b.pin ?? 0)) @@ -153,19 +168,20 @@ function reconcilePins() { } export async function clearAll(keepTabs = false) { - if (keepTabs) MetadataStore.images = MetadataStore.images.filter((im) => im.pin != null) - else MetadataStore.images = [] + if (keepTabs) getMetadataStore().images = getMetadataStore().images.filter((im) => im.pin != null) + else getMetadataStore().images = [] await syncImageStore() } async function clearImage(images: Pick[]) { const ids = images.map((image) => image.id) - MetadataStore.images = MetadataStore.images.filter((image) => !ids.includes(image.id)) + getMetadataStore().images = getMetadataStore().images.filter((image) => !ids.includes(image.id)) await syncImageStore() } export async function clearCurrent() { - if (MetadataStore.currentImage) await clearImage([MetadataStore.currentImage]) + const cur = getMetadataStore().currentImage + if (cur) await clearImage([cur]) } export async function createImageItem( @@ -197,10 +213,10 @@ export async function createImageItem( } const imageItem = bind(proxy(new ImageItem(item))) - const itemIndex = MetadataStore.images.push(imageItem) - 1 + const itemIndex = getMetadataStore().images.push(imageItem) - 1 selectImage(itemIndex) - return MetadataStore.images[itemIndex] + return getMetadataStore().images[itemIndex] } /** @@ -213,7 +229,7 @@ async function replaceWithBetter( imageType: string, source: ImageSource, ) { - const index = MetadataStore.images.indexOf(imageItem) + const index = getMetadataStore().images.indexOf(imageItem) if (index === -1) return const exif = await getExif(imageData.buffer) @@ -233,7 +249,7 @@ async function replaceWithBetter( exif, dtData, } - MetadataStore.images[index] = bind(proxy(new ImageItem(item))) + getMetadataStore().images[index] = bind(proxy(new ImageItem(item))) } await syncImageStore() if (dtData) return dtData diff --git a/src/metadata/toolbar/Toolbar.tsx b/src/metadata/toolbar/Toolbar.tsx index 2f57155..a14701a 100644 --- a/src/metadata/toolbar/Toolbar.tsx +++ b/src/metadata/toolbar/Toolbar.tsx @@ -2,7 +2,7 @@ import { Box } from "@chakra-ui/react" import { AnimatePresence, LayoutGroup, motion } from "motion/react" import { useSnapshot } from "valtio" import { useMessages } from "@/context/Messages" -import { MetadataStore } from "../state/store" +import { getMetadataStore } from "../state/store" import { toolbarCommands } from "./commands" import { ContentHeaderContainer, ToolbarButtonGroup, ToolbarContainer, ToolbarRoot } from "./parts" import ToolbarItem from "./ToolbarItem" @@ -10,7 +10,7 @@ import ToolbarItem from "./ToolbarItem" function Toolbar(props: ChakraProps) { const { ...restProps } = props - const snap = useSnapshot(MetadataStore) + const snap = useSnapshot(getMetadataStore()) const messageChannel = useMessages("toolbar") diff --git a/src/metadata/toolbar/ToolbarButton.tsx b/src/metadata/toolbar/ToolbarButton.tsx index 962be1b..deafa98 100644 --- a/src/metadata/toolbar/ToolbarButton.tsx +++ b/src/metadata/toolbar/ToolbarButton.tsx @@ -1,32 +1,32 @@ import type { ComponentProps, ComponentType, PropsWithChildren, SVGProps } from "react" -import type { IconType } from "@/components/icons" import { IconButton } from "@/components" +import type { IconType } from "@/components/icons/icons" import Tooltip from "@/components/Tooltip" type ToolbarButtonProps = ComponentProps & { - icon?: IconType | ComponentType> - tip?: string + icon?: IconType | ComponentType> + tip?: string } function ToolbarButton(props: PropsWithChildren) { - const { icon: Icon, children, onClick, tip, ...restProps } = props + const { icon: Icon, children, onClick, tip, ...restProps } = props - const content = Icon ? : children + const content = Icon ? : children - return ( - - - {content} - - - ) + return ( + + + {content} + + + ) } export default ToolbarButton diff --git a/src/metadata/toolbar/ToolbarItem.tsx b/src/metadata/toolbar/ToolbarItem.tsx index 2a04f92..b31cfa8 100644 --- a/src/metadata/toolbar/ToolbarItem.tsx +++ b/src/metadata/toolbar/ToolbarItem.tsx @@ -1,6 +1,6 @@ import { useSnapshot } from "valtio" import { MotionBox } from "@/components/common" -import { MetadataStore } from "../state/store" +import { getMetadataStore } from "../state/store" import type { ToolbarCommand } from "./commands" import ToolbarButton from "./ToolbarButton" @@ -14,14 +14,14 @@ const separatorProps: ChakraProps["_before"] = { } interface ToolbarItemProps { - command: ToolbarCommand + command: ToolbarCommand> showSeparator?: boolean state: "hide" | "show" } export function ToolbarItem(props: ToolbarItemProps) { const { command, showSeparator, state } = props - const snap = useSnapshot(MetadataStore) as ReadonlyState + const snap = useSnapshot(getMetadataStore()) as ReadonlyState> const tip = command.tip ?? command.getTip?.(snap) const Icon = command.icon @@ -66,7 +66,7 @@ export function ToolbarItem(props: ToolbarItemProps) { // exit={"hide"} // layout={"preserve-aspect"} > - command.action(MetadataStore)}> + command.action(getMetadataStore())}> {content} diff --git a/src/metadata/toolbar/UpgradeButton.tsx b/src/metadata/toolbar/UpgradeButton.tsx index e9a0e0d..29e0efd 100644 --- a/src/metadata/toolbar/UpgradeButton.tsx +++ b/src/metadata/toolbar/UpgradeButton.tsx @@ -1,7 +1,7 @@ -import { Icon } from "@chakra-ui/react" +import { Icon, Popover, Portal } from "@chakra-ui/react" import { relaunch } from "@tauri-apps/plugin-process" import { motion } from "motion/react" -import { type ComponentProps, useEffect, useState } from "react" +import { type ComponentProps, useCallback, useEffect, useState } from "react" import { useSnapshot } from "valtio" import { SidebarButton } from "@/components/sidebar/Sidebar" import { type ColorMode, useColorMode } from "@/components/ui/color-mode" @@ -16,6 +16,7 @@ const statusTips = { downloading: "Downloading update", installing: "Installing update", } as const + function getStatusTip(status: (typeof AppStore.store)["updateStatus"]) { if (status in statusTips) return statusTips[status as keyof typeof statusTips] else return undefined @@ -24,19 +25,32 @@ function getStatusTip(status: (typeof AppStore.store)["updateStatus"]) { const UpgradeButton = (props: Omit, "label" | "icon">) => { const appSnap = useSnapshot(AppStore.store) const [showHiddenButton, setShowHiddenButton] = useState(false) + const [message, setMessage] = useState(null) + // const [prevStatus, setPrevStatus] = useState(appSnap.updateStatus) + + const showMessage = useCallback((message: string) => { + setMessage(message) + setTimeout(() => setMessage(null), 4000) + }, []) useEffect(() => { if (appSnap.updateStatus === "unknown") AppStore.checkForUpdate() - if ( - appSnap.updateStatus === "found" || - appSnap.updateStatus === "installed" || - appSnap.updateStatus === "error" - ) { - setShowHiddenButton(true) - setTimeout(() => setShowHiddenButton(false), 5000) + if (appSnap.updateStatus === "found") { + showMessage("Update available! Click to download.") + } + if (appSnap.updateStatus === "installed") { + showMessage("Update installed! Click to restart.") + } + if (appSnap.updateStatus === "error") { + showMessage("Update failed! Click to retry.") } - }, [appSnap.updateStatus]) + + // { + // setShowHiddenButton(true) + // setTimeout(() => setShowHiddenButton(false), 5000) + // } + }, [appSnap.updateStatus, showMessage]) if (appSnap.updateAttempts >= 3) return null @@ -44,23 +58,35 @@ const UpgradeButton = (props: Omit, "label" if (["found", "installed"].includes(appSnap.updateStatus)) { return ( - { - if (AppStore.store.updateStatus === "found") { - await AppStore.downloadAndInstallUpdate() - } else if (appSnap.updateStatus === "installed") await relaunch() - else if (appSnap.updateStatus === "error") await AppStore.retryUpdate() - }} - {...props} - /> + + + { + if (AppStore.store.updateStatus === "found") { + await AppStore.downloadAndInstallUpdate() + } else if (appSnap.updateStatus === "installed") await relaunch() + else if (appSnap.updateStatus === "error") await AppStore.retryUpdate() + }} + {...props} + /> + + + + + + {message} + + + + ) } if (appSnap.updateStatus === "downloading" || appSnap.updateStatus === "installing") { - return + return } } diff --git a/src/metadata/toolbar/commands.tsx b/src/metadata/toolbar/commands.tsx index 2f6f525..ebd5a4d 100644 --- a/src/metadata/toolbar/commands.tsx +++ b/src/metadata/toolbar/commands.tsx @@ -1,121 +1,128 @@ import { save } from "@tauri-apps/plugin-dialog" import { openUrl, revealItemInDir } from "@tauri-apps/plugin-opener" -import type { IconType } from "@/components/icons" -import { FiClipboard, FiCopy, FiFolder, FiSave, FiXCircle, TbBrowser } from "@/components/icons" +import type { IconType } from "@/components/icons/icons" +import { + FiClipboard, + FiCopy, + FiFolder, + FiSave, + FiXCircle, + TbBrowser, +} from "@/components/icons/icons" import { postMessage } from "@/context/Messages" import ImageStore from "@/utils/imageStore" import { loadImage2 } from "../state/imageLoaders" -import { clearAll, MetadataStore, pinImage } from "../state/store" +import { clearAll, getMetadataStore, pinImage } from "../state/store" import PinnedIcon from "./PinnedIcon" let separatorId = 0 const separator = () => - ({ id: `separator-${separatorId++}`, separator: true }) as ToolbarCommand + ({ id: `separator-${separatorId++}`, separator: true }) as ToolbarCommand -export const toolbarCommands: ToolbarCommand[] = [ - { - id: "loadFromClipboard", - tip: "Load image from clipboard", - icon: FiClipboard, - action: async () => { - try { - await loadImage2("general") - } catch (e) { - console.error(e) - } - }, - }, - { - id: "copyImage", - tip: "Copy image to clipboard", - action: async (store) => { - if (!store.currentImage) return - await ImageStore.copy(store.currentImage?.id) - }, - check: (snap) => snap.currentImage != null, - icon: FiCopy, - }, - separator(), - { - id: "pinImage", - getTip: (snap) => (snap.currentImage?.pin ? "Unpin image" : "Pin image"), - getIcon: (snap: ReadonlyState) => ( - - ), - check: (snap) => snap.currentImage != null, - action: async () => { - const pin = MetadataStore.currentImage?.pin !== null ? null : true - pinImage(true, pin) - postMessage({ - message: pin ? "Image pinned" : "Pin removed", - uType: "pinimage", - duration: 2000, - channel: "toolbar", - }) - }, - }, - { - id: "clearUnpinned", - tip: "Clear unpinned images", - action: () => clearAll(true), - check: (snap) => snap.images.some((im) => im.pin == null), - icon: FiXCircle, - }, - separator(), - { - id: "saveImage", - tip: "Save a copy", - action: async (store) => { - if (!store.currentImage) return - const savePath = await save({ - canCreateDirectories: true, - title: "Save image", - filters: [{ name: "Image", extensions: [store.currentImage.type] }], - }) - if (savePath) { - await ImageStore.saveCopy(store.currentImage.id, savePath) - } - }, - check: (snap) => snap.currentImage != null, - icon: FiSave, - }, - { - id: "openFolder", - tip: "Open folder", - slotId: "sourceOpen", - action: async (store) => { - if (!store.currentImage?.source?.file) return - await revealItemInDir(store.currentImage?.source?.file) - }, - check: (snap) => snap.currentImage?.source?.file != null, - icon: FiFolder, - }, - { - id: "openUrl", - slotId: "sourceOpen", - tip: "Open URL", - action: async (store) => { - if (!store.currentImage?.source?.url) return - await openUrl(store.currentImage.source.url) - }, - check: (snap) => snap.currentImage?.source?.url != null, - icon: TbBrowser, - }, +export const toolbarCommands: ToolbarCommand>[] = [ + { + id: "loadFromClipboard", + tip: "Load image from clipboard", + icon: FiClipboard, + action: async () => { + try { + await loadImage2("general") + } catch (e) { + console.error(e) + } + }, + }, + { + id: "copyImage", + tip: "Copy image to clipboard", + action: async (store) => { + if (!store.currentImage) return + await ImageStore.copy(store.currentImage?.id) + }, + check: (snap) => snap.currentImage != null, + icon: FiCopy, + }, + separator(), + { + id: "pinImage", + getTip: (snap) => (snap.currentImage?.pin ? "Unpin image" : "Pin image"), + getIcon: (snap: ReadonlyState>) => ( + + ), + check: (snap) => snap.currentImage != null, + action: async () => { + const pin = getMetadataStore().currentImage?.pin !== null ? null : true + pinImage(true, pin) + postMessage({ + message: pin ? "Image pinned" : "Pin removed", + uType: "pinimage", + duration: 2000, + channel: "toolbar", + }) + }, + }, + { + id: "clearUnpinned", + tip: "Clear unpinned images", + action: () => clearAll(true), + check: (snap) => snap.images.some((im) => im.pin == null), + icon: FiXCircle, + }, + separator(), + { + id: "saveImage", + tip: "Save a copy", + action: async (store) => { + if (!store.currentImage) return + const savePath = await save({ + canCreateDirectories: true, + title: "Save image", + filters: [{ name: "Image", extensions: [store.currentImage.type] }], + }) + if (savePath) { + await ImageStore.saveCopy(store.currentImage.id, savePath) + } + }, + check: (snap) => snap.currentImage != null, + icon: FiSave, + }, + { + id: "openFolder", + tip: "Open folder", + slotId: "sourceOpen", + action: async (store) => { + if (!store.currentImage?.source?.file) return + await revealItemInDir(store.currentImage?.source?.file) + }, + check: (snap) => snap.currentImage?.source?.file != null, + icon: FiFolder, + }, + { + id: "openUrl", + slotId: "sourceOpen", + tip: "Open URL", + action: async (store) => { + if (!store.currentImage?.source?.url) return + await openUrl(store.currentImage.source.url) + }, + check: (snap) => snap.currentImage?.source?.url != null, + icon: TbBrowser, + }, ] type SnapCallback = ( - snap: ReadonlyState, - arg?: T2Arg, + snap: ReadonlyState, + arg?: T2Arg, ) => TRet export type ToolbarCommand = { - id: string - action: (state: TArg, arg?: T2Arg) => void - check?: SnapCallback - tip?: string - getTip?: SnapCallback - icon?: IconType - getIcon?: SnapCallback - separator?: true - slotId?: string + id: string + action: (state: TArg, arg?: T2Arg) => void + check?: SnapCallback + tip?: string + getTip?: SnapCallback + icon?: IconType + getIcon?: SnapCallback + separator?: true + slotId?: string } diff --git a/src/mocks/tauri-updater.ts b/src/mocks/tauri-updater.ts index 8be77c9..1a1f162 100644 --- a/src/mocks/tauri-updater.ts +++ b/src/mocks/tauri-updater.ts @@ -1 +1,34 @@ -export const check = async () => null; +const updateAvailable = true + +export const check = async () => { + // Mock an update being available + await new Promise((resolve) => setTimeout(resolve, 2000)) + if (!updateAvailable) return null + + return { + version: "1.0.1", + date: new Date().toISOString(), + body: "Mock update for testing", + + download: async (onProgress?: (chunkLength: number, contentLength?: number) => void) => { + // Simulate download with progress + const totalSize = 10_000_000 // 10MB mock size + const chunkSize = 500_000 // 500KB chunks + let downloaded = 0 + + while (downloaded < totalSize) { + await new Promise((resolve) => setTimeout(resolve, 1000)) // Simulate network delay + downloaded += chunkSize + if (onProgress) { + onProgress(chunkSize, totalSize) + } + } + }, + + install: async () => { + // Simulate installation time + await new Promise((resolve) => setTimeout(resolve, 1000)) + console.log("Mock update installed") + }, + } +} diff --git a/src/scratch/Coffee.tsx b/src/scratch/Coffee.tsx new file mode 100644 index 0000000..a5beb89 --- /dev/null +++ b/src/scratch/Coffee.tsx @@ -0,0 +1,77 @@ +import { motion, useAnimate } from "motion/react" +import { useEffect, useRef } from "react" +import { CheckRoot, Panel } from "@/components" + +function Empty() { + const svgRef = useRef(null) + + const [scope, anim] = useAnimate() + + useEffect(() => { + anim( + [ + [scope.current, { rotate: [0, 0] }], + [scope.current, { y: [0, -20] }], + ["#s1", { y: [0, 8] }], + ["#s2", { y: [0, 8] }], + ["#s3", { y: [0, 8] }], + ], + { + repeat: Infinity, + repeatType: "loop", + duration: 2, + }, + ) + }, [anim, scope.current]) + + return ( + + + + + + + + + + + ) +} + +export default Empty diff --git a/src/scratch/EmptyDesign.tsx b/src/scratch/EmptyDesign.tsx new file mode 100644 index 0000000..8a924b0 --- /dev/null +++ b/src/scratch/EmptyDesign.tsx @@ -0,0 +1,14 @@ +import { motion } from "motion/react" +import { CheckRoot, Panel } from "@/components" + +function Empty() { + return ( + + + + + + ) +} + +export default Empty diff --git a/src/scratch/Empty.tsx b/src/scratch/EmptyValtio.tsx similarity index 100% rename from src/scratch/Empty.tsx rename to src/scratch/EmptyValtio.tsx diff --git a/src/scratch/FilmStrip.tsx b/src/scratch/FilmStrip.tsx new file mode 100644 index 0000000..7c0c00f --- /dev/null +++ b/src/scratch/FilmStrip.tsx @@ -0,0 +1,85 @@ +import { Fragment } from "react/jsx-runtime" +import { CheckRoot, Panel } from "@/components" + +const topEdge = 35 +const bottomEdge = 165 +const width = 220 +const height = 200 +const thickness = 12 + +function Empty() { + return ( + + + + + + + + {Array.from({ length: 4 }).map((_, i) => ( + + + + + ))} + + 81 + + + + + ) +} + +export default Empty diff --git a/src/scratch/Reactive.tsx b/src/scratch/Reactive.tsx deleted file mode 100644 index 3cd695e..0000000 --- a/src/scratch/Reactive.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { Box, Button, Grid } from "@chakra-ui/react" -import { proxy, useSnapshot } from "valtio" -import { CheckRoot, Panel } from "@/components" -import { computed } from "valtio-reactive" - -const store = proxy({ - a: 0, - b: 0, - c: 0, -}) - -function log(msg: string) { - console.log(msg) -} - -const preSum = computed({ - a: () => { - const { a, b, c } = store - return { a, b, c } - }, -}) - -const preDoubleA = computed({ - a: () => store.a, -}) - -const something = computed({ - sum: () => { - log("sum computed") - return preSum.a + preSum.b + preSum.c - }, - doubleA: () => { - log("doubleA computed") - return preDoubleA.a * 2 - }, -}) - -function Empty() { - const snap = useSnapshot(store) - const snap2 = useSnapshot(something) - // const snaplog = useSnapshot(logproxy) - console.log(snap2) - return ( - - - - - {snap.a} - {snap2.sum} - - {snap.b} - - - {snap.c} - - - - {/* {snaplog.log.join("\n")} */} - - - ) -} - -export default Empty diff --git a/src/scratch/Vid.tsx b/src/scratch/Vid.tsx new file mode 100644 index 0000000..b6d89f1 --- /dev/null +++ b/src/scratch/Vid.tsx @@ -0,0 +1,73 @@ +import { Box, Button, Grid } from "@chakra-ui/react" +import { listen } from "@tauri-apps/api/event" +import { useEffect } from "react" +import { proxy, useSnapshot } from "valtio" +import * as vid from "@/commands/vid" +import { CheckRoot, Panel } from "@/components" + +const store = proxy({ + a: undefined as boolean | undefined, + progress: 0, + total: 0, + received: 0, + downloadResult: undefined, + callResult: "", +}) + +function Empty() { + const snap = useSnapshot(store) + + useEffect(() => { + listen("ffmpeg_download_progress", (e) => { + store.progress = e.payload.progress + store.total = e.payload.total + store.received = e.payload.received + }) + }, []) + + return ( + + + + + {`Check: ${snap.a}`} + + + {`Progress: ${snap.progress}, Total: ${snap.total}, Received: ${snap.received}`} + {`Result: ${snap.downloadResult}`} + + {snap.callResult} + + + + + ) +} + +export default Empty diff --git a/src/theme/theme.ts b/src/theme/theme.ts index d72cf60..148955d 100644 --- a/src/theme/theme.ts +++ b/src/theme/theme.ts @@ -1,207 +1,241 @@ import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react" const themeConfig = defineConfig({ - globalCss: { - html: { - overscrollBehavior: "none", - fontSize: "var(--app-base-size)", - // zoom: 1.5 - }, - body: { - fontFamily: "-apple-system, BlinkMacSystemFont, sans-serif;", - }, - ".check-bg": { - bgImage: { - _light: "url(check_light.png)", - _dark: "url(check_dark.png)", - }, - bgSize: "50px 50px", - }, - ".hide-scrollbar": { - scrollbarWidth: "none", - }, - ".hide-scrollbar::-webkit-scrollbar": { - /*Chrome, Safari, Edge*/ - display: "none", - }, - "#root": { - bgColor: "#73747540", - overflow: "clip", - height: "100vh", - width: "100vw", - position: "relative", - }, - }, - theme: { - breakpoints: { - tall: "300px", - wide: "600px", - // sm: "300px", - // md: "600px", - // lg: "900px", - // xl: "1200px", - }, - semanticTokens: { - colors: { - check: { - "1": { - value: { - _light: "#f5f5f7", - _dark: "#565e67", - }, - }, - "2": { - value: { - _light: "#dbdddf", - _dark: "#434753", - }, - }, - "3": { - value: { - _light: "#e0e1e2", - _dark: "#4c525b", - }, - }, - "4": { - value: { - _light: "#c9cbcd", - _dark: "#3b3f4a", - }, - }, - }, - bg: { - "1": { - value: { - _light: "#e0e1e2", - _dark: "#141617ff", - }, - }, - deep: { - value: { - _light: "#c7c9caff", - _dark: "#0e0f10ff", - }, - }, - "2": { - value: { - _light: "#e8eaeb", - _dark: "#1f2224ff", - }, - }, - "3": { - value: { - _light: "#f2f3f4", - _dark: "#272a2dff", - }, - }, - "0": { - value: { - _light: "#ffffff", - _dark: "#434753", - }, - }, - }, - fg: { - "1": { - value: { - _light: "#272932", - _dark: "#dbdddf", - }, - }, - "2": { - value: { - _light: "#434753", - _dark: "#b9bfc5", - }, - }, - "3": { - value: { - _light: "#565e67", - _dark: "#8e97a2", - }, - }, - }, - highlight: { - DEFAULT: { - value: { - _light: "#EC5F47", - // _light: "#e9624dff", - _dark: "#d25542", - }, - }, - }, - info: { - DEFAULT: { - value: { - _light: "#5098dbff", - _dark: "#689fd3", - }, - }, - }, - bonus: { - DEFAULT: { - value: { - _light: "#c6b9fa", - _dark: "#2d2244", - }, - }, - }, - success: { - "1": { - value: { - _light: "#51ac35", - _dark: "#66b851ff", - }, - }, - DEFAULT: { - value: { - _light: "#d0fcc9", - _dark: "#5bc640ff", - }, - }, - }, - }, - }, - tokens: { - borders: { - pane1: { - value: "1px solid #77777722", - }, - }, - shadows: { - pane0: { - value: - "0px 0px 3px -1px #00000033, 0px 1px 5px -2px #00000033, 0px 2px 8px -3px #00000033", - }, - pane1: { - value: - "0px 0px 4px -1px #00000033, 2px 4px 6px -2px #00000022, -1px 4px 6px -2px #00000022, 0px 3px 12px -3px #00000033", - }, - pane2: { - value: - "0px 1px 4px -1px #00000044, 2px 6px 10px -4px #00000022, -1px 6px 10px -4px #00000022, 0px 4px 16px -4px #00000044", - }, - }, - fontSizes: { - // xs: { value: "0.75rem" }, - // sm: { value: "1rem" }, - }, - }, - keyframes: { - test: { - from: { transform: "translateX(0)" }, - to: { transform: "translateX(100%)" }, - }, - fadeOut: { - from: { opacity: 1 }, - to: { opacity: 0 }, - }, - fadeIn: { - from: { opacity: 0 }, - to: { opacity: 1 }, - }, - }, - }, + globalCss: { + html: { + overscrollBehavior: "none", + fontSize: "var(--app-base-size)", + // zoom: 1.5 + }, + body: { + fontFamily: "-apple-system, BlinkMacSystemFont, sans-serif;", + }, + ".check-bg": { + bgImage: { + _light: "url(check_light.png)", + _dark: "url(check_dark.png)", + }, + bgSize: "50px 50px", + }, + ".hide-scrollbar": { + scrollbarWidth: "none", + }, + ".hide-scrollbar::-webkit-scrollbar": { + /*Chrome, Safari, Edge*/ + display: "none", + }, + ".panel-scroll": { + scrollbarGutter: "stable", + _scrollbar: { backgroundColor: "none", width: "8px", borderRadius: "0 50% 50% 0" }, + _scrollbarThumb: { + backgroundColor: "fg.2/50", + width: "4px", + borderRadius: "2px 7px 7px 2px", + boxShadow: "pane1", + borderRight: "1px solid", + borderColor: "bg.1", + }, + }, + "#root": { + bgColor: "#73747540", + overflow: "clip", + height: "100vh", + width: "100vw", + position: "relative", + }, + }, + theme: { + breakpoints: { + tall: "300px", + wide: "600px", + // sm: "300px", + // md: "600px", + // lg: "900px", + // xl: "1200px", + }, + semanticTokens: { + colors: { + check: { + "1": { + value: { + _light: "#f5f5f7", + _dark: "#565e67", + }, + }, + "2": { + value: { + _light: "#dbdddf", + _dark: "#434753", + }, + }, + "3": { + value: { + _light: "#e0e1e2", + _dark: "#4c525b", + }, + }, + "4": { + value: { + _light: "#c9cbcd", + _dark: "#3b3f4a", + }, + }, + }, + bg: { + "1": { + value: { + _light: "#e0e1e2", + _dark: "#141617", + }, + }, + deep: { + value: { + _light: "#c7c9ca", + _dark: "#0e0f10", + }, + }, + "2": { + value: { + _light: "#e8eaeb", + _dark: "#1f2224", + }, + }, + "3": { + value: { + _light: "#f2f3f4", + _dark: "#272a2d", + }, + }, + "0": { + value: { + _light: "#ffffff", + _dark: "#434753", + }, + }, + }, + fg: { + "1": { + value: { + _light: "#272932", + _dark: "#dbdddf", + }, + }, + "2": { + value: { + _light: "#434753", + _dark: "#b9bfc5", + }, + }, + "3": { + value: { + _light: "#565e67", + _dark: "#8e97a2", + }, + }, + }, + grays: { + "0": { value: "#0e0f10" }, + "1": { value: "#141617" }, + "2": { value: "#1f2224" }, + "3": { value: "#272932" }, + "4": { value: "#272a2d" }, + "5": { value: "#434753" }, + "6": { value: "#434753" }, + "7": { value: "#565e67" }, + "8": { value: "#8e97a2" }, + "9": { value: "#b9bfc5" }, + "10": { value: "#c7c9ca" }, + "11": { value: "#dbdddf" }, + "12": { value: "#e0e1e2" }, + "13": { value: "#e8eaeb" }, + "14": { value: "#f2f3f4" }, + }, + highlight: { + DEFAULT: { + value: { + _light: "#EC5F47", + // _light: "#e9624dff", + _dark: "#d25542", + }, + }, + "1": { + value: { + _light: "#d25741ff", + // _light: "#e9624dff", + _dark: "#d25542", + }, + }, + }, + info: { + DEFAULT: { + value: { + _light: "#5098dbff", + _dark: "#689fd3", + }, + }, + }, + bonus: { + DEFAULT: { + value: { + _light: "#c6b9fa", + _dark: "#2d2244", + }, + }, + }, + success: { + "1": { + value: { + _light: "#51ac35", + _dark: "#66b851ff", + }, + }, + DEFAULT: { + value: { + _light: "#d0fcc9", + _dark: "#5bc640ff", + }, + }, + }, + }, + }, + tokens: { + borders: { + pane1: { + value: "1px solid #77777722", + }, + }, + shadows: { + pane0: { + value: "0px 0px 3px -1px #00000033, 0px 1px 5px -2px #00000033, 0px 2px 8px -3px #00000033", + }, + pane1: { + value: "0px 0px 4px -1px #00000033, 2px 4px 6px -2px #00000022, -1px 4px 6px -2px #00000022, 0px 3px 12px -3px #00000033", + }, + pane2: { + value: "0px 1px 4px -1px #00000044, 2px 6px 10px -4px #00000022, -1px 6px 10px -4px #00000022, 0px 4px 16px -4px #00000044", + }, + }, + fontSizes: { + // xs: { value: "0.6rem" }, + // sm: { value: "0.75rem" }, + // md: { value: "0.9rem" }, + }, + }, + keyframes: { + test: { + from: { transform: "translateX(0)" }, + to: { transform: "translateX(100%)" }, + }, + fadeOut: { + from: { opacity: 1 }, + to: { opacity: 0 }, + }, + fadeIn: { + from: { opacity: 0 }, + to: { opacity: 1 }, + }, + }, + }, }) export const system = createSystem(defaultConfig, themeConfig) diff --git a/src/types.ts b/src/types.ts index e7b84f8..63956f5 100644 --- a/src/types.ts +++ b/src/types.ts @@ -232,4 +232,9 @@ export const SeedModeLabels = [ 'Torch Cpu Compatible', 'Scale Alike', 'Nvidia Gpu Compatible', -] \ No newline at end of file +] + +export enum MediaType { + Image = 0, + Video = 1, +} \ No newline at end of file diff --git a/src/utils/DebounceMap.ts b/src/utils/DebounceMap.ts new file mode 100644 index 0000000..1eb0880 --- /dev/null +++ b/src/utils/DebounceMap.ts @@ -0,0 +1,20 @@ +export class DebounceMap { + delay: number + map = new Map() + + constructor(delay: number) { + this.delay = delay + } + + set(key: K, callback: () => void) { + const existing = this.map.get(key) + if (existing) { + clearTimeout(existing) + } + const timeout = setTimeout(() => { + this.map.delete(key) + callback() + }, this.delay) + this.map.set(key, timeout) + } +} \ No newline at end of file diff --git a/src/utils/TMap.ts b/src/utils/TMap.ts new file mode 100644 index 0000000..b22f6b9 --- /dev/null +++ b/src/utils/TMap.ts @@ -0,0 +1,32 @@ +type TMapFilterFn = (key: K, value: V) => boolean + +export class TMap extends Map { + /** + * removes and returns the value for the provided key + */ + take(key: K): V | undefined { + const value = this.get(key) + if (value) this.delete(key) + return value + } + + /** + * removes any entries that do not pass the predicate function, keeping those + * that do. This is a destructive operation. + */ + retain(predicate: TMapFilterFn): void { + for (const [key, value] of this.entries()) { + if (!predicate(key, value)) { + this.delete(key) + } + } + } + + static from(iterable: Iterable, keyFn: (value: V) => K): TMap { + const result = new TMap() + for (const value of iterable) { + result.set(keyFn(value), value) + } + return result + } +} diff --git a/src/utils/config.ts b/src/utils/config.ts index 9c78ad1..dec29eb 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -1,281 +1,281 @@ -import type { TensorHistoryNode } from "@/commands" -import { SeedModeLabels, type DrawThingsConfigGrouped, type DrawThingsMetaData } from "@/types" +import type { TensorHistoryNode } from "@/generated/types" +import { type DrawThingsConfigGrouped, type DrawThingsMetaData, SeedModeLabels } from "@/types" export function extractConfigFromTensorHistoryNode( - node: MaybeReadonly | undefined | null, - ): DrawThingsMetaData["config"] | null { - if (!node) return null - return { - aestheticScore: node.aesthetic_score, - batchCount: 1, // Defaulting to 1 as it's not in TensorHistoryNode - batchSize: node.batch_size, - causalInference: node.causal_inference, - causalInferencePad: node.causal_inference_pad, - cfgZeroInitSteps: node.cfg_zero_init_steps, - cfgZeroStar: node.cfg_zero_star, - clipLText: node.clip_l_text ?? "", - clipSkip: node.clip_skip, - clipWeight: node.clip_weight, - controls: node.controls ?? [], - cropLeft: node.crop_left, - cropTop: node.crop_top, - decodingTileHeight: node.decoding_tile_height * 64, - decodingTileOverlap: node.decoding_tile_overlap * 64, - decodingTileWidth: node.decoding_tile_width * 64, - diffusionTileHeight: node.diffusion_tile_height * 64, - diffusionTileOverlap: node.diffusion_tile_overlap * 64, - diffusionTileWidth: node.diffusion_tile_width * 64, - fps: node.fps_id, // Assuming fps_id maps to fps - guidanceEmbed: node.guidance_embed, - guidanceScale: node.guidance_scale, - guidingFrameNoise: node.cond_aug, - height: node.start_height * 64, - hiresFix: node.hires_fix, - hiresFixHeight: node.hires_fix_start_height * 64, - hiresFixStrength: node.hires_fix_strength, - hiresFixWidth: node.hires_fix_start_width * 64, - id: node.tensor_id, - imageGuidanceScale: node.image_guidance_scale, - imagePriorSteps: node.image_prior_steps, - loras: (node.loras as any) ?? [], // Casting to any to avoid type mismatch with ObjectConstructor[][] - maskBlur: node.mask_blur, - maskBlurOutset: node.mask_blur_outset, - model: node.model ?? "", - motionScale: node.motion_bucket_id, - negativeAestheticScore: node.negative_aesthetic_score, - negativeOriginalImageHeight: node.negative_original_image_height, - negativeOriginalImageWidth: node.negative_original_image_width, - negativePromptForImagePrior: node.negative_prompt_for_image_prior, - numFrames: node.num_frames, - openClipGText: node.open_clip_g_text ?? null, - originalImageHeight: node.original_image_height, - originalImageWidth: node.original_image_width, - preserveOriginalAfterInpaint: node.preserve_original_after_inpaint, - refinerModel: node.refiner_model ?? null, - refinerStart: node.refiner_start, - resolutionDependentShift: node.resolution_dependent_shift, - sampler: node.sampler, - seed: node.seed, - seedMode: node.seed_mode, - separateClipL: node.separate_clip_l, - separateOpenClipG: node.separate_open_clip_g, - separateT5: node.separate_t5, - sharpness: node.sharpness, - shift: node.shift, - speedUpWithGuidanceEmbed: node.speed_up_with_guidance_embed, - stage2Guidance: node.stage_2_cfg, - stage2Shift: node.stage_2_shift, - stage2Steps: node.stage_2_steps, - startFrameGuidance: node.start_frame_cfg, - steps: node.steps, - stochasticSamplingGamma: node.stochastic_sampling_gamma, - strength: node.strength, - t5Text: node.t5_text ?? null, - t5TextEncoder: node.t5_text_encoder, - targetImageHeight: node.target_image_height, - targetImageWidth: node.target_image_width, - teaCache: node.tea_cache, - teaCacheEnd: node.tea_cache_end, - teaCacheMaxSkipSteps: node.tea_cache_max_skip_steps, - teaCacheStart: node.tea_cache_start, - teaCacheThreshold: node.tea_cache_threshold, - tiledDecoding: node.tiled_decoding, - tiledDiffusion: node.tiled_diffusion, - upscalerModel: node.upscaler ?? null, - upscalerScaleFactor: node.upscaler_scale_factor, - width: node.start_width * 64, - zeroNegativePrompt: node.zero_negative_prompt, - } - } + node: MaybeReadonly | undefined | null, +): DrawThingsMetaData["config"] | null { + if (!node) return null + return { + aestheticScore: node.aesthetic_score, + batchCount: 1, // Defaulting to 1 as it's not in TensorHistoryNode + batchSize: node.batch_size, + causalInference: node.causal_inference, + causalInferencePad: node.causal_inference_pad, + cfgZeroInitSteps: node.cfg_zero_init_steps, + cfgZeroStar: node.cfg_zero_star, + clipLText: node.clip_l_text ?? "", + clipSkip: node.clip_skip, + clipWeight: node.clip_weight, + controls: node.controls ?? [], + cropLeft: node.crop_left, + cropTop: node.crop_top, + decodingTileHeight: node.decoding_tile_height * 64, + decodingTileOverlap: node.decoding_tile_overlap * 64, + decodingTileWidth: node.decoding_tile_width * 64, + diffusionTileHeight: node.diffusion_tile_height * 64, + diffusionTileOverlap: node.diffusion_tile_overlap * 64, + diffusionTileWidth: node.diffusion_tile_width * 64, + fps: node.fps_id, // Assuming fps_id maps to fps + guidanceEmbed: node.guidance_embed, + guidanceScale: node.guidance_scale, + guidingFrameNoise: node.cond_aug, + height: node.start_height * 64, + hiresFix: node.hires_fix, + hiresFixHeight: node.hires_fix_start_height * 64, + hiresFixStrength: node.hires_fix_strength, + hiresFixWidth: node.hires_fix_start_width * 64, + id: node.tensor_id, + imageGuidanceScale: node.image_guidance_scale, + imagePriorSteps: node.image_prior_steps, + loras: (node.loras as any) ?? [], // Casting to any to avoid type mismatch with ObjectConstructor[][] + maskBlur: node.mask_blur, + maskBlurOutset: node.mask_blur_outset, + model: node.model ?? "", + motionScale: node.motion_bucket_id, + negativeAestheticScore: node.negative_aesthetic_score, + negativeOriginalImageHeight: node.negative_original_image_height, + negativeOriginalImageWidth: node.negative_original_image_width, + negativePromptForImagePrior: node.negative_prompt_for_image_prior, + numFrames: node.num_frames, + openClipGText: node.open_clip_g_text ?? null, + originalImageHeight: node.original_image_height, + originalImageWidth: node.original_image_width, + preserveOriginalAfterInpaint: node.preserve_original_after_inpaint, + refinerModel: node.refiner_model ?? null, + refinerStart: node.refiner_start, + resolutionDependentShift: node.resolution_dependent_shift, + sampler: node.sampler, + seed: node.seed, + seedMode: node.seed_mode, + separateClipL: node.separate_clip_l, + separateOpenClipG: node.separate_open_clip_g, + separateT5: node.separate_t5, + sharpness: node.sharpness, + shift: node.shift, + speedUpWithGuidanceEmbed: node.speed_up_with_guidance_embed, + stage2Guidance: node.stage_2_cfg, + stage2Shift: node.stage_2_shift, + stage2Steps: node.stage_2_steps, + startFrameGuidance: node.start_frame_cfg, + steps: node.steps, + stochasticSamplingGamma: node.stochastic_sampling_gamma, + strength: node.strength, + t5Text: node.t5_text ?? null, + t5TextEncoder: node.t5_text_encoder, + targetImageHeight: node.target_image_height, + targetImageWidth: node.target_image_width, + teaCache: node.tea_cache, + teaCacheEnd: node.tea_cache_end, + teaCacheMaxSkipSteps: node.tea_cache_max_skip_steps, + teaCacheStart: node.tea_cache_start, + teaCacheThreshold: node.tea_cache_threshold, + tiledDecoding: node.tiled_decoding, + tiledDiffusion: node.tiled_diffusion, + upscalerModel: node.upscaler ?? null, + upscalerScaleFactor: node.upscaler_scale_factor, + width: node.start_width * 64, + zeroNegativePrompt: node.zero_negative_prompt, + } +} export function groupConfigProperties( - config?: Partial | null, - ): DrawThingsConfigGrouped | undefined { - if (!config) return + config?: Partial | null, +): DrawThingsConfigGrouped | undefined { + if (!config) return - const { - tiledDecoding, - decodingTileWidth, - decodingTileHeight, - decodingTileOverlap, - width, - height, - shift, - resolutionDependentShift, - seed, - seedMode, - hiresFix, - hiresFixWidth, - hiresFixHeight, - hiresFixStrength, - tiledDiffusion, - diffusionTileWidth, - diffusionTileHeight, - diffusionTileOverlap, - teaCache, - teaCacheStart, - teaCacheEnd, - teaCacheThreshold, - teaCacheMaxSkipSteps, - stage2Guidance, - stage2Shift, - stage2Steps, - originalImageWidth, - originalImageHeight, - targetImageWidth, - targetImageHeight, - negativeOriginalImageWidth, - negativeOriginalImageHeight, - maskBlur, - maskBlurOutset, - causalInference, - causalInferencePad, - cfgZeroInitSteps, - cfgZeroStar, - cropLeft, - cropTop, - guidanceEmbed, - speedUpWithGuidanceEmbed, - aestheticScore, - negativeAestheticScore, - refinerModel, - refinerStart, - upscalerModel, - upscalerScaleFactor, - sampler, - stochasticSamplingGamma, - separateClipL, - clipLText, - separateOpenClipG, - openClipGText, - separateT5, - t5Text, - batchSize, - batchCount, - imagePriorSteps, - negativePromptForImagePrior, - ...rest - } = config + const { + tiledDecoding, + decodingTileWidth, + decodingTileHeight, + decodingTileOverlap, + width, + height, + shift, + resolutionDependentShift, + seed, + seedMode, + hiresFix, + hiresFixWidth, + hiresFixHeight, + hiresFixStrength, + tiledDiffusion, + diffusionTileWidth, + diffusionTileHeight, + diffusionTileOverlap, + teaCache, + teaCacheStart, + teaCacheEnd, + teaCacheThreshold, + teaCacheMaxSkipSteps, + stage2Guidance, + stage2Shift, + stage2Steps, + originalImageWidth, + originalImageHeight, + targetImageWidth, + targetImageHeight, + negativeOriginalImageWidth, + negativeOriginalImageHeight, + maskBlur, + maskBlurOutset, + causalInference, + causalInferencePad, + cfgZeroInitSteps, + cfgZeroStar, + cropLeft, + cropTop, + guidanceEmbed, + speedUpWithGuidanceEmbed, + aestheticScore, + negativeAestheticScore, + refinerModel, + refinerStart, + upscalerModel, + upscalerScaleFactor, + sampler, + stochasticSamplingGamma, + separateClipL, + clipLText, + separateOpenClipG, + openClipGText, + separateT5, + t5Text, + batchSize, + batchCount, + imagePriorSteps, + negativePromptForImagePrior, + ...rest + } = config - return { - ...rest, - tiledDecoding: { - value: tiledDecoding, - width: decodingTileWidth, - height: decodingTileHeight, - overlap: decodingTileOverlap, - }, - size: { width, height }, - shift: { - value: shift, - resDependentShift: resolutionDependentShift, - }, - seed: { - value: seed, - seedMode: seedMode, - }, - hiresFix: { - value: hiresFix, - width: hiresFixWidth, - height: hiresFixHeight, - strength: hiresFixStrength, - }, - tiledDiffusion: { - value: tiledDiffusion, - width: diffusionTileWidth, - height: diffusionTileHeight, - overlap: diffusionTileOverlap, - }, - teaCache: { - value: teaCache, - start: teaCacheStart, - end: teaCacheEnd, - threshold: teaCacheThreshold, - maxSkipSteps: teaCacheMaxSkipSteps, - }, - stage2: { - guidance: stage2Guidance, - shift: stage2Shift, - steps: stage2Steps, - }, - originalSize: { - width: originalImageWidth, - height: originalImageHeight, - }, - targetImageSize: { - width: targetImageWidth, - height: targetImageHeight, - }, - negativeOriginalSize: { - width: negativeOriginalImageWidth, - height: negativeOriginalImageHeight, - }, - maskBlur: { - value: maskBlur, - outset: maskBlurOutset, - }, - causalInference: { - value: causalInference, - pad: causalInferencePad, - }, - cfgZero: { - initSteps: cfgZeroInitSteps, - star: cfgZeroStar, - }, - crop: { left: cropLeft, top: cropTop }, - guidanceEmbed: { value: guidanceEmbed, speedUp: speedUpWithGuidanceEmbed }, - aestheticScore: { positive: aestheticScore, negative: negativeAestheticScore }, - refiner: { model: refinerModel, start: refinerStart }, - upscaler: { value: upscalerModel, scaleFactor: upscalerScaleFactor }, - sampler: { value: sampler, stochasticSamplingGamma: stochasticSamplingGamma }, - separateClipL: { value: separateClipL, text: clipLText }, - separateOpenClipG: { value: separateOpenClipG, text: openClipGText }, - separateT5: { value: separateT5, text: t5Text }, - batch: { size: batchSize, count: batchCount }, - imagePrior: { steps: imagePriorSteps, negativePrompt: negativePromptForImagePrior }, - } - } + return { + ...rest, + tiledDecoding: { + value: tiledDecoding, + width: decodingTileWidth, + height: decodingTileHeight, + overlap: decodingTileOverlap, + }, + size: { width, height }, + shift: { + value: shift, + resDependentShift: resolutionDependentShift, + }, + seed: { + value: seed, + seedMode: seedMode, + }, + hiresFix: { + value: hiresFix, + width: hiresFixWidth, + height: hiresFixHeight, + strength: hiresFixStrength, + }, + tiledDiffusion: { + value: tiledDiffusion, + width: diffusionTileWidth, + height: diffusionTileHeight, + overlap: diffusionTileOverlap, + }, + teaCache: { + value: teaCache, + start: teaCacheStart, + end: teaCacheEnd, + threshold: teaCacheThreshold, + maxSkipSteps: teaCacheMaxSkipSteps, + }, + stage2: { + guidance: stage2Guidance, + shift: stage2Shift, + steps: stage2Steps, + }, + originalSize: { + width: originalImageWidth, + height: originalImageHeight, + }, + targetImageSize: { + width: targetImageWidth, + height: targetImageHeight, + }, + negativeOriginalSize: { + width: negativeOriginalImageWidth, + height: negativeOriginalImageHeight, + }, + maskBlur: { + value: maskBlur, + outset: maskBlurOutset, + }, + causalInference: { + value: causalInference, + pad: causalInferencePad, + }, + cfgZero: { + initSteps: cfgZeroInitSteps, + star: cfgZeroStar, + }, + crop: { left: cropLeft, top: cropTop }, + guidanceEmbed: { value: guidanceEmbed, speedUp: speedUpWithGuidanceEmbed }, + aestheticScore: { positive: aestheticScore, negative: negativeAestheticScore }, + refiner: { model: refinerModel, start: refinerStart }, + upscaler: { value: upscalerModel, scaleFactor: upscalerScaleFactor }, + sampler: { value: sampler, stochasticSamplingGamma: stochasticSamplingGamma }, + separateClipL: { value: separateClipL, text: clipLText }, + separateOpenClipG: { value: separateOpenClipG, text: openClipGText }, + separateT5: { value: separateT5, text: t5Text }, + batch: { size: batchSize, count: batchCount }, + imagePrior: { steps: imagePriorSteps, negativePrompt: negativePromptForImagePrior }, + } +} export const samplerLabels = [ - "DPM++ 2M Karras", - "Euler A", - "DDIM", - "PLMS", - "DPM++ SDE Karras", - "UniPC", - "LCM", - "Euler A Substep", - "DPM++ SDE Substep", - "TCD", - "Euler A Trailing", - "DPM++ SDE Trailing", - "DPM++ 2M AYS", - "Euler A AYS", - "DPM++ SDE AYS", - "DPM++ 2M Trailing", - "DDIM Trailing", - "UniPC Trailing", - "UniPC AYS", + "DPM++ 2M Karras", + "Euler A", + "DDIM", + "PLMS", + "DPM++ SDE Karras", + "UniPC", + "LCM", + "Euler A Substep", + "DPM++ SDE Substep", + "TCD", + "Euler A Trailing", + "DPM++ SDE Trailing", + "DPM++ 2M AYS", + "Euler A AYS", + "DPM++ SDE AYS", + "DPM++ 2M Trailing", + "DDIM Trailing", + "UniPC Trailing", + "UniPC AYS", ] export function getSampler(sampler?: number | string | null) { - if (typeof sampler === "number") { - return samplerLabels[sampler] - } - const parsed = parseInt(sampler ?? "", 10) - if (!Number.isNaN(parsed)) { - return samplerLabels[parsed] - } - return sampler + if (typeof sampler === "number") { + return samplerLabels[sampler] + } + const parsed = parseInt(sampler ?? "", 10) + if (!Number.isNaN(parsed)) { + return samplerLabels[parsed] + } + return sampler } export function getSeedMode(seedMode?: number | string | null) { - if (typeof seedMode === "number") { - return SeedModeLabels[seedMode] - } - const parsed = parseInt(seedMode ?? "", 10) - if (!Number.isNaN(parsed)) { - return SeedModeLabels[parsed] - } - return seedMode + if (typeof seedMode === "number") { + return SeedModeLabels[seedMode] + } + const parsed = parseInt(seedMode ?? "", 10) + if (!Number.isNaN(parsed)) { + return SeedModeLabels[parsed] + } + return seedMode } diff --git a/src/utils/container/StateController.ts b/src/utils/container/StateController.ts index 9e2b743..f4ef76e 100644 --- a/src/utils/container/StateController.ts +++ b/src/utils/container/StateController.ts @@ -1,6 +1,6 @@ import { type Snapshot, useSnapshot } from "valtio" import type { IContainer, IStateController } from "./interfaces" -import { Service } from './Service' +import { Service } from "./Service" export interface ContainerEvent { on: (fn: EventHandler) => void @@ -9,7 +9,10 @@ export interface ContainerEvent { } export type EventHandler = (e: E) => void -export abstract class StateController +export abstract class StateController< + C extends IContainer = IContainer, + T extends { [K in keyof T]: unknown } = object, + > extends Service implements IStateController { @@ -20,7 +23,7 @@ export abstract class StateController { return useSnapshot(this.state) } diff --git a/src/utils/container/container.ts b/src/utils/container/container.ts index 19a2aac..ffe3427 100644 --- a/src/utils/container/container.ts +++ b/src/utils/container/container.ts @@ -1,17 +1,14 @@ import { listen } from "@tauri-apps/api/event" import EventEmitter from "eventemitter3" -import { - type EventMap, - type IContainer, - type IStateService, - isDisposable -} from "./interfaces" +import { type EventMap, type IContainer, type IStateService, isDisposable } from "./interfaces" type FutureServices = Record> = Partial<{ [K in keyof T]: PromiseWithResolvers }> type TagHandler = (tag: string, data?: Record) => void +type TagFormatter = (tag: string, data?: Record) => string +type TagService = { formatTags: TagFormatter, handleTags: TagHandler } export class Container< T extends { [K in keyof T]: IStateService> } = object, @@ -25,30 +22,32 @@ export class Container< private futureServices: FutureServices = {} private invalidateUnlistenPromise: Promise<() => void> private updateUnlistenPromise: Promise<() => void> - private tagHandlers: Map = new Map() + private tagHandlers: Map = new Map() constructor(servicesInit: () => T) { super() - buildContainer>(this, servicesInit, (name: keyof T, service: T[keyof T]) => { - this.services[name] = service + buildContainer>( + this, + servicesInit, + (name: keyof T, service: T[keyof T]) => { + this.services[name] = service - const future = this.futureServices[name] - if (future) { - future.resolve(service) - delete this.futureServices[name] - } - }) + const future = this.futureServices[name] + if (future) { + future.resolve(service) + delete this.futureServices[name] + } + }, + ) this.invalidateUnlistenPromise = listen("invalidate-tags", (event) => { - console.debug("invalidate-tags", event) - const payload = event.payload as { tag: string; desc: string } - this.handleTags(payload.tag, { desc: payload.desc }) + const { tag, desc } = event.payload as { tag: string; desc: string } + this.handleTags(tag, { desc }) }) this.updateUnlistenPromise = listen("update-tags", (event) => { - console.debug("update-tags", event) - const payload = event.payload as { tag: string; data: Record } - this.handleTags(payload.tag, payload.data) + const { tag, data } = event.payload as { tag: string; data: Record } + this.handleTags(tag, data) }) } @@ -69,24 +68,29 @@ export class Container< return future.promise } - addTagHandler(tagRoot: string, handler: TagHandler) { + addTagHandler(tagRoot: string, handler: TagHandler, formatter: TagFormatter) { if (this.tagHandlers.has(tagRoot)) { throw new Error(`Tag handler for ${tagRoot} already exists`) } - this.tagHandlers.set(tagRoot, handler) + this.tagHandlers.set(tagRoot, { handleTags: handler, formatTags: formatter }) } async handleTags(tag: string, data?: Record) { const root = tag.split(":")[0] const handler = this.tagHandlers.get(root) + if (handler) { - handler(tag, data) + handler.handleTags(tag, data) + console.debug(handler.formatTags(tag, data)) } else { console.warn("no handler for tag", tag) } } - override emit>(eventName: EN, ...args: EventEmitter.EventArgs): boolean { + override emit>( + eventName: EN, + ...args: EventEmitter.EventArgs + ): boolean { console.debug("emit", eventName, args) return super.emit(eventName, ...args) } @@ -122,7 +126,7 @@ export function registerContainerService(name: string, ser function buildContainer( container: C, servicesInit: () => C["services"], - register: (name: keyof C["services"], service: C["services"][keyof C["services"]] ) => void, + register: (name: keyof C["services"], service: C["services"][keyof C["services"]]) => void, ) { _containerStack.push({ container, register }) const services = servicesInit() diff --git a/src/utils/container/interfaces.ts b/src/utils/container/interfaces.ts index 3ae8b2a..6a5f0f9 100644 --- a/src/utils/container/interfaces.ts +++ b/src/utils/container/interfaces.ts @@ -10,12 +10,15 @@ export interface IContainer< services: T getService(name: K): T[K] getFutureService(name: K): Promise - addTagHandler(tagRoot: string, handler: TagHandler): void + addTagHandler(tagRoot: string, handler: TagHandler, formatter: TagFormatter): void handleTags(tag: string, data?: Record): Promise + suppressTags(tags: string[]): void + stopSuppressingTags(tags: string[]): void get isDisposed(): boolean dispose(): void } +export type TagFormatter = (tag: string, data?: D) => string export type TagHandler = (tag: string, data?: D) => boolean | Promise export type EventMap = { diff --git a/src/utils/container/queue.ts b/src/utils/container/queue.ts index aa768b4..ce242ec 100644 --- a/src/utils/container/queue.ts +++ b/src/utils/container/queue.ts @@ -15,9 +15,13 @@ export interface JobSpec< K extends keyof JM = keyof JM, > { type: K - tag?: string + subtype?: string + label?: string data: JM[K]["data"] - execute: (data: JM[K]["data"], container: C) => Promise> | Promise + execute: ( + data: JM[K]["data"], + container: C, + ) => Promise | undefined> | Promise callback?: JobCallback merge?: "first" | "last" retries?: number @@ -55,6 +59,9 @@ export class JobQueue extends Servi mutex = new Mutex() private static idCounter = 0 + private addingInternalJob = false + private internalJobsAdded = 0 + private internalJobsMerged = 0 constructor() { super("jobs") @@ -78,18 +85,29 @@ export class JobQueue extends Servi if (item.merge === "first") { // merge all instances into the first position, and replace with this instance let firstIndex: number | null = null + const callbacks: JobCallback[] = [] const jobsData = [] this.jobs.forEach((j, i) => { - if (j.type === item.type && j.tag === item.tag) { + if (j.type === item.type && j.subtype === item.subtype) { firstIndex = firstIndex === null ? i : Math.min(firstIndex, i) j.status = "canceled" if (Array.isArray(j.data)) jobsData.push(...j.data) + if (j.callback) callbacks.push(j.callback) + this.internalJobsMerged++ } }) if (firstIndex !== null) { this.jobs.splice(firstIndex, 1, item) + this.internalJobsAdded++ if (Array.isArray(item.data)) item.data.unshift(...jobsData) - console.debug("merged job", formatJob(item)) + if (!this.addingInternalJob) console.debug("merged job", formatJob(item)) + const itemCallback = item.callback + item.callback = (result, error) => { + for (const callback of callbacks) { + callback(result, error) + } + itemCallback?.(result, error) + } return } // if no matching jobs were found, continue as if normal @@ -97,23 +115,35 @@ export class JobQueue extends Servi if (item.merge === "last") { // cancel all jobs jobs of same type tag, add this one to the end of the queue if (addToFront) throw new Error("Cannot add job to front with merge=last") + const callbacks: JobCallback[] = [] const jobsData = [] this.jobs.forEach((j) => { - if (j.type === item.type && j.tag === item.tag) { + if (j.type === item.type && j.subtype === item.subtype) { + this.internalJobsMerged++ j.status = "canceled" if (Array.isArray(j.data)) jobsData.push(...j.data) + if (j.callback) callbacks.push(j.callback) } }) this.jobs.push(item) + this.internalJobsAdded++ if (Array.isArray(item.data)) item.data.unshift(...jobsData) - console.debug("merged job", formatJob(item)) + if (!this.addingInternalJob) console.debug("merged job", formatJob(item)) + const itemCallback = item.callback + item.callback = (result, error) => { + for (const callback of callbacks) { + callback(result, error) + } + itemCallback?.(result, error) + } return } if (addToFront) this.jobs.unshift(item) else this.jobs.push(item) + this.internalJobsAdded++ - console.debug("added job", formatJob(item)) + if (!this.addingInternalJob) console.debug("added job", formatJob(item)) if (!this.isActive) this.start() } @@ -124,6 +154,17 @@ export class JobQueue extends Servi } } + private internalAddJobs(jobs: JobUnion[], addToFront = false) { + this.addingInternalJob = true + this.internalJobsAdded = 0 + this.internalJobsMerged = 0 + for (const job of jobs) { + this.addJob(job, addToFront) + } + this.addingInternalJob = false + return { added: this.internalJobsAdded, merged: this.internalJobsMerged } + } + async start() { if (this.isActive) return this.isActive = true @@ -139,10 +180,12 @@ export class JobQueue extends Servi job.status = "active" try { + console.log("starting job", formatJob(job)) const result = await job.execute(job.data, this.container) if (Array.isArray(result?.jobs) && result.jobs.length > 0) { - this.addJobs(result.jobs) + const { added, merged } = this.internalAddJobs(result.jobs) + console.debug(`job ${formatJob(job)} added ${added} jobs (${merged} merged)`) } job.status = "completed" @@ -161,7 +204,7 @@ export class JobQueue extends Servi this.addJob(spec, false) } else { job.status = "failed" - console.error("a job failed", job) + console.error("a job failed", job, error) } } } @@ -171,5 +214,9 @@ export class JobQueue extends Servi } function formatJob(job: Job) { - return `${job.id}:${String(job.type)}:${job.tag}` + let formatted = `${job.id}:${String(job.type)}` + + if (job.subtype) formatted += `:${job.subtype}` + if (job.label) formatted += `:${job.label}` + return formatted } diff --git a/src/utils/helpers.test.ts b/src/utils/helpers.test.ts index 9a9f175..549ea12 100644 --- a/src/utils/helpers.test.ts +++ b/src/utils/helpers.test.ts @@ -1,102 +1,120 @@ -import { describe, it, expect } from "vitest" -import { compareItems } from "./helpers" +import { describe, expect, it } from "vitest" +import { compareItems, plural } from "./helpers" describe("compareItems", () => { - const keyFn = (item: { id: number }) => item.id + const keyFn = (item: { id: number }) => item.id - it("should handle empty arrays", () => { - const result = compareItems([], [], keyFn) - expect(result.added).toEqual([]) - expect(result.removed).toEqual([]) - expect(result.changed).toEqual([]) - expect(result.same).toEqual([]) - expect(result.itemsChanged).toBe(false) - }) + it("should handle empty arrays", () => { + const result = compareItems([], [], keyFn) + expect(result.added).toEqual([]) + expect(result.removed).toEqual([]) + expect(result.changed).toEqual([]) + expect(result.same).toEqual([]) + expect(result.itemsChanged).toBe(false) + }) - it("should identify added items", () => { - const a = [{ id: 1, name: "item1" }] - const b = [ - { id: 1, name: "item1" }, - { id: 2, name: "item2" }, - ] - const result = compareItems(a, b, keyFn) - expect(result.added).toEqual([{ id: 2, name: "item2" }]) - expect(result.removed).toEqual([]) - expect(result.changed).toEqual([]) - expect(result.same).toEqual([{ id: 1, name: "item1" }]) - expect(result.itemsChanged).toBe(true) - }) + it("should identify added items", () => { + const a = [{ id: 1, name: "item1" }] + const b = [ + { id: 1, name: "item1" }, + { id: 2, name: "item2" }, + ] + const result = compareItems(a, b, keyFn) + expect(result.added).toEqual([{ id: 2, name: "item2" }]) + expect(result.removed).toEqual([]) + expect(result.changed).toEqual([]) + expect(result.same).toEqual([{ id: 1, name: "item1" }]) + expect(result.itemsChanged).toBe(true) + }) - it("should identify removed items", () => { - const a = [ - { id: 1, name: "item1" }, - { id: 2, name: "item2" }, - ] - const b = [{ id: 1, name: "item1" }] - const result = compareItems(a, b, keyFn) - expect(result.added).toEqual([]) - expect(result.removed).toEqual([{ id: 2, name: "item2" }]) - expect(result.changed).toEqual([]) - expect(result.same).toEqual([{ id: 1, name: "item1" }]) - expect(result.itemsChanged).toBe(true) - }) + it("should identify removed items", () => { + const a = [ + { id: 1, name: "item1" }, + { id: 2, name: "item2" }, + ] + const b = [{ id: 1, name: "item1" }] + const result = compareItems(a, b, keyFn) + expect(result.added).toEqual([]) + expect(result.removed).toEqual([{ id: 2, name: "item2" }]) + expect(result.changed).toEqual([]) + expect(result.same).toEqual([{ id: 1, name: "item1" }]) + expect(result.itemsChanged).toBe(true) + }) - it("should identify changed items", () => { - const a = [{ id: 1, name: "item1" }] - const b = [{ id: 1, name: "item1-changed" }] - const result = compareItems(a, b, keyFn) - expect(result.added).toEqual([]) - expect(result.removed).toEqual([]) - expect(result.changed).toEqual([{ id: 1, name: "item1-changed" }]) - expect(result.same).toEqual([]) - expect(result.itemsChanged).toBe(true) - }) + it("should identify changed items", () => { + const a = [{ id: 1, name: "item1" }] + const b = [{ id: 1, name: "item1-changed" }] + const result = compareItems(a, b, keyFn) + expect(result.added).toEqual([]) + expect(result.removed).toEqual([]) + expect(result.changed).toEqual([{ id: 1, name: "item1-changed" }]) + expect(result.same).toEqual([]) + expect(result.itemsChanged).toBe(true) + }) - it("should respect ignoreObjects parameter", () => { - const a = [{ id: 1, name: "item1", data: { foo: "bar" } }] - const b = [{ id: 1, name: "item1", data: { foo: "baz" } }] // different object reference + it("should respect ignoreObjects parameter", () => { + const a = [{ id: 1, name: "item1", data: { foo: "bar" } }] + const b = [{ id: 1, name: "item1", data: { foo: "baz" } }] // different object reference - // Without ignoreObjects, they are considered changed because data is a different object - const result1 = compareItems(a, b, keyFn, { ignoreObjects: false }) - expect(result1.changed).toEqual(b) - expect(result1.same).toEqual([]) + // Without ignoreObjects, they are considered changed because data is a different object + const result1 = compareItems(a, b, keyFn, { ignoreObjects: false }) + expect(result1.changed).toEqual(b) + expect(result1.same).toEqual([]) - // With ignoreObjects, they are considered same because the object property is skipped - const result2 = compareItems(a, b, keyFn, { ignoreObjects: true }) - expect(result2.changed).toEqual([]) - expect(result2.same).toEqual(b) - }) + // With ignoreObjects, they are considered same because the object property is skipped + const result2 = compareItems(a, b, keyFn, { ignoreObjects: true }) + expect(result2.changed).toEqual([]) + expect(result2.same).toEqual(b) + }) - it("should respect ignoreFunctions parameter", () => { - const a = [{ id: 1, name: "item1", fn: () => "foo" }] - const b = [{ id: 1, name: "item1", fn: () => "bar" }] // different function reference + it("should respect ignoreFunctions parameter", () => { + const a = [{ id: 1, name: "item1", fn: () => "foo" }] + const b = [{ id: 1, name: "item1", fn: () => "bar" }] // different function reference - // Without ignoreFunctions, they are considered changed - const result1 = compareItems(a, b, keyFn, { ignoreFunctions: false }) - expect(result1.changed).toEqual(b) - expect(result1.same).toEqual([]) + // Without ignoreFunctions, they are considered changed + const result1 = compareItems(a, b, keyFn, { ignoreFunctions: false }) + expect(result1.changed).toEqual(b) + expect(result1.same).toEqual([]) - // With ignoreFunctions, they are considered same - const result2 = compareItems(a, b, keyFn, { ignoreFunctions: true }) - expect(result2.changed).toEqual([]) - expect(result2.same).toEqual(b) - }) + // With ignoreFunctions, they are considered same + const result2 = compareItems(a, b, keyFn, { ignoreFunctions: true }) + expect(result2.changed).toEqual([]) + expect(result2.same).toEqual(b) + }) - it("should handle complex scenarios", () => { - const a = [ - { id: 1, name: "same" }, - { id: 2, name: "removed" }, - { id: 3, name: "changed-old" }, - ] - const b = [ - { id: 1, name: "same" }, - { id: 3, name: "changed-new" }, - { id: 4, name: "added" }, - ] - const result = compareItems(a, b, keyFn) - expect(result.added).toEqual([{ id: 4, name: "added" }]) - expect(result.removed).toEqual([{ id: 2, name: "removed" }]) - expect(result.changed).toEqual([{ id: 3, name: "changed-new" }]) - expect(result.same).toEqual([{ id: 1, name: "same" }]) - }) + it("should handle complex scenarios", () => { + const a = [ + { id: 1, name: "same" }, + { id: 2, name: "removed" }, + { id: 3, name: "changed-old" }, + ] + const b = [ + { id: 1, name: "same" }, + { id: 3, name: "changed-new" }, + { id: 4, name: "added" }, + ] + const result = compareItems(a, b, keyFn) + expect(result.added).toEqual([{ id: 4, name: "added" }]) + expect(result.removed).toEqual([{ id: 2, name: "removed" }]) + expect(result.changed).toEqual([{ id: 3, name: "changed-new" }]) + expect(result.same).toEqual([{ id: 1, name: "same" }]) + }) +}) + +describe("plural", () => { + it("returns s or not", () => { + expect(plural(0)).toBe("s") + expect(plural(1)).toBe("") + expect(plural(7)).toBe("s") + }) + + it("pluralizes the provided word", () => { + expect(plural(1, "image")).toBe("image") + expect(plural(7, "image")).toBe("images") + }) + + it("pluralizes the provided word with a custom plural", () => { + expect(plural(1, "child", "children")).toBe("child") + expect(plural(7, "child", "children")).toBe("children") + }) }) diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index 528187a..9858ea8 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -60,8 +60,8 @@ export function shuffle(array: T[]): T[] { // Pick a random index const i = Math.floor(Math.random() * m--) - // Swap element at m with element at i - ;[array[m], array[i]] = [array[i], array[m]] + // Swap element at m with element at i + ;[array[m], array[i]] = [array[i], array[m]] } return array @@ -107,7 +107,8 @@ export async function openAnd( callback: SingleOpenAndCallback | MultiOpenAndCallback, options: Parameters[0] = {}, ) { - const files = await open(options) + + const files = await pickFileForImport(options) if (!files || (Array.isArray(files) && files.length === 0)) return null if (options.multiple) { @@ -158,7 +159,7 @@ export function getUnknown(obj: unknown, key: string): T | undefined { */ export function plural(n?: number, singular?: string, plural?: string) { if (!Number.isNaN(n) && n === 1) return singular ?? "" - return plural ?? "s" + return plural ?? (singular ? `${singular}s` : "s") } export interface CompareOptions { @@ -238,3 +239,22 @@ function shallowCompare>(a: T, b: T, opts: Com } return true } + +export function everyNth(arr: T[], n: number): T[] { + return arr.filter((_, i) => i % n === 0) +} + +export async function pickFileForImport(options?: Parameters[0]) { + const e2eFilePath = (window as any).__E2E_FILE_PATH__ + console.debug("E2E file path:", e2eFilePath); + if (e2eFilePath) { + return e2eFilePath; + } + + return await open(options); +} + +export function truncate(text: string, length: number) { + if (text.length <= length) return text + return `${text.slice(0, length)}...` +} diff --git a/src/utils/tauriLogger.ts b/src/utils/tauriLogger.ts new file mode 100644 index 0000000..132a3e0 --- /dev/null +++ b/src/utils/tauriLogger.ts @@ -0,0 +1,18 @@ +import { debug, error, info, trace, warn } from "@tauri-apps/plugin-log" + +function forwardConsole( + fnName: "log" | "debug" | "info" | "warn" | "error", + logger: (message: string) => Promise, +) { + const original = console[fnName] + console[fnName] = (...data) => { + original(...data) + logger(data.map((d) => String(d)).join(" ")) + } +} + +forwardConsole("log", trace) +forwardConsole("debug", debug) +forwardConsole("info", info) +forwardConsole("warn", warn) +forwardConsole("error", error) diff --git a/src/views.ts b/src/views.ts index 525357f..c9fced7 100644 --- a/src/views.ts +++ b/src/views.ts @@ -1,4 +1,5 @@ -import { BiDetail, PiCoffee, PiListMagnifyingGlassBold } from "./components/icons" +import { lazy } from "react" +import { BiDetail, PiCoffee, PiListMagnifyingGlassBold } from "./components/icons/icons" export const viewDescription = [ { @@ -21,3 +22,17 @@ export const viewDescription = [ { viewId: "projects", label: "Projects", icon: PiCoffee }, { viewId: "scratch", label: "Scratch", icon: BiDetail, devOnly: true }, ].filter((item) => import.meta.env.DEV || !item.devOnly) + +export const views = { + metadata: lazy(() => import("./metadata/Metadata")), + mini: lazy(() => import("./Mini")), + vid: lazy(() => import("./vid/Vid")), + library: lazy(() => import("./library/Library")), + projects: lazy(() => import("./dtProjects/DTProjects")), + // scratch: lazy(() => import("./scratch/Coffee")), +} + +// export const views = { +// metadata: Metadata, +// projects: DTProjects +// } \ No newline at end of file diff --git a/tauri-codegen.toml b/tauri-codegen.toml new file mode 100644 index 0000000..7149c9e --- /dev/null +++ b/tauri-codegen.toml @@ -0,0 +1,19 @@ +[input] +source_dir = "src-tauri/src" +exclude = [ + "tests", + "target", + "fbs", + "tensor_history_mod" +] +use_cargo_expand = true + +[output] +types_file = "src/generated/types.ts" +commands_file = "src/generated/commands.ts" + +[naming] +type_prefix = "" +type_suffix = "" +function_prefix = "" +function_suffix = "" diff --git a/test/.testrunner.env b/test/.testrunner.env new file mode 100644 index 0000000..d74ba7e --- /dev/null +++ b/test/.testrunner.env @@ -0,0 +1,5 @@ +REUSE_BUILD=true +# location for original test data, will not be modified +TEST_DATA_STORAGE=/media/share/dtm-test-data/ +# working directory for DTP tests, will be modified during tests +DTP_TEST_DIR=/home/debian/dtm-test-data/ \ No newline at end of file diff --git a/test/package-lock.json b/test/package-lock.json new file mode 100644 index 0000000..7d2e474 --- /dev/null +++ b/test/package-lock.json @@ -0,0 +1,6301 @@ +{ + "name": "webdriverio", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "webdriverio", + "version": "1.0.0", + "dependencies": { + "@wdio/cli": "^9.19.0" + }, + "devDependencies": { + "@wdio/local-runner": "^9.19.0", + "@wdio/mocha-framework": "^9.19.0", + "@wdio/spec-reporter": "^9.19.0", + "@wdio/types": "^9.23.3", + "dotenv": "^17.2.4", + "fs-extra": "^11.3.3", + "tsx": "^4.21.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/ansi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz", + "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz", + "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.1.21", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz", + "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz", + "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.23", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz", + "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/external-editor": "^1.0.3", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz", + "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", + "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz", + "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz", + "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz", + "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.10.1.tgz", + "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==", + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.3.2", + "@inquirer/confirm": "^5.1.21", + "@inquirer/editor": "^4.2.23", + "@inquirer/expand": "^4.0.23", + "@inquirer/input": "^4.3.1", + "@inquirer/number": "^3.0.23", + "@inquirer/password": "^4.0.23", + "@inquirer/rawlist": "^4.1.11", + "@inquirer/search": "^3.2.2", + "@inquirer/select": "^4.4.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz", + "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz", + "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz", + "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz", + "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@jest/diff-sequences": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", + "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", + "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/pattern": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", + "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-regex-util": "30.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/schemas": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/types": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", + "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "license": "MIT", + "dependencies": { + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@promptbook/utils": { + "version": "0.69.5", + "resolved": "https://registry.npmjs.org/@promptbook/utils/-/utils-0.69.5.tgz", + "integrity": "sha512-xm5Ti/Hp3o4xHrsK9Yy3MS6KbDxYbq485hDsFvxqaNA7equHLPdo8H8faTitTeb14QCDfLW4iwCxdVYu5sn6YQ==", + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/webgptorg/promptbook/blob/main/README.md#%EF%B8%8F-contributing" + } + ], + "license": "CC-BY-4.0", + "dependencies": { + "spacetrim": "0.11.59" + } + }, + "node_modules/@puppeteer/browsers": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.12.0.tgz", + "integrity": "sha512-Xuq42yxcQJ54ti8ZHNzF5snFvtpgXzNToJ1bXUGQRaiO8t+B6UM8sTUJfvV+AJnqtkJU/7hdy6nbKyA12aHtRw==", + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.4.3", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.5.0", + "semver": "^7.7.3", + "tar-fs": "^3.1.1", + "yargs": "^17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "license": "MIT" + }, + "node_modules/@sinclair/typebox": { + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "license": "MIT" + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/mocha": { + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.33", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.33.tgz", + "integrity": "sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "license": "MIT" + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", + "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", + "license": "MIT" + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "license": "MIT" + }, + "node_modules/@types/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", + "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "license": "MIT" + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", + "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@wdio/cli": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-9.23.3.tgz", + "integrity": "sha512-u4mx+uISonKI970LivyEn1qZGJn7izoTKUFUfLX89Y9fOtiASP/6a9KjCdMSw3MZU1cmKZs+yooeO7n0LnQHUA==", + "license": "MIT", + "dependencies": { + "@vitest/snapshot": "^2.1.1", + "@wdio/config": "9.23.3", + "@wdio/globals": "9.23.0", + "@wdio/logger": "9.18.0", + "@wdio/protocols": "9.23.3", + "@wdio/types": "9.23.3", + "@wdio/utils": "9.23.3", + "async-exit-hook": "^2.0.1", + "chalk": "^5.4.1", + "chokidar": "^4.0.0", + "create-wdio": "9.21.0", + "dotenv": "^17.2.0", + "import-meta-resolve": "^4.0.0", + "lodash.flattendeep": "^4.4.0", + "lodash.pickby": "^4.6.0", + "lodash.union": "^4.6.0", + "read-pkg-up": "^10.0.0", + "tsx": "^4.7.2", + "webdriverio": "9.23.3", + "yargs": "^17.7.2" + }, + "bin": { + "wdio": "bin/wdio.js" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/config": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-9.23.3.tgz", + "integrity": "sha512-tQCT1R6R3hdib7Qb+82Dxgn/sB+CiR8+GS4zyJh5vU0dzLGeYsCo2B5W89VLItvRjveTmsmh8NOQGV2KH0FHTQ==", + "license": "MIT", + "dependencies": { + "@wdio/logger": "9.18.0", + "@wdio/types": "9.23.3", + "@wdio/utils": "9.23.3", + "deepmerge-ts": "^7.0.3", + "glob": "^10.2.2", + "import-meta-resolve": "^4.0.0", + "jiti": "^2.6.1" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/dot-reporter": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/@wdio/dot-reporter/-/dot-reporter-9.23.3.tgz", + "integrity": "sha512-behiP6+SbQDO51GMtJ120X1vvc2I+qEdmTjfEG66e9hYozcg+iiaaPQd9RnCl8GJiU320APA91FXUGkz2ehSVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/reporter": "9.23.3", + "@wdio/types": "9.23.3", + "chalk": "^5.0.1" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/globals": { + "version": "9.23.0", + "resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-9.23.0.tgz", + "integrity": "sha512-OmwPKV8c5ecLqo+EkytN7oUeYfNmRI4uOXGIR1ybP7AK5Zz+l9R0dGfoadEuwi1aZXAL0vwuhtq3p0OL3dfqHQ==", + "license": "MIT", + "engines": { + "node": ">=18.20.0" + }, + "peerDependencies": { + "expect-webdriverio": "^5.3.4", + "webdriverio": "^9.0.0" + }, + "peerDependenciesMeta": { + "expect-webdriverio": { + "optional": false + }, + "webdriverio": { + "optional": false + } + } + }, + "node_modules/@wdio/local-runner": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-9.23.3.tgz", + "integrity": "sha512-ToafGHzdszOn8yc2BqUCAw0w9AX6158WKCHe50czZrHL04Q4eMCaqhb4XHY2wltSPPuubqCiPE2OgRssYi2kdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0", + "@wdio/logger": "9.18.0", + "@wdio/repl": "9.16.2", + "@wdio/runner": "9.23.3", + "@wdio/types": "9.23.3", + "@wdio/xvfb": "9.23.3", + "exit-hook": "^4.0.0", + "expect-webdriverio": "^5.3.4", + "split2": "^4.1.0", + "stream-buffers": "^3.0.2" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/logger": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-9.18.0.tgz", + "integrity": "sha512-HdzDrRs+ywAqbXGKqe1i/bLtCv47plz4TvsHFH3j729OooT5VH38ctFn5aLXgECmiAKDkmH/A6kOq2Zh5DIxww==", + "license": "MIT", + "dependencies": { + "chalk": "^5.1.2", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "safe-regex2": "^5.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/mocha-framework": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-9.23.3.tgz", + "integrity": "sha512-iCgKR69zMq6ATsORM4zoOF1Gk/82uEg5wbaEWQhgjv1TIK+D5VVFLYlVFwMOWcmAuGH4gAIj9TJoWX9cADh3/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mocha": "^10.0.6", + "@types/node": "^20.11.28", + "@wdio/logger": "9.18.0", + "@wdio/types": "9.23.3", + "@wdio/utils": "9.23.3", + "mocha": "^10.3.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/protocols": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-9.23.3.tgz", + "integrity": "sha512-QfA3Gfl9/3QRX1FnH7x2+uZrgpkwYcksgk1bxGLzl/E0Qefp3BkhgHAfSB1+iKsiYIw9iFOLVx+x+zh0F4BSeg==", + "license": "MIT" + }, + "node_modules/@wdio/repl": { + "version": "9.16.2", + "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-9.16.2.tgz", + "integrity": "sha512-FLTF0VL6+o5BSTCO7yLSXocm3kUnu31zYwzdsz4n9s5YWt83sCtzGZlZpt7TaTzb3jVUfxuHNQDTb8UMkCu0lQ==", + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/reporter": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-9.23.3.tgz", + "integrity": "sha512-ObIvV+FydWGsvt7kqRBCq5ItAzWhWiWG63t5P0mQKrADCtuJMjrI0Y/IrYQzcv2KnYcmkMKOQLwXFWp8D+D/OA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0", + "@wdio/logger": "9.18.0", + "@wdio/types": "9.23.3", + "diff": "^8.0.2", + "object-inspect": "^1.12.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/runner": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-9.23.3.tgz", + "integrity": "sha512-CnN4JubPmgVjWS9+S4nR8iDrVpjzsrClVlrAkhyG7+GF6PqzqMUpUABkFh7WlBxOATyxky/q6JCqgdFE+teVIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.11.28", + "@wdio/config": "9.23.3", + "@wdio/dot-reporter": "9.23.3", + "@wdio/globals": "9.23.0", + "@wdio/logger": "9.18.0", + "@wdio/types": "9.23.3", + "@wdio/utils": "9.23.3", + "deepmerge-ts": "^7.0.3", + "webdriver": "9.23.3", + "webdriverio": "9.23.3" + }, + "engines": { + "node": ">=18.20.0" + }, + "peerDependencies": { + "expect-webdriverio": "^5.3.4", + "webdriverio": "^9.0.0" + }, + "peerDependenciesMeta": { + "expect-webdriverio": { + "optional": false + }, + "webdriverio": { + "optional": false + } + } + }, + "node_modules/@wdio/spec-reporter": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-9.23.3.tgz", + "integrity": "sha512-4sARJ7ijOHGYo1mm4IRJttFiNYXYy3rf8YLPxKAlr1cKiYMHNtfZNcPiUsD4iU80TpEeP442ueV93ESog1oe4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/reporter": "9.23.3", + "@wdio/types": "9.23.3", + "chalk": "^5.1.2", + "easy-table": "^1.2.0", + "pretty-ms": "^9.0.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/types": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-9.23.3.tgz", + "integrity": "sha512-Ufjh06DAD7cGTMORUkq5MTZLw1nAgBSr2y8OyiNNuAfPGCwHEU3EwEfhG/y0V7S7xT5pBxliqWi7AjRrCgGcIA==", + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/utils": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-9.23.3.tgz", + "integrity": "sha512-LO/cTpOcb3r49psjmWTxjFduHUMHDOhVfSzL1gfBCS5cGv6h3hAWOYw/94OrxLn1SIOgZu/hyLwf3SWeZB529g==", + "license": "MIT", + "dependencies": { + "@puppeteer/browsers": "^2.2.0", + "@wdio/logger": "9.18.0", + "@wdio/types": "9.23.3", + "decamelize": "^6.0.0", + "deepmerge-ts": "^7.0.3", + "edgedriver": "^6.1.2", + "geckodriver": "^6.1.0", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.2.24", + "mitt": "^3.0.1", + "safaridriver": "^1.0.0", + "split2": "^4.2.0", + "wait-port": "^1.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/@wdio/xvfb": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/@wdio/xvfb/-/xvfb-9.23.3.tgz", + "integrity": "sha512-m0uITSBWk5hZyBdCFChpU05rkZCrTlu19qOHlSoJq19HX7m7mLbAz3tuu4SE+6jSw/E16I99zTC5S1bpxj7bEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/logger": "9.18.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@zip.js/zip.js": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.8.17.tgz", + "integrity": "sha512-3UdSsm9D9wy8+Oclimd3W9mWqiGptbrL7kBxAdXr/FLN2FSmNnAiyRol93heAffLGDzNwY5nnvDEjMmo8JbeeA==", + "license": "BSD-3-Clause", + "dependencies": { + "web-worker": "^1.5.0" + }, + "engines": { + "bun": ">=0.7.0", + "deno": ">=1.0.0", + "node": ">=18.0.0" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/archiver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.2", + "async": "^3.2.4", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^6.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", + "license": "MIT", + "dependencies": { + "glob": "^10.0.0", + "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/async-exit-hook": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/b4a": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/bare-events": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", + "license": "Apache-2.0", + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } + }, + "node_modules/bare-fs": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.3.tgz", + "integrity": "sha512-9+kwVx8QYvt3hPWnmb19tPnh38c6Nihz8Lx3t0g9+4GoIf3/fTgYwM4Z6NxgI+B9elLQA7mLE9PpqcWtOMRDiQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4", + "bare-url": "^2.2.2", + "fast-fifo": "^1.3.2" + }, + "engines": { + "bare": ">=1.16.0" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } + } + }, + "node_modules/bare-os": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", + "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "bare": ">=1.14.0" + } + }, + "node_modules/bare-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-os": "^3.0.1" + } + }, + "node_modules/bare-stream": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz", + "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "streamx": "^2.21.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-events": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-events": { + "optional": true + } + } + }, + "node_modules/bare-url": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz", + "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-path": "^3.0.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/basic-ftp": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.1.0.tgz", + "integrity": "sha512-RkaJzeJKDbaDWTIPiJwubyljaEPwpVWkm9Rt5h9Nd6h7tEXTJ3VB4qxdZBioV7JO5yLUaOKwz7vDOzlncUsegw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "license": "ISC" + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "license": "MIT" + }, + "node_modules/cheerio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.19.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio/node_modules/undici": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.21.0.tgz", + "integrity": "sha512-Hn2tCQpoDt1wv23a68Ctc8Cr/BHpUSfaPYrkajTXOS9IKpxVRx/X5m1K2YkbK2ipgZgxXSgsUinl3x+2YdSSfg==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/compress-commons": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/compress-commons/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/create-wdio": { + "version": "9.21.0", + "resolved": "https://registry.npmjs.org/create-wdio/-/create-wdio-9.21.0.tgz", + "integrity": "sha512-L6gsQLArY3AH5uTGpf3VfUezIsmZKufkF3ixSWqCuA/m458YVKeGghu1bBOWBdDIzqa6GX4e29dv0uVam0CTpw==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "commander": "^14.0.0", + "cross-spawn": "^7.0.3", + "ejs": "^3.1.10", + "execa": "^9.6.0", + "import-meta-resolve": "^4.1.0", + "inquirer": "^12.7.0", + "normalize-package-data": "^7.0.0", + "read-pkg-up": "^10.1.0", + "recursive-readdir": "^2.2.3", + "semver": "^7.6.3", + "type-fest": "^4.41.0", + "yargs": "^17.7.2" + }, + "bin": { + "create-wdio": "bin/wdio.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-shorthand-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/css-shorthand-properties/-/css-shorthand-properties-1.1.2.tgz", + "integrity": "sha512-C2AugXIpRGQTxaCW0N7n5jD/p5irUmCrwl03TrnMFBHDbdq44CFWR2zO7rK9xPN4Eo3pUxC4vQzQgbIpzrD1PQ==", + "license": "MIT" + }, + "node_modules/css-value": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz", + "integrity": "sha512-FUV3xaJ63buRLgHrLQVlVgQnQdR4yqdLGaDu7g8CQcWjInDfM9plBTPI9FRfpahju1UBSaMckeb2/46ApS/V1Q==" + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.1.tgz", + "integrity": "sha512-G7Cqgaelq68XHJNGlZ7lrNQyhZGsFqpwtGFexqUv4IQdjKoSYF7ipZ9UuTJZUSQXFj/XaoBLuEVIVqr8EJngEQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deepmerge-ts": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz", + "integrity": "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/diff": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dotenv": { + "version": "17.2.4", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.4.tgz", + "integrity": "sha512-mudtfb4zRB4bVvdj0xRo+e6duH1csJRM8IukBqfTRvHotn9+LBXB8ynAidP9zHqoRC/fsllXgk4kCKlR21fIhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/easy-table": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.2.0.tgz", + "integrity": "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "optionalDependencies": { + "wcwidth": "^1.0.1" + } + }, + "node_modules/edge-paths": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", + "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", + "license": "MIT", + "dependencies": { + "@types/which": "^2.0.1", + "which": "^2.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/shirshak55" + } + }, + "node_modules/edgedriver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-6.3.0.tgz", + "integrity": "sha512-ggEQL+oEyIcM4nP2QC3AtCQ04o4kDNefRM3hja0odvlPSnsaxiruMxEZ93v3gDCKWYW6BXUr51PPradb+3nffw==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@wdio/logger": "^9.18.0", + "@zip.js/zip.js": "^2.8.11", + "decamelize": "^6.0.1", + "edge-paths": "^3.0.5", + "fast-xml-parser": "^5.3.3", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "which": "^6.0.0" + }, + "bin": { + "edgedriver": "bin/edgedriver.js" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/edgedriver/node_modules/isexe": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.4.tgz", + "integrity": "sha512-jCErc4h4RnTPjFq53G4whhjAMbUAqinGrCrTT4dmMNyi4zTthK+wphqbRLJtL4BN/Mq7Zzltr0m/b1X0m7PGFQ==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/edgedriver/node_modules/which": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", + "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/encoding-sniffer/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, + "node_modules/execa": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", + "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-4.0.0.tgz", + "integrity": "sha512-Fqs7ChZm72y40wKjOFXBKg7nJZvQJmewP5/7LtePDdnah/+FH9Hp5sgMujSCMPXlxOAW2//1jrW9pnsY7o20vQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/expect": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", + "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==", + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "30.2.0", + "@jest/get-type": "30.1.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-util": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/expect-webdriverio": { + "version": "5.6.4", + "resolved": "https://registry.npmjs.org/expect-webdriverio/-/expect-webdriverio-5.6.4.tgz", + "integrity": "sha512-Bkoqs+39fHwjos51qab7ZWmvZrYNBbzgSAIykH2CrgLOLhHJXzC30DP9lZq2MsmaUsbBnN5c5m8VqAhOHTrCRw==", + "license": "MIT", + "dependencies": { + "@vitest/snapshot": "^4.0.16", + "deep-eql": "^5.0.2", + "expect": "^30.2.0", + "jest-matcher-utils": "^30.2.0" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "@wdio/globals": "^9.0.0", + "@wdio/logger": "^9.0.0", + "webdriverio": "^9.0.0" + }, + "peerDependenciesMeta": { + "@wdio/globals": { + "optional": false + }, + "@wdio/logger": { + "optional": false + }, + "webdriverio": { + "optional": false + } + } + }, + "node_modules/expect-webdriverio/node_modules/@vitest/pretty-format": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.18.tgz", + "integrity": "sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==", + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/expect-webdriverio/node_modules/@vitest/snapshot": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.18.tgz", + "integrity": "sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==", + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.18", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/expect-webdriverio/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, + "node_modules/expect-webdriverio/node_modules/tinyrainbow": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", + "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", + "license": "MIT" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "license": "MIT" + }, + "node_modules/fast-xml-parser": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.5.tgz", + "integrity": "sha512-JeaA2Vm9ffQKp9VjvfzObuMCjUYAp5WDYhRYL5LrBPY/jUDlUtOvDfot0vKSkB9tuX885BDHjtw4fZadD95wnA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^2.1.2" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs-extra": { + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", + "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/geckodriver": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-6.1.0.tgz", + "integrity": "sha512-ZRXLa4ZaYTTgUO4Eefw+RsQCleugU2QLb1ME7qTYxxuRj51yAhfnXaItXNs5/vUzfIaDHuZ+YnSF005hfp07nQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@wdio/logger": "^9.18.0", + "@zip.js/zip.js": "^2.8.11", + "decamelize": "^6.0.1", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "modern-tar": "^0.7.2" + }, + "bin": { + "geckodriver": "bin/geckodriver.js" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-port": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", + "integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.6", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz", + "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==", + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hosted-git-info": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz", + "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==", + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/htmlfy": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/htmlfy/-/htmlfy-0.8.1.tgz", + "integrity": "sha512-xWROBw9+MEGwxpotll0h672KCaLrKKiCYzsyN8ZgL9cQbVumFnyvsk2JqiB9ELAV1GLj1GG/jxZUjV9OZZi/yQ==", + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "12.11.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-12.11.1.tgz", + "integrity": "sha512-9VF7mrY+3OmsAfjH3yKz/pLbJ5z22E23hENKw3/LNSaA/sAt3v49bDRY+Ygct1xwuKT+U+cBfTzjCPySna69Qw==", + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/prompts": "^7.10.1", + "@inquirer/type": "^3.0.10", + "mute-stream": "^2.0.0", + "run-async": "^4.0.6", + "rxjs": "^7.8.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-diff": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", + "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", + "license": "MIT", + "dependencies": { + "@jest/diff-sequences": "30.0.1", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz", + "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "jest-diff": "30.2.0", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz", + "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.2.0", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "micromatch": "^4.0.8", + "pretty-format": "30.2.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-mock": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz", + "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "jest-util": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-regex-util": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", + "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-util": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", + "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lines-and-columns": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", + "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/locate-app": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/locate-app/-/locate-app-2.5.0.tgz", + "integrity": "sha512-xIqbzPMBYArJRmPGUZD9CzV9wOqmVtQnaAn3wrj3s6WYW0bQvPI7x+sPYUGmDTYMHefVK//zc6HEYZ1qnxIK+Q==", + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/hejny/locate-app/blob/main/README.md#%EF%B8%8F-contributing" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@promptbook/utils": "0.69.5", + "type-fest": "4.26.0", + "userhome": "1.0.1" + } + }, + "node_modules/locate-app/node_modules/type-fest": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.0.tgz", + "integrity": "sha512-OduNjVJsFbifKb57UqZ2EMP1i4u64Xwow3NYXUtBbD4vIwJdQd4+xl8YDou1dlm4DVrtwT/7Ky8z8WyCULVfxw==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "license": "MIT" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "license": "MIT" + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "license": "MIT" + }, + "node_modules/lodash.pickby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", + "integrity": "sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==", + "license": "MIT" + }, + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", + "license": "MIT" + }, + "node_modules/lodash.zip": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", + "integrity": "sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==", + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/loglevel": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/loglevel-plugin-prefix": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", + "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "license": "MIT" + }, + "node_modules/mocha": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/mocha/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/mocha/node_modules/diff": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz", + "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/mocha/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mocha/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/mocha/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/modern-tar": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/modern-tar/-/modern-tar-0.7.3.tgz", + "integrity": "sha512-4W79zekKGyYU4JXVmB78DOscMFaJth2gGhgfTl2alWE4rNe3nf4N2pqenQ0rEtIewrnD79M687Ouba3YGTLOvg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/normalize-package-data": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-7.0.1.tgz", + "integrity": "sha512-linxNAT6M0ebEYZOx2tO6vBEFsVgnPpv+AVjk0wJHfaUIbq31Jm3T6vvZaarnOeWDh8ShnwXuaAyM7WT3RzErA==", + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^8.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, + "node_modules/parse-json": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz", + "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.21.4", + "error-ex": "^1.3.2", + "json-parse-even-better-errors": "^3.0.0", + "lines-and-columns": "^2.0.3", + "type-fest": "^3.8.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "license": "MIT" + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pretty-format": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", + "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/pretty-ms": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz", + "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==", + "license": "MIT", + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/query-selector-shadow-dom": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz", + "integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==", + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/read-pkg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.1.0.tgz", + "integrity": "sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==", + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.1", + "normalize-package-data": "^6.0.0", + "parse-json": "^7.0.0", + "type-fest": "^4.2.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-10.1.0.tgz", + "integrity": "sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==", + "license": "MIT", + "dependencies": { + "find-up": "^6.3.0", + "read-pkg": "^8.1.0", + "type-fest": "^4.2.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "license": "MIT", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/read-pkg-up/node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/recursive-readdir/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/recursive-readdir/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/resq": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resq/-/resq-1.11.0.tgz", + "integrity": "sha512-G10EBz+zAAy3zUd/CDoBbXRL6ia9kOo3xRHrMDsHljI0GDkhYlyjwoCx5+3eCC4swi1uCoZQhskuJkj7Gp57Bw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^2.0.1" + } + }, + "node_modules/ret": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.5.0.tgz", + "integrity": "sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/rgb2hex": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.2.5.tgz", + "integrity": "sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==", + "license": "MIT" + }, + "node_modules/run-async": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-4.0.6.tgz", + "integrity": "sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safaridriver": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safaridriver/-/safaridriver-1.0.1.tgz", + "integrity": "sha512-jkg4434cYgtrIF2AeY/X0Wmd2W73cK5qIEFE3hDrrQenJH/2SDJIXGvPAigfvQTcE9+H31zkiNHbUqcihEiMRA==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex2": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-5.0.0.tgz", + "integrity": "sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "ret": "~0.5.0" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-error": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-12.0.0.tgz", + "integrity": "sha512-ZYkZLAvKTKQXWuh5XpBw7CdbSzagarX39WyZ2H07CDLC5/KfsRGlIXV8d4+tfqX1M7916mRqR1QfNHSij+c9Pw==", + "license": "MIT", + "dependencies": { + "type-fest": "^4.31.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spacetrim": { + "version": "0.11.59", + "resolved": "https://registry.npmjs.org/spacetrim/-/spacetrim-0.11.59.tgz", + "integrity": "sha512-lLYsktklSRKprreOm7NXReW8YiX2VBjbgmXYEziOoGf/qsJqAEACaDvoTtUOycwjpaSh+bT8eu0KrJn7UNxiCg==", + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/hejny/spacetrim/blob/main/README.md#%EF%B8%8F-contributing" + } + ], + "license": "Apache-2.0" + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "license": "CC0-1.0" + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stream-buffers": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.3.tgz", + "integrity": "sha512-pqMqwQCso0PBJt2PQmDO0cFj0lyqmiwOMiMSkVtRokl7e+ZTRYgDHKnuZNbqjiJXgsg4nuqtD/zxuo9KqTp0Yw==", + "dev": true, + "license": "Unlicense", + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/streamx": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "license": "MIT", + "dependencies": { + "events-universal": "^1.0.0", + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strnum": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", + "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tar-fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", + "license": "MIT", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz", + "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/urlpattern-polyfill": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.1.0.tgz", + "integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==", + "license": "MIT" + }, + "node_modules/userhome": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/userhome/-/userhome-1.0.1.tgz", + "integrity": "sha512-5cnLm4gseXjAclKowC4IjByaGsjtAoV6PrOQOljplNB54ReUYJP8HdAFq2muHinSDAh09PPX/uXDPfdxRHvuSA==", + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/wait-port": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/wait-port/-/wait-port-1.1.0.tgz", + "integrity": "sha512-3e04qkoN3LxTMLakdqeWth8nih8usyg+sf1Bgdf9wwUkp05iuK1eSY/QpLvscT/+F/gA89+LpUmmgBtesbqI2Q==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "commander": "^9.3.0", + "debug": "^4.3.4" + }, + "bin": { + "wait-port": "bin/wait-port.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/wait-port/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wait-port/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/wait-port/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/wait-port/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/web-worker": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.5.0.tgz", + "integrity": "sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==", + "license": "Apache-2.0" + }, + "node_modules/webdriver": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.23.3.tgz", + "integrity": "sha512-8FdXOhzkxqDI6F1dyIsQONhKLDZ9HPSEwNBnH3bD1cHnj/6nVvyYrUtDPo/+J324BuwOa1IVTH3m8mb3B2hTlA==", + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0", + "@types/ws": "^8.5.3", + "@wdio/config": "9.23.3", + "@wdio/logger": "9.18.0", + "@wdio/protocols": "9.23.3", + "@wdio/types": "9.23.3", + "@wdio/utils": "9.23.3", + "deepmerge-ts": "^7.0.3", + "https-proxy-agent": "^7.0.6", + "undici": "^6.21.3", + "ws": "^8.8.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/webdriverio": { + "version": "9.23.3", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.23.3.tgz", + "integrity": "sha512-1dhMsBx/GLHJsDLhg/xuEQ48JZPrbldz7qdFT+MXQZADj9CJ4bJywWtVBME648MmVMfgDvLc5g2ThGIOupSLvQ==", + "license": "MIT", + "dependencies": { + "@types/node": "^20.11.30", + "@types/sinonjs__fake-timers": "^8.1.5", + "@wdio/config": "9.23.3", + "@wdio/logger": "9.18.0", + "@wdio/protocols": "9.23.3", + "@wdio/repl": "9.16.2", + "@wdio/types": "9.23.3", + "@wdio/utils": "9.23.3", + "archiver": "^7.0.1", + "aria-query": "^5.3.0", + "cheerio": "^1.0.0-rc.12", + "css-shorthand-properties": "^1.1.1", + "css-value": "^0.0.1", + "grapheme-splitter": "^1.0.4", + "htmlfy": "^0.8.1", + "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", + "lodash.clonedeep": "^4.5.0", + "lodash.zip": "^4.2.0", + "query-selector-shadow-dom": "^1.0.1", + "resq": "^1.11.0", + "rgb2hex": "0.2.5", + "serialize-error": "^12.0.0", + "urlpattern-polyfill": "^10.0.0", + "webdriver": "9.23.3" + }, + "engines": { + "node": ">=18.20.0" + }, + "peerDependencies": { + "puppeteer-core": ">=22.x || <=24.x" + }, + "peerDependenciesMeta": { + "puppeteer-core": { + "optional": true + } + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yauzl/node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zip-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + } + } +} diff --git a/test/package.json b/test/package.json new file mode 100644 index 0000000..a5e774b --- /dev/null +++ b/test/package.json @@ -0,0 +1,22 @@ +{ + "name": "webdriverio", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "test": "wdio run wdio.conf.ts", + "test:dev": "REUSE_BUILD=true wdio run wdio.conf.ts" + }, + "dependencies": { + "@wdio/cli": "^9.19.0" + }, + "devDependencies": { + "@wdio/local-runner": "^9.19.0", + "@wdio/mocha-framework": "^9.19.0", + "@wdio/spec-reporter": "^9.19.0", + "@wdio/types": "^9.23.3", + "dotenv": "^17.2.4", + "fs-extra": "^11.3.3", + "tsx": "^4.21.0" + } +} diff --git a/test/pageobjects/App.ts b/test/pageobjects/App.ts new file mode 100644 index 0000000..b7e8883 --- /dev/null +++ b/test/pageobjects/App.ts @@ -0,0 +1,30 @@ +const r$ = (...args) => browser.react$(...args) +const r$$ = (...args) => browser.react$$(...args) +import * as fs from "node:fs" +import * as path from "node:path" +import * as os from "node:os" + +class App { + get projectsButton() { return $("button=Projects") } + get metadataButton() { return $("button=Metadata") } + + async selectView(view: "projects" | "metadata") { + if (view === "projects") { + await this.projectsButton.click(); + await expect(this.projectsButton).toHaveAttribute("aria-selected", "true") + } else if (view === "metadata") { + await this.metadataButton.click(); + await expect(this.metadataButton).toHaveAttribute("aria-selected", "true") + } + } + + clearAllData() { + console.log("Clearing data...") + try { + fs.rmSync(path.join(os.homedir(), ".local/share/com.kcjer.dtm"), { recursive: true }) + } catch (e) { + } + } +} + +export default new App() \ No newline at end of file diff --git a/test/pageobjects/DTProjects.ts b/test/pageobjects/DTProjects.ts new file mode 100644 index 0000000..55bd81f --- /dev/null +++ b/test/pageobjects/DTProjects.ts @@ -0,0 +1,97 @@ +import fse from "fs-extra" + +class DTProjects { + get projectA() { return $('[data-test-id="project-item"]*=test-project-a') } + get projectB() { return $('[data-test-id="project-item"]*=test-project-b') } + + get images() { return $$('[data-testid="image-item"]') } + + getProject(projectName: string) { + return $(`[data-test-id="project-item"]*=${projectName}`) + } + + getProjectId(projectName: string) { + return this.getProject(projectName).getAttribute("data-project-id") + } + + async selectProject(projectName: string) { + await this.getProject(projectName).click() + await expect(this.getProject(projectName)).toHaveAttribute("aria-selected", "true") + } + + async deselectProject(projectName: string) { + await this.getProject(projectName).click() + await expect(this.getProject(projectName)).toHaveAttribute("aria-selected", "false") + } + + async countVisibleImages() { + return (await this.images).length + } + + helpers = { + checkProjectFiles: async () => { + // check that all files in TEST_DATA_STORAGE are also in DTP_TEST_DIR + // if not, copy them + const testDataStorage = process.env.TEST_DATA_STORAGE + const dtpTestDir = process.env.DTP_TEST_DIR + + if (!testDataStorage || !dtpTestDir) { + throw new Error('TEST_DATA_STORAGE and DTP_TEST_DIR environment variables must be set') + } + + await fse.ensureDir(dtpTestDir) + const files = await fse.readdir(testDataStorage, { recursive: true }) + + for (const file of files) { + const srcPath = `${testDataStorage}${file}` + const destPath = `${dtpTestDir}${file}` + const destExists = await fse.pathExists(destPath) + + if (!destExists) { + await fse.copy(srcPath, destPath) + } + } + }, + + removeProjectFiles: async (projectName: string) => { + // remove files for the given project from DTP_TEST_DIR + // remove both .sqlite3 and .sqlite3-shm and .sqlite3-wal if they exist + const dtpTestDir = process.env.DTP_TEST_DIR + + if (!dtpTestDir) { + throw new Error('DTP_TEST_DIR environment variable must be set') + } + + const extensions = ['.sqlite3', '.sqlite3-shm', '.sqlite3-wal'] + + for (const ext of extensions) { + const filePath = `${dtpTestDir}/projects/${projectName}${ext}` + await fse.remove(filePath) + } + }, + + renameProjectFiles: async (oldName: string, newName: string) => { + // rename project files in DTP_TEST_DIR from oldName to newName + // rename both .sqlite3 and .sqlite3-shm and .sqlite3-wal if they exist + const dtpTestDir = process.env.DTP_TEST_DIR + + if (!dtpTestDir) { + throw new Error('DTP_TEST_DIR environment variable must be set') + } + + const extensions = ['.sqlite3', '.sqlite3-shm', '.sqlite3-wal'] + + for (const ext of extensions) { + const oldPath = `${dtpTestDir}/projects/${oldName}${ext}` + const newPath = `${dtpTestDir}/projects/${newName}${ext}` + const exists = await fse.pathExists(oldPath) + + if (exists) { + await fse.rename(oldPath, newPath) + } + } + } + } +} + +export default new DTProjects() \ No newline at end of file diff --git a/test/specs/example.e2e.ts b/test/specs/example.e2e.ts new file mode 100644 index 0000000..193242f --- /dev/null +++ b/test/specs/example.e2e.ts @@ -0,0 +1,27 @@ +import App from "../pageobjects/App" + +before(async () => { + await App.clearAllData() +}) + +describe('Hello Tauri', () => { + it('should be the correct title', async () => { + await expect(browser).toHaveTitle('DTM') + }) +}) + +describe('Basic', () => { + it('can switch views', async () => { + await new Promise(resolve => setTimeout(resolve, 2000)) + + await App.metadataButton.click(); + await expect(App.metadataButton).toHaveAttribute("aria-selected", "true") + + await expect($("div*=Drop image here")).toBeDisplayedInViewport() + + await App.projectsButton.click(); + await expect(App.projectsButton).toHaveAttribute("aria-selected", "true") + + await expect($("aria/Projects")).toBeDisplayedInViewport() + }) +}) \ No newline at end of file diff --git a/test/specs/projects-reset.e2e.ts b/test/specs/projects-reset.e2e.ts new file mode 100644 index 0000000..534957b --- /dev/null +++ b/test/specs/projects-reset.e2e.ts @@ -0,0 +1,45 @@ + +import path from "path"; +import App from "../pageobjects/App"; +import DTProjects from "../pageobjects/DTProjects"; + +const testProjectsDir = path.join(process.env.DTP_TEST_DIR, "projects") + +// these tests will have the app data cleared before running +// so there will be no watched folders set up already + +beforeEach(async () => { + App.clearAllData() + await DTProjects.helpers.checkProjectFiles() +}) + +describe('Projects', () => { + it('can add a watchfolder', async () => { + await App.projectsButton.click(); + await expect(App.projectsButton).toHaveAttribute("aria-selected", "true") + + const settingsHeader = $("p=Settings") + await expect(settingsHeader).toBeDisplayedInViewport() + + await browser.execute((folderPath) => { + (window as any).__E2E_FILE_PATH__ = folderPath + }, testProjectsDir); + + // the progress bar goes by fast so we start waiting before adding the folder + const progressBarWait = $("div*=images scanned").waitForDisplayed({ timeout: 5000 }) + + await $("aria/add folder").click() + + // make sure progress appeared... + await progressBarWait + // ...and then went away + await $("div*=images scanned").waitForDisplayed({ timeout: 5000, reverse: true }) + + await expect($(`div=${testProjectsDir}`)).toBeDisplayedInViewport() + + await $('button[aria-label="close settings"]').click() + + await expect($("div=test-project-a")).toBeDisplayedInViewport() + await expect($("div=test-project-b")).toBeDisplayedInViewport() + }) +}) \ No newline at end of file diff --git a/test/specs/projects.e2e.ts b/test/specs/projects.e2e.ts new file mode 100644 index 0000000..6a05ba0 --- /dev/null +++ b/test/specs/projects.e2e.ts @@ -0,0 +1,130 @@ +import path from "node:path" +import App from "../pageobjects/App" +import DTProjects from "../pageobjects/DTProjects" +import os from "node:os" +import * as fs from "node:fs" + +const testDataRoot = process.env.TEST_DATA_DIR || path.join(os.homedir(), "dtm-test-data") +const testProjectsDir = path.join(testDataRoot, "projects") + +// these tests will not clear the app data +// they all depend on the projects watchfolder already existing + +before(async () => { + await DTProjects.helpers.checkProjectFiles() +}) + +afterEach(async () => { + // await new Promise(resolve => setTimeout(resolve, 200000)) +}) + +describe('Projects', () => { + it('can select a project', async () => { + await App.projectsButton.click(); + await expect(App.projectsButton).toHaveAttribute("aria-selected", "true") + + // verify projects are listed + await expect(DTProjects.projectA).toBeDisplayedInViewport() + await expect(DTProjects.projectB).toBeDisplayedInViewport() + + // count images + await browser.waitUntil(async () => + (await $('[data-testid="image-grid"]').getAttribute('aria-busy')) === 'false' + ) + const countBefore = await DTProjects.countVisibleImages() + + // select project A + await DTProjects.selectProject("test-project-a") + await browser.waitUntil(async () => + (await $('[data-testid="image-grid"]').getAttribute('aria-busy')) === 'false' + ) + + // verify only project A's images are shown + let updatedCount = await DTProjects.countVisibleImages() + expect(updatedCount).toBeLessThan(countBefore) + + const projectAId = await DTProjects.projectA.getAttribute("data-project-id") + for (const el of await DTProjects.images.getElements()) { + await expect(el).toHaveAttribute('data-project-id', projectAId) + } + + // select project B + await DTProjects.selectProject("test-project-b") + await browser.waitUntil(async () => + (await $('[data-testid="image-grid"]').getAttribute('aria-busy')) === 'false' + ) + + // verify only project B's images are shown + updatedCount = await DTProjects.countVisibleImages() + expect(updatedCount).toBeLessThan(countBefore) + + const projectBId = await DTProjects.projectB.getAttribute("data-project-id") + for (const el of await DTProjects.images.getElements()) { + await expect(el).toHaveAttribute('data-project-id', projectBId) + } + + // deselect project + await DTProjects.deselectProject("test-project-b") + await browser.waitUntil(async () => + (await $('[data-testid="image-grid"]').getAttribute('aria-busy')) === 'false' + ) + + // verify all images are shown again + await expect(DTProjects.images).toBeElementsArrayOfSize(countBefore) + }) + + it("projects list stays in sync with file system", async () => { + await App.selectView("projects") + + // verify test-project-b is listed + await expect(DTProjects.projectB).toBeDisplayedInViewport() + + // wait a moment to ensure folder is being watched + await new Promise(resolve => setTimeout(resolve, 2000)) + + // remove project files + await DTProjects.helpers.removeProjectFiles("test-project-b") + + // verify test-project-b is no longer listed + await DTProjects.projectB.waitForExist({ reverse: true, timeout: 15000 }) + + // restore project files + await DTProjects.helpers.checkProjectFiles() + + // verify test-project-b is listed again + await DTProjects.projectB.waitForExist({ timeout: 15000 }) + await expect(DTProjects.projectB).toBeDisplayedInViewport() + }) + + it("projects are removed and readded when a files are renamed", async () => { + await App.selectView("projects") + + // verify test-project-a is listed + await expect(DTProjects.projectA).toBeDisplayedInViewport() + + // wait a moment to ensure folder is being watched + await new Promise(resolve => setTimeout(resolve, 2000)) + + // rename files + await DTProjects.helpers.renameProjectFiles("test-project-a", "test-project-rename") + + // verify test-project-a is no longer listed + await DTProjects.projectA.waitForExist({ reverse: true, timeout: 15000 }) + + // BUG: renamed projects are listed twice + // verify the renamed project appears, only once + await expect(DTProjects.getProject("test-project-rename")).toBeDisplayedInViewport() + await expect($$(`[data-test-id="project-item"]*=${"test-project-rename"}`)).toBeElementsArrayOfSize(1) + + // rename back to original name + await DTProjects.helpers.renameProjectFiles("test-project-rename", "test-project-a") + + // verify the renamed project disappears + await DTProjects.getProject("test-project-rename").waitForExist({ reverse: true, timeout: 15000 }) + + // verify test-project-a is listed again, only once + await expect(DTProjects.projectA).toBeDisplayedInViewport() + await expect($$(`[data-test-id="project-item"]*=${"test-project-a"}`)).toBeElementsArrayOfSize(1) + }) +}) + diff --git a/test/tsconfig.json b/test/tsconfig.json new file mode 100644 index 0000000..47d75d1 --- /dev/null +++ b/test/tsconfig.json @@ -0,0 +1,11 @@ +{ + "include": ["./"], + "compilerOptions": { + "target": "esnext", + "types": ["node", "@wdio/globals/types", "@wdio/mocha-framework"], + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "moduleResolution": "node", + "module": "commonjs", + } +} \ No newline at end of file diff --git a/test/wdio.conf.ts b/test/wdio.conf.ts new file mode 100644 index 0000000..eba386c --- /dev/null +++ b/test/wdio.conf.ts @@ -0,0 +1,132 @@ +import os from 'os'; +import fse from 'fs-extra'; +import path from 'path'; +import { spawn, spawnSync } from 'child_process'; +import { fileURLToPath } from 'url'; + +const __dirname = fileURLToPath(new URL('.', import.meta.url)); +const testDataSource = "/media/share/dtm-test-data/" +const testDataDest = path.join(os.homedir(), "dtm-test-data") + +const reuse = process.env.REUSE_BUILD === 'true'; + +// keep track of the `tauri-driver` child process +let tauriDriver; +let exit = false; + +export const config: WebdriverIO.Config = { + host: '127.0.0.1', + port: 4444, + specs: ['./specs/**/*.ts'], + maxInstances: 1, + capabilities: [ + { + maxInstances: 1, + 'tauri:options': { + application: '../src-tauri/target/debug/dtm', + }, + }, + ], + reporters: ['spec'], + framework: 'mocha', + mochaOpts: { + ui: 'bdd', + timeout: 60000, + }, + + // ensure the rust project is built since we expect this binary to exist for the webdriver sessions + onPrepare: () => { + if (!reuse) + spawnSync( + 'npm', + ['run', 'tauri', 'build', '--', '--debug', '--no-bundle'], + { + cwd: path.resolve(__dirname, '..'), + stdio: 'inherit', + shell: true, + } + ); + }, + + // ensure we are running `tauri-driver` before the session starts so that we can proxy the webdriver requests + beforeSession: () => { + console.log("BEFORE SESSION") + tauriDriver = spawn( + path.resolve(os.homedir(), '.cargo', 'bin', 'tauri-driver'), + [], + { stdio: [null, process.stdout, process.stderr] } + ); + + tauriDriver.on('error', (error) => { + console.error('tauri-driver error:', error); + process.exit(1); + }); + tauriDriver.on('exit', (code) => { + if (!exit) { + console.error('tauri-driver exited with code:', code); + process.exit(1); + } + }); + }, + + before: async () => { + fse.emptyDirSync(testDataDest) + fse.copySync(testDataSource, testDataDest) + }, + + // afterTest: async function ( + // test, + // context, + // { error, result, duration, passed } + // ) { + // if (passed) return + + // const screenshotsDir = path.resolve("./screenshots") + // if (!fs.existsSync(screenshotsDir)) { + // fs.mkdirSync(screenshotsDir, { recursive: true }) + // } + + // const name = test.title + // .replace(/[^a-z0-9]+/gi, "_") + // .toLowerCase() + + // const filePath = path.join( + // screenshotsDir, + // `${name}-${Date.now()}.png` + // ) + + // await browser.saveScreenshot(filePath) + // }, + + // clean up the `tauri-driver` process we spawned at the start of the session + // note that afterSession might not run if the session fails to start, so we also run the cleanup on shutdown + afterSession: () => { + closeTauriDriver(); + }, +}; + +function closeTauriDriver() { + exit = true; + tauriDriver?.kill(); +} + +function onShutdown(fn) { + const cleanup = () => { + try { + fn(); + } finally { + process.exit(); + } + }; + + process.on('exit', cleanup); + process.on('SIGINT', cleanup); + process.on('SIGTERM', cleanup); + process.on('SIGHUP', cleanup); + process.on('SIGBREAK', cleanup); +} + +// ensure tauri-driver is closed when our test process exits +onShutdown(() => { + closeTauriDriver(); +}); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index f46ba52..2616a98 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,9 +26,10 @@ "@/*": [ "./src/*" ] - } + }, + "types": ["node", "@wdio/globals/types", "@types/mocha"] }, - "include": ["./src", "./src/global.ts"], + "include": ["./src", "./src/global.ts", "./test"], // "exclude": ["src/scratch/*"], "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/tsconfig.node.json b/tsconfig.node.json index 42872c5..b4c1863 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -4,7 +4,8 @@ "skipLibCheck": true, "module": "ESNext", "moduleResolution": "bundler", - "allowSyntheticDefaultImports": true + "allowSyntheticDefaultImports": true, + "types": ["node", "@wdio/globals/types"] }, "include": ["vite.config.ts"] } diff --git a/vite.config.ts b/vite.config.ts index 9fcb272..de875c1 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -2,19 +2,34 @@ import { defineConfig, ViteDevServer } from "vite"; import react from "@vitejs/plugin-react"; import tsconfigPaths from "vite-tsconfig-paths" import { htmlInjectionPlugin } from "vite-plugin-html-injection"; -import wasm from "vite-plugin-wasm"; +// import wasm from "vite-plugin-wasm"; -import { visualizer } from 'rollup-plugin-visualizer' +// import { visualizer } from 'rollup-plugin-visualizer' const host = process.env.TAURI_DEV_HOST; const isMock = process.env.MOCK_TAURI === "true"; +const reactDevtools = process.env.REACT_DEVTOOLS === "true"; const hmr = true // https://vite.dev/config/ export default defineConfig(async () => ({ + base: "./", + build: { + target: "esnext", + assetsInlineLimit: 0, + // cssCodeSplit: false, + // sourcemap: true, + // rollupOptions: { + // output: { + // manualChunks() { + // return 'app' + // } + // } + // } + }, plugins: [ - htmlInjectionPlugin({ + reactDevtools ? htmlInjectionPlugin({ order: "pre", injections: [ { @@ -25,7 +40,7 @@ export default defineConfig(async () => ({ buildModes: "dev", }, ], - }), + }) : null, react({ babel: { plugins: ['babel-plugin-react-compiler', @@ -34,8 +49,8 @@ export default defineConfig(async () => ({ } }), tsconfigPaths(), - wasm(), - visualizer({ open: true }), + // wasm(), + // visualizer({ open: true }), ], resolve: { alias: { diff --git a/vitest.config.ts b/vitest.config.ts index 993bae5..ed10b04 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -8,5 +8,8 @@ export default defineConfig({ environment: 'jsdom', setupFiles: ['./src/test/setup.ts'], globals: true, + env: { + MOCK_TAURI: "true" + } }, })