From 879e29b4abc456d171bfb22909d96f7b0b40c0e9 Mon Sep 17 00:00:00 2001 From: Maxime Baconnais Date: Fri, 1 Mar 2024 16:47:17 +0100 Subject: [PATCH 01/17] WiP --- package-lock.json | 1559 +++++----------------- package.json | 9 +- src/electron/actions.js | 34 +- src/electron/cameras/canon.js | 84 ++ src/electron/cameras/index.js | 47 + src/electron/index.js | 2 +- src/renderer/cameras/NativeProxy.js | 86 ++ src/renderer/{core => cameras}/Webcam.js | 95 +- src/renderer/cameras/index.js | 143 ++ src/renderer/core/Devices.js | 21 +- src/renderer/index.js | 2 +- src/renderer/views/Animator.jsx | 9 +- src/renderer/views/Home.jsx | 9 +- src/renderer/views/Settings.jsx | 2 +- static/i18n/fr.json | 2 +- 15 files changed, 767 insertions(+), 1337 deletions(-) create mode 100644 src/electron/cameras/canon.js create mode 100644 src/electron/cameras/index.js create mode 100644 src/renderer/cameras/NativeProxy.js rename src/renderer/{core => cameras}/Webcam.js (72%) create mode 100644 src/renderer/cameras/index.js diff --git a/package-lock.json b/package-lock.json index 44519ee..c0d59fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "2.3.1", "license": "GPL-3.0", "dependencies": { + "@dimensional/napi-canon-cameras": "file:../../node_packages/@dimensional/napi-canon-cameras.tgz", "animated-scroll-to": "^2.3.0", "compare-versions": "^6.0.0", "env-paths": "^2.2.1", @@ -37,8 +38,8 @@ "@parcel/config-default": "^2.8.3", "@parcel/transformer-svg-react": "^2.8.3", "buffer": "^5.5.0", - "electron": "^25.5.0", - "electron-builder": "^24.4.0", + "electron": "^29.1.0", + "electron-builder": "^24.12.0", "eslint": "8.45.0", "eslint-plugin-react": "7.33.0", "husky": "^8.0.3", @@ -537,13 +538,28 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/@dimensional/napi-canon-cameras": { + "version": "0.1.0", + "resolved": "file:../../node_packages/@dimensional/napi-canon-cameras.tgz", + "integrity": "sha512-nyq4u3oOrPsSr0/FJcXAUBQH4IrBMOatNAuYy7esAMP95HIau7Ams6YEwOrsoPVEbFBtadafkPcXW28AZAIr1Q==", + "hasInstallScript": true, + "license": "GPL-3.0-or-later", + "dependencies": { + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.8.0" + } + }, + "node_modules/@dimensional/napi-canon-cameras/node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, "node_modules/@electron/asar": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.4.tgz", - "integrity": "sha512-lykfY3TJRRWFeTxccEKdf1I6BLl2Plw81H0bbp4Fc5iEc67foDCa5pjJQULVgo0wF+Dli75f3xVcdb/67FFZ/g==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.8.tgz", + "integrity": "sha512-cmskk5M06ewHMZAplSiF4AlME3IrnnZhKnWbtwKVLRkdJkKyUVjMLhDIiPIx/+6zQWVlKX/LtmK9xDme7540Sg==", "dev": true, "dependencies": { - "chromium-pickle-js": "^0.2.0", "commander": "^5.0.0", "glob": "^7.1.6", "minimatch": "^3.0.4" @@ -593,13 +609,14 @@ } }, "node_modules/@electron/notarize": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-1.2.4.tgz", - "integrity": "sha512-W5GQhJEosFNafewnS28d3bpQ37/s91CDWqxVchHfmv2dQSTWpOzNlUVQwYzC1ay5bChRV/A9BTL68yj0Pa+TSg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.1.0.tgz", + "integrity": "sha512-Q02xem1D0sg4v437xHgmBLxI2iz/fc0D4K7fiVWHa/AnW8o7D751xyKNXgziA6HrTOme9ul1JfWN5ark8WH1xA==", "dev": true, "dependencies": { "debug": "^4.1.1", - "fs-extra": "^9.0.1" + "fs-extra": "^9.0.1", + "promise-retry": "^2.0.1" }, "engines": { "node": ">= 10.0.0" @@ -633,18 +650,18 @@ } }, "node_modules/@electron/notarize/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "engines": { "node": ">= 10.0.0" } }, "node_modules/@electron/osx-sign": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.0.4.tgz", - "integrity": "sha512-xfhdEcIOfAZg7scZ9RQPya1G1lWo8/zMCwUXAulq0SfY7ONIW+b9qGyKdMyuMctNYwllrIS+vmxfijSfjeh97g==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.0.5.tgz", + "integrity": "sha512-k9ZzUQtamSoweGQDV2jILiRIHUu7lYlJ3c6IEmjv1hC17rclE+eb9U+f6UFlOOETo0JzY1HNlXy4YOlCvl+Lww==", "dev": true, "dependencies": { "compare-version": "^0.1.2", @@ -701,122 +718,18 @@ } }, "node_modules/@electron/osx-sign/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@electron/rebuild": { - "version": "3.2.13", - "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.13.tgz", - "integrity": "sha512-DH9Ol4JCnHDYVOD0fKWq+Qqbn/0WU1O6QR0mIpMXEVU4YFM4PlaqNC9K36mGShNBxxGFotZCMDrB1wl/iHM12g==", - "dev": true, - "dependencies": { - "@malept/cross-spawn-promise": "^2.0.0", - "chalk": "^4.0.0", - "debug": "^4.1.1", - "detect-libc": "^2.0.1", - "fs-extra": "^10.0.0", - "got": "^11.7.0", - "node-abi": "^3.0.0", - "node-api-version": "^0.1.4", - "node-gyp": "^9.0.0", - "ora": "^5.1.0", - "semver": "^7.3.5", - "tar": "^6.0.5", - "yargs": "^17.0.1" - }, - "bin": { - "electron-rebuild": "lib/cli.js" - }, - "engines": { - "node": ">=12.13.0" - } - }, - "node_modules/@electron/rebuild/node_modules/detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@electron/rebuild/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@electron/rebuild/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@electron/rebuild/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/rebuild/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/rebuild/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "engines": { "node": ">= 10.0.0" } }, - "node_modules/@electron/rebuild/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@electron/universal": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.3.4.tgz", - "integrity": "sha512-BdhBgm2ZBnYyYRLRgOjM5VHkyFItsbggJ0MHycOjKWdFGYwK97ZFXH54dTvUWEfha81vfvwr5On6XBjt99uDcg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.4.1.tgz", + "integrity": "sha512-lE/U3UNw1YHuowNbTmKNs9UlS3En3cPgwM5MI+agIgr/B1hSze9NdOP0qn7boZaI9Lph8IDv3/24g9IxnJP7aQ==", "dev": true, "dependencies": { "@electron/asar": "^3.2.1", @@ -831,28 +744,6 @@ "node": ">=8.6" } }, - "node_modules/@electron/universal/node_modules/@malept/cross-spawn-promise": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" - } - ], - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/@electron/universal/node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -881,9 +772,9 @@ } }, "node_modules/@electron/universal/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "engines": { "node": ">= 10.0.0" @@ -1318,9 +1209,9 @@ ] }, "node_modules/@malept/cross-spawn-promise": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz", - "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", + "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", "dev": true, "funding": [ { @@ -1336,7 +1227,7 @@ "cross-spawn": "^7.0.1" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 10" } }, "node_modules/@malept/flatpak-bundler": { @@ -1382,9 +1273,9 @@ } }, "node_modules/@malept/flatpak-bundler/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "engines": { "node": ">= 10.0.0" @@ -1447,51 +1338,6 @@ "node": ">= 8" } }, - "node_modules/@npmcli/fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz", - "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/fs/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@npmcli/fs/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@npmcli/fs/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@parcel/bundler-default": { "version": "2.8.3", "dev": true, @@ -2826,9 +2672,9 @@ } }, "node_modules/@types/debug": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz", - "integrity": "sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", "dev": true, "dependencies": { "@types/ms": "*" @@ -2863,16 +2709,19 @@ "dev": true }, "node_modules/@types/ms": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", "dev": true }, "node_modules/@types/node": { - "version": "18.16.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.3.tgz", - "integrity": "sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==", - "dev": true + "version": "20.11.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz", + "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -2885,9 +2734,9 @@ "license": "MIT" }, "node_modules/@types/plist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz", - "integrity": "sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.5.tgz", + "integrity": "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==", "dev": true, "optional": true, "dependencies": { @@ -2928,9 +2777,9 @@ "license": "MIT" }, "node_modules/@types/verror": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.6.tgz", - "integrity": "sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ==", + "version": "1.10.9", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.9.tgz", + "integrity": "sha512-MLx9Z+9lGzwEuW16ubGeNkpBDE84RpB/NyGgg6z2BTpWzKkGU451cAY3UkUzZEp72RHF585oJ3V8JVNqIplcAQ==", "dev": true, "optional": true }, @@ -2953,15 +2802,9 @@ } }, "node_modules/7zip-bin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz", - "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==", - "dev": true - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.2.0.tgz", + "integrity": "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==", "dev": true }, "node_modules/abortcontroller-polyfill": { @@ -3068,42 +2911,6 @@ "node": ">= 6.0.0" } }, - "node_modules/agentkeepalive": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz", - "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==", - "dev": true, - "dependencies": { - "debug": "^4.1.0", - "depd": "^2.0.0", - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/aggregate-error/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, - "engines": { - "node": ">=8" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -3173,27 +2980,25 @@ "dev": true }, "node_modules/app-builder-lib": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-24.4.0.tgz", - "integrity": "sha512-EcdqtWvg1LAApKCfyRBukcVkmsa94s2e1VKHjZLpvA9/D14QEt8rHhffYeaA+cH/pVeoNVn2ob735KnfJKEEow==", + "version": "24.12.0", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-24.12.0.tgz", + "integrity": "sha512-t/xinVrMbsEhwljLDoFOtGkiZlaxY1aceZbHERGAS02EkUHJp9lgs/+L8okXLlYCaDSqYdB05Yb8Co+krvguXA==", "dev": true, "dependencies": { "@develar/schema-utils": "~2.6.5", - "@electron/notarize": "^1.2.3", - "@electron/osx-sign": "^1.0.4", - "@electron/rebuild": "^3.2.13", - "@electron/universal": "1.3.4", + "@electron/notarize": "2.1.0", + "@electron/osx-sign": "1.0.5", + "@electron/universal": "1.4.1", "@malept/flatpak-bundler": "^0.4.0", "@types/fs-extra": "9.0.13", - "7zip-bin": "~5.1.1", "async-exit-hook": "^2.0.1", "bluebird-lst": "^1.0.9", - "builder-util": "24.4.0", - "builder-util-runtime": "9.2.1", + "builder-util": "24.9.4", + "builder-util-runtime": "9.2.3", "chromium-pickle-js": "^0.2.0", "debug": "^4.3.4", "ejs": "^3.1.8", - "electron-publish": "24.4.0", + "electron-publish": "24.9.4", "form-data": "^4.0.0", "fs-extra": "^10.1.0", "hosted-git-info": "^4.1.0", @@ -3272,9 +3077,9 @@ } }, "node_modules/app-builder-lib/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -3287,9 +3092,9 @@ } }, "node_modules/app-builder-lib/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "engines": { "node": ">= 10.0.0" @@ -3301,25 +3106,6 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true - }, - "node_modules/are-we-there-yet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", - "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", - "dev": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/argparse": { "version": "2.0.1", "dev": true, @@ -3408,9 +3194,9 @@ } }, "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", "dev": true }, "node_modules/async-exit-hook": { @@ -3622,16 +3408,16 @@ "license": "MIT" }, "node_modules/builder-util": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-24.4.0.tgz", - "integrity": "sha512-tONb/GIK1MKa1BcOPHE1naId3o5nj6gdka5kP7yUJh2DOfF+jMq3laiu+UOZH6A7ZtkMtnGNMYFKFTIv408n/A==", + "version": "24.9.4", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-24.9.4.tgz", + "integrity": "sha512-YNon3rYjPSm4XDDho9wD6jq7vLRJZUy9FR+yFZnHoWvvdVCnZakL4BctTlPABP41MvIH5yk2cTZ2YfkOhGistQ==", "dev": true, "dependencies": { "@types/debug": "^4.1.6", - "7zip-bin": "~5.1.1", + "7zip-bin": "~5.2.0", "app-builder-bin": "4.0.0", "bluebird-lst": "^1.0.9", - "builder-util-runtime": "9.2.1", + "builder-util-runtime": "9.2.3", "chalk": "^4.1.2", "cross-spawn": "^7.0.3", "debug": "^4.3.4", @@ -3646,9 +3432,9 @@ } }, "node_modules/builder-util-runtime": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.1.tgz", - "integrity": "sha512-2rLv/uQD2x+dJ0J3xtsmI12AlRyk7p45TEbE/6o/fbb633e/S3pPgm+ct+JHsoY7r39dKHnGEFk/AASRFdnXmA==", + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.3.tgz", + "integrity": "sha512-FGhkqXdFFZ5dNC4C+yuQB9ak311rpGAw+/ASz8ZdxwODCv1GGMWgLDeofRkdi0F3VCHQEWy/aXcJQozx2nOPiw==", "dev": true, "dependencies": { "debug": "^4.3.4", @@ -3685,124 +3471,46 @@ } }, "node_modules/builder-util/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "engines": { "node": ">= 10.0.0" } }, - "node_modules/cacache": { - "version": "17.1.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.3.tgz", - "integrity": "sha512-jAdjGxmPxZh0IipMdR7fK/4sDSrHMLUV0+GvVUsjwyGNKHsh79kW/otg+GkbXwl6Uzvy9wsvHOX4nUoWldeZMg==", + "node_modules/cacheable-lookup": { + "version": "5.0.4", "dev": true, - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, + "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=10.6.0" } }, - "node_modules/cacache/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "node_modules/cacheable-request": { + "version": "7.0.2", "dev": true, + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/cacache/node_modules/glob": { - "version": "10.3.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz", - "integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==", + "node_modules/call-bind": { + "version": "1.0.2", "dev": true, + "license": "MIT", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cacache/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, - "engines": { - "node": ">=12" - } - }, - "node_modules/cacache/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cacheable-lookup": { - "version": "5.0.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cacheable-request": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3856,20 +3564,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001449", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ], - "license": "CC-BY-4.0" - }, "node_modules/caseless": { "version": "0.12.0", "license": "Apache-2.0" @@ -3913,9 +3607,9 @@ "dev": true }, "node_modules/ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, "funding": [ { @@ -3931,39 +3625,6 @@ "version": "2.3.2", "license": "MIT" }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", - "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/cli-truncate": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", @@ -3983,8 +3644,9 @@ }, "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": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -4067,15 +3729,6 @@ "simple-swizzle": "^0.2.2" } }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, - "bin": { - "color-support": "bin.js" - } - }, "node_modules/colord": { "version": "2.9.3", "dev": true, @@ -4134,20 +3787,60 @@ } }, "node_modules/config-file-ts": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.4.tgz", - "integrity": "sha512-cKSW0BfrSaAUnxpgvpXPLaaW/umg4bqg4k3GO1JqlRfpx+d5W0GDXznCMkWotJQek5Mmz1MJVChQnz3IVaeMZQ==", + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.6.tgz", + "integrity": "sha512-6boGVaglwblBgJqGyxm4+xCmEGcWgnWHSWHY5jad58awQhB6gftq0G8HbzU39YqCIYHMLAiL1yjwiZ36m/CL8w==", "dev": true, "dependencies": { - "glob": "^7.1.6", - "typescript": "^4.0.2" + "glob": "^10.3.10", + "typescript": "^5.3.3" } }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "dev": true + "node_modules/config-file-ts/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/config-file-ts/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/config-file-ts/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/convert-source-map": { "version": "1.9.0", @@ -4384,27 +4077,6 @@ "node": ">=0.10.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, - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/defaults/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, - "engines": { - "node": ">=0.8" - } - }, "node_modules/defer-to-connect": { "version": "2.0.1", "dev": true, @@ -4437,21 +4109,6 @@ "node": ">=0.4.0" } }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "dev": true - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/detect-libc": { "version": "1.0.3", "dev": true, @@ -4491,14 +4148,14 @@ } }, "node_modules/dmg-builder": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.4.0.tgz", - "integrity": "sha512-p5z9Cx539GSBYb+b09Z+hMhuBTh/BrI71VRg4rgF6f2xtIRK/YlTGVS/O08k5OojoyhZcpS7JXxDVSmQoWgiiQ==", + "version": "24.12.0", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.12.0.tgz", + "integrity": "sha512-nS22OyHUIYcK40UnILOtqC5Qffd1SN1Ljqy/6e+QR2H1wM3iNBrKJoEbDRfEmYYaALKNFRkKPqSbZKRsGUBdPw==", "dev": true, "dependencies": { - "app-builder-lib": "24.4.0", - "builder-util": "24.4.0", - "builder-util-runtime": "9.2.1", + "app-builder-lib": "24.12.0", + "builder-util": "24.9.4", + "builder-util-runtime": "9.2.3", "fs-extra": "^10.1.0", "iconv-lite": "^0.6.2", "js-yaml": "^4.1.0" @@ -4534,9 +4191,9 @@ } }, "node_modules/dmg-builder/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "engines": { "node": ">= 10.0.0" @@ -4680,14 +4337,14 @@ } }, "node_modules/electron": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-25.5.0.tgz", - "integrity": "sha512-w1DNj1LuAk0Vaas1rQ0pAkTe2gZ5YG75J27mC2m88y0G6Do5b5YoFDaF84fOGQHeQ4j8tC5LngSgWhbwmqDlrw==", + "version": "29.1.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-29.1.0.tgz", + "integrity": "sha512-giJVIm0sWVp+8V1GXrKqKTb+h7no0P3ooYqEd34AD9wMJzGnAeL+usj+R0155/0pdvvP1mgydnA7lcaFA2M9lw==", "dev": true, "hasInstallScript": true, "dependencies": { "@electron/get": "^2.0.0", - "@types/node": "^18.11.18", + "@types/node": "^20.9.0", "extract-zip": "^2.0.1" }, "bin": { @@ -4698,21 +4355,21 @@ } }, "node_modules/electron-builder": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-24.4.0.tgz", - "integrity": "sha512-D5INxodxaUIJgEX6p/fqBd8wQNS8XRAToNIJ9SQC+taNS5D73ZsjLuXiRraFGCB0cVk9KeKhEkdEOH5AaVya4g==", + "version": "24.12.0", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-24.12.0.tgz", + "integrity": "sha512-dH4O9zkxFxFbBVFobIR5FA71yJ1TZSCvjZ2maCskpg7CWjBF+SNRSQAThlDyUfRuB+jBTMwEMzwARywmap0CSw==", "dev": true, "dependencies": { - "app-builder-lib": "24.4.0", - "builder-util": "24.4.0", - "builder-util-runtime": "9.2.1", + "app-builder-lib": "24.12.0", + "builder-util": "24.9.4", + "builder-util-runtime": "9.2.3", "chalk": "^4.1.2", - "dmg-builder": "24.4.0", + "dmg-builder": "24.12.0", "fs-extra": "^10.1.0", "is-ci": "^3.0.0", "lazy-val": "^1.0.5", "read-config-file": "6.3.2", - "simple-update-notifier": "^1.1.0", + "simple-update-notifier": "2.0.0", "yargs": "^17.6.2" }, "bin": { @@ -4756,14 +4413,14 @@ } }, "node_modules/electron-publish": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.4.0.tgz", - "integrity": "sha512-U3mnVSxIfNrLW7ZnwiedFhcLf6ExPFXgAsx89WpfQFsV4gFAt/LG+H74p0m9NSvsLXiZuF82yXoxi7Ou8GHq4Q==", + "version": "24.9.4", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.9.4.tgz", + "integrity": "sha512-FghbeVMfxHneHjsG2xUSC0NMZYWOOWhBxfZKPTbibcJ0CjPH0Ph8yb5CUO62nqywXfA5u1Otq6K8eOdOixxmNg==", "dev": true, "dependencies": { "@types/fs-extra": "^9.0.11", - "builder-util": "24.4.0", - "builder-util-runtime": "9.2.1", + "builder-util": "24.9.4", + "builder-util-runtime": "9.2.3", "chalk": "^4.1.2", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", @@ -4797,9 +4454,9 @@ } }, "node_modules/electron-publish/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "engines": { "node": ">= 10.0.0" @@ -4818,6 +4475,7 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "optional": true, + "peer": true, "dependencies": { "iconv-lite": "^0.6.2" } @@ -5236,12 +4894,6 @@ "node": ">=6" } }, - "node_modules/exponential-backoff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", - "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", - "dev": true - }, "node_modules/extract-zip": { "version": "2.0.1", "dev": true, @@ -5518,17 +5170,35 @@ } }, "node_modules/fs-minipass": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.2.tgz", - "integrity": "sha512-2GAfyfoaCDRrM6jaOS3UsBts8yJ55VioXdWcOL7dK9zdAuKT71+WBA4ifnNYqVjYv+4SsPxjK0JT4yIIn4cA/g==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, "dependencies": { - "minipass": "^5.0.0" + "minipass": "^3.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, + "node_modules/fs-minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/fs-mkdirp-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", @@ -5576,31 +5246,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", - "dev": true, - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/gauge/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "license": "MIT", @@ -5610,8 +5255,9 @@ }, "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.*" } @@ -6024,12 +5670,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true - }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "license": "BSD-3-Clause", @@ -6211,15 +5851,6 @@ "node": ">= 6" } }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "dev": true, - "dependencies": { - "ms": "^2.0.0" - } - }, "node_modules/husky": { "version": "8.0.3", "dev": true, @@ -6484,12 +6115,6 @@ "loose-envify": "^1.0.0" } }, - "node_modules/ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", - "dev": true - }, "node_modules/is-array-buffer": { "version": "3.0.1", "dev": true, @@ -6606,26 +6231,11 @@ "node": ">=0.10.0" } }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-json": { "version": "2.0.1", "dev": true, "license": "ISC" }, - "node_modules/is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "dev": true - }, "node_modules/is-negated-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", @@ -6768,18 +6378,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-valid-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", @@ -6806,12 +6404,12 @@ "license": "MIT" }, "node_modules/isbinaryfile": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.0.tgz", - "integrity": "sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz", + "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==", "dev": true, "engines": { - "node": ">= 14.0.0" + "node": ">= 18.0.0" }, "funding": { "url": "https://github.com/sponsors/gjtorikian/" @@ -6830,9 +6428,9 @@ } }, "node_modules/jackspeak": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz", - "integrity": "sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -7240,22 +6838,6 @@ "dev": true, "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, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/loose-envify": { "version": "1.4.0", "license": "MIT", @@ -7281,41 +6863,6 @@ "yallist": "^3.0.2" } }, - "node_modules/make-fetch-happen": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", - "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", - "dev": true, - "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^17.0.0", - "http-cache-semantics": "^4.1.1", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/make-fetch-happen/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, - "engines": { - "node": ">=12" - } - }, "node_modules/map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", @@ -7470,15 +7017,6 @@ "node": ">= 0.6" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/mimic-response": { "version": "1.0.1", "dev": true, @@ -7537,143 +7075,6 @@ "node": ">=8" } }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-collect/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/minipass-fetch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.3.tgz", - "integrity": "sha512-n5ITsTkDqYkYJZjcRWzZt9qnZKCT7nKCosJhHoj7S7zD+BP4jVbWs+odsniw5TA3E0sLomhTKOKjF86wf11PuQ==", - "dev": true, - "dependencies": { - "minipass": "^5.0.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-flush/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-pipeline/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", @@ -7785,15 +7186,6 @@ "dev": true, "license": "MIT" }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/node-abi": { "version": "3.33.0", "dev": true, @@ -7815,57 +7207,11 @@ "engines": { "node": ">=10" } - }, - "node_modules/node-abi/node_modules/semver": { - "version": "7.3.8", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/node-addon-api": { - "version": "3.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/node-api-version": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz", - "integrity": "sha512-KGXihXdUChwJAOHO53bv9/vXcLmdUsZ6jIptbvYvkpKfth+r7jw44JkVxQFA3kX5nQjzjmGu1uAu/xNNLNlI5g==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - } - }, - "node_modules/node-api-version/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-api-version/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.3.8", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -7876,11 +7222,15 @@ "node": ">=10" } }, - "node_modules/node-api-version/node_modules/yallist": { + "node_modules/node-abi/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" + }, + "node_modules/node-addon-api": { + "version": "3.2.1", + "dev": true, + "license": "MIT" }, "node_modules/node-fetch": { "version": "2.6.12", @@ -7901,35 +7251,10 @@ } } }, - "node_modules/node-gyp": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz", - "integrity": "sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==", - "dev": true, - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^11.0.3", - "nopt": "^6.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^12.13 || ^14.13 || >=16" - } - }, "node_modules/node-gyp-build": { - "version": "4.6.0", - "dev": true, - "license": "MIT", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", + "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -7946,73 +7271,10 @@ "node-gyp-build-optional-packages-test": "build-test.js" } }, - "node_modules/node-gyp/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-gyp/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/node-gyp/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-gyp/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/node-releases": { "version": "2.0.8", "license": "MIT" }, - "node_modules/nopt": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", - "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", - "dev": true, - "dependencies": { - "abbrev": "^1.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -8093,21 +7355,6 @@ "node": ">= 10.13.0" } }, - "node_modules/npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", - "dev": true, - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/nth-check": { "version": "2.1.1", "dev": true, @@ -8229,21 +7476,6 @@ "wrappy": "1" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -8261,29 +7493,6 @@ "node": ">= 0.8.0" } }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ordered-binary": { "version": "1.4.0", "dev": true, @@ -8327,21 +7536,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/parcel": { "version": "2.8.3", "dev": true, @@ -9136,8 +8330,9 @@ }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9200,25 +8395,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, "node_modules/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", @@ -9383,9 +8559,9 @@ } }, "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==", "dev": true }, "node_modules/scheduler": { @@ -9436,12 +8612,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, "node_modules/shallow-clone": { "version": "3.0.1", "dev": true, @@ -9616,24 +8786,50 @@ "license": "MIT" }, "node_modules/simple-update-notifier": { - "version": "1.1.0", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-update-notifier/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "license": "MIT", "dependencies": { - "semver": "~7.0.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">=8.10.0" + "node": ">=10" } }, "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.0.0", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, - "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, + "node_modules/simple-update-notifier/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/slash": { "version": "3.0.0", "dev": true, @@ -9662,39 +8858,12 @@ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, + "optional": true, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" } }, - "node_modules/socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", - "dev": true, - "dependencies": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", - "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", - "dev": true, - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/sortobject": { "version": "4.16.0", "dev": true, @@ -9780,18 +8949,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ssri": { - "version": "10.0.4", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.4.tgz", - "integrity": "sha512-12+IR2CB2C28MMAw0Ncqwj5QbTcs0nGIhgJzYWzDkb21vWmfNI83KS4f3Ci6GI98WreIfG7o9UXp3C0qbpA8nQ==", - "dev": true, - "dependencies": { - "minipass": "^5.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/stable": { "version": "0.1.8", "dev": true, @@ -10236,9 +9393,9 @@ } }, "node_modules/tar": { - "version": "6.1.15", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", - "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", "dev": true, "dependencies": { "chownr": "^2.0.0", @@ -10283,30 +9440,6 @@ "node": ">=6" } }, - "node_modules/tar/node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/tar/node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -10371,9 +9504,9 @@ } }, "node_modules/temp-file/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "engines": { "node": ">= 10.0.0" @@ -10442,15 +9575,12 @@ "license": "MIT" }, "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, "engines": { - "node": ">=8.17.0" + "node": ">=14.14" } }, "node_modules/tmp-promise": { @@ -10462,21 +9592,6 @@ "tmp": "^0.2.0" } }, - "node_modules/tmp/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/to-fast-properties": { "version": "2.0.0", "license": "MIT", @@ -10589,16 +9704,16 @@ "license": "MIT" }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/unbox-primitive": { @@ -10615,29 +9730,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/unique-filename": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", - "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", - "dev": true, - "dependencies": { - "unique-slug": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/unique-slug": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", - "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true }, "node_modules/universalify": { "version": "0.1.2", @@ -10881,15 +9978,6 @@ "node": ">=0.10.0" } }, - "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, - "dependencies": { - "defaults": "^1.0.3" - } - }, "node_modules/weak-lru-cache": { "version": "1.2.2", "dev": true, @@ -10954,19 +10042,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, "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", @@ -11038,8 +10118,9 @@ }, "node_modules/y18n": { "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } @@ -11056,9 +10137,10 @@ } }, "node_modules/yargs": { - "version": "17.6.2", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, - "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -11074,8 +10156,9 @@ }, "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==", "dev": true, - "license": "ISC", "engines": { "node": ">=12" } @@ -11102,4 +10185,4 @@ } } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index ac8a140..d6e797e 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,8 @@ "@parcel/config-default": "^2.8.3", "@parcel/transformer-svg-react": "^2.8.3", "buffer": "^5.5.0", - "electron": "^25.5.0", - "electron-builder": "^24.4.0", + "electron": "^29.1.0", + "electron-builder": "^24.12.0", "eslint": "8.45.0", "eslint-plugin-react": "7.33.0", "husky": "^8.0.3", @@ -46,11 +46,12 @@ "parcel-reporter-static-files-copy": "^1.5.0", "process": "^0.11.10", "sharp": "^0.31.3", + "stylelint": "^15.10.2", "stylelint-config-standard": "^34.0.0", - "stylelint-order": "^6.0.3", - "stylelint": "^15.10.2" + "stylelint-order": "^6.0.3" }, "dependencies": { + "@dimensional/napi-canon-cameras": "file:../../node_packages/@dimensional/napi-canon-cameras.tgz", "animated-scroll-to": "^2.3.0", "compare-versions": "^6.0.0", "env-paths": "^2.2.1", diff --git a/src/electron/actions.js b/src/electron/actions.js index ca33164..8aa420d 100644 --- a/src/electron/actions.js +++ b/src/electron/actions.js @@ -13,11 +13,12 @@ import { exportProjectScene, getSyncList, normalizePictures, saveSyncList } from import { getProfile } from './core/ffmpeg'; import { uploadFile } from './core/api'; import { existsSync } from 'fs'; +import { getCamera, getCameras } from './cameras'; const OLD_PROJECTS_PATH = join(homedir(), DIRECTORY_NAME); const PROJECTS_PATH = existsSync(OLD_PROJECTS_PATH) ? OLD_PROJECTS_PATH : envPaths(DIRECTORY_NAME, { suffix: '' }).data; -console.log(PROJECTS_PATH) +console.log(`💾 Eagle Animation files will be saved in the following folder: ${PROJECTS_PATH}`); const getDefaultPreview = (data) => { for (let i = 0; i < (data?.project?.scenes?.length || 0); i++) { @@ -110,6 +111,28 @@ const actions = { const data = await takePicture(join(PROJECTS_PATH, project_id), track_id, 'jpg', before_frame_id, buffer); return computeProject(data); }, + LIST_NATIVE_CAMERAS: () => { + return getCameras(); + }, + TAKE_PICTURE_NATIVE_CAMERA: async (evt, { camera_id }) => { + const camera = await getCamera(camera_id); + if (camera) { + return camera.takePicture(); + } + return null; + }, + CONNECT_NATIVE_CAMERA: async (evt, { camera_id }) => { + const camera = await getCamera(camera_id); + if (camera) { + camera.connect(); + } + }, + DISCONNECT_NATIVE_CAMERA: async (evt, { camera_id }) => { + const camera = await getCamera(camera_id); + if (camera) { + camera.disconnect(); + } + }, GET_SETTINGS: async () => { return getSettings(PROJECTS_PATH); }, @@ -118,23 +141,20 @@ const actions = { }, SYNC: async () => { let syncList = await getSyncList(PROJECTS_PATH); - - console.log('[SYNC]', 'Starting event videos sync', syncList); - for (let i = 0; i < syncList.length; i++) { const syncElement = syncList[i]; try { if (!syncElement.isUploaded) { + console.log(`☁️ Sync start ${syncElement.publicCode} (${syncElement.apiKey})`); await uploadFile(syncElement.apiKey, syncElement.publicCode, syncElement.fileExtension, join(PROJECTS_PATH, '/.sync/', syncElement.fileName)); syncList[i].isUploaded = true; await saveSyncList(PROJECTS_PATH, syncList); + console.log(`✅ Sync finished ${syncElement.publicCode} (${syncElement.apiKey})`); } } catch (err) { - console.error(err); + console.log(`❌ Sync failed ${syncElement.publicCode} (${syncElement.apiKey})`, err); } } - - console.log('[SYNC]', 'End of sync', syncList); }, EXPORT: async (evt, { project_id, diff --git a/src/electron/cameras/canon.js b/src/electron/cameras/canon.js new file mode 100644 index 0000000..cffac21 --- /dev/null +++ b/src/electron/cameras/canon.js @@ -0,0 +1,84 @@ +import { + Camera as InternalCamera, CameraBrowser as InternalCameraBrowser, CameraProperty, ImageQuality, Option, watchCameras +} from '@dimensional/napi-canon-cameras'; + +// Allow event listing +watchCameras(); + +const cameraBrowser = new InternalCameraBrowser(); + +const MODULE_ID = 'EDSDK'; + +class CanonCameraBrowser { + static async getCameras() { + try { + const data = await cameraBrowser.getCameras(); + return [...data].map(camera => ({ + module: MODULE_ID, + label: camera.description, + deviceId: camera.portName, + })); + } catch (err) { + console.error(err); + } + return []; + } +} + +class CanonCamera { + constructor(deviceId, context = {}) { + this.deviceId = deviceId; + this.context = context; + + // NAPI Canon camera + this.canonCamera = new InternalCamera(this.deviceId); + + // Last captured frame + this.lastFrame = null; + } + + async connect() { + this.canonCamera.connect(true); + this.canonCamera.setProperties( + { + [CameraProperty.ID.SaveTo]: Option.SaveTo.Host, + //[CameraProperty.ID.SaveTo]: Option.SaveTo.Camera, + [CameraProperty.ID.ImageQuality]: ImageQuality.ID.LargeJPEGFine, + [CameraProperty.ID.WhiteBalance]: Option.WhiteBalance.Fluorescent + } + ); + this.canonCamera.setEventHandler((eventName, event) => { + if (event.file && [Camera.EventName.FileCreate, Camera.EventName.DownloadRequest].includes(eventName)) { + this.lastFrame = `${event.file.downloadToString()}`; + } + }); + } + + async disconnect() { + this.canonCamera.disconnect(); + } + + takePicture() { + return new Promise((resolve, reject) => { + const clock = setInterval(() => { + if (this.lastFrame !== null) { + clearInterval(clock); + resolve(Buffer.from(this.lastFrame, 'base64')); + this.lastFrame = null; + } + }, 100) + + try { + this.canonCamera.takePicture(); + + } catch (err) { + clearInterval(clock); + this.lastFrame = null; + reject(err); + } + }); + } +} + +export const Camera = CanonCamera; +export const CameraBrowser = CanonCameraBrowser; diff --git a/src/electron/cameras/index.js b/src/electron/cameras/index.js new file mode 100644 index 0000000..a3508ca --- /dev/null +++ b/src/electron/cameras/index.js @@ -0,0 +1,47 @@ +import { Camera as CanonCamera, CameraBrowser as CanonCameraBrowser } from './canon'; + +const Cameras = [ + { browser: CanonCameraBrowser, item: CanonCamera }, +]; + +let cachedCameras = {}; + +export const getCameras = async () => { + const availableCameras = []; + + for (const camType of Cameras) { + const cameras = await camType?.browser?.getCameras() || []; + for (const camera of cameras) { + availableCameras.push({ + ...camera, + type: 'NATIVE', + id: `NATIVE-${camera.module}-${camera.deviceId}`, + }) + } + } + + return availableCameras; +} + +export const getCamera = async (id) => { + if (cachedCameras[id]) { + return cachedCameras[id]; + } + + for (const camType of Cameras) { + const cameras = await camType?.browser?.getCameras() || []; + for (const camera of cameras) { + if (id === `NATIVE-${camera.module}-${camera.deviceId}`) { + const CameraClass = camType?.item; + cachedCameras[id] = new CameraClass(camera.deviceId, { + ...camera, + type: 'NATIVE', + id: `NATIVE-${camera.module}-${camera.deviceId}`, + }); + return cachedCameras[id]; + } + } + } + + return null; +} \ No newline at end of file diff --git a/src/electron/index.js b/src/electron/index.js index 1810e9c..78c407a 100644 --- a/src/electron/index.js +++ b/src/electron/index.js @@ -62,7 +62,7 @@ app.on('window-all-closed', () => { app.whenReady().then(() => { Object.keys(actions).forEach((name) => { ipcMain.handle(name, (evt, args) => { - console.log('[IPC]', name, args || {}); + console.log('📣 IPC', name, args || {}); return actions[name](evt, args); }) }) diff --git a/src/renderer/cameras/NativeProxy.js b/src/renderer/cameras/NativeProxy.js new file mode 100644 index 0000000..037a703 --- /dev/null +++ b/src/renderer/cameras/NativeProxy.js @@ -0,0 +1,86 @@ +class NativeProxy { + constructor(deviceId = null, context = {}) { + this.context = context; + this.deviceId = deviceId, + + console.log(deviceId, context) + + /*this.stream = false; + this.deviceId = deviceId; + + this.video = false; + this.width = false; + this.height = false; + + this.capabilitiesState = {}; + this.previousCapabilitiesState = {}; + this.capabilities = null;*/ + + } + + get id() { + return this?.context?.id || null; + } + + initPreview() { + return new Promise(async (resolve) => { // eslint-disable-line no-async-promise-executor + resolve(true); + }); + } + + resetCapabilities() { + + } + + applyCapability(key, value) { // eslint-disable-line no-unused-vars + + } + + getCapabilities() { + return []; + } + + async connect(video = false, settings = {}) { + this.video = video; + this.settings = settings; + await window.EA('CONNECT_NATIVE_CAMERA', { camera_id: this.context.id }); + return this.initPreview(); + } + + isInitialized() { + return true; + //return this.width !== false; + } + + getPreviewWidth() { + return this.width; + } + + getPreviewHeight() { + return this.height; + } + + async takePicture() { + const data = await window.EA('TAKE_PICTURE_NATIVE_CAMERA', { camera_id: this.context.id }); + return data; + } + + async disconnect() { + await window.EA('DISCONNECT_NATIVE_CAMERA', { camera_id: this.context.id }); + } +} + +class NativeProxyBrowser { + static async getCameras() { + try { + const cameras = await window.EA('LIST_NATIVE_CAMERAS'); + return cameras; + } catch (err) { + console.error(err); + } + return []; + } +} + +export const Camera = NativeProxy; +export const CameraBrowser = NativeProxyBrowser; diff --git a/src/renderer/core/Webcam.js b/src/renderer/cameras/Webcam.js similarity index 72% rename from src/renderer/core/Webcam.js rename to src/renderer/cameras/Webcam.js index 1251643..2fe75b0 100644 --- a/src/renderer/core/Webcam.js +++ b/src/renderer/cameras/Webcam.js @@ -79,6 +79,10 @@ class Webcam { this.previousCapabilitiesState = { ...this.capabilitiesState }; }, 100); } + + get id() { + return this?.context?.id || null; + } initPreview() { return new Promise(async (resolve) => { // eslint-disable-line no-async-promise-executor @@ -149,7 +153,7 @@ class Webcam { })) } - init(video = false, settings = {}) { + connect(video = false, settings = {}) { this.video = video; this.settings = settings; return this.initPreview(); @@ -167,56 +171,7 @@ class Webcam { return this.height; } - getPictureWidth() { - return this.width; - } - - getPictureHeight() { - return this.height; - } - - mergePictures(picturesCanvas = []) { - const width = this.getPictureWidth(); - const height = this.getPictureHeight(); - const imageData = picturesCanvas.map(canvas => canvas.getContext('2d', { alpha: false }).getImageData(0, 0, width, height).data) - const nbImageData = imageData.length; - const dataArray = new Uint8ClampedArray(width * height * 4); - - for (let x = 0; x < width; x++) { - for (let y = 0; y < height; y++) { - const redIdx = y * (width * 4) + x * 4; - const greenIdx = y * (width * 4) + x * 4 + 1; - const blueIdx = y * (width * 4) + x * 4 + 2; - const alphaIdx = y * (width * 4) + x * 4 + 3; - - let redValue = 0; - let greenValue = 0; - let blueValue = 0; - - for (let i = 0; i < nbImageData; i++) { - redValue += imageData[i][redIdx]; - greenValue += imageData[i][greenIdx]; - blueValue += imageData[i][blueIdx]; - } - dataArray[redIdx] = ~~(redValue / nbImageData); - dataArray[greenIdx] = ~~(greenValue / nbImageData); - dataArray[blueIdx] = ~~(blueValue / nbImageData); - dataArray[alphaIdx] = 255; - } - } - - const imgValues = new ImageData(dataArray, width, height) - - const canvas = document.createElement('canvas'); - canvas.width = width; - canvas.height = height; - const ctx = canvas.getContext('2d', { alpha: false }); - ctx.putImageData(imgValues, 0, 0, 0, 0, width, height); - - return canvas; - } - - async takePictureToCanvas() { + async takePicture() { if (!this.stream) { console.error('[Camera]', 'Not correctly initialized!') return; @@ -239,22 +194,7 @@ class Webcam { return canvas; } - async takePicture(nbFramesToTake = 1) { - const canvasList = []; - - for (let i = 0; i < nbFramesToTake || i < 1; i++) { - const data = await this.takePictureToCanvas(); - if (data) { - canvasList.push(data); - } - } - - const finalCanvas = (canvasList.length > 1) ? await this.mergePictures(canvasList) : canvasList?.[0]; - const data = finalCanvas.toDataURL('image/jpeg'); - return Buffer.from(data.replace(/^data:image\/\w+;base64,/, ''), 'base64'); - } - - async stop() { + async disconnect() { if (this.stream) { this.stream.getTracks().forEach(track => { track.stop(); @@ -264,4 +204,23 @@ class Webcam { } } -export default Webcam; +class WebcamBrowser { + static async getCameras() { + try { + const streams = await navigator.mediaDevices.enumerateDevices() + return streams.filter(stream => stream.kind === 'videoinput').map((stream) => ({ + deviceId: stream.deviceId, + type: 'WEB', + module: 'WEBCAM', + label: stream.label, + })); + + } catch (err) { + console.error(err); + } + return []; + } +} + +export const Camera = Webcam; +export const CameraBrowser = WebcamBrowser; \ No newline at end of file diff --git a/src/renderer/cameras/index.js b/src/renderer/cameras/index.js new file mode 100644 index 0000000..46a4f68 --- /dev/null +++ b/src/renderer/cameras/index.js @@ -0,0 +1,143 @@ +import { Camera as WebcamCamera, CameraBrowser as WebcamCameraBrowser } from './Webcam'; +import { Camera as NativeProxyCamera, CameraBrowser as NativeProxyBrowser } from './NativeProxy'; + +const Cameras = [ + { browser: WebcamCameraBrowser, item: WebcamCamera }, + { browser: NativeProxyBrowser, item: NativeProxyCamera }, +]; + +let cachedCameras = {}; +let cachedAvailableCameras = []; + +export const getCameras = async () => { + const availableCameras = []; + + for (const camType of Cameras) { + const cameras = await camType?.browser?.getCameras() || []; + for (const camera of cameras) { + availableCameras.push({ + ...camera, + id: `${camera.type}-${camera.module}-${camera.deviceId}`, + entityClass: camType?.item || null, + }); + } + } + + cachedAvailableCameras = availableCameras; + return availableCameras; +} + +export const getCamera = (id) => { + if (cachedCameras[id]) { + return cachedCameras[id]; + } + + const cameras = cachedAvailableCameras || []; + + for (const camera of cameras) { + if (id === camera.id) { + const CameraClass = camera?.entityClass; + cachedCameras[id] = new CameraClass(camera.deviceId, camera); + return cachedCameras[id]; + } + } + + return null; +} + +const convertBufferToCanvas = (buffer, type = 'image/jpeg') => new Promise((resolve, reject) => { + const blob = new Blob([buffer], { type }); + const url = URL.createObjectURL(blob); + const imgObj = new Image; + + imgObj.onerror = reject; + imgObj.onload = function () { + const tmpCanvas = document.createElement('canvas'); + tmpCanvas.height = this.naturalHeight; + tmpCanvas.width = this.naturalWidth; + const ctx = tmpCanvas.getContext('2d', { alpha: false }); + ctx.drawImage(imgObj, 0, 0, this.naturalWidth, this.naturalHeight); + resolve(tmpCanvas); + } + imgObj.src = url; +}); + +// "pictures" can be Canvas or Buffer +const mergePictures = async (pictures = []) => { + const imageData = []; + + // Convert each picture to ImageData + for (const pictData of pictures) { + let canvas = pictData; + + if (!(pictData instanceof HTMLCanvasElement)) { + canvas = await convertBufferToCanvas(pictData); + } + + imageData.push({ + width: canvas.width, + height: canvas.height, + data: canvas.getContext('2d', { alpha: false }).getImageData(0, 0, canvas.width, canvas.height).data + }); + } + + // Control if all images have the same size + if ((new Set(imageData.map(e => e.width))).length > 1 || (new Set(imageData.map(e => e.height))).length > 1) { + throw new Error('MERGE_SIZE_INCONSISTENCIES'); + } + + // Define final width and height + const width = imageData[0].width; + const height = imageData[0].height; + + const nbImageData = imageData.length; + const dataArray = new Uint8ClampedArray(width * height * 4); + + for (let x = 0; x < width; x++) { + for (let y = 0; y < height; y++) { + const redIdx = y * (width * 4) + x * 4; + const greenIdx = y * (width * 4) + x * 4 + 1; + const blueIdx = y * (width * 4) + x * 4 + 2; + const alphaIdx = y * (width * 4) + x * 4 + 3; + + let redValue = 0; + let greenValue = 0; + let blueValue = 0; + + for (let i = 0; i < nbImageData; i++) { + redValue += imageData[i].data[redIdx]; + greenValue += imageData[i].data[greenIdx]; + blueValue += imageData[i].data[blueIdx]; + } + dataArray[redIdx] = ~~(redValue / nbImageData); + dataArray[greenIdx] = ~~(greenValue / nbImageData); + dataArray[blueIdx] = ~~(blueValue / nbImageData); + dataArray[alphaIdx] = 255; + } + } + + const imgValues = new ImageData(dataArray, width, height) + + const canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + const ctx = canvas.getContext('2d', { alpha: false }); + ctx.putImageData(imgValues, 0, 0, 0, 0, width, height); + + return canvas; +} + +export const takePicture = async (camera, nbFramesToTake = 1) => { + const bufferList = []; + + for (let i = 0; i < nbFramesToTake || i < 1; i++) { + const data = await camera.takePicture(); + if (data) { + bufferList.push(data); + } + } + + const finalCanvas = (bufferList.length > 1) ? await mergePictures(bufferList) : bufferList?.[0]; + const data = finalCanvas.toDataURL('image/jpeg'); + return Buffer.from(data.replace(/^data:image\/\w+;base64,/, ''), 'base64'); +} \ No newline at end of file diff --git a/src/renderer/core/Devices.js b/src/renderer/core/Devices.js index 68a4a0c..3a8bdee 100644 --- a/src/renderer/core/Devices.js +++ b/src/renderer/core/Devices.js @@ -1,4 +1,4 @@ -import Webcam from './Webcam'; +import { getCamera, getCameras } from '../cameras'; class Devices { constructor() { @@ -7,14 +7,11 @@ class Devices { } async list() { - const streams = await navigator.mediaDevices.enumerateDevices() - return streams.filter(stream => stream.kind === 'videoinput').map((stream, i) => ({ - id: `webcamera-${stream.deviceId}`, - label: `[${i}] ${stream.label}`, - })); + const cameras = await getCameras(); + return cameras.map((e,i) => ({...e, label: `[${i}] ${e.label || ''}`})); } - async init() { + async connect() { const list = await this.list(); if (!this.currentId || !list.some(camera => camera.id === this.currentId)) { this.currentId = list?.[0]?.id || null @@ -28,18 +25,18 @@ class Devices { this.currentId = id; if (this.currentCamera) { - this.currentCamera.stop(); + this.currentCamera.disconnect(); } this.currentCamera = null; } - async stop() { + async disconnect() { if (!this.currentId) { return; } if (this.currentCamera) { - this.currentCamera.stop(); + this.currentCamera.disconnect(); } this.currentCamera = null; @@ -50,8 +47,8 @@ class Devices { return this.currentCamera; } - if (this.currentId && this.currentId.startsWith('webcamera-')) { - this.currentCamera = new Webcam(this.currentId.replace('webcamera-', '')); + if (this.currentId) { + return getCamera(this.currentId); } return this.currentCamera || null; diff --git a/src/renderer/index.js b/src/renderer/index.js index 7467210..d7d734c 100644 --- a/src/renderer/index.js +++ b/src/renderer/index.js @@ -7,7 +7,7 @@ import { BUILD } from './config'; console.log('Build', BUILD); window.EA = (action, data) => { - console.log('[IPC]', action, data); + console.log('📣 IPC', action, data); return window.IPC.call(action, data); } diff --git a/src/renderer/views/Animator.jsx b/src/renderer/views/Animator.jsx index 78ffd03..1720c69 100644 --- a/src/renderer/views/Animator.jsx +++ b/src/renderer/views/Animator.jsx @@ -11,6 +11,7 @@ import Timeline from "../components/Timeline"; import soundDelete from 'url:~/static/sounds/delete.mp3'; import soundShutter from 'url:~/static/sounds/shutter.mp3'; import DevicesInstance from "../core/Devices"; +import { takePicture } from "../cameras"; const Camera = () => DevicesInstance.getMainCamera(); @@ -142,8 +143,10 @@ const Animator = ({ t }) => { if (!isMuted && settings.SOUNDS) { shutterSoundRef?.current?.play(); } - const buffer = await Camera().takePicture((settings.AVERAGING_ENABLED ? parseInt(settings.AVERAGING_VALUE, 10) : 1) || 1); - setProject(await window.EA('TAKE_PICTURE', { project_id: id, track_id: track, buffer, before_frame_id: currentFrameId })); + + const nbFramesToTake = (settings.AVERAGING_ENABLED ? parseInt(settings.AVERAGING_VALUE, 10) : 1) || 1; + const buffer = await takePicture(Camera(), nbFramesToTake); + setProject(await window.EA('TAKE_PICTURE', { project_id: id, track_id: track, buffer, before_frame_id: currentFrameId })); } flushSync(() => { setIsTakingPicture(false); }); @@ -216,7 +219,7 @@ const Animator = ({ t }) => { return; } - Camera().init(dom, { forceMaxQuality: !!settings.FORCE_QUALITY }).catch(() => { + Camera().connect(dom, { forceMaxQuality: !!settings.FORCE_QUALITY }).catch(() => { setIsCameraReady(false); setCameraCapabilities(Camera().getCapabilities()); }).then(() => { diff --git a/src/renderer/views/Home.jsx b/src/renderer/views/Home.jsx index 431fb1a..0c0eb53 100644 --- a/src/renderer/views/Home.jsx +++ b/src/renderer/views/Home.jsx @@ -14,6 +14,13 @@ const HomeView = ({ t }) => { const [projects, setProjects] = useState([]); const navigate = useNavigate(); + useEffect(() => { + (async () => { + await DevicesInstance.disconnect(); + await DevicesInstance.list(); + })(); + }, []); + useEffect(() => { (async () => { setProjects(await window.EA('GET_PROJECTS')); @@ -24,7 +31,7 @@ const HomeView = ({ t }) => { if (userSettings.CAMERA_ID && !DevicesInstance.getMainCamera()) { DevicesInstance.setMainCamera(userSettings.CAMERA_ID); } - DevicesInstance.init(); + DevicesInstance.connect(); // Fetch updates setLatestVersion((await window.EA('GET_LAST_VERSION').catch(() => null))?.version || null); diff --git a/src/renderer/views/Settings.jsx b/src/renderer/views/Settings.jsx index 964be91..0906423 100644 --- a/src/renderer/views/Settings.jsx +++ b/src/renderer/views/Settings.jsx @@ -61,7 +61,7 @@ const SettingsView = ({ t }) => { useEffect(() => { (async () => { - await DevicesInstance.stop(); + await DevicesInstance.disconnect(); setDevices(await DevicesInstance.list()); const values = await window.EA('GET_SETTINGS'); applySettings(values) diff --git a/static/i18n/fr.json b/static/i18n/fr.json index 858c063..e186506 100644 --- a/static/i18n/fr.json +++ b/static/i18n/fr.json @@ -74,7 +74,7 @@ "Video resolution": "Résolution de la vidéo", "The exported video resolution": "La résolution de la vidéo exportée", "Custom video output framerate": "Personnaliser le taux de rafraîchissement de la vidéo de sortie", - "Change the exported video framerate (This is not your animation framerate)": "Changer le taux de rafraîchissement de la vidéo de sortie (Ce n'est pas le nomdre d'IPS de votre animation)", + "Change the exported video framerate (This is not your animation framerate)": "Changer le taux de rafraîchissement de la vidéo de sortie (Ce n'est pas le nombre d'IPS de votre animation)", "Duplicate first and last frames": "Dupliquer la première et la dernière image", "Automatically duplicate the first and last frames": "Dupliquer automatiquement la première et la dernière image", "Duplicate frames": "Dupliquer les images", From 5bd8a27c7a3dfaf25ff1fa076493348978418e22 Mon Sep 17 00:00:00 2001 From: Maxime Baconnais Date: Fri, 1 Mar 2024 18:33:26 +0100 Subject: [PATCH 02/17] Preview --- src/electron/actions.js | 4 +- src/electron/cameras/canon.js | 78 +++++++++++++++++++++++- src/electron/index.js | 4 +- src/electron/preload.js | 1 + src/renderer/cameras/NativeProxy.js | 39 +++++++++++- src/renderer/cameras/Webcam.js | 10 +-- src/renderer/components/Player/index.jsx | 7 ++- src/renderer/views/Animator.jsx | 4 +- 8 files changed, 132 insertions(+), 15 deletions(-) diff --git a/src/electron/actions.js b/src/electron/actions.js index 8aa420d..83ba086 100644 --- a/src/electron/actions.js +++ b/src/electron/actions.js @@ -121,10 +121,10 @@ const actions = { } return null; }, - CONNECT_NATIVE_CAMERA: async (evt, { camera_id }) => { + CONNECT_NATIVE_CAMERA: async (evt, { camera_id }, sendToRenderer) => { const camera = await getCamera(camera_id); if (camera) { - camera.connect(); + camera.connect((data) => { sendToRenderer('LIVE_VIEW_DATA', { camera_id, data }) }); } }, DISCONNECT_NATIVE_CAMERA: async (evt, { camera_id }) => { diff --git a/src/electron/cameras/canon.js b/src/electron/cameras/canon.js index cffac21..f0451d7 100644 --- a/src/electron/cameras/canon.js +++ b/src/electron/cameras/canon.js @@ -35,10 +35,20 @@ class CanonCamera { // Last captured frame this.lastFrame = null; + + // Live mode + //this.liveModeEnabled = false; + //this.liveModeClock = null; } - async connect() { + async connect(liveModeCallback = null) { + // Save live mode callback + this.liveModeCallback = liveModeCallback; + + // Create persistent connection this.canonCamera.connect(true); + + // Set properties this.canonCamera.setProperties( { [CameraProperty.ID.SaveTo]: Option.SaveTo.Host, @@ -47,14 +57,64 @@ class CanonCamera { [CameraProperty.ID.WhiteBalance]: Option.WhiteBalance.Fluorescent } ); + + // Catch events this.canonCamera.setEventHandler((eventName, event) => { if (event.file && [Camera.EventName.FileCreate, Camera.EventName.DownloadRequest].includes(eventName)) { this.lastFrame = `${event.file.downloadToString()}`; } }); + + // Init live mode + /*if (this.canonCamera.getProperty(CameraProperty.ID.Evf_Mode).available) { + const setLiveMode = () => { + if (this.liveModeEnabled) { + this.canonCamera.startLiveView(); + } else { + this.canonCamera.stopLiveView(); + } + } + setLiveMode(); + this.liveModeClock = setInterval(setLiveMode, 5000); + }*/ + + // Fetch live mode picture + if (this.canonCamera.getProperty(CameraProperty.ID.Evf_Mode).available) { + this.canonCamera.startLiveView(); + setInterval(() => { + try { + this.canonCamera.startLiveView(); + const image = this.canonCamera.getLiveViewImage(); + if (image) { + this.liveModeCallback(image.getDataURL()); + } + } catch (e) { } + }, 100); + } + +//---------------------------TEST + + + + + + + + +//------------------------- + + + + + + } async disconnect() { + if (this.canonCamera.getProperty(CameraProperty.ID.Evf_Mode).available) { + this.canonCamera.stopLiveView(); + } + this.canonCamera.disconnect(); } @@ -68,6 +128,14 @@ class CanonCamera { } }, 100) + try { + if (this.canonCamera.getProperty(CameraProperty.ID.Evf_Mode).available) { + this.canonCamera.stopLiveView(); + } + } catch (e1) { + + } + try { this.canonCamera.takePicture(); @@ -76,6 +144,14 @@ class CanonCamera { this.lastFrame = null; reject(err); } + + try { + if (this.canonCamera.getProperty(CameraProperty.ID.Evf_Mode).available) { + this.canonCamera.startLiveView(); + } + } catch (e1) { + + } }); } } diff --git a/src/electron/index.js b/src/electron/index.js index 78c407a..949c197 100644 --- a/src/electron/index.js +++ b/src/electron/index.js @@ -59,11 +59,13 @@ app.on('window-all-closed', () => { } }); +const sendToRenderer = (channel, value) => mainWindow.webContents.send(channel, value); + app.whenReady().then(() => { Object.keys(actions).forEach((name) => { ipcMain.handle(name, (evt, args) => { console.log('📣 IPC', name, args || {}); - return actions[name](evt, args); + return actions[name](evt, args, sendToRenderer); }) }) diff --git a/src/electron/preload.js b/src/electron/preload.js index 8a37f69..a5d83e4 100644 --- a/src/electron/preload.js +++ b/src/electron/preload.js @@ -2,4 +2,5 @@ const { contextBridge, ipcRenderer } = require('electron'); contextBridge.exposeInMainWorld('IPC', { call: (channel, data) => ipcRenderer.invoke(channel, data), + stream: (channel, callback) => ipcRenderer.on(channel, callback), }); diff --git a/src/renderer/cameras/NativeProxy.js b/src/renderer/cameras/NativeProxy.js index 037a703..70a2d8a 100644 --- a/src/renderer/cameras/NativeProxy.js +++ b/src/renderer/cameras/NativeProxy.js @@ -3,7 +3,7 @@ class NativeProxy { this.context = context; this.deviceId = deviceId, - console.log(deviceId, context) + console.log(deviceId, context) /*this.stream = false; this.deviceId = deviceId; @@ -22,9 +22,42 @@ class NativeProxy { return this?.context?.id || null; } + #drawLivePreview(dom, src) { + if (!dom || !src) { + return; + } + + const ctx = dom.getContext('2d'); + const img = new Image(); + img.addEventListener('error', () => { + ctx.clearRect(0, 0, dom.width, dom.height); + }); + img.addEventListener('load', function () { + dom.width = this.naturalWidth; + dom.height = this.naturalHeight; + ctx.drawImage( + img, + 0, + 0, + img.naturalWidth, + img.naturalHeight, + 0, + 0, + img.naturalWidth, + img.naturalHeight, + ); + }, false); + img.src = src; + } + initPreview() { return new Promise(async (resolve) => { // eslint-disable-line no-async-promise-executor resolve(true); + + // TODO: ADD EA Interface for that + window.IPC.stream('LIVE_VIEW_DATA', (evt, args) => { + this.#drawLivePreview(this.video, args.data); + }); }); } @@ -40,8 +73,8 @@ class NativeProxy { return []; } - async connect(video = false, settings = {}) { - this.video = video; + async connect({ imageDOM } = { imageDOM: false }, settings = {}) { + this.video = imageDOM; this.settings = settings; await window.EA('CONNECT_NATIVE_CAMERA', { camera_id: this.context.id }); return this.initPreview(); diff --git a/src/renderer/cameras/Webcam.js b/src/renderer/cameras/Webcam.js index 2fe75b0..2d42899 100644 --- a/src/renderer/cameras/Webcam.js +++ b/src/renderer/cameras/Webcam.js @@ -79,7 +79,7 @@ class Webcam { this.previousCapabilitiesState = { ...this.capabilitiesState }; }, 100); } - + get id() { return this?.context?.id || null; } @@ -101,7 +101,7 @@ class Webcam { window.DEVICE = this.stream; this.capabilities = this.stream?.getVideoTracks()?.[0] ? this.stream.getVideoTracks()[0].getCapabilities() : []; - this.capabilitiesState = {...defaultCapabilities}; + this.capabilitiesState = { ...defaultCapabilities }; // Launch preview if (this.video) { @@ -119,7 +119,7 @@ class Webcam { } resetCapabilities() { - this.capabilitiesState = {...defaultCapabilities}; + this.capabilitiesState = { ...defaultCapabilities }; return allowedCapabilities.filter(e => this.capabilities[e]).map(e => ({ id: e, type: ['exposureMode', 'focusMode', 'resizeMode', 'whiteBalanceMode'].includes(e) ? 'SWITCH' : 'RANGE', @@ -153,8 +153,8 @@ class Webcam { })) } - connect(video = false, settings = {}) { - this.video = video; + connect({ videoDOM } = {videoDOM : false}, settings = {}) { + this.video = videoDOM; this.settings = settings; return this.initPreview(); } diff --git a/src/renderer/components/Player/index.jsx b/src/renderer/components/Player/index.jsx index 21caddb..1df9118 100644 --- a/src/renderer/components/Player/index.jsx +++ b/src/renderer/components/Player/index.jsx @@ -23,6 +23,7 @@ class Player extends Component { this.dom = { container: React.createRef(), video: React.createRef(), + videoFrame: React.createRef(), picture: React.createRef(), grid: React.createRef() }; @@ -125,7 +126,7 @@ class Player extends Component { componentDidMount() { const { onInit } = this.props; - onInit(this.dom.video.current); + onInit(this.dom.video.current, this.dom.videoFrame.current); this.dom.picture.current.width = this.getSize().width; this.dom.picture.current.height = this.getSize().height; this.dom.picture.current.style.width = this.getSize().width; @@ -305,6 +306,10 @@ class Player extends Component { className={style.layout} style={{ opacity: frameIndex === false ? 1 : 0 }} /> + { }, } - const handlePlayerInit = (dom) => { + const handlePlayerInit = (videoDOM = null, imageDOM = null) => { if (!Camera()) { return; } - Camera().connect(dom, { forceMaxQuality: !!settings.FORCE_QUALITY }).catch(() => { + Camera().connect({videoDOM, imageDOM}, { forceMaxQuality: !!settings.FORCE_QUALITY }).catch(() => { setIsCameraReady(false); setCameraCapabilities(Camera().getCapabilities()); }).then(() => { From 547dc28d0e23ba01b19b673a2c5e74e87f59c43e Mon Sep 17 00:00:00 2001 From: Maxime Baconnais Date: Fri, 1 Mar 2024 21:26:43 +0100 Subject: [PATCH 03/17] Improve stability and bugfixes --- src/electron/cameras/canon.js | 114 +++++++++++++++------------------- src/renderer/cameras/index.js | 7 ++- 2 files changed, 55 insertions(+), 66 deletions(-) diff --git a/src/electron/cameras/canon.js b/src/electron/cameras/canon.js index f0451d7..8f51984 100644 --- a/src/electron/cameras/canon.js +++ b/src/electron/cameras/canon.js @@ -37,14 +37,21 @@ class CanonCamera { this.lastFrame = null; // Live mode - //this.liveModeEnabled = false; - //this.liveModeClock = null; + this.liveModeEnabled = false; + this.liveModeClock = null; + + // Catch events + this.canonCamera.setEventHandler((eventName, event) => { + if (event.file && [InternalCamera.EventName.FileCreate, InternalCamera.EventName.DownloadRequest].includes(eventName)) { + this.lastFrame = `${event.file.downloadToString()}`; + } + }); } async connect(liveModeCallback = null) { // Save live mode callback this.liveModeCallback = liveModeCallback; - + // Create persistent connection this.canonCamera.connect(true); @@ -54,87 +61,73 @@ class CanonCamera { [CameraProperty.ID.SaveTo]: Option.SaveTo.Host, //[CameraProperty.ID.SaveTo]: Option.SaveTo.Camera, [CameraProperty.ID.ImageQuality]: ImageQuality.ID.LargeJPEGFine, - [CameraProperty.ID.WhiteBalance]: Option.WhiteBalance.Fluorescent + [CameraProperty.ID.WhiteBalance]: Option.WhiteBalance.Fluorescent, + [CameraProperty.ID.AFMode]: Option.AFMode.ManualFocus, } ); - // Catch events - this.canonCamera.setEventHandler((eventName, event) => { - if (event.file && [Camera.EventName.FileCreate, Camera.EventName.DownloadRequest].includes(eventName)) { - this.lastFrame = `${event.file.downloadToString()}`; - } - }); - - // Init live mode - /*if (this.canonCamera.getProperty(CameraProperty.ID.Evf_Mode).available) { - const setLiveMode = () => { - if (this.liveModeEnabled) { - this.canonCamera.startLiveView(); - } else { - this.canonCamera.stopLiveView(); - } - } - setLiveMode(); - this.liveModeClock = setInterval(setLiveMode, 5000); - }*/ - // Fetch live mode picture + this.liveModeEnabled = true; + clearInterval(this.liveModeClock); if (this.canonCamera.getProperty(CameraProperty.ID.Evf_Mode).available) { this.canonCamera.startLiveView(); - setInterval(() => { - try { - this.canonCamera.startLiveView(); - const image = this.canonCamera.getLiveViewImage(); - if (image) { - this.liveModeCallback(image.getDataURL()); - } - } catch (e) { } + this.liveModeClock = setInterval(() => { + if (this.liveModeEnabled) { + try { + const image = this.canonCamera.getLiveViewImage(); + if (image) { + this.liveModeCallback(image.getDataURL()); + } + } catch (e) { } + } }, 100); } -//---------------------------TEST - - - - - - - - -//------------------------- - - - - - + //---------------------------TEST + + /* const settings = []; + for (const propertyID of Object.values(CameraProperty.ID)) { + const p = this.canonCamera.getProperty(propertyID); + if (!p.available) { + continue; + } + try { + const value = p.value; + settings.push(p); + } catch (e) { + console.error( + p, e + ); + } + } + console.log(JSON.parse(JSON.stringify(settings))); + + */ + //------------------------- } async disconnect() { + clearInterval(this.liveModeClock); if (this.canonCamera.getProperty(CameraProperty.ID.Evf_Mode).available) { this.canonCamera.stopLiveView(); + this.liveModeEnabled = false; } this.canonCamera.disconnect(); } takePicture() { + this.liveModeEnabled = false; return new Promise((resolve, reject) => { const clock = setInterval(() => { if (this.lastFrame !== null) { clearInterval(clock); resolve(Buffer.from(this.lastFrame, 'base64')); this.lastFrame = null; + this.liveModeEnabled = true; } - }, 100) - - try { - if (this.canonCamera.getProperty(CameraProperty.ID.Evf_Mode).available) { - this.canonCamera.stopLiveView(); - } - } catch (e1) { - - } + }, 100); try { this.canonCamera.takePicture(); @@ -142,16 +135,9 @@ class CanonCamera { } catch (err) { clearInterval(clock); this.lastFrame = null; + this.liveModeEnabled = true; reject(err); } - - try { - if (this.canonCamera.getProperty(CameraProperty.ID.Evf_Mode).available) { - this.canonCamera.startLiveView(); - } - } catch (e1) { - - } }); } } diff --git a/src/renderer/cameras/index.js b/src/renderer/cameras/index.js index 46a4f68..f6ace0a 100644 --- a/src/renderer/cameras/index.js +++ b/src/renderer/cameras/index.js @@ -138,6 +138,9 @@ export const takePicture = async (camera, nbFramesToTake = 1) => { } const finalCanvas = (bufferList.length > 1) ? await mergePictures(bufferList) : bufferList?.[0]; - const data = finalCanvas.toDataURL('image/jpeg'); - return Buffer.from(data.replace(/^data:image\/\w+;base64,/, ''), 'base64'); + if (finalCanvas instanceof HTMLCanvasElement) { + const data = finalCanvas.toDataURL('image/jpeg'); + return Buffer.from(data.replace(/^data:image\/\w+;base64,/, ''), 'base64'); + } + return finalCanvas; } \ No newline at end of file From 5f8d792cbe6aae26c23c851e05ed9bd36aafd9f5 Mon Sep 17 00:00:00 2001 From: Maxime Baconnais Date: Sat, 2 Mar 2024 00:53:50 +0100 Subject: [PATCH 04/17] Improvements --- TODO.md | 10 +- src/electron/actions.js | 23 ++++ src/electron/cameras/canon.js | 104 +++++++++++++----- src/renderer/cameras/NativeProxy.js | 17 +-- src/renderer/cameras/Webcam.js | 8 +- src/renderer/components/Button/index.jsx | 4 +- .../components/Button/style.module.css | 30 +++-- .../components/Container/vars.module.css | 2 +- src/renderer/components/ControlBar/index.jsx | 2 +- src/renderer/components/Player/index.jsx | 14 ++- .../components/Player/style.module.css | 13 +++ src/renderer/views/Animator.jsx | 14 +-- src/renderer/views/Settings.jsx | 11 +- static/i18n/en.json | 3 +- static/i18n/fr.json | 3 +- 15 files changed, 186 insertions(+), 72 deletions(-) diff --git a/TODO.md b/TODO.md index f84c84b..ee5ff21 100644 --- a/TODO.md +++ b/TODO.md @@ -9,7 +9,6 @@ - Add a light theme - Add the ability to mirror the camera image (X + Y) - Aspect ratio support and allow opacity configuration on settings page -- Ability to mark frame as "masked" to test an animation without some frames, can be usefull before a deletion - Multi scene/take support - Allow drawing for easing help - Allow to export/import a project @@ -17,3 +16,12 @@ - Support cameras - Webapp version - Mobile version (Based on capacitor) + + +--- + +- Nom du projet dans la barre en haut +- Parametre de projet +- opti thumbnail +- Ability to mark frame as "masked" to test an animation without some frames, can be usefull before a deletion +-le m ne synchro pas le mute dans les settings diff --git a/src/electron/actions.js b/src/electron/actions.js index 83ba086..40362e9 100644 --- a/src/electron/actions.js +++ b/src/electron/actions.js @@ -121,6 +121,29 @@ const actions = { } return null; }, + GET_CAPABILITIES_NATIVE_CAMERA: async (evt, { camera_id }) => { + const camera = await getCamera(camera_id); + if (camera) { + return camera.getCapabilities(); + } + return []; + }, + APPLY_CAPABILITY_NATIVE_CAMERA: async (evt, { camera_id, key, value }) => { + const camera = await getCamera(camera_id); + if (camera) { + camera.applyCapability(key, value); + return null; + } + return null; + }, + RESET_CAPABILITIES_NATIVE_CAMERA: async (evt, { camera_id }) => { + const camera = await getCamera(camera_id); + if (camera) { + camera.resetCapabilities(); + return camera.getCapabilities(); + } + return []; + }, CONNECT_NATIVE_CAMERA: async (evt, { camera_id }, sendToRenderer) => { const camera = await getCamera(camera_id); if (camera) { diff --git a/src/electron/cameras/canon.js b/src/electron/cameras/canon.js index 8f51984..ab4f5b8 100644 --- a/src/electron/cameras/canon.js +++ b/src/electron/cameras/canon.js @@ -1,5 +1,10 @@ import { - Camera as InternalCamera, CameraBrowser as InternalCameraBrowser, CameraProperty, ImageQuality, Option, watchCameras + Camera as InternalCamera, + CameraBrowser as InternalCameraBrowser, + CameraProperty, + ImageQuality, + Option, + watchCameras, } from '@dimensional/napi-canon-cameras'; // Allow event listing @@ -42,16 +47,19 @@ class CanonCamera { // Catch events this.canonCamera.setEventHandler((eventName, event) => { - if (event.file && [InternalCamera.EventName.FileCreate, InternalCamera.EventName.DownloadRequest].includes(eventName)) { - this.lastFrame = `${event.file.downloadToString()}`; - } - }); + if (event.file && [InternalCamera.EventName.FileCreate, InternalCamera.EventName.DownloadRequest].includes(eventName)) { + this.lastFrame = `${event.file.downloadToString()}`; + } + }); + + // Camera capabilities + this.capabilities = []; } async connect(liveModeCallback = null) { // Save live mode callback this.liveModeCallback = liveModeCallback; - + // Create persistent connection this.canonCamera.connect(true); @@ -78,33 +86,23 @@ class CanonCamera { if (image) { this.liveModeCallback(image.getDataURL()); } - } catch (e) { } + } catch (e) { } // eslint-disable-line no-empty } }, 100); } - //---------------------------TEST - - /* const settings = []; - for (const propertyID of Object.values(CameraProperty.ID)) { - const p = this.canonCamera.getProperty(propertyID); - if (!p.available) { - continue; - } - try { - const value = p.value; - settings.push(p); - } catch (e) { - console.error( - p, e - ); - } - } - console.log(JSON.parse(JSON.stringify(settings))); - - */ - //------------------------- - + // Fetch capabilities + this.capabilities = []; + for (const propertyID of Object.values(CameraProperty.ID)) { + const p = this.canonCamera.getProperty(propertyID); + if (!p.available) { + continue; + } + try { + //const value = p.value; + this.capabilities.push(p); + } catch (e) { } // eslint-disable-line no-empty + } } async disconnect() { @@ -140,6 +138,54 @@ class CanonCamera { } }); } + + applyCapability(key, value) { + // Focus mode + if (key === 'focusMode' && this.capabilities.some(c => c.label === 'AFMode')) { + this.canonCamera.setProperties({ + [CameraProperty.ID.AFMode]: value === 'continuous' ? Option.AFMode.AIFocus : Option.AFMode.ManualFocus, + }); + } + + // TODO + + return null; + } + + resetCapabilities() { + // TODO + } + + getCapabilities() { + const AFMode = this.capabilities.find(c => c.label === 'AFMode'); + + const allowedCapabilities = [ + // Focus mode + ...(AFMode ? [ + { id: 'focusMode', type: 'SWITCH', value: AFMode.value.label === 'AFMode.ManualFocus' ? 'manual' : 'continuous' }, + ] : []), + + /* + 'focusMode', + 'focusDistance', + 'brightness', + 'contrast', + + 'saturation', + 'sharpness', + + 'whiteBalanceMode', + 'colorTemperature', + 'exposureMode', + 'exposureCompensation', + 'exposureTime', + 'zoom', + 'tilt', + 'pan'*/ + ]; + + return allowedCapabilities; + } } export const Camera = CanonCamera; diff --git a/src/renderer/cameras/NativeProxy.js b/src/renderer/cameras/NativeProxy.js index 70a2d8a..2b3a286 100644 --- a/src/renderer/cameras/NativeProxy.js +++ b/src/renderer/cameras/NativeProxy.js @@ -22,7 +22,7 @@ class NativeProxy { return this?.context?.id || null; } - #drawLivePreview(dom, src) { + _drawLivePreview(dom, src) { if (!dom || !src) { return; } @@ -56,21 +56,22 @@ class NativeProxy { // TODO: ADD EA Interface for that window.IPC.stream('LIVE_VIEW_DATA', (evt, args) => { - this.#drawLivePreview(this.video, args.data); + this._drawLivePreview(this.video, args.data); }); }); } - resetCapabilities() { - + async resetCapabilities() { + return window.EA('RESET_CAPABILITIES_NATIVE_CAMERA', { camera_id: this.context.id }); } - applyCapability(key, value) { // eslint-disable-line no-unused-vars - + async applyCapability(key, value = null) { + window.EA('APPLY_CAPABILITY_NATIVE_CAMERA', { camera_id: this.context.id, key, value }); + return null; } - getCapabilities() { - return []; + async getCapabilities() { + return window.EA('GET_CAPABILITIES_NATIVE_CAMERA', { camera_id: this.context.id }); } async connect({ imageDOM } = { imageDOM: false }, settings = {}) { diff --git a/src/renderer/cameras/Webcam.js b/src/renderer/cameras/Webcam.js index 2d42899..e5d9133 100644 --- a/src/renderer/cameras/Webcam.js +++ b/src/renderer/cameras/Webcam.js @@ -118,7 +118,7 @@ class Webcam { }); } - resetCapabilities() { + async resetCapabilities() { this.capabilitiesState = { ...defaultCapabilities }; return allowedCapabilities.filter(e => this.capabilities[e]).map(e => ({ id: e, @@ -128,15 +128,17 @@ class Webcam { })) } - applyCapability(key, value) { + async applyCapability(key, value) { if (!this.stream || !this.capabilities) { return null; } this.capabilitiesState[key] = value; + + return null; } - getCapabilities() { + async getCapabilities() { if (!this.stream || !this.capabilities) { return []; } diff --git a/src/renderer/components/Button/index.jsx b/src/renderer/components/Button/index.jsx index 6ac4998..7489f63 100644 --- a/src/renderer/components/Button/index.jsx +++ b/src/renderer/components/Button/index.jsx @@ -5,7 +5,7 @@ import { useMemo } from 'react'; import CustomTooltip from '../Tooltip'; import * as style from './style.module.css'; -const Button = ({ icon, onClick, title = '', size = 'mini', disabled = false, selected = false, tooltipPosition = 'TOP', ...rest }) => { +const Button = ({ icon, onClick, title = '', size = 'mini', disabled = false, selected = false, selectedColor = 'normal', tooltipPosition = 'TOP', ...rest }) => { const uid = useMemo(() => uniqueId(), []); return (
@@ -15,7 +15,7 @@ const Button = ({ icon, onClick, title = '', size = 'mini', disabled = false, se role="button" tabIndex={0} onClick={() => onClick && onClick()} - className={`${(size === 'mini') ? style.buttonMini : style.button} ${(selected) ? style.selected : ''} ${(disabled) ? style.disabled : ''}`} + className={`${(size === 'mini') ? style.buttonMini : style.button} ${(selected && selectedColor === 'normal') ? style.selected : ''} ${(selected && selectedColor === 'warning') ? style.selectedWarning : ''} ${(disabled) ? style.disabled : ''}`} > {icon}
diff --git a/src/renderer/components/Button/style.module.css b/src/renderer/components/Button/style.module.css index a67f672..1514cdb 100644 --- a/src/renderer/components/Button/style.module.css +++ b/src/renderer/components/Button/style.module.css @@ -10,23 +10,23 @@ line-height: 80px; margin-left: 5px; margin-right: 5px; - opacity: 0.8; padding: 10px; position: relative; text-align: center; - transition: all .5s ease-in-out; + transition: all .3s ease-in-out; user-select: none; width: 80px; } .button:hover { - opacity: 1; + background-color: hsl(225 75% 62% / 1); } .buttonMini { align-content: center; align-items: center; - background-color: #7f8186; + /*background-color: #7f8186;*/ + background-color: var(--color-theme-medium); border-radius: 50%; cursor: pointer; display: flex; @@ -34,22 +34,38 @@ justify-content: center; line-height: 40px; margin: 5px; - opacity: 0.5; padding: 5px; position: relative; text-align: center; user-select: none; width: 40px; + transition: all .3s ease-in-out; } .buttonMini:hover { - opacity: 0.6; + background-color: var(--color-theme-light); } .buttonMini.selected { - opacity: 1; + background-color: var(--color-primary); +} + +.buttonMini.selectedWarning { + background-color: var(--color-alert); +} + + +.buttonMini.selected:hover { + background-color: hsl(225 75% 62% / 1); } +.buttonMini.selectedWarning:hover { + background-color: hsl(0 75% 62% / 1); +} + + + + .button>svg, .buttonMini>svg { background-size: contain; diff --git a/src/renderer/components/Container/vars.module.css b/src/renderer/components/Container/vars.module.css index e0860d7..5aa64bd 100644 --- a/src/renderer/components/Container/vars.module.css +++ b/src/renderer/components/Container/vars.module.css @@ -28,7 +28,7 @@ body { --input-height: 30px; --color-primary: #486ee5; --color-alert: #e54848; - --color-theme-light: #7f8186; + --color-theme-light: hsl(223 4% 45% / 1); --color-theme-medium: #5f6166; --color-theme-dark: #2f3136; } \ No newline at end of file diff --git a/src/renderer/components/ControlBar/index.jsx b/src/renderer/components/ControlBar/index.jsx index 3f0ccfa..f19c728 100644 --- a/src/renderer/components/ControlBar/index.jsx +++ b/src/renderer/components/ControlBar/index.jsx @@ -73,7 +73,7 @@ const ControlBar = ({ {frameQuantity} -