diff --git a/.erb/scripts/build-rust-scripts.js b/.erb/scripts/build-rust-scripts.js new file mode 100644 index 00000000..9b6ebca2 --- /dev/null +++ b/.erb/scripts/build-rust-scripts.js @@ -0,0 +1,33 @@ +import path from 'path'; +import { copyFileSync, existsSync, readdirSync } from 'fs-extra'; +import { execSync } from 'child_process'; + +const eternalsFolder = path.join(__dirname, '..', '..', 'externals'); + +// Get rust project folders from externals +const rustProjects = readdirSync(eternalsFolder).filter(folder => existsSync(path.join(eternalsFolder, folder, 'Cargo.toml'))); + +// Build each rust project in release mode +rustProjects.forEach(project => { + console.log(`Building ${project}`); + execSync(`cargo build --release`, { + cwd: path.join(eternalsFolder, project), + stdio: 'inherit', + }); +}); + +// Copy the built files exe to the assests/scripts folder +rustProjects.forEach(project => { + // read the project name from Cargo.toml using toml parser + const projectMetadata = execSync('cargo metadata --no-deps --format-version 1', { + cwd: path.join(eternalsFolder, project), + stdio: 'pipe', + }); + const projectMetadataJson = JSON.parse(projectMetadata); + const projectName = projectMetadataJson.packages[0].name; + + const source = path.join(eternalsFolder, project, 'target', 'release', `${projectName}.exe`); + const destination = path.join(__dirname, '..', '..', 'assets', 'scripts', `${projectName}.exe`); + console.log(`Copying ${source} to ${destination}`); + copyFileSync(source, destination); +}); diff --git a/.gitignore b/.gitignore index ad436745..acbb16c1 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,4 @@ npm-debug.log.* *.scss.d.ts # externals -externals/bs-admin-start/target/* +externals/**/target/* diff --git a/assets/jsons/bs-versions.json b/assets/jsons/bs-versions.json index 8a2b7fdb..6484682a 100644 --- a/assets/jsons/bs-versions.json +++ b/assets/jsons/bs-versions.json @@ -699,5 +699,14 @@ "ReleaseImg": "https://clan.cloudflare.steamstatic.com/images/32055887/e7c75bdfc76d00713adc3fbdf221c9ce8ab3620d.png", "ReleaseDate": "1708091473", "year": "2024" + }, + { + "BSVersion": "1.35.0", + "BSManifest": "1490986193481243578", + "OculusBinaryId": "6720809361352119", + "ReleaseURL": "https://store.steampowered.com/news/app/620980/view/4142820264819707009", + "ReleaseImg": "https://clan.cloudflare.steamstatic.com/images//32055887/9a141be5c44ca6fc81551a2c7e7f28407df413ed.png", + "ReleaseDate": "1709831174", + "year": "2024" } -] \ No newline at end of file +] diff --git a/assets/jsons/patreons.json b/assets/jsons/patreons.json index dba45720..873f2d41 100644 --- a/assets/jsons/patreons.json +++ b/assets/jsons/patreons.json @@ -79,5 +79,15 @@ }, { "username": "mereknom" + }, + { + "username": "Jascha" + }, + { + "username": "Celldweller", + "type": "gold" + }, + { + "username": "rhythmshade" } ] diff --git a/assets/jsons/translations/de.json b/assets/jsons/translations/de.json index 0e4ec724..e807e2b4 100644 --- a/assets/jsons/translations/de.json +++ b/assets/jsons/translations/de.json @@ -94,8 +94,7 @@ "edit": "Bearbeiten", "uninstall": "Entfernen", "create-shortcut": "Verknüpfung erstellen", - "shared-folders": "Geteilte Ordner", - "restore-oculus-folder": "Ordner wiederherstellen" + "shared-folders": "Geteilte Ordner" } }, "available-versions": { @@ -464,7 +463,7 @@ }, "maps": { "one-click-install": { - "success": "Map installation abegschlossen", + "success": "Map installation abgeschlossen", "error": "Ein Fehler ist aufgetreten während der installation der Map" } }, @@ -699,9 +698,7 @@ "title": "Achtung", "body": { "must-be-installed-once": "Sie müssen Beat Saber mindestens einmal aus dem Oculus Store installiert haben, sonst könnte sich Beat Saber nach dem Start automatisch schließen.", - "need-backup": "Um diese Version zu starten, wird der Installationsordner von Beat Saber in Ihrer Oculus-Bibliothek umbenannt.", - "can-restore-later": "Bei Bedarf können Sie ihn vom BSManager aus wiederherstellen, indem Sie zu den Optionen der originalen Oculus-Version gehen und auf 'Ordner wiederherstellen' klicken", - "tips-launch-oculus": "Tipp: Sie können diese Version direkt über Oculus starten, solange die Originalversion nicht wiederhergestellt ist." + "will-backup": "Um diese Version zu starten, wird der ursprüngliche Installationsordner von Beat Saber in Ihrer Oculus-Bibliothek umbenannt und beim Schließen von Beat Saber automatisch wiederhergestellt." }, "not-remind-me": "Nicht mehr erinnern", "understood": "Verstanden" @@ -741,7 +738,8 @@ "nps" : "Noten Pro Sekunde", "tags": "Stichworte", "specificities": "Allgemein", - "requirements": "Anforderungen" + "requirements": "Anforderungen", + "exclude": "ausschließen" }, "map-types": { "accuracy": "Präzision", @@ -797,6 +795,9 @@ "verified": "verifiziert", "fullSpread": "full spread" }, + "map-excludes": { + "installed": "installiert" + }, "difficulties": { "Easy": "einfach", "Normal": "normal", diff --git a/assets/jsons/translations/en.json b/assets/jsons/translations/en.json index c3acdaca..6672bd48 100644 --- a/assets/jsons/translations/en.json +++ b/assets/jsons/translations/en.json @@ -94,8 +94,7 @@ "edit": "Edit", "uninstall": "Uninstall", "create-shortcut": "Create a shortcut", - "shared-folders": "Shared Folders", - "restore-oculus-folder": "Restore the folder" + "shared-folders": "Shared Folders" } }, "available-versions": { @@ -699,9 +698,7 @@ "title": "Warning", "body": { "must-be-installed-once": "You must have installed Beat Saber at least once from the Oculus Store, otherwise Beat Saber might automatically close after launching.", - "need-backup": "To launch this version, the Beat Saber installation folder located in your Oculus library will be renamed.", - "can-restore-later": "If needed, you can restore it from BSManager by going to the options of the original Oculus version and clicking on 'Restore the folder'", - "tips-launch-oculus": "Tip: You can launch this version directly from Oculus, as long as the original version is not restored." + "will-backup": "To launch this version, the original installation folder of Beat Saber located in your Oculus library will be renamed and will be automatically restored when Beat Saber is closed." }, "not-remind-me": "Do not remind me", "understood": "Understood" @@ -741,7 +738,8 @@ "nps" : "Notes Per Second", "tags": "tags", "specificities": "general", - "requirements": "requirements" + "requirements": "requirements", + "exclude": "exclude" }, "map-types": { "accuracy": "accuracy", @@ -797,6 +795,9 @@ "verified": "verified", "fullSpread": "full spread" }, + "map-excludes": { + "installed": "installed" + }, "difficulties": { "Easy": "easy", "Normal": "normal", diff --git a/assets/jsons/translations/es.json b/assets/jsons/translations/es.json index 3dd0c6d9..169d687d 100644 --- a/assets/jsons/translations/es.json +++ b/assets/jsons/translations/es.json @@ -94,8 +94,7 @@ "edit": "Editar", "uninstall": "Desinstalar", "create-shortcut": "Crear un atajo", - "shared-folders": "Carpetas Compartidas", - "restore-oculus-folder": "Restaurar la carpeta" + "shared-folders": "Carpetas Compartidas" } }, "available-versions": { @@ -699,9 +698,7 @@ "title": "Atención", "body": { "must-be-installed-once": "Debes haber instalado Beat Saber al menos una vez desde la Oculus Store, de lo contrario, Beat Saber podría cerrarse automáticamente después de iniciar.", - "need-backup": "Para iniciar esta versión, la carpeta de instalación de Beat Saber que se encuentra en tu biblioteca de Oculus será renombrada.", - "can-restore-later": "Si es necesario, podrás restaurarla desde el BSManager accediendo a las opciones de la versión original de Oculus y haciendo clic en 'Restaurar la carpeta'", - "tips-launch-oculus": "Consejo: Podrás iniciar esta versión directamente desde Oculus, siempre que la versión original no haya sido restaurada." + "will-backup": "Para lanzar esta versión, la carpeta de instalación original de Beat Saber ubicada en tu biblioteca de Oculus será renombrada y se restaurará automáticamente al cerrar Beat Saber." }, "not-remind-me": "No volver a recordármelo", "understood": "Entendido" @@ -741,7 +738,8 @@ "nps" : "Notas Por Segundo", "tags": "tags", "specificities": "general", - "requirements": "requisitos" + "requirements": "requisitos", + "exclude": "excluir" }, "map-types": { "accuracy": "precisión", @@ -797,6 +795,9 @@ "verified": "verificado", "fullSpread": "panel completo" }, + "map-excludes": { + "installed": "instalado" + }, "difficulties": { "Easy": "fácil", "Normal": "normal", diff --git a/assets/jsons/translations/fr.json b/assets/jsons/translations/fr.json index 4bdc643f..7b8b8716 100644 --- a/assets/jsons/translations/fr.json +++ b/assets/jsons/translations/fr.json @@ -94,8 +94,7 @@ "edit": "Modifier", "uninstall": "Désinstaller", "create-shortcut": "Créer un raccourci", - "shared-folders": "Dossiers partagés", - "restore-oculus-folder": "Restaurer le dossier" + "shared-folders": "Dossiers partagés" } }, "available-versions": { @@ -699,9 +698,7 @@ "title": "Attention", "body": { "must-be-installed-once": "Vous devez avoir installé au moins une fois Beat Saber depuis l'Oculus Store, sinon Beat Saber pourrait se fermer automatiquement après son lancement.", - "need-backup": "Pour lancer cette version, le dossier d'installation de Beat Saber se trouvant dans votre librairie Oculus va être renommé.", - "can-restore-later": "Au besoin, vous pourrez le restaurer depuis BSManager en vous rendant dans les options de la version originale Oculus et en cliquant sur \"Restaurer le dossier\"", - "tips-launch-oculus": "Astuce : Vous pourrez lancer cette version directement depuis Oculus, tant que la version originale n'est pas restaurée." + "will-backup": "Afin de lancer cette version, le dossier d'installation original de Beat Saber se trouvant dans votre bibliothèque Oculus va être renommé et sera automatiquement restauré à l'arrêt de Beat Saber." }, "not-remind-me": "Ne plus me rappeler", "understood": "J'ai compris" @@ -741,7 +738,8 @@ "nps" : "Notes Par Seconde", "tags": "tags", "specificities": "général", - "requirements": "requis" + "requirements": "requis", + "exclude": "exclure" }, "map-types": { "accuracy": "précision", @@ -797,6 +795,9 @@ "verified": "vérifiée", "fullSpread": "panel complet" }, + "map-excludes": { + "installed": "installé" + }, "difficulties": { "Easy": "facile", "Normal": "normal", diff --git a/assets/jsons/translations/ja.json b/assets/jsons/translations/ja.json index 6066151f..f6f61799 100644 --- a/assets/jsons/translations/ja.json +++ b/assets/jsons/translations/ja.json @@ -94,8 +94,7 @@ "edit": "編集", "uninstall": "アンインストール", "create-shortcut": "ショートカットを作成", - "shared-folders": "共有フォルダー", - "restore-oculus-folder": "フォルダーの復元" + "shared-folders": "共有フォルダー" } }, "available-versions": { @@ -699,9 +698,7 @@ "title": "注意", "body": { "must-be-installed-once": "少なくとも一度はOculus StoreからBeat Saberをインストールしている必要があります。そうしないとBeat Saberは起動後に自動的に終了する可能性があります。", - "need-backup": "このバージョンを起動するには、OculusライブラリにあるBeat Saberインストールフォルダの名前を変更します。", - "can-restore-later": "必要であれば、BSManagerから元のOculusバージョンのオプションに行き、'フォルダを復元'をクリックして復元することができます。", - "tips-launch-oculus": "ヒント: 元のバージョンが復元されない限り、Oculusから直接このバージョンを起動することができます。" + "will-backup": "このバージョンを起動するために、OculusライブラリにあるBeat Saberの元のインストールフォルダは名前が変更され、Beat Saberの終了時に自動的に復元されます。" }, "not-remind-me": "二度と表示しないでください", "understood": "分かった" @@ -741,7 +738,8 @@ "nps" : "秒間ノート数", "tags": "タグ", "specificities": "一般", - "requirements": "要Mod" + "requirements": "要Mod", + "exclude": "除外する" }, "map-types": { "accuracy": "正確", @@ -797,6 +795,9 @@ "verified": "認証済み", "fullSpread": "フルスプレッド" }, + "map-excludes": { + "installed": "インストール済み" + }, "difficulties": { "Easy": "easy", "Normal": "normal", diff --git a/assets/jsons/translations/ru.json b/assets/jsons/translations/ru.json index bce2403d..0d77b028 100644 --- a/assets/jsons/translations/ru.json +++ b/assets/jsons/translations/ru.json @@ -94,8 +94,7 @@ "edit": "Редактировать", "uninstall": "Удалить", "create-shortcut": "Создать ярлык", - "shared-folders": "Общие папки", - "restore-oculus-folder": "Восстановить папку" + "shared-folders": "Общие папки" } }, "available-versions": { @@ -699,9 +698,7 @@ "title": "Внимание", "body": { "must-be-installed-once": "Вы должны были установить Beat Saber хотя бы один раз из Oculus Store, иначе Beat Saber может автоматически закрыться после запуска.", - "need-backup": "Для запуска этой версии папка установки Beat Saber в вашей библиотеке Oculus будет переименована.", - "can-restore-later": "При необходимости вы можете восстановить её через BSManager, перейдя в опции оригинальной версии Oculus и нажав на 'Восстановить папку'", - "tips-launch-oculus": "Совет: Вы можете запустить эту версию напрямую через Oculus, пока оригинальная версия не восстановлена." + "will-backup": "Для запуска этой версии исходная папка установки Beat Saber, находящаяся в вашей библиотеке Oculus, будет переименована и автоматически восстановлена при выходе из Beat Saber." }, "not-remind-me": "Больше не напоминать", "understood": "Понял" @@ -740,7 +737,8 @@ "nps" : "Нот в Секунду", "tags": "тэги", "specificities": "основное", - "requirements": "требуемые моды" + "requirements": "требуемые моды", + "exclude": "исключить" }, "map-types": { "accuracy": "точность", @@ -796,6 +794,9 @@ "verified": "проверенные авторы", "fullSpread": "полный набор" }, + "map-excludes": { + "installed": "установленный" + }, "difficulties": { "Easy": "легко", "Normal": "нормально", diff --git a/assets/jsons/translations/zh-tw.json b/assets/jsons/translations/zh-tw.json index e05baa8b..92fa9855 100644 --- a/assets/jsons/translations/zh-tw.json +++ b/assets/jsons/translations/zh-tw.json @@ -94,8 +94,7 @@ "edit": "編輯", "uninstall": "移除", "create-shortcut": "創建捷徑", - "shared-folders": "Shared Folders", - "restore-oculus-folder": "Restore the folder" + "shared-folders": "Shared Folders" } }, "available-versions": { @@ -699,9 +698,7 @@ "title": "警告", "body": { "must-be-installed-once": "你必須至少從 Oculus 商店安裝過一次 BeatSaber,否則 BeatSaber 可能會在啟動後自動關閉。", - "need-backup": "要啟動該版本,位於你的 Oculus 庫中的 BeatSaber 安裝文件夾將被重命名。", - "can-restore-later": "如果需要,你可以通過前往 BSManager 的原始 Oculus 版本選項並點擊'恢復文件夾'來恢復它。", - "tips-launch-oculus": "提示:只要原始版本沒有被恢復,你就可以直接從 Oculus 啟動該版本。" + "will-backup": "為了啟動這個版本,位於您的Oculus庫中的Beat Saber的原始安裝文件夾將被重新命名,並且在Beat Saber關閉時會自動恢復。" }, "not-remind-me": "不再提醒我", "understood": "明白了" @@ -741,7 +738,8 @@ "nps" : "每秒音符數", "tags": "標籤", "specificities": "general", - "requirements": "要求" + "requirements": "要求", + "exclude": "排除" }, "map-types": { "accuracy": "精確度", @@ -797,6 +795,9 @@ "verified": "Verified", "fullSpread": "Full spread" }, + "map-excludes": { + "installed": "已安裝" + }, "difficulties": { "Easy": "Easy", "Normal": "Normal", diff --git a/assets/jsons/translations/zh.json b/assets/jsons/translations/zh.json index c1a3724c..08d262f6 100644 --- a/assets/jsons/translations/zh.json +++ b/assets/jsons/translations/zh.json @@ -94,8 +94,7 @@ "edit": "编辑", "uninstall": "卸载", "create-shortcut": "创建快捷方式", - "shared-folders": "Shared Folders", - "restore-oculus-folder": "Restore the folder" + "shared-folders": "Shared Folders" } }, "available-versions": { @@ -699,9 +698,7 @@ "title": "警告", "body": { "must-be-installed-once": "你必须至少从 Oculus 商店安装过一次 BeatSaber,否则 BeatSaber 可能会在启动后自动关闭。", - "need-backup": "要启动该版本,位于你的 Oculus 库中的 BeatSaber 安装文件夹将被重命名。", - "can-restore-later": "如果需要,你可以通过前往 BSManager 的原始 Oculus 版本选项并点击'恢复文件夹'来恢复它。", - "tips-launch-oculus": "提示:只要原始版本没有被恢复,你就可以直接从 Oculus 启动该版本。" + "will-backup": "为了启动这个版本,位于您的Oculus库中的Beat Saber的原始安装文件夹将被重命名,并且在Beat Saber关闭时会自动恢复。" }, "not-remind-me": "不再提醒我", "understood": "明白了" @@ -741,7 +738,8 @@ "nps" : "每秒音符数", "tags": "标签", "specificities": "general", - "requirements": "要求" + "requirements": "要求", + "exclude": "排除" }, "map-types": { "accuracy": "精确度", @@ -797,6 +795,9 @@ "verified": "verified", "fullSpread": "full spread" }, + "map-excludes": { + "installed": "已安装" + }, "difficulties": { "Easy": "easy", "Normal": "normal", diff --git a/assets/scripts/oculus_symlink_cleaner.exe b/assets/scripts/oculus_symlink_cleaner.exe new file mode 100644 index 00000000..05659aeb Binary files /dev/null and b/assets/scripts/oculus_symlink_cleaner.exe differ diff --git a/externals/oculus-symlink-cleaner/.cargo/config.toml b/externals/oculus-symlink-cleaner/.cargo/config.toml new file mode 100644 index 00000000..0c17df09 --- /dev/null +++ b/externals/oculus-symlink-cleaner/.cargo/config.toml @@ -0,0 +1,2 @@ +[target.x86_64-pc-windows-msvc] +rustflags = ["-C", "target-feature=+crt-static"] \ No newline at end of file diff --git a/externals/oculus-symlink-cleaner/Cargo.lock b/externals/oculus-symlink-cleaner/Cargo.lock new file mode 100644 index 00000000..233feb34 --- /dev/null +++ b/externals/oculus-symlink-cleaner/Cargo.lock @@ -0,0 +1,281 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "either" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + +[[package]] +name = "oculus_symlink_cleaner" +version = "0.1.0" +dependencies = [ + "sysinfo", + "winres", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "2.0.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sysinfo" +version = "0.30.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6746919caf9f2a85bff759535664c060109f21975c5ac2e8652e60102bd4d196" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + +[[package]] +name = "winres" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" +dependencies = [ + "toml", +] diff --git a/externals/oculus-symlink-cleaner/Cargo.toml b/externals/oculus-symlink-cleaner/Cargo.toml new file mode 100644 index 00000000..f7dcb7e0 --- /dev/null +++ b/externals/oculus-symlink-cleaner/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "oculus_symlink_cleaner" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[build-dependencies] +winres = "0.1.12" + +[dependencies] +sysinfo = "0.30.6" + +[profile.release] +codegen-units = 1 +lto = true +opt-level = "z" + +[package.metadata.winres] +FileDescription = "Clean Oculus Symlink after Beat Saber ends" +LegalCopyright = "Copyright © 2024 Zagrios" +CompanyName = "Zagrios" diff --git a/externals/oculus-symlink-cleaner/build.rs b/externals/oculus-symlink-cleaner/build.rs new file mode 100644 index 00000000..ac40e20c --- /dev/null +++ b/externals/oculus-symlink-cleaner/build.rs @@ -0,0 +1,9 @@ +extern crate winres; + +fn main() { + if cfg!(target_os = "windows") { + let mut res = winres::WindowsResource::new(); + res.set_icon("./icon.ico"); + res.compile().unwrap(); + } +} diff --git a/externals/oculus-symlink-cleaner/icon.ico b/externals/oculus-symlink-cleaner/icon.ico new file mode 100644 index 00000000..660923e2 Binary files /dev/null and b/externals/oculus-symlink-cleaner/icon.ico differ diff --git a/externals/oculus-symlink-cleaner/src/main.rs b/externals/oculus-symlink-cleaner/src/main.rs new file mode 100644 index 00000000..5d3a39ed --- /dev/null +++ b/externals/oculus-symlink-cleaner/src/main.rs @@ -0,0 +1,78 @@ +use sysinfo::{Pid, ProcessRefreshKind, System}; +use std::{env, thread, time::Duration, fs}; +use std::ffi::OsStr; +use std::path::Path; +use std::str::FromStr; + +const BEAT_SABER_OCULUS_FOLDER_NAME: &str = "hyperbolic-magnetism-beat-saber"; + +fn main() { + let args: Vec = env::args().collect(); + if args.len() != 3 { + eprintln!("Usage: {} ", args[0]); + std::process::exit(1); + } + + let pid: Pid = Pid::from_str(&args[1]).expect("Invalid pid"); + let directory_path = Path::new(&args[2]); + + if directory_path.file_name() != Some(OsStr::new(BEAT_SABER_OCULUS_FOLDER_NAME)) { + eprintln!("Directory name is not {}", BEAT_SABER_OCULUS_FOLDER_NAME); + std::process::exit(1); + } + + // we want to monitor only processes + let mut system = System::new_with_specifics(sysinfo::RefreshKind::new().with_processes(ProcessRefreshKind::everything())); + + loop { + system.refresh_processes(); + let process = system.process(pid); + + match process { + Some(_) => { + println!("Process {} is still running.", pid); + thread::sleep(Duration::from_secs(2)); + }, + None => { + println!("Process {} has stopped, deleting directory {:?}", pid, directory_path); + match delete_dir_if_is_symlink(directory_path) { + Ok(_) => { + println!("Directory {:?} deleted successfully.", directory_path); + if let Err(e) = rename_specific_backup_directory(directory_path.parent().unwrap()) { + eprintln!("Failed to rename backup directory: {}", e); + } + }, + Err(e) => eprintln!("Failed to delete directory {:?}: {}", directory_path, e), + } + break; + } + } + } +} + +fn delete_dir_if_is_symlink(path: &Path) -> Result<(), Box>{ + match path.symlink_metadata()?.file_type().is_symlink() { + true => { + fs::remove_dir_all(path)?; + Ok(()) + }, + false => { + eprintln!("Path {:?} is not a symlink.", path); + Err("Path is not a symlink.".into()) + } + } +} + +fn rename_specific_backup_directory(parent_path: &Path) -> Result<(), Box> { + let backup_dir_name = format!("{}.bsmbak", BEAT_SABER_OCULUS_FOLDER_NAME); + let backup_path = parent_path.join(&backup_dir_name); + if backup_path.exists() && backup_path.is_dir() { + let new_path = parent_path.join(BEAT_SABER_OCULUS_FOLDER_NAME); + fs::rename(&backup_path, &new_path)?; + println!("Renamed {:?} to {:?}", backup_path, new_path); + Ok(()) + } else { + Err(format!("Backup directory {:?} does not exist or is not a directory.", backup_path).into()) + } +} + diff --git a/package-lock.json b/package-lock.json index 2d14e785..ebbdc0c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,21 +14,21 @@ "color": "^4.2.3", "crypto-js": "^4.2.0", "dateformat": "^5.0.3", - "dompurify": "^3.0.8", + "dompurify": "^3.0.9", "dot-prop": "^8.0.2", "electron-debug": "^3.2.0", "electron-log": "^4.4.8", "electron-store": "^8.1.0", - "electron-updater": "^6.1.7", + "electron-updater": "^6.1.8", "fast-deep-equal": "^3.1.3", - "framer-motion": "^11.0.3", + "framer-motion": "^11.0.6", "fs-extra": "^11.2.0", "got": "^14.2.0", "history": "^5.3.0", "is-elevated": "^4.0.0", "jszip": "^3.10.1", "md5-file": "^5.0.0", - "node-abi": "^3.54.0", + "node-abi": "^3.56.0", "node-fetch": "^3.3.2", "node-stream-zip": "^1.15.0", "pako": "^2.1.0", @@ -39,14 +39,14 @@ "react-colorful": "^5.6.1", "react-dom": "^18.2.0", "react-range": "^1.8.14", - "react-router-dom": "^6.21.3", - "react-virtualized-auto-sizer": "^1.0.21", + "react-router-dom": "^6.22.1", + "react-virtualized-auto-sizer": "^1.0.23", "react-window": "^1.8.10", "recursive-readdir": "^2.2.3", "rfdc": "^1.3.1", "rxjs": "^7.8.1", "sanitize-filename": "^1.6.3", - "semver": "^7.5.4", + "semver": "^7.6.0", "serialize-error": "^11.0.3", "striptags": "^4.0.0-alpha.4", "tailwind-scrollbar-hide": "^1.1.7", @@ -58,7 +58,7 @@ }, "devDependencies": { "@electron/fuses": "^1.7.0", - "@electron/notarize": "^2.2.1", + "@electron/notarize": "^2.3.0", "@electron/rebuild": "^3.6.0", "@pmmmwh/react-refresh-webpack-plugin": "0.5.5", "@teamsupercell/typings-for-css-modules-loader": "^2.5.2", @@ -92,16 +92,16 @@ "browserslist-config-erb": "^0.0.3", "chalk": "^4.1.2", "concurrently": "^8.2.2", - "core-js": "^3.35.1", + "core-js": "^3.36.0", "cross-env": "^7.0.3", "css-loader": "^6.10.0", "css-minimizer-webpack-plugin": "^6.0.0", "detect-port": "^1.5.1", - "electron": "^28.2.1", - "electron-builder": "^24.9.1", + "electron": "^28.2.4", + "electron-builder": "^24.12.0", "electron-devtools-installer": "^3.2.0", "electronmon": "^2.0.2", - "esbuild": "^0.20.0", + "esbuild": "^0.20.1", "esbuild-register": "^3.5.0", "eslint": "^8.56.0", "eslint-config-airbnb-base": "^15.0.0", @@ -132,14 +132,14 @@ "sass": "^1.70.0", "sass-loader": "^14.1.0", "style-loader": "^3.3.4", - "tailwind-scrollbar": "^3.0.5", + "tailwind-scrollbar": "^3.1.0", "tailwindcss": "^3.4.1", "terser-webpack-plugin": "^5.3.10", "ts-jest": "^29.1.2", "ts-loader": "^9.5.1", "typescript": "^5.3.3", "url-loader": "^4.1.1", - "webpack": "^5.90.0", + "webpack": "^5.90.3", "webpack-bundle-analyzer": "^4.10.1", "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.15.1", @@ -838,8 +838,9 @@ }, "node_modules/@develar/schema-utils": { "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==", "dev": true, - "license": "MIT", "dependencies": { "ajv": "^6.12.0", "ajv-keywords": "^3.4.1" @@ -862,8 +863,9 @@ }, "node_modules/@electron/asar": { "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.8.tgz", + "integrity": "sha512-cmskk5M06ewHMZAplSiF4AlME3IrnnZhKnWbtwKVLRkdJkKyUVjMLhDIiPIx/+6zQWVlKX/LtmK9xDme7540Sg==", "dev": true, - "license": "MIT", "dependencies": { "commander": "^5.0.0", "glob": "^7.1.6", @@ -878,8 +880,9 @@ }, "node_modules/@electron/asar/node_modules/commander": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 6" } @@ -1101,9 +1104,10 @@ } }, "node_modules/@electron/notarize": { - "version": "2.2.1", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.3.0.tgz", + "integrity": "sha512-EiTBU0BwE7HZZjAG1fFWQaiQpCuPrVGn7jPss1kUjD6eTTdXXd29RiZqEqkgN7xqt/Pgn4g3I7Saqovanrfj3w==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.1.1", "fs-extra": "^9.0.1", @@ -1129,8 +1133,9 @@ }, "node_modules/@electron/osx-sign": { "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, - "license": "BSD-2-Clause", "dependencies": { "compare-version": "^0.1.2", "debug": "^4.3.4", @@ -1149,8 +1154,9 @@ }, "node_modules/@electron/osx-sign/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, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -1162,8 +1168,9 @@ }, "node_modules/@electron/osx-sign/node_modules/isbinaryfile": { "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8.0.0" }, @@ -1344,8 +1351,9 @@ }, "node_modules/@electron/universal": { "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, - "license": "MIT", "dependencies": { "@electron/asar": "^3.2.1", "@malept/cross-spawn-promise": "^1.1.0", @@ -1361,6 +1369,8 @@ }, "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": [ { @@ -1372,7 +1382,6 @@ "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" } ], - "license": "Apache-2.0", "dependencies": { "cross-spawn": "^7.0.1" }, @@ -1382,8 +1391,9 @@ }, "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", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, - "license": "MIT", "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -1407,13 +1417,366 @@ "license": "MIT", "optional": true }, - "node_modules/@esbuild/win32-x64": { - "version": "0.20.0", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz", + "integrity": "sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.1.tgz", + "integrity": "sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.1.tgz", + "integrity": "sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.1.tgz", + "integrity": "sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.1.tgz", + "integrity": "sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.1.tgz", + "integrity": "sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.1.tgz", + "integrity": "sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.1.tgz", + "integrity": "sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.1.tgz", + "integrity": "sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.1.tgz", + "integrity": "sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.1.tgz", + "integrity": "sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.1.tgz", + "integrity": "sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.1.tgz", + "integrity": "sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.1.tgz", + "integrity": "sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.1.tgz", + "integrity": "sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.1.tgz", + "integrity": "sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.1.tgz", + "integrity": "sha512-5gRPk7pKuaIB+tmH+yKd2aQTRpqlf1E4f/mC+tawIm/CGJemZcHZpp2ic8oD83nKgUPMEd0fNanrnFljiruuyA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.1.tgz", + "integrity": "sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.1.tgz", + "integrity": "sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.1.tgz", + "integrity": "sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.1.tgz", + "integrity": "sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.1.tgz", + "integrity": "sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.1.tgz", + "integrity": "sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" @@ -2105,8 +2468,9 @@ }, "node_modules/@malept/flatpak-bundler": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz", + "integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.1.1", "fs-extra": "^9.0.0", @@ -2119,8 +2483,9 @@ }, "node_modules/@malept/flatpak-bundler/node_modules/fs-extra": { "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, - "license": "MIT", "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -2411,9 +2776,9 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "node_modules/@remix-run/router": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.2.tgz", - "integrity": "sha512-ACXpdMM9hmKZww21yEqWwiLws/UPLhNKvimN8RrYSqPSvB3ov7sLvAcfvaxePeLvccTQKGdkDIhLYApZVDFuKg==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.1.tgz", + "integrity": "sha512-zcU0gM3z+3iqj8UX45AmWY810l3oUmXM7uH4dt5xtzvMhRtYVhKGOmgOd1877dOPPepfCjUv57w+syamWIYe7w==", "engines": { "node": ">=14.0.0" } @@ -2791,8 +3156,9 @@ }, "node_modules/@types/debug": { "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/ms": "*" } @@ -2852,8 +3218,9 @@ }, "node_modules/@types/fs-extra": { "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } @@ -2994,8 +3361,9 @@ }, "node_modules/@types/ms": { "version": "0.7.34", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "dev": true }, "node_modules/@types/node": { "version": "20.11.15", @@ -3036,6 +3404,17 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/plist": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.5.tgz", + "integrity": "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*", + "xmlbuilder": ">=11.0.1" + } + }, "node_modules/@types/prop-types": { "version": "15.7.5", "dev": true, @@ -3207,6 +3586,13 @@ "@types/react": "*" } }, + "node_modules/@types/verror": { + "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 + }, "node_modules/@types/webpack-bundle-analyzer": { "version": "4.6.0", "dev": true, @@ -3940,8 +4326,9 @@ }, "node_modules/@xmldom/xmldom": { "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.0.0" } @@ -3958,8 +4345,9 @@ }, "node_modules/7zip-bin": { "version": "5.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.2.0.tgz", + "integrity": "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==", + "dev": true }, "node_modules/abbrev": { "version": "1.1.1", @@ -4206,13 +4594,15 @@ }, "node_modules/app-builder-bin": { "version": "4.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-4.0.0.tgz", + "integrity": "sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==", + "dev": true }, "node_modules/app-builder-lib": { - "version": "24.9.1", + "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, - "license": "MIT", "dependencies": { "@develar/schema-utils": "~2.6.5", "@electron/notarize": "2.1.0", @@ -4220,15 +4610,14 @@ "@electron/universal": "1.4.1", "@malept/flatpak-bundler": "^0.4.0", "@types/fs-extra": "9.0.13", - "7zip-bin": "~5.2.0", "async-exit-hook": "^2.0.1", "bluebird-lst": "^1.0.9", - "builder-util": "24.8.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.8.1", + "electron-publish": "24.9.4", "form-data": "^4.0.0", "fs-extra": "^10.1.0", "hosted-git-info": "^4.1.0", @@ -4249,8 +4638,9 @@ }, "node_modules/app-builder-lib/node_modules/@electron/notarize": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.1.0.tgz", + "integrity": "sha512-Q02xem1D0sg4v437xHgmBLxI2iz/fc0D4K7fiVWHa/AnW8o7D751xyKNXgziA6HrTOme9ul1JfWN5ark8WH1xA==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.1.1", "fs-extra": "^9.0.1", @@ -4262,8 +4652,9 @@ }, "node_modules/app-builder-lib/node_modules/@electron/notarize/node_modules/fs-extra": { "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, - "license": "MIT", "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -4276,16 +4667,18 @@ }, "node_modules/app-builder-lib/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, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/app-builder-lib/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, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -4297,8 +4690,9 @@ }, "node_modules/app-builder-lib/node_modules/minimatch": { "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -4579,14 +4973,25 @@ "dev": true, "license": "MIT" }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/async": { "version": "3.2.4", "license": "MIT" }, "node_modules/async-exit-hook": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -4851,13 +5256,15 @@ }, "node_modules/bluebird": { "version": "3.7.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true }, "node_modules/bluebird-lst": { "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz", + "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==", "dev": true, - "license": "MIT", "dependencies": { "bluebird": "^3.5.5" } @@ -5063,8 +5470,9 @@ }, "node_modules/buffer-equal": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", + "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.4" }, @@ -5082,9 +5490,10 @@ "license": "MIT" }, "node_modules/builder-util": { - "version": "24.8.1", + "version": "24.9.4", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-24.9.4.tgz", + "integrity": "sha512-YNon3rYjPSm4XDDho9wD6jq7vLRJZUy9FR+yFZnHoWvvdVCnZakL4BctTlPABP41MvIH5yk2cTZ2YfkOhGistQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/debug": "^4.1.6", "7zip-bin": "~5.2.0", @@ -5117,8 +5526,9 @@ }, "node_modules/builder-util/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, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -5443,8 +5853,9 @@ }, "node_modules/chromium-pickle-js": { "version": "0.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", + "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", + "dev": true }, "node_modules/ci-info": { "version": "3.6.1", @@ -5711,8 +6122,9 @@ }, "node_modules/compare-version": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", + "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5877,24 +6289,68 @@ "license": "MIT" }, "node_modules/config-file-ts": { - "version": "0.2.4", + "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, - "license": "MIT", "dependencies": { - "glob": "^7.1.6", - "typescript": "^4.0.2" + "glob": "^10.3.10", + "typescript": "^5.3.3" } }, - "node_modules/config-file-ts/node_modules/typescript": { - "version": "4.9.5", + "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, - "license": "Apache-2.0", + "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": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=4.2.0" + "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/config-file-ts/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" } }, "node_modules/confusing-browser-globals": { @@ -5972,10 +6428,11 @@ "license": "MIT" }, "node_modules/core-js": { - "version": "3.35.1", + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.0.tgz", + "integrity": "sha512-mt7+TUBbTFg5+GngsAxeKBTl5/VS0guFeJacYge9OmHb+m058UwwIm41SE9T4Den7ClatV57B6TYTuJ0CX1MAw==", "dev": true, "hasInstallScript": true, - "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" @@ -6010,6 +6467,16 @@ "node": ">=10" } }, + "node_modules/crc": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "dev": true, + "optional": true, + "dependencies": { + "buffer": "^5.1.0" + } + }, "node_modules/crc-32": { "version": "1.2.2", "license": "Apache-2.0", @@ -6770,8 +7237,9 @@ }, "node_modules/dir-compare": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz", + "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==", "dev": true, - "license": "MIT", "dependencies": { "buffer-equal": "^1.0.0", "minimatch": "^3.0.4" @@ -6793,12 +7261,13 @@ "license": "MIT" }, "node_modules/dmg-builder": { - "version": "24.9.1", + "version": "24.12.0", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.12.0.tgz", + "integrity": "sha512-nS22OyHUIYcK40UnILOtqC5Qffd1SN1Ljqy/6e+QR2H1wM3iNBrKJoEbDRfEmYYaALKNFRkKPqSbZKRsGUBdPw==", "dev": true, - "license": "MIT", "dependencies": { - "app-builder-lib": "24.9.1", - "builder-util": "24.8.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", @@ -6810,8 +7279,9 @@ }, "node_modules/dmg-builder/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, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -6821,6 +7291,32 @@ "node": ">=12" } }, + "node_modules/dmg-license": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz", + "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "@types/plist": "^3.0.1", + "@types/verror": "^1.10.3", + "ajv": "^6.10.0", + "crc": "^3.8.0", + "iconv-corefoundation": "^1.1.7", + "plist": "^3.0.4", + "smart-buffer": "^4.0.2", + "verror": "^1.10.0" + }, + "bin": { + "dmg-license": "bin/dmg-license.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/dns-equal": { "version": "1.0.0", "dev": true, @@ -6957,16 +7453,18 @@ }, "node_modules/dotenv": { "version": "9.0.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", + "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=10" } }, "node_modules/dotenv-expand": { "version": "5.1.0", - "dev": true, - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", + "dev": true }, "node_modules/duplexer": { "version": "0.1.2", @@ -6992,8 +7490,9 @@ }, "node_modules/ejs": { "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "jake": "^10.8.5" }, @@ -7005,10 +7504,11 @@ } }, "node_modules/electron": { - "version": "28.2.1", + "version": "28.2.4", + "resolved": "https://registry.npmjs.org/electron/-/electron-28.2.4.tgz", + "integrity": "sha512-XrSsqKCmpGwz1pqzmdLhdGonYvatDXor60rBd+TfURMQQRSxyTaSwrds9kV0aab9YRpeYUH6NJDAOwBhQYDDkA==", "dev": true, "hasInstallScript": true, - "license": "MIT", "dependencies": { "@electron/get": "^2.0.0", "@types/node": "^18.11.18", @@ -7022,15 +7522,16 @@ } }, "node_modules/electron-builder": { - "version": "24.9.1", + "version": "24.12.0", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-24.12.0.tgz", + "integrity": "sha512-dH4O9zkxFxFbBVFobIR5FA71yJ1TZSCvjZ2maCskpg7CWjBF+SNRSQAThlDyUfRuB+jBTMwEMzwARywmap0CSw==", "dev": true, - "license": "MIT", "dependencies": { - "app-builder-lib": "24.9.1", - "builder-util": "24.8.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.9.1", + "dmg-builder": "24.12.0", "fs-extra": "^10.1.0", "is-ci": "^3.0.0", "lazy-val": "^1.0.5", @@ -7118,12 +7619,13 @@ "license": "MIT" }, "node_modules/electron-publish": { - "version": "24.8.1", + "version": "24.9.4", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.9.4.tgz", + "integrity": "sha512-FghbeVMfxHneHjsG2xUSC0NMZYWOOWhBxfZKPTbibcJ0CjPH0Ph8yb5CUO62nqywXfA5u1Otq6K8eOdOixxmNg==", "dev": true, - "license": "MIT", "dependencies": { "@types/fs-extra": "^9.0.11", - "builder-util": "24.8.1", + "builder-util": "24.9.4", "builder-util-runtime": "9.2.3", "chalk": "^4.1.2", "fs-extra": "^10.1.0", @@ -7133,8 +7635,9 @@ }, "node_modules/electron-publish/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, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -7161,8 +7664,9 @@ "license": "ISC" }, "node_modules/electron-updater": { - "version": "6.1.7", - "license": "MIT", + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.1.8.tgz", + "integrity": "sha512-hhOTfaFAd6wRHAfUaBhnAOYc+ymSGCWJLtFkw4xJqOvtpHmIdNHnXDV9m1MHC+A6q08Abx4Ykgyz/R5DGKNAMQ==", "dependencies": { "builder-util-runtime": "9.2.3", "fs-extra": "^10.1.0", @@ -7187,9 +7691,13 @@ } }, "node_modules/electron/node_modules/@types/node": { - "version": "18.15.11", + "version": "18.19.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.18.tgz", + "integrity": "sha512-80CP7B8y4PzZF0GWx15/gVWRrB5y/bIjNI84NK3cmQJu0WZwvmj2WMA5LcofQFVfLqqCSp545+U2LsrVzX36Zg==", "dev": true, - "license": "MIT" + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/electronmon": { "version": "2.0.2", @@ -7476,10 +7984,11 @@ "license": "MIT" }, "node_modules/esbuild": { - "version": "0.20.0", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.1.tgz", + "integrity": "sha512-OJwEgrpWm/PCMsLVWXKqvcjme3bHNpOgN7Tb6cQnR5n0TPbQx1/Xrn7rqM+wn17bYeT6MGB5sn1Bh5YiGi70nA==", "dev": true, "hasInstallScript": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -7487,29 +7996,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.0", - "@esbuild/android-arm": "0.20.0", - "@esbuild/android-arm64": "0.20.0", - "@esbuild/android-x64": "0.20.0", - "@esbuild/darwin-arm64": "0.20.0", - "@esbuild/darwin-x64": "0.20.0", - "@esbuild/freebsd-arm64": "0.20.0", - "@esbuild/freebsd-x64": "0.20.0", - "@esbuild/linux-arm": "0.20.0", - "@esbuild/linux-arm64": "0.20.0", - "@esbuild/linux-ia32": "0.20.0", - "@esbuild/linux-loong64": "0.20.0", - "@esbuild/linux-mips64el": "0.20.0", - "@esbuild/linux-ppc64": "0.20.0", - "@esbuild/linux-riscv64": "0.20.0", - "@esbuild/linux-s390x": "0.20.0", - "@esbuild/linux-x64": "0.20.0", - "@esbuild/netbsd-x64": "0.20.0", - "@esbuild/openbsd-x64": "0.20.0", - "@esbuild/sunos-x64": "0.20.0", - "@esbuild/win32-arm64": "0.20.0", - "@esbuild/win32-ia32": "0.20.0", - "@esbuild/win32-x64": "0.20.0" + "@esbuild/aix-ppc64": "0.20.1", + "@esbuild/android-arm": "0.20.1", + "@esbuild/android-arm64": "0.20.1", + "@esbuild/android-x64": "0.20.1", + "@esbuild/darwin-arm64": "0.20.1", + "@esbuild/darwin-x64": "0.20.1", + "@esbuild/freebsd-arm64": "0.20.1", + "@esbuild/freebsd-x64": "0.20.1", + "@esbuild/linux-arm": "0.20.1", + "@esbuild/linux-arm64": "0.20.1", + "@esbuild/linux-ia32": "0.20.1", + "@esbuild/linux-loong64": "0.20.1", + "@esbuild/linux-mips64el": "0.20.1", + "@esbuild/linux-ppc64": "0.20.1", + "@esbuild/linux-riscv64": "0.20.1", + "@esbuild/linux-s390x": "0.20.1", + "@esbuild/linux-x64": "0.20.1", + "@esbuild/netbsd-x64": "0.20.1", + "@esbuild/openbsd-x64": "0.20.1", + "@esbuild/sunos-x64": "0.20.1", + "@esbuild/win32-arm64": "0.20.1", + "@esbuild/win32-ia32": "0.20.1", + "@esbuild/win32-x64": "0.20.1" } }, "node_modules/esbuild-register": { @@ -8727,6 +9236,16 @@ "@types/yauzl": "^2.9.1" } }, + "node_modules/extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "optional": true + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "license": "MIT" @@ -8866,24 +9385,27 @@ }, "node_modules/filelist": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "dev": true, - "license": "Apache-2.0", "dependencies": { "minimatch": "^5.0.1" } }, "node_modules/filelist/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, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/filelist/node_modules/minimatch": { "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -9046,8 +9568,9 @@ }, "node_modules/form-data": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, - "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -9097,9 +9620,9 @@ } }, "node_modules/framer-motion": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.0.3.tgz", - "integrity": "sha512-6x2poQpIWBdbZwLd73w6cKZ1I9IEPIU94C6/Swp1Zt3LJ+sB5bPe1E2wC6EH5hSISXNkMJ4afH7AdwS7MrtkWw==", + "version": "11.0.6", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.0.6.tgz", + "integrity": "sha512-BpO3mWF8UwxzO3Ca5AmSkrg14QYTeJa9vKgoLOoBdBdTPj0e81i1dMwnX6EQJXRieUx20uiDBXq8bA6y7N6b8Q==", "dependencies": { "tslib": "^2.4.0" }, @@ -9657,8 +10180,9 @@ }, "node_modules/hosted-git-info": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -9937,6 +10461,55 @@ "ms": "^2.0.0" } }, + "node_modules/iconv-corefoundation": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", + "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "cli-truncate": "^2.1.0", + "node-addon-api": "^1.6.3" + }, + "engines": { + "node": "^8.11.2 || >=10" + } + }, + "node_modules/iconv-corefoundation/node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "optional": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/iconv-corefoundation/node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "optional": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "dev": true, @@ -10245,8 +10818,9 @@ }, "node_modules/is-ci": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", "dev": true, - "license": "MIT", "dependencies": { "ci-info": "^3.2.0" }, @@ -10630,11 +11204,12 @@ "license": "MIT" }, "node_modules/isbinaryfile": { - "version": "5.0.0", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz", + "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==", "dev": true, - "license": "MIT", "engines": { - "node": ">= 14.0.0" + "node": ">= 18.0.0" }, "funding": { "url": "https://github.com/sponsors/gjtorikian/" @@ -10764,8 +11339,9 @@ }, "node_modules/jake": { "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", "dev": true, - "license": "Apache-2.0", "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", @@ -12845,8 +13421,9 @@ }, "node_modules/mime": { "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true, - "license": "MIT", "bin": { "mime": "cli.js" }, @@ -13175,8 +13752,9 @@ } }, "node_modules/node-abi": { - "version": "3.54.0", - "license": "MIT", + "version": "3.56.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.56.0.tgz", + "integrity": "sha512-fZjdhDOeRcaS+rcpve7XuwHBmktS1nS1gzgghwKUQQ8nTy2FdSDr6ZT8k6YhvlJeHmmQMYiT/IH9hfco5zeW2Q==", "dependencies": { "semver": "^7.3.5" }, @@ -13184,6 +13762,13 @@ "node": ">=10" } }, + "node_modules/node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "dev": true, + "optional": true + }, "node_modules/node-api-version": { "version": "0.2.0", "dev": true, @@ -14005,8 +14590,9 @@ }, "node_modules/plist": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", "dev": true, - "license": "MIT", "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", @@ -15277,11 +15863,11 @@ } }, "node_modules/react-router": { - "version": "6.21.3", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.21.3.tgz", - "integrity": "sha512-a0H638ZXULv1OdkmiK6s6itNhoy33ywxmUFT/xtSoVyf9VnC7n7+VT4LjVzdIHSaF5TIh9ylUgxMXksHTgGrKg==", + "version": "6.22.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.1.tgz", + "integrity": "sha512-0pdoRGwLtemnJqn1K0XHUbnKiX0S4X8CgvVVmHGOWmofESj31msHo/1YiqcJWK7Wxfq2a4uvvtS01KAQyWK/CQ==", "dependencies": { - "@remix-run/router": "1.14.2" + "@remix-run/router": "1.15.1" }, "engines": { "node": ">=14.0.0" @@ -15291,12 +15877,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.21.3", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.21.3.tgz", - "integrity": "sha512-kNzubk7n4YHSrErzjLK72j0B5i969GsuCGazRl3G6j1zqZBLjuSlYBdVdkDOgzGdPIffUOc9nmgiadTEVoq91g==", + "version": "6.22.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.1.tgz", + "integrity": "sha512-iwMyyyrbL7zkKY7MRjOVRy+TMnS/OPusaFVxM2P11x9dzSzGmLsebkCvYirGq0DWB9K9hOspHYYtDz33gE5Duw==", "dependencies": { - "@remix-run/router": "1.14.2", - "react-router": "6.21.3" + "@remix-run/router": "1.15.1", + "react-router": "6.22.1" }, "engines": { "node": ">=14.0.0" @@ -15337,9 +15923,9 @@ "license": "MIT" }, "node_modules/react-virtualized-auto-sizer": { - "version": "1.0.21", - "resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.21.tgz", - "integrity": "sha512-RedZxj452+ITLfqIrR02BjvCaXV63YVIcVrvmruDZXFpJGazg4gHNs1AShPGVLvEuLGZdZ9AtkGKhWvzEujL8g==", + "version": "1.0.23", + "resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.23.tgz", + "integrity": "sha512-5id3UTx+fG7b7SIOKL9/7aR1vP8+MtIT84cJCf09F6pYalB/nvHlx5EQvsSk27SwHUKjgPamG/nS8ynI0uSfKA==", "peerDependencies": { "react": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0", "react-dom": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0" @@ -15388,8 +15974,9 @@ }, "node_modules/read-config-file": { "version": "6.3.2", + "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.3.2.tgz", + "integrity": "sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q==", "dev": true, - "license": "MIT", "dependencies": { "config-file-ts": "^0.2.4", "dotenv": "^9.0.2", @@ -16036,8 +16623,9 @@ } }, "node_modules/semver": { - "version": "7.5.4", - "license": "ISC", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -16575,8 +17163,9 @@ }, "node_modules/stat-mode": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", + "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 6" } @@ -17039,9 +17628,10 @@ } }, "node_modules/tailwind-scrollbar": { - "version": "3.0.5", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tailwind-scrollbar/-/tailwind-scrollbar-3.1.0.tgz", + "integrity": "sha512-pmrtDIZeHyu2idTejfV59SbaJyvp1VRjYxAjZBH0jnyrPRo6HL1kD5Glz8VPagasqr6oAx6M05+Tuw429Z8jxg==", "dev": true, - "license": "MIT", "engines": { "node": ">=12.13.0" }, @@ -17204,8 +17794,9 @@ }, "node_modules/temp-file": { "version": "3.4.0", + "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", + "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==", "dev": true, - "license": "MIT", "dependencies": { "async-exit-hook": "^2.0.1", "fs-extra": "^10.0.0" @@ -17213,8 +17804,9 @@ }, "node_modules/temp-file/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, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -17342,8 +17934,9 @@ }, "node_modules/tmp-promise": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", "dev": true, - "license": "MIT", "dependencies": { "tmp": "^0.2.0" } @@ -18007,6 +18600,28 @@ "node": ">= 0.8" } }, + "node_modules/verror": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", + "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", + "dev": true, + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true, + "optional": true + }, "node_modules/walker": { "version": "1.0.8", "dev": true, @@ -18074,9 +18689,10 @@ } }, "node_modules/webpack": { - "version": "5.90.0", + "version": "5.90.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", + "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", "dev": true, - "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", @@ -18699,8 +19315,9 @@ }, "node_modules/xmlbuilder": { "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.0" } diff --git a/package.json b/package.json index d7a2f6c2..02badae0 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "description": "Manage maps, mods and more for Beat Saber", "main": "./src/main/main.ts", "scripts": { + "build-rust-scripts": "node -r esbuild-register ./.erb/scripts/build-rust-scripts.js", "build": "concurrently \"npm run build:main\" \"npm run build:renderer\"", "build:dll": "cross-env NODE_ENV=development webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.ts", "build:main": "cross-env NODE_ENV=production webpack --config ./.erb/configs/webpack.config.main.prod.ts", @@ -159,7 +160,7 @@ }, "devDependencies": { "@electron/fuses": "^1.7.0", - "@electron/notarize": "^2.2.1", + "@electron/notarize": "^2.3.0", "@electron/rebuild": "^3.6.0", "@pmmmwh/react-refresh-webpack-plugin": "0.5.5", "@teamsupercell/typings-for-css-modules-loader": "^2.5.2", @@ -193,16 +194,16 @@ "browserslist-config-erb": "^0.0.3", "chalk": "^4.1.2", "concurrently": "^8.2.2", - "core-js": "^3.35.1", + "core-js": "^3.36.0", "cross-env": "^7.0.3", "css-loader": "^6.10.0", "css-minimizer-webpack-plugin": "^6.0.0", "detect-port": "^1.5.1", - "electron": "^28.2.1", - "electron-builder": "^24.9.1", + "electron": "^28.2.4", + "electron-builder": "^24.12.0", "electron-devtools-installer": "^3.2.0", "electronmon": "^2.0.2", - "esbuild": "^0.20.0", + "esbuild": "^0.20.1", "esbuild-register": "^3.5.0", "eslint": "^8.56.0", "eslint-config-airbnb-base": "^15.0.0", @@ -233,14 +234,14 @@ "sass": "^1.70.0", "sass-loader": "^14.1.0", "style-loader": "^3.3.4", - "tailwind-scrollbar": "^3.0.5", + "tailwind-scrollbar": "^3.1.0", "tailwindcss": "^3.4.1", "terser-webpack-plugin": "^5.3.10", "ts-jest": "^29.1.2", "ts-loader": "^9.5.1", "typescript": "^5.3.3", "url-loader": "^4.1.1", - "webpack": "^5.90.0", + "webpack": "^5.90.3", "webpack-bundle-analyzer": "^4.10.1", "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.15.1", @@ -253,21 +254,21 @@ "color": "^4.2.3", "crypto-js": "^4.2.0", "dateformat": "^5.0.3", - "dompurify": "^3.0.8", + "dompurify": "^3.0.9", "dot-prop": "^8.0.2", "electron-debug": "^3.2.0", "electron-log": "^4.4.8", "electron-store": "^8.1.0", - "electron-updater": "^6.1.7", + "electron-updater": "^6.1.8", "fast-deep-equal": "^3.1.3", - "framer-motion": "^11.0.3", + "framer-motion": "^11.0.6", "fs-extra": "^11.2.0", "got": "^14.2.0", "history": "^5.3.0", "is-elevated": "^4.0.0", "jszip": "^3.10.1", "md5-file": "^5.0.0", - "node-abi": "^3.54.0", + "node-abi": "^3.56.0", "node-fetch": "^3.3.2", "node-stream-zip": "^1.15.0", "pako": "^2.1.0", @@ -278,14 +279,14 @@ "react-colorful": "^5.6.1", "react-dom": "^18.2.0", "react-range": "^1.8.14", - "react-router-dom": "^6.21.3", - "react-virtualized-auto-sizer": "^1.0.21", + "react-router-dom": "^6.22.1", + "react-virtualized-auto-sizer": "^1.0.23", "react-window": "^1.8.10", "recursive-readdir": "^2.2.3", "rfdc": "^1.3.1", "rxjs": "^7.8.1", "sanitize-filename": "^1.6.3", - "semver": "^7.5.4", + "semver": "^7.6.0", "serialize-error": "^11.0.3", "striptags": "^4.0.0-alpha.4", "tailwind-scrollbar-hide": "^1.1.7", diff --git a/release/app/package-lock.json b/release/app/package-lock.json index 48e52adf..5d6f063b 100644 --- a/release/app/package-lock.json +++ b/release/app/package-lock.json @@ -1,12 +1,12 @@ { "name": "bs-manager", - "version": "1.4.4", + "version": "1.5.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "bs-manager", - "version": "1.4.4", + "version": "1.5.0", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/release/app/package.json b/release/app/package.json index 242c90e1..8434da43 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -19,5 +19,8 @@ "regedit-rs": "^1.0.2", "sharp": "^0.33.2" }, - "license": "MIT" + "license": "MIT", + "volta": { + "node": "20.11.0" + } } diff --git a/src/main/ipcs/bs-launcher-ipcs.ts b/src/main/ipcs/bs-launcher-ipcs.ts index 53614fb1..8f70af62 100644 --- a/src/main/ipcs/bs-launcher-ipcs.ts +++ b/src/main/ipcs/bs-launcher-ipcs.ts @@ -36,10 +36,3 @@ ipc.on("bs-launch.restore-steamvr", (_, reply) => { const steamLauncher = SteamLauncherService.getInstance(); reply(from(steamLauncher.restoreSteamVR())); }); - -ipc.on("restore-original-oculus-folder", (_, reply) => { - const oculusLauncher = OculusLauncherService.getInstance(); - reply(from( - oculusLauncher.deleteBsSymlinks().then(() => oculusLauncher.restoreOriginalBeatSaber()) - )); -}); diff --git a/src/main/services/bs-launcher/abstract-launcher.service.ts b/src/main/services/bs-launcher/abstract-launcher.service.ts index 86c0c0c3..b5827999 100644 --- a/src/main/services/bs-launcher/abstract-launcher.service.ts +++ b/src/main/services/bs-launcher/abstract-launcher.service.ts @@ -5,9 +5,9 @@ import path from "path"; import log from "electron-log"; export abstract class AbstractLauncherService { - + protected readonly localVersions = BSLocalVersionService.getInstance(); - + constructor(){ this.localVersions = BSLocalVersionService.getInstance(); } @@ -46,18 +46,20 @@ export abstract class AbstractLauncherService { } - protected launchBs(bsExePath: string, args: string[], options?: SpawnOptionsWithoutStdio): Promise { - return new Promise((resolve, reject) => { - const bsProcess = this.launchBSProcess(bsExePath, args, options); + protected launchBs(bsExePath: string, args: string[], options?: SpawnOptionsWithoutStdio): {process: ChildProcessWithoutNullStreams, exit: Promise} { + const process = this.launchBSProcess(bsExePath, args, options); - bsProcess.on("error", reject); - bsProcess.on("exit", resolve); - - setTimeout(() => { - bsProcess.removeAllListeners("error"); - bsProcess.removeAllListeners("exit"); - resolve(-1); - }, 30_000); + const exit = new Promise((resolve, reject) => { + process.on("error", (err) => { + log.error(`Error while launching BS`, err); + reject(err); + }); + process.on("exit", (code) => { + log.info(`BS process exit with code ${code}`); + resolve(code); + }); }); + + return { process, exit }; } -} \ No newline at end of file +} diff --git a/src/main/services/bs-launcher/oculus-launcher.service.ts b/src/main/services/bs-launcher/oculus-launcher.service.ts index d6edc3ed..89678809 100644 --- a/src/main/services/bs-launcher/oculus-launcher.service.ts +++ b/src/main/services/bs-launcher/oculus-launcher.service.ts @@ -12,6 +12,9 @@ import { taskRunning } from "../../helpers/os.helpers"; import { CustomError } from "../../../shared/models/exceptions/custom-error.class"; import { InstallationLocationService } from "../installation-location.service"; import { ensurePathNotAlreadyExist } from "../../helpers/fs.helpers"; +import { UtilsService } from "../utils.service"; +import { spawn } from "child_process"; +import { tryit } from "../../../shared/helpers/error.helpers"; export class OculusLauncherService extends AbstractLauncherService implements StoreLauncherInterface { @@ -26,6 +29,7 @@ export class OculusLauncherService extends AbstractLauncherService implements St private readonly oculus: OculusService; private readonly pathsService: InstallationLocationService; + private readonly util: UtilsService; private readonly oculusLib$ = new ReplaySubject(); @@ -33,6 +37,7 @@ export class OculusLauncherService extends AbstractLauncherService implements St super(); this.oculus = OculusService.getInstance(); this.pathsService = InstallationLocationService.getInstance(); + this.util = UtilsService.getInstance(); this.oculus.tryGetGameFolder([OCULUS_BS_DIR, OCULUS_BS_BACKUP_DIR]).then(async dirPath => { if(dirPath){ @@ -100,6 +105,15 @@ export class OculusLauncherService extends AbstractLauncherService implements St return rename(bsFolderBackupPath, originalPath); } + private launchSymlinkCleaner(pid: number, symlinkPath: string){ + + log.info("Launch Symlink Cleaner", pid, symlinkPath); + + const exeName = "oculus_symlink_cleaner.exe"; + const scriptPath = this.util.getAssetsScriptsPath(); + spawn(path.join(scriptPath, exeName), [`${pid}`, symlinkPath], { detached: true, stdio: "ignore" }); + } + public launch(launchOptions: LaunchOption): Observable { const prepareOriginalVersion: () => Promise = async () => { @@ -157,7 +171,16 @@ export class OculusLauncherService extends AbstractLauncherService implements St obs.next({type: BSLaunchEvent.BS_LAUNCHING}); // Launch Beat Saber - return this.launchBs(exePath, this.buildBsLaunchArgs(launchOptions)).catch(err => { + const process = this.launchBs(exePath, this.buildBsLaunchArgs(launchOptions)); + + if(launchOptions.version.oculus !== true && process?.process?.pid){ + const { error } = tryit(() => this.launchSymlinkCleaner(process.process.pid, bsPath)); + if(error){ + log.error("Error while launching symlink cleaner", error); + } + } + + return process.exit.catch(err => { throw CustomError.fromError(err, BSLaunchError.BS_EXIT_ERROR); }); diff --git a/src/main/services/bs-launcher/steam-launcher.service.ts b/src/main/services/bs-launcher/steam-launcher.service.ts index b0d18a63..a9d1c76c 100644 --- a/src/main/services/bs-launcher/steam-launcher.service.ts +++ b/src/main/services/bs-launcher/steam-launcher.service.ts @@ -107,7 +107,7 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto obs.next({type: BSLaunchEvent.BS_LAUNCHING}); const launchPromise = !launchOptions.admin ? ( - this.launchBs(exePath, launchArgs, { env: {...process.env, "SteamAppId": BS_APP_ID} }) + this.launchBs(exePath, launchArgs, { env: {...process.env, "SteamAppId": BS_APP_ID} }).exit ) : ( new Promise(resolve => { const adminProcess = exec(`"${this.getStartBsAsAdminExePath()}" "${exePath}" ${launchArgs.join(" ")}`, { env: {...process.env, "SteamAppId": BS_APP_ID} }); @@ -123,13 +123,16 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto }) ); - await launchPromise.then(exitCode => { + try { + const exitCode = await launchPromise; log.info("BS process exit code", exitCode); - }).catch(err => { + } + catch(err: any) { throw CustomError.fromError(err, BSLaunchError.BS_EXIT_ERROR); - }).finally(() => { - this.restoreSteamVR().catch(log.error); - }); + } + finally { + await this.restoreSteamVR().catch(log.error); + } })().then(() => { obs.complete(); diff --git a/src/main/services/installation-location.service.ts b/src/main/services/installation-location.service.ts index 26cad983..ee0b52e6 100644 --- a/src/main/services/installation-location.service.ts +++ b/src/main/services/installation-location.service.ts @@ -1,7 +1,8 @@ import path from "path"; import { app } from "electron"; import ElectronStore from "electron-store"; -import { copyDirectoryWithJunctions, deleteFolder, ensureFolderExist } from "../helpers/fs.helpers"; +import { copyDirectoryWithJunctions, deleteFolder, ensureFolderExist, pathExist } from "../helpers/fs.helpers"; +import { tryit } from "../../shared/helpers/error.helpers"; import { pathExistsSync } from "fs-extra"; export class InstallationLocationService { @@ -69,8 +70,8 @@ export class InstallationLocationService { return this.installPathConfig.get(this.STORE_INSTALLATION_PATH_KEY) as string; } - const oldPath = path.join(app.getPath("documents"), this.INSTALLATION_FOLDER); - if(pathExistsSync(oldPath)){ + const { result: oldPath } = tryit(() => path.join(app.getPath("documents"), this.INSTALLATION_FOLDER)); + if(oldPath && pathExistsSync(oldPath)){ return app.getPath("documents"); } diff --git a/src/renderer/components/maps-playlists-panel/maps/filter-panel.component.tsx b/src/renderer/components/maps-playlists-panel/maps/filter-panel.component.tsx index 7c09a4d6..70326fc7 100644 --- a/src/renderer/components/maps-playlists-panel/maps/filter-panel.component.tsx +++ b/src/renderer/components/maps-playlists-panel/maps/filter-panel.component.tsx @@ -11,6 +11,7 @@ import { useTranslation } from "renderer/hooks/use-translation.hook"; import { MAP_SPECIFICITIES } from "renderer/partials/maps/map-general/map-specificity"; import { MAP_REQUIREMENTS } from "renderer/partials/maps/map-requirements/map-requirements"; import { MAP_DIFFICULTIES_COLORS } from "renderer/partials/maps/map-difficulties/map-difficulties-colors"; +import { MapExclude, MAP_EXCLUDES } from "renderer/partials/maps/map-excludes/map-excludes"; import { BsmButton } from "../../shared/bsm-button.component"; import equal from "fast-deep-equal/es6"; import clone from "rfdc"; @@ -21,12 +22,13 @@ export type Props = { ref?: MutableRefObject; playlist?: boolean; filter: MapFilter; + localData?: boolean; onChange?: (filter: MapFilter) => void; onApply?: (filter: MapFilter) => void; onClose?: (filter: MapFilter) => void; }; -export function FilterPanel({ className, ref, playlist = false, filter, onChange, onApply, onClose }: Props) { +export function FilterPanel({ className, ref, playlist = false, filter, localData = true, onChange, onApply, onClose }: Props) { const t = useTranslation(); const [haveChanged, setHaveChanged] = useState(false); @@ -147,6 +149,10 @@ export function FilterPanel({ className, ref, playlist = false, filter, onChange return t(`maps.map-specificities.${specificity}`); }; + const translateMapExclude = (exclude: MapExclude): string => { + return t(`maps.map-excludes.${exclude}`); + }; + type BooleanKeys = { [k in keyof T]: T[k] extends boolean ? k : never }[keyof T]; const handleCheckbox = (key: BooleanKeys) => { @@ -189,6 +195,17 @@ export function FilterPanel({ className, ref, playlist = false, filter, onChange {requirement} ))} + { !localData && ( + <> +

{t("maps.map-filter-panel.exclude")}

+ {MAP_EXCLUDES.map(exclude => ( +
handleCheckbox(exclude)}> + handleCheckbox(exclude)} /> + {translateMapExclude(exclude)} +
+ ))} + + )}

{t("maps.map-filter-panel.tags")}

diff --git a/src/renderer/components/modal/modal-types/download-maps-modal.component.tsx b/src/renderer/components/modal/modal-types/download-maps-modal.component.tsx index fce1d1eb..3ed27f68 100644 --- a/src/renderer/components/modal/modal-types/download-maps-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/download-maps-modal.component.tsx @@ -77,12 +77,48 @@ export const DownloadMapsModal: ModalComponent { + const applyInstalledFilter = (maps: BsvMapDetail[]): BsvMapDetail[] => { + return maps.filter(map => { + if (!filter.installed) { + return true; + } + + return !map.versions.some(version => ownedMapHashs.includes(version.hash)); + }); + } + + const loadMaps = (params: SearchParams, tryToLoad = 5) => { setLoading(() => true); - beatSaver - .searchMaps(params) - .then(maps => setMaps(prev => [...prev, ...maps])) - .finally(() => setLoading(() => false)); + + const searchResult = beatSaver.searchMaps(params); + + if (!filter.installed) { + searchResult + .then(maps => setMaps(prev => [...prev, ...maps])) + .finally(() => setLoading(() => false)); + + return; + } + + searchResult + .then(maps => { + if (!maps.length) { + setLoading(() => false); + + return; + } + + maps = applyInstalledFilter(maps); + setMaps(prev => [...prev, ...maps]) + + if (maps.length < tryToLoad) { + handleLoadMore(); + + return; + } + + setLoading(() => false); + }) }; const renderMap = (map: BsvMapDetail) => { @@ -155,7 +191,7 @@ export const DownloadMapsModal: ModalComponent
- filterContainerRef.current.close()} /> + filterContainerRef.current.close()} /> setQuery(e.target.value)} /> = (

{t("modals.original-version-backup-oculus.title")}

- +

{t("modals.original-version-backup-oculus.body.must-be-installed-once")}

-

{t("modals.original-version-backup-oculus.body.need-backup")}

-

{t("modals.original-version-backup-oculus.body.can-restore-later")}

-

{t("modals.original-version-backup-oculus.body.tips-launch-oculus")}

+

{t("modals.original-version-backup-oculus.body.will-backup")}

diff --git a/src/renderer/pages/version-viewer.component.tsx b/src/renderer/pages/version-viewer.component.tsx index dc1282c0..f250da0f 100644 --- a/src/renderer/pages/version-viewer.component.tsx +++ b/src/renderer/pages/version-viewer.component.tsx @@ -99,20 +99,6 @@ export function VersionViewer() { }); } - const restoreOriginalOculusFolder = () => { - lastValueFrom(ipcService.sendV2("restore-original-oculus-folder")).then(() => { - notification.notifySuccess({ - title: "Restauration réussie", - desc: "Le dossier a été restauré avec succès" - }); - }).catch(() => { - notification.notifyError({ - title: "Erreur lors de la restauration", - desc: "Le dossier n'a pas pu être restauré" - }); - }); - } - return ( <> @@ -131,7 +117,6 @@ export function VersionViewer() {