From c6e4ba4789b79cf6ceb87739405c40ab8cb062d9 Mon Sep 17 00:00:00 2001 From: lilezek Date: Mon, 29 Apr 2024 20:44:14 +0200 Subject: [PATCH 01/52] feat: add the dependencies for real debrid --- package.json | 4 +++ yarn.lock | 69 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index b8396713..64021f00 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "@reduxjs/toolkit": "^2.2.2", "@sentry/electron": "^4.22.0", "@sentry/react": "^7.110.1", + "@types/node-fetch": "^2.6.11", "@vanilla-extract/css": "^1.14.1", "@vanilla-extract/recipes": "^0.5.2", "axios": "^1.6.8", @@ -80,6 +81,7 @@ "color": "^4.2.3", "color.js": "^1.2.0", "date-fns": "^3.5.0", + "electron-dl-manager": "^3.0.0", "electron-squirrel-startup": "^1.0.0", "flexsearch": "^0.7.43", "got-scraping": "^4.0.5", @@ -88,6 +90,8 @@ "jsdom": "^24.0.0", "lodash": "^4.17.21", "lottie-react": "^2.4.0", + "node-fetch": "^2.6.1", + "node-unrar-js": "^2.0.2", "parse-torrent": "9.1.5", "ps-list": "^8.1.1", "react": "^18.2.0", diff --git a/yarn.lock b/yarn.lock index 78c336e0..b4bac2e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2877,6 +2877,14 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== +"@types/node-fetch@^2.6.11": + version "2.6.11" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" + integrity sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g== + dependencies: + "@types/node" "*" + form-data "^4.0.0" + "@types/node-forge@^1.3.0": version "1.3.11" resolved "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz" @@ -4974,6 +4982,14 @@ ee-first@1.1.1: resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== +electron-dl-manager@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/electron-dl-manager/-/electron-dl-manager-3.0.0.tgz#1b6ef6ee59f45733a5f13e8e916cb8189a21f8c8" + integrity sha512-DRyic9aY/6mSg7MvokrFWWY+NLYOnZcKGarujcBE4snobWND0hvV79s9b91kbo7+PLlANroK+jc/NDVliMSfbQ== + dependencies: + ext-name "^5.0.0" + unused-filename "^3.0.1" + electron-installer-common@^0.10.2: version "0.10.3" resolved "https://registry.yarnpkg.com/electron-installer-common/-/electron-installer-common-0.10.3.tgz#40f9db644ca60eb28673d545b67ee0113aef4444" @@ -5768,6 +5784,21 @@ express@^4.17.1, express@^4.17.3: utils-merge "1.0.1" vary "~1.1.2" +ext-list@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" + integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA== + dependencies: + mime-db "^1.28.0" + +ext-name@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-5.0.0.tgz#70781981d183ee15d13993c8822045c506c8f0a6" + integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ== + dependencies: + ext-list "^2.0.0" + sort-keys-length "^1.0.0" + ext@^1.7.0: version "1.7.0" resolved "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz" @@ -7041,6 +7072,11 @@ is-path-inside@^3.0.3: resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== + is-plain-obj@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz" @@ -7756,7 +7792,7 @@ micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" -mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2", mime-db@^1.28.0: version "1.52.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== @@ -8064,9 +8100,9 @@ node-dir@^0.1.17: dependencies: minimatch "^3.0.2" -node-fetch@^2.6.7: +node-fetch@^2.6.1, node-fetch@^2.6.7: version "2.7.0" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" @@ -8121,6 +8157,11 @@ node-releases@^2.0.14: resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz" integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== +node-unrar-js@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-unrar-js/-/node-unrar-js-2.0.2.tgz#03ef602052497263b9aed8ff1e7afb315024f9ec" + integrity sha512-hLNmoJzqaKJnod8yiTVGe9hnlNRHotUi0CreSv/8HtfRi/3JnRC8DvsmKfeGGguRjTEulhZK6zXX5PXoVuDZ2w== + nopt@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz" @@ -9724,6 +9765,20 @@ socks@^2.6.2: ip-address "^9.0.5" smart-buffer "^4.2.0" +sort-keys-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" + integrity sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw== + dependencies: + sort-keys "^1.0.0" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg== + dependencies: + is-plain-obj "^1.0.0" + source-map-js@^1.0.1, source-map-js@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz" @@ -10536,6 +10591,14 @@ unplugin@1.0.1: webpack-sources "^3.2.3" webpack-virtual-modules "^0.5.0" +unused-filename@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/unused-filename/-/unused-filename-3.0.1.tgz#41b0600f8909e39cbdbbcf2467591bd3dd83fa7b" + integrity sha512-UbMRaEaT+/3mGh40GBRnF2++1VqFG1w0Kjzd5q/uQjagKn5pkCS8goJTgYDpQ6e0tB2GywamMJy1BzbSrMcIWw== + dependencies: + escape-string-regexp "^4.0.0" + path-exists "^4.0.0" + update-browserslist-db@^1.0.13: version "1.0.13" resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz" From 6fa4c178a77b8e2b8127264c05e51fd4dac87033 Mon Sep 17 00:00:00 2001 From: lilezek Date: Mon, 29 Apr 2024 20:50:10 +0200 Subject: [PATCH 02/52] refactor: moved the game status to a global file (accessible to the render part) and used it in game entity --- src/globals.ts | 10 ++++++++++ src/main/constants.ts | 9 --------- src/main/entity/game.entity.ts | 3 ++- src/main/events/library/get-library.ts | 2 +- src/main/events/torrenting/cancel-game-download.ts | 2 +- src/main/events/torrenting/delete-game-folder.ts | 2 +- src/main/events/torrenting/pause-game-download.ts | 2 +- .../events/torrenting/remove-game-from-download.ts | 2 +- src/main/events/torrenting/resume-game-download.ts | 2 +- src/main/events/torrenting/start-game-download.ts | 2 +- src/main/index.ts | 3 ++- src/types/index.ts | 4 +++- tsconfig.json | 3 ++- 13 files changed, 26 insertions(+), 20 deletions(-) create mode 100644 src/globals.ts diff --git a/src/globals.ts b/src/globals.ts new file mode 100644 index 00000000..e4675aa7 --- /dev/null +++ b/src/globals.ts @@ -0,0 +1,10 @@ +export enum GameStatus { + Seeding = "seeding", + Downloading = "downloading", + Paused = "paused", + CheckingFiles = "checking_files", + DownloadingMetadata = "downloading_metadata", + Cancelled = "cancelled", + Finished = "finished", + Decompressing = "decompressing", +} \ No newline at end of file diff --git a/src/main/constants.ts b/src/main/constants.ts index 43d9d44e..1a87c27b 100644 --- a/src/main/constants.ts +++ b/src/main/constants.ts @@ -34,15 +34,6 @@ export const months = [ "Dec", ]; -export enum GameStatus { - Seeding = "seeding", - Downloading = "downloading", - Paused = "paused", - CheckingFiles = "checking_files", - DownloadingMetadata = "downloading_metadata", - Cancelled = "cancelled", -} - export const defaultDownloadsPath = path.join(os.homedir(), "downloads"); export const databasePath = path.join( diff --git a/src/main/entity/game.entity.ts b/src/main/entity/game.entity.ts index 811ecf74..8798a15d 100644 --- a/src/main/entity/game.entity.ts +++ b/src/main/entity/game.entity.ts @@ -9,6 +9,7 @@ import { } from "typeorm"; import type { GameShop } from "@types"; import { Repack } from "./repack.entity"; +import { GameStatus } from "@globals"; @Entity("game") export class Game { @@ -40,7 +41,7 @@ export class Game { shop: GameShop; @Column("text", { nullable: true }) - status: string; + status: GameStatus | ""; @Column("float", { default: 0 }) progress: number; diff --git a/src/main/events/library/get-library.ts b/src/main/events/library/get-library.ts index c86d1902..047d848b 100644 --- a/src/main/events/library/get-library.ts +++ b/src/main/events/library/get-library.ts @@ -1,9 +1,9 @@ import { gameRepository } from "@main/repository"; -import { GameStatus } from "@main/constants"; import { searchRepacks } from "../helpers/search-games"; import { registerEvent } from "../register-event"; import sortBy from "lodash/sortBy"; +import { GameStatus } from "@globals"; const getLibrary = async (_event: Electron.IpcMainInvokeEvent) => gameRepository diff --git a/src/main/events/torrenting/cancel-game-download.ts b/src/main/events/torrenting/cancel-game-download.ts index a1a2e6b7..bcd4fdab 100644 --- a/src/main/events/torrenting/cancel-game-download.ts +++ b/src/main/events/torrenting/cancel-game-download.ts @@ -1,10 +1,10 @@ -import { GameStatus } from "@main/constants"; import { gameRepository } from "@main/repository"; import { registerEvent } from "../register-event"; import { WindowManager, writePipe } from "@main/services"; import { In } from "typeorm"; +import { GameStatus } from "@globals"; const cancelGameDownload = async ( _event: Electron.IpcMainInvokeEvent, diff --git a/src/main/events/torrenting/delete-game-folder.ts b/src/main/events/torrenting/delete-game-folder.ts index c8821415..e913a23a 100644 --- a/src/main/events/torrenting/delete-game-folder.ts +++ b/src/main/events/torrenting/delete-game-folder.ts @@ -1,7 +1,7 @@ import path from "node:path"; import fs from "node:fs"; -import { GameStatus } from "@main/constants"; +import { GameStatus } from "@globals"; import { gameRepository } from "@main/repository"; import { getDownloadsPath } from "../helpers/get-downloads-path"; diff --git a/src/main/events/torrenting/pause-game-download.ts b/src/main/events/torrenting/pause-game-download.ts index d89f2f72..e1da552a 100644 --- a/src/main/events/torrenting/pause-game-download.ts +++ b/src/main/events/torrenting/pause-game-download.ts @@ -1,9 +1,9 @@ import { WindowManager, writePipe } from "@main/services"; import { registerEvent } from "../register-event"; -import { GameStatus } from "../../constants"; import { gameRepository } from "../../repository"; import { In } from "typeorm"; +import { GameStatus } from "@globals"; const pauseGameDownload = async ( _event: Electron.IpcMainInvokeEvent, diff --git a/src/main/events/torrenting/remove-game-from-download.ts b/src/main/events/torrenting/remove-game-from-download.ts index 47c1ebe6..2ca608ef 100644 --- a/src/main/events/torrenting/remove-game-from-download.ts +++ b/src/main/events/torrenting/remove-game-from-download.ts @@ -1,4 +1,4 @@ -import { GameStatus } from "@main/constants"; +import { GameStatus } from "@globals"; import { gameRepository } from "@main/repository"; import { registerEvent } from "../register-event"; diff --git a/src/main/events/torrenting/resume-game-download.ts b/src/main/events/torrenting/resume-game-download.ts index c1e2e798..9d96ab18 100644 --- a/src/main/events/torrenting/resume-game-download.ts +++ b/src/main/events/torrenting/resume-game-download.ts @@ -1,9 +1,9 @@ import { registerEvent } from "../register-event"; -import { GameStatus } from "../../constants"; import { gameRepository } from "../../repository"; import { getDownloadsPath } from "../helpers/get-downloads-path"; import { In } from "typeorm"; import { writePipe } from "@main/services"; +import { GameStatus } from "@globals"; const resumeGameDownload = async ( _event: Electron.IpcMainInvokeEvent, diff --git a/src/main/events/torrenting/start-game-download.ts b/src/main/events/torrenting/start-game-download.ts index 1bdb1a6b..a5853208 100644 --- a/src/main/events/torrenting/start-game-download.ts +++ b/src/main/events/torrenting/start-game-download.ts @@ -1,12 +1,12 @@ import { getSteamGameIconUrl, writePipe } from "@main/services"; import { gameRepository, repackRepository } from "@main/repository"; -import { GameStatus } from "@main/constants"; import { registerEvent } from "../register-event"; import type { GameShop } from "@types"; import { getImageBase64 } from "@main/helpers"; import { In } from "typeorm"; +import { GameStatus } from "@globals"; const startGameDownload = async ( _event: Electron.IpcMainInvokeEvent, diff --git a/src/main/index.ts b/src/main/index.ts index 5637bbd3..1657540d 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -1,5 +1,5 @@ import { stateManager } from "./state-manager"; -import { GameStatus, repackers } from "./constants"; +import { repackers } from "./constants"; import { getNewGOGGames, getNewRepacksFromCPG, @@ -22,6 +22,7 @@ import { Repack } from "./entity"; import { Notification } from "electron"; import { t } from "i18next"; import { In } from "typeorm"; +import { GameStatus } from "@globals"; startProcessWatcher(); diff --git a/src/types/index.ts b/src/types/index.ts index 768f110b..d9070451 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,3 +1,5 @@ +import { GameStatus } from "@globals"; + export type GameShop = "steam" | "epic"; export type CatalogueCategory = "recently_added" | "trending"; @@ -75,7 +77,7 @@ export interface Game extends Omit { id: number; title: string; iconUrl: string; - status: string; + status: GameStatus | ""; folderName: string; downloadPath: string | null; repacks: GameRepack[]; diff --git a/tsconfig.json b/tsconfig.json index ee7e5c2b..aeb1de53 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,8 @@ "@main/*": ["src/main/*"], "@renderer/*": ["src/renderer/*"], "@types": ["src/types/index.ts"], - "@locales": ["src/locales/index.ts"] + "@locales": ["src/locales/index.ts"], + "@globals": ["src/globals.ts"] } }, "include": ["src/**/*"] From 3ef2f87412a93fcf54fe133614deb9f98a0ba7c9 Mon Sep 17 00:00:00 2001 From: lilezek Date: Mon, 29 Apr 2024 20:52:53 +0200 Subject: [PATCH 03/52] feat: added fields in entities to support rar decompression progress, and real debrid api token settings --- src/main/entity/game.entity.ts | 9 +++++++++ src/main/entity/user-preferences.entity.ts | 4 ++++ src/renderer/hooks/use-download.ts | 14 +++++++++----- src/renderer/pages/settings/settings.tsx | 10 ++++++++++ src/types/index.ts | 2 ++ 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/main/entity/game.entity.ts b/src/main/entity/game.entity.ts index 8798a15d..60daeb64 100644 --- a/src/main/entity/game.entity.ts +++ b/src/main/entity/game.entity.ts @@ -34,6 +34,9 @@ export class Game { @Column("text", { nullable: true }) executablePath: string | null; + @Column("text", { nullable: true }) + rarPath: string | null; + @Column("int", { default: 0 }) playTimeInMilliseconds: number; @@ -43,12 +46,18 @@ export class Game { @Column("text", { nullable: true }) status: GameStatus | ""; + /** + * Progress is a float between 0 and 1 + */ @Column("float", { default: 0 }) progress: number; @Column("float", { default: 0 }) fileVerificationProgress: number; + @Column("float", { default: 0 }) + decompressionProgress: number; + @Column("int", { default: 0 }) bytesDownloaded: number; diff --git a/src/main/entity/user-preferences.entity.ts b/src/main/entity/user-preferences.entity.ts index 40f1a26a..8cb06aa5 100644 --- a/src/main/entity/user-preferences.entity.ts +++ b/src/main/entity/user-preferences.entity.ts @@ -17,6 +17,9 @@ export class UserPreferences { @Column("text", { default: "en" }) language: string; + @Column("text", { nullable: true }) + realDebridApiToken: string | null; + @Column("boolean", { default: false }) downloadNotificationsEnabled: boolean; @@ -32,3 +35,4 @@ export class UserPreferences { @UpdateDateColumn() updatedAt: Date; } + diff --git a/src/renderer/hooks/use-download.ts b/src/renderer/hooks/use-download.ts index 0c649229..861a0591 100644 --- a/src/renderer/hooks/use-download.ts +++ b/src/renderer/hooks/use-download.ts @@ -12,6 +12,7 @@ import { import type { GameShop, TorrentProgress } from "@types"; import { useDate } from "./use-date"; import { formatBytes } from "@renderer/utils"; +import { GameStatus } from "@globals"; export function useDownload() { const { updateLibrary } = useLibrary(); @@ -63,9 +64,10 @@ export function useDownload() { updateLibrary(); }); - const isVerifying = ["downloading_metadata", "checking_files"].includes( - lastPacket?.game.status - ); + const isVerifying = + GameStatus.DownloadingMetadata == lastPacket?.game.status || + GameStatus.CheckingFiles == lastPacket?.game.status || + GameStatus.Decompressing == lastPacket?.game.status; const getETA = () => { if (isVerifying || !isFinite(lastPacket?.timeRemaining)) { @@ -84,8 +86,10 @@ export function useDownload() { }; const getProgress = () => { - if (lastPacket?.game.status === "checking_files") { + if (lastPacket?.game.status === GameStatus.CheckingFiles) { return formatDownloadProgress(lastPacket?.game.fileVerificationProgress); + } else if (lastPacket?.game.status === GameStatus.Decompressing) { + return formatDownloadProgress(lastPacket?.game.decompressionProgress); } return formatDownloadProgress(lastPacket?.game.progress); @@ -98,7 +102,7 @@ export function useDownload() { dispatch(setGameDeleting(gameId)); return window.electron.deleteGameFolder(gameId); }) - .catch(() => {}) + .catch(() => { }) .finally(() => { updateLibrary(); dispatch(removeGameFromDeleting(gameId)); diff --git a/src/renderer/pages/settings/settings.tsx b/src/renderer/pages/settings/settings.tsx index 47bd604b..23451b35 100644 --- a/src/renderer/pages/settings/settings.tsx +++ b/src/renderer/pages/settings/settings.tsx @@ -11,6 +11,7 @@ export function Settings() { downloadNotificationsEnabled: false, repackUpdatesNotificationsEnabled: false, telemetryEnabled: false, + realDebridApiToken: null, }); const { t } = useTranslation("settings"); @@ -27,6 +28,7 @@ export function Settings() { repackUpdatesNotificationsEnabled: userPreferences?.repackUpdatesNotificationsEnabled, telemetryEnabled: userPreferences?.telemetryEnabled, + realDebridApiToken: userPreferences.realDebridApiToken, }); }); }, []); @@ -107,6 +109,14 @@ export function Settings() { updateUserPreferences("telemetryEnabled", !form.telemetryEnabled) } /> + + { + updateUserPreferences("realDebridApiToken", event.target.value); + }} + /> ); diff --git a/src/types/index.ts b/src/types/index.ts index d9070451..a8071a6f 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -84,6 +84,7 @@ export interface Game extends Omit { repack: GameRepack; progress: number; fileVerificationProgress: number; + decompressionProgress: number; bytesDownloaded: number; playTimeInMilliseconds: number; executablePath: string | null; @@ -107,6 +108,7 @@ export interface UserPreferences { downloadNotificationsEnabled: boolean; repackUpdatesNotificationsEnabled: boolean; telemetryEnabled: boolean; + realDebridApiToken: string | null; } export interface HowLongToBeatCategory { From 76a64fca4a982b80acb2e9ff6c8cb399ba568597 Mon Sep 17 00:00:00 2001 From: lilezek Date: Mon, 29 Apr 2024 20:53:58 +0200 Subject: [PATCH 04/52] feat: added support to unrar files --- src/main/services/unrar.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/main/services/unrar.ts diff --git a/src/main/services/unrar.ts b/src/main/services/unrar.ts new file mode 100644 index 00000000..b7c35393 --- /dev/null +++ b/src/main/services/unrar.ts @@ -0,0 +1,25 @@ +import { Extractor, createExtractorFromFile } from 'node-unrar-js'; +import fs from 'node:fs'; + +const wasmBinary = fs.readFileSync(require.resolve('node-unrar-js/esm/js/unrar.wasm')); + +export class Unrar { + private constructor(private extractor: Extractor) { } + + static async fromFilePath(filePath: string, targetFolder: string) { + console.log(filePath, targetFolder); + const extractor = await createExtractorFromFile({ + filepath: filePath, + targetPath: targetFolder, + wasmBinary, + }); + return new Unrar(extractor); + } + + extract() { + const files = this.extractor.extract().files; + for (const file of files) { + console.log("File:", file.fileHeader.name); + } + } +} From 6bb22655e850208d6dbf5aab81724c3e22125cbc Mon Sep 17 00:00:00 2001 From: lilezek Date: Mon, 29 Apr 2024 20:54:27 +0200 Subject: [PATCH 05/52] feat: added support to add magnets and download from real debrid --- .../services/donwloaders/real-debrid.d.ts | 65 +++++++++++++++++++ src/main/services/donwloaders/real-debrid.ts | 55 ++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 src/main/services/donwloaders/real-debrid.d.ts create mode 100644 src/main/services/donwloaders/real-debrid.ts diff --git a/src/main/services/donwloaders/real-debrid.d.ts b/src/main/services/donwloaders/real-debrid.d.ts new file mode 100644 index 00000000..4ee5228a --- /dev/null +++ b/src/main/services/donwloaders/real-debrid.d.ts @@ -0,0 +1,65 @@ +interface RealDebridUnrestrictLink { + id: string; + filename: string; + mimeType: string; + filesize: number; + link: string; + host: string; + host_icon: string; + chunks: number; + crc: number; + download: string; + streamable: number; +} + +interface RealDebridAddMagnet { + "id": string, + // URL of the created ressource + "uri": string +} + +interface RealDebridTorrentInfo { + "id": string, + "filename": string, + "original_filename": string, // Original name of the torrent + "hash": string, // SHA1 Hash of the torrent + "bytes": number, // Size of selected files only + "original_bytes": number, // Total size of the torrent + "host": string, // Host main domain + "split": number, // Split size of links + "progress": number, // Possible values: 0 to 100 + "status": "downloaded", // Current status of the torrent: magnet_error, magnet_conversion, waiting_files_selection, queued, downloading, downloaded, error, virus, compressing, uploading, dead + "added": string, // jsonDate + "files": [ + { + "id": number, + "path": string, // Path to the file inside the torrent, starting with "/" + "bytes": number, + "selected": number // 0 or 1 + }, + { + "id": number, + "path": string, // Path to the file inside the torrent, starting with "/" + "bytes": number, + "selected": number // 0 or 1 + } + ], + "links": [ + "string" // Host URL + ], + "ended": string, // !! Only present when finished, jsonDate + "speed": number, // !! Only present in "downloading", "compressing", "uploading" status + "seeders": number // !! Only present in "downloading", "magnet_conversion" status +} + +declare module 'real-debrid-api' { + interface Torrent { + addMagnet(magnet: string): Promise; + info(id: string): Promise; + } + + export default class { + constructor(token: string); + torrents: Torrent; + } +} \ No newline at end of file diff --git a/src/main/services/donwloaders/real-debrid.ts b/src/main/services/donwloaders/real-debrid.ts new file mode 100644 index 00000000..0ab290d0 --- /dev/null +++ b/src/main/services/donwloaders/real-debrid.ts @@ -0,0 +1,55 @@ +/// +import { userPreferencesRepository } from "@main/repository"; +import fetch from "node-fetch"; + +const base = "https://api.real-debrid.com/rest/1.0"; + +export class RealDebridClient { + static async addMagnet(magnet: string) { + const response = await fetch(`${base}/torrents/addMagnet`, { + method: "POST", + headers: { + "Authorization": `Bearer ${await this.getApiToken()}`, + }, + body: `magnet=${encodeURIComponent(magnet)}` + }); + + return response.json() as Promise; + } + + static async getInfo(id: string) { + const response = await fetch(`${base}/torrents/info/${id}`, { + headers: { + "Authorization": `Bearer ${await this.getApiToken()}` + } + }); + + return response.json() as Promise; + } + + static async selectAllFiles(id: string) { + const response = await fetch(`${base}/torrents/selectFiles/${id}`, { + method: "POST", + headers: { + "Authorization": `Bearer ${await this.getApiToken()}`, + }, + body: "files=all" + }); + } + + static async unrestrictLink(link: string) { + const response = await fetch(`${base}/unrestrict/link`, { + method: "POST", + headers: { + "Authorization": `Bearer ${await this.getApiToken()}`, + }, + body: `link=${link}` + }); + + return response.json() as Promise; + } + + static getApiToken() { + return userPreferencesRepository.findOne({ where: { id: 1 } }).then(userPreferences => userPreferences.realDebridApiToken); + } +} \ No newline at end of file From 666b1afcb62a3a4d6b324919539b5a3e5a1b2e54 Mon Sep 17 00:00:00 2001 From: lilezek Date: Mon, 29 Apr 2024 20:57:04 +0200 Subject: [PATCH 06/52] feat: added a Downloader helper to choose between real debrid and torrent when downloading --- .../events/torrenting/cancel-game-download.ts | 5 +- .../events/torrenting/pause-game-download.ts | 5 +- .../events/torrenting/resume-game-download.ts | 11 +- .../events/torrenting/start-game-download.ts | 17 +- src/main/index.ts | 10 +- src/main/services/donwloaders/downloader.ts | 147 ++++++++++++++++++ .../services/donwloaders/http-downloader.ts | 89 +++++++++++ .../{ => donwloaders}/torrent-client.ts | 65 ++------ src/main/services/index.ts | 2 +- 9 files changed, 268 insertions(+), 83 deletions(-) create mode 100644 src/main/services/donwloaders/downloader.ts create mode 100644 src/main/services/donwloaders/http-downloader.ts rename src/main/services/{ => donwloaders}/torrent-client.ts (62%) diff --git a/src/main/events/torrenting/cancel-game-download.ts b/src/main/events/torrenting/cancel-game-download.ts index bcd4fdab..32aa79ae 100644 --- a/src/main/events/torrenting/cancel-game-download.ts +++ b/src/main/events/torrenting/cancel-game-download.ts @@ -1,9 +1,10 @@ import { gameRepository } from "@main/repository"; import { registerEvent } from "../register-event"; -import { WindowManager, writePipe } from "@main/services"; +import { WindowManager } from "@main/services"; import { In } from "typeorm"; +import { Downloader } from "@main/services/donwloaders/downloader"; import { GameStatus } from "@globals"; const cancelGameDownload = async ( @@ -41,7 +42,7 @@ const cancelGameDownload = async ( game.status !== GameStatus.Paused && game.status !== GameStatus.Seeding ) { - writePipe.write({ action: "cancel" }); + Downloader.cancelDownload(); if (result.affected) WindowManager.mainWindow.setProgressBar(-1); } }); diff --git a/src/main/events/torrenting/pause-game-download.ts b/src/main/events/torrenting/pause-game-download.ts index e1da552a..6e728ede 100644 --- a/src/main/events/torrenting/pause-game-download.ts +++ b/src/main/events/torrenting/pause-game-download.ts @@ -1,8 +1,9 @@ -import { WindowManager, writePipe } from "@main/services"; +import { WindowManager } from "@main/services"; import { registerEvent } from "../register-event"; import { gameRepository } from "../../repository"; import { In } from "typeorm"; +import { Downloader } from "@main/services/donwloaders/downloader"; import { GameStatus } from "@globals"; const pauseGameDownload = async ( @@ -23,7 +24,7 @@ const pauseGameDownload = async ( ) .then((result) => { if (result.affected) { - writePipe.write({ action: "pause" }); + Downloader.pauseDownload(); WindowManager.mainWindow.setProgressBar(-1); } }); diff --git a/src/main/events/torrenting/resume-game-download.ts b/src/main/events/torrenting/resume-game-download.ts index 9d96ab18..a394c84a 100644 --- a/src/main/events/torrenting/resume-game-download.ts +++ b/src/main/events/torrenting/resume-game-download.ts @@ -2,7 +2,7 @@ import { registerEvent } from "../register-event"; import { gameRepository } from "../../repository"; import { getDownloadsPath } from "../helpers/get-downloads-path"; import { In } from "typeorm"; -import { writePipe } from "@main/services"; +import { Downloader } from "@main/services/donwloaders/downloader"; import { GameStatus } from "@globals"; const resumeGameDownload = async ( @@ -18,17 +18,12 @@ const resumeGameDownload = async ( if (!game) return; - writePipe.write({ action: "pause" }); + Downloader.resumeDownload(); if (game.status === GameStatus.Paused) { const downloadsPath = game.downloadPath ?? (await getDownloadsPath()); - writePipe.write({ - action: "start", - game_id: gameId, - magnet: game.repack.magnet, - save_path: downloadsPath, - }); + Downloader.downloadGame(game, game.repack); await gameRepository.update( { diff --git a/src/main/events/torrenting/start-game-download.ts b/src/main/events/torrenting/start-game-download.ts index a5853208..f6125c8a 100644 --- a/src/main/events/torrenting/start-game-download.ts +++ b/src/main/events/torrenting/start-game-download.ts @@ -6,6 +6,7 @@ import { registerEvent } from "../register-event"; import type { GameShop } from "@types"; import { getImageBase64 } from "@main/helpers"; import { In } from "typeorm"; +import { Downloader } from "@main/services/donwloaders/downloader"; import { GameStatus } from "@globals"; const startGameDownload = async ( @@ -35,7 +36,7 @@ const startGameDownload = async ( return; } - writePipe.write({ action: "pause" }); + Downloader.pauseDownload(); await gameRepository.update( { @@ -61,12 +62,7 @@ const startGameDownload = async ( } ); - writePipe.write({ - action: "start", - game_id: game.id, - magnet: repack.magnet, - save_path: downloadPath, - }); + Downloader.downloadGame(game, repack); game.status = GameStatus.DownloadingMetadata; @@ -84,12 +80,7 @@ const startGameDownload = async ( repack: { id: repackId }, }); - writePipe.write({ - action: "start", - game_id: createdGame.id, - magnet: repack.magnet, - save_path: downloadPath, - }); + Downloader.downloadGame(createdGame, repack); const { repack: _, ...rest } = createdGame; diff --git a/src/main/index.ts b/src/main/index.ts index 1657540d..cc89a58e 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -17,11 +17,12 @@ import { steamGameRepository, userPreferencesRepository, } from "./repository"; -import { TorrentClient } from "./services/torrent-client"; +import { TorrentClient } from "./services/donwloaders/torrent-client"; import { Repack } from "./entity"; import { Notification } from "electron"; import { t } from "i18next"; import { In } from "typeorm"; +import { Downloader } from "./services/donwloaders/downloader"; import { GameStatus } from "@globals"; startProcessWatcher(); @@ -41,12 +42,7 @@ Promise.all([writePipe.createPipe(), readPipe.createPipe()]).then(async () => { }); if (game) { - writePipe.write({ - action: "start", - game_id: game.id, - magnet: game.repack.magnet, - save_path: game.downloadPath, - }); + Downloader.downloadGame(game, game.repack); } readPipe.socket.on("data", (data) => { diff --git a/src/main/services/donwloaders/downloader.ts b/src/main/services/donwloaders/downloader.ts new file mode 100644 index 00000000..9c3f1a72 --- /dev/null +++ b/src/main/services/donwloaders/downloader.ts @@ -0,0 +1,147 @@ +import { Game, Repack } from "@main/entity"; +import { writePipe } from "../fifo"; +import { gameRepository, userPreferencesRepository } from "@main/repository"; +import { RealDebridClient } from "./real-debrid"; +import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity"; +import { t } from "i18next"; +import { Notification } from "electron"; +import { WindowManager } from "../window-manager"; +import { TorrentUpdate } from "./torrent-client"; +import { HTTPDownloader } from "./http-downloader"; +import { Unrar } from "../unrar"; +import { GameStatus } from "@globals"; + +interface DownloadStatus { + numPeers: number; + numSeeds: number; + downloadSpeed: number; + timeRemaining: number; +} + +export class Downloader { + private static lastHttpDownloader: HTTPDownloader | null = null; + + static async usesRealDebrid() { + const userPreferences = await userPreferencesRepository.findOne({ where: { id: 1 } }); + return userPreferences.realDebridApiToken !== null; + } + + static async cancelDownload() { + if (!await this.usesRealDebrid()) { + writePipe.write({ action: "cancel" }); + } else { + if (this.lastHttpDownloader) { + this.lastHttpDownloader.cancel(); + } + } + } + + static async pauseDownload() { + if (!await this.usesRealDebrid()) { + writePipe.write({ action: "pause" }); + } else { + if (this.lastHttpDownloader) { + this.lastHttpDownloader.pause(); + } + } + } + + static async resumeDownload() { + if (!await this.usesRealDebrid()) { + writePipe.write({ action: "pause" }); + } else { + if (this.lastHttpDownloader) { + this.lastHttpDownloader.resume(); + } + } + } + + static async downloadGame(game: Game, repack: Repack) { + if (!await this.usesRealDebrid()) { + writePipe.write({ + action: "start", + game_id: game.id, + magnet: repack.magnet, + save_path: game.downloadPath, + }); + } else { + try { + const torrent = await RealDebridClient.addMagnet(repack.magnet); + if (torrent && torrent.id) { + await RealDebridClient.selectAllFiles(torrent.id); + const { links } = await RealDebridClient.getInfo(torrent.id); + const { download } = await RealDebridClient.unrestrictLink(links[0]); + this.lastHttpDownloader = new HTTPDownloader(); + this.lastHttpDownloader.download(download, game.downloadPath, game.id); + } + } catch (e) { + console.error(e); + } + } + } + + static async updateGameProgress(gameId: number, gameUpdate: QueryDeepPartialEntity, downloadStatus: DownloadStatus) { + await gameRepository.update({ id: gameId }, gameUpdate); + + const game = await gameRepository.findOne({ + where: { id: gameId }, + relations: { repack: true }, + }); + + if (gameUpdate.progress === 1 && gameUpdate.status !== GameStatus.Decompressing) { + const userPreferences = await userPreferencesRepository.findOne({ + where: { id: 1 }, + }); + + if (userPreferences?.downloadNotificationsEnabled) { + new Notification({ + title: t("download_complete", { + ns: "notifications", + lng: userPreferences.language, + }), + body: t("game_ready_to_install", { + ns: "notifications", + lng: userPreferences.language, + title: game.title, + }), + }).show(); + } + } + + if (gameUpdate.decompressionProgress === 0 && gameUpdate.status === GameStatus.Decompressing) { + const unrar = await Unrar.fromFilePath(game.rarPath, game.downloadPath); + unrar.extract(); + this.updateGameProgress(gameId, { + decompressionProgress: 1, + status: GameStatus.Finished, + }, downloadStatus); + } + + if (WindowManager.mainWindow) { + const progress = this.getGameProgress(game); + WindowManager.mainWindow.setProgressBar(progress === 1 ? -1 : progress); + + WindowManager.mainWindow.webContents.send( + "on-download-progress", + JSON.parse(JSON.stringify({ + ...{ + progress: gameUpdate.progress, + bytesDownloaded: gameUpdate.bytesDownloaded, + fileSize: gameUpdate.fileSize, + gameId, + numPeers: downloadStatus.numPeers, + numSeeds: downloadStatus.numSeeds, + downloadSpeed: downloadStatus.downloadSpeed, + timeRemaining: downloadStatus.timeRemaining, + } as TorrentUpdate, game + })) + ); + } + } + + static getGameProgress(game: Game) { + if (game.status === GameStatus.CheckingFiles) return game.fileVerificationProgress; + if (game.status === GameStatus.Decompressing) return game.decompressionProgress; + return game.progress; + } +} \ No newline at end of file diff --git a/src/main/services/donwloaders/http-downloader.ts b/src/main/services/donwloaders/http-downloader.ts new file mode 100644 index 00000000..aec963e0 --- /dev/null +++ b/src/main/services/donwloaders/http-downloader.ts @@ -0,0 +1,89 @@ +import { Game } from '@main/entity'; +import { ElectronDownloadManager } from 'electron-dl-manager'; +import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity'; +import { WindowManager } from '../window-manager'; +import { Downloader } from './downloader'; +import { GameStatus } from '@globals'; + +export class HTTPDownloader { + private downloadManager: ElectronDownloadManager; + private downloadId: string | null = null; + + constructor() { + this.downloadManager = new ElectronDownloadManager(); + } + + async download(url: string, destination: string, gameId: number) { + const window = WindowManager.mainWindow; + + this.downloadId = await this.downloadManager.download({ + url, + window: window, + callbacks: { + onDownloadStarted: async (ev) => { + const updatePayload: QueryDeepPartialEntity = { + status: GameStatus.Downloading, + progress: 0, + bytesDownloaded: 0, + fileSize: ev.item.getTotalBytes(), + rarPath: `${destination}/.rd/${ev.resolvedFilename}`, + }; + const downloadStatus = { + numPeers: 0, + numSeeds: 0, + downloadSpeed: 0, + timeRemaining: Number.POSITIVE_INFINITY, + }; + await Downloader.updateGameProgress(gameId, updatePayload, downloadStatus); + }, + onDownloadCompleted: async (ev) => { + const updatePayload: QueryDeepPartialEntity = { + progress: 1, + decompressionProgress: 0, + bytesDownloaded: ev.item.getReceivedBytes(), + status: GameStatus.Decompressing, + }; + const downloadStatus = { + numPeers: 1, + numSeeds: 1, + downloadSpeed: 0, + timeRemaining: 0, + }; + await Downloader.updateGameProgress(gameId, updatePayload, downloadStatus); + }, + onDownloadProgress: async (ev) => { + const updatePayload: QueryDeepPartialEntity = { + progress: ev.percentCompleted / 100, + bytesDownloaded: ev.item.getReceivedBytes(), + }; + const downloadStatus = { + numPeers: 1, + numSeeds: 1, + downloadSpeed: ev.downloadRateBytesPerSecond, + timeRemaining: ev.estimatedTimeRemainingSeconds, + }; + await Downloader.updateGameProgress(gameId, updatePayload, downloadStatus); + } + }, + directory: `${destination}/.rd/`, + }); + } + + pause() { + if (this.downloadId) { + this.downloadManager.pauseDownload(this.downloadId); + } + } + + cancel() { + if (this.downloadId) { + this.downloadManager.cancelDownload(this.downloadId); + } + } + + resume() { + if (this.downloadId) { + this.downloadManager.resumeDownload(this.downloadId); + } + } +} \ No newline at end of file diff --git a/src/main/services/torrent-client.ts b/src/main/services/donwloaders/torrent-client.ts similarity index 62% rename from src/main/services/torrent-client.ts rename to src/main/services/donwloaders/torrent-client.ts index fa1cd59d..8e48bbbd 100644 --- a/src/main/services/torrent-client.ts +++ b/src/main/services/donwloaders/torrent-client.ts @@ -2,13 +2,12 @@ import path from "node:path"; import cp from "node:child_process"; import fs from "node:fs"; import * as Sentry from "@sentry/electron/main"; -import { Notification, app, dialog } from "electron"; +import { app, dialog } from "electron"; import type { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity"; import { Game } from "@main/entity"; -import { gameRepository, userPreferencesRepository } from "@main/repository"; -import { t } from "i18next"; -import { WindowManager } from "./window-manager"; +import { Downloader } from "./downloader"; +import { GameStatus } from "@globals"; const binaryNameByPlatform: Partial> = { darwin: "hydra-download-manager", @@ -75,6 +74,7 @@ export class TorrentClient { __dirname, "..", "..", + "..", "torrent-client", "main.py" ); @@ -85,20 +85,15 @@ export class TorrentClient { } private static getTorrentStateName(state: TorrentState) { - if (state === TorrentState.CheckingFiles) return "checking_files"; - if (state === TorrentState.Downloading) return "downloading"; + if (state === TorrentState.CheckingFiles) return GameStatus.CheckingFiles; + if (state === TorrentState.Downloading) return GameStatus.Downloading; if (state === TorrentState.DownloadingMetadata) - return "downloading_metadata"; - if (state === TorrentState.Finished) return "finished"; - if (state === TorrentState.Seeding) return "seeding"; + return GameStatus.DownloadingMetadata; + if (state === TorrentState.Finished) return GameStatus.Finished; + if (state === TorrentState.Seeding) return GameStatus.Seeding; return ""; } - private static getGameProgress(game: Game) { - if (game.status === "checking_files") return game.fileVerificationProgress; - return game.progress; - } - public static async onSocketData(data: Buffer) { const message = Buffer.from(data).toString("utf-8"); @@ -127,44 +122,14 @@ export class TorrentClient { updatePayload.progress = payload.progress; } - await gameRepository.update({ id: payload.gameId }, updatePayload); - - const game = await gameRepository.findOne({ - where: { id: payload.gameId }, - relations: { repack: true }, + Downloader.updateGameProgress(payload.gameId, updatePayload, { + numPeers: payload.numPeers, + numSeeds: payload.numSeeds, + downloadSpeed: payload.downloadSpeed, + timeRemaining: payload.timeRemaining, }); - - if (game.progress === 1) { - const userPreferences = await userPreferencesRepository.findOne({ - where: { id: 1 }, - }); - - if (userPreferences?.downloadNotificationsEnabled) { - new Notification({ - title: t("download_complete", { - ns: "notifications", - lng: userPreferences.language, - }), - body: t("game_ready_to_install", { - ns: "notifications", - lng: userPreferences.language, - title: game.title, - }), - }).show(); - } - } - - if (WindowManager.mainWindow) { - const progress = this.getGameProgress(game); - WindowManager.mainWindow.setProgressBar(progress === 1 ? -1 : progress); - - WindowManager.mainWindow.webContents.send( - "on-download-progress", - JSON.parse(JSON.stringify({ ...payload, game })) - ); - } } catch (err) { Sentry.captureException(err); } } -} +} \ No newline at end of file diff --git a/src/main/services/index.ts b/src/main/services/index.ts index 2544c6f4..215cd016 100644 --- a/src/main/services/index.ts +++ b/src/main/services/index.ts @@ -6,6 +6,6 @@ export * from "./steam-grid"; export * from "./update-resolver"; export * from "./window-manager"; export * from "./fifo"; -export * from "./torrent-client"; +export * from "./donwloaders/torrent-client"; export * from "./how-long-to-beat"; export * from "./process-watcher"; From f1d2a8844281ef99f75dfb06b73d544fe7e63951 Mon Sep 17 00:00:00 2001 From: lilezek Date: Tue, 30 Apr 2024 09:29:29 +0200 Subject: [PATCH 07/52] feat: added helper functions to the game status to keep it simple to read. --- src/globals.ts | 16 ++++++++++++++++ .../events/torrenting/cancel-game-download.ts | 2 ++ .../components/bottom-panel/bottom-panel.tsx | 5 +++-- src/renderer/components/sidebar/sidebar.tsx | 13 +++++-------- src/renderer/hooks/use-download.ts | 5 +---- src/renderer/pages/downloads/downloads.tsx | 19 ++++++++++--------- .../pages/game-details/hero-panel-actions.tsx | 9 +++++---- .../pages/game-details/hero-panel.tsx | 7 ++++--- 8 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/globals.ts b/src/globals.ts index e4675aa7..b240172a 100644 --- a/src/globals.ts +++ b/src/globals.ts @@ -7,4 +7,20 @@ export enum GameStatus { Cancelled = "cancelled", Finished = "finished", Decompressing = "decompressing", +} + +export namespace GameStatus { + export const isDownloading = (status: GameStatus | "") => + status === GameStatus.Downloading || + status === GameStatus.DownloadingMetadata || + status === GameStatus.CheckingFiles; + + export const isVerifying = (status: GameStatus | "") => + GameStatus.DownloadingMetadata == status || + GameStatus.CheckingFiles == status || + GameStatus.Decompressing == status; + + export const isReady = (status: GameStatus | "") => + status === GameStatus.Finished || + status === GameStatus.Seeding; } \ No newline at end of file diff --git a/src/main/events/torrenting/cancel-game-download.ts b/src/main/events/torrenting/cancel-game-download.ts index 32aa79ae..af8ae89f 100644 --- a/src/main/events/torrenting/cancel-game-download.ts +++ b/src/main/events/torrenting/cancel-game-download.ts @@ -20,6 +20,8 @@ const cancelGameDownload = async ( GameStatus.CheckingFiles, GameStatus.Paused, GameStatus.Seeding, + GameStatus.Finished, + GameStatus.Decompressing, ]), }, }); diff --git a/src/renderer/components/bottom-panel/bottom-panel.tsx b/src/renderer/components/bottom-panel/bottom-panel.tsx index c870823e..46e278ca 100644 --- a/src/renderer/components/bottom-panel/bottom-panel.tsx +++ b/src/renderer/components/bottom-panel/bottom-panel.tsx @@ -7,6 +7,7 @@ import { vars } from "@renderer/theme.css"; import { useEffect, useMemo, useState } from "react"; import { useNavigate } from "react-router-dom"; import { VERSION_CODENAME } from "@renderer/constants"; +import { GameStatus } from "@globals"; export function BottomPanel() { const { t } = useTranslation("bottom_panel"); @@ -23,10 +24,10 @@ export function BottomPanel() { const status = useMemo(() => { if (isDownloading) { - if (game.status === "downloading_metadata") + if (game.status === GameStatus.DownloadingMetadata) return t("downloading_metadata", { title: game.title }); - if (game.status === "checking_files") + if (game.status === GameStatus.CheckingFiles) return t("checking_files", { title: game.title, percentage: progress, diff --git a/src/renderer/components/sidebar/sidebar.tsx b/src/renderer/components/sidebar/sidebar.tsx index 2d853553..cd4aff92 100644 --- a/src/renderer/components/sidebar/sidebar.tsx +++ b/src/renderer/components/sidebar/sidebar.tsx @@ -14,6 +14,7 @@ import { MarkGithubIcon } from "@primer/octicons-react"; import DiscordLogo from "@renderer/assets/discord-icon.svg"; import XLogo from "@renderer/assets/x-icon.svg"; import * as styles from "./sidebar.css"; +import { GameStatus } from "@globals"; const socials = [ { @@ -57,9 +58,7 @@ export function Sidebar() { }, [gameDownloading?.id, updateLibrary]); const isDownloading = library.some((game) => - ["downloading", "checking_files", "downloading_metadata"].includes( - game.status - ) + GameStatus.isDownloading(game.status) ); const sidebarRef = useRef(null); @@ -118,12 +117,10 @@ export function Sidebar() { }, [isResizing]); const getGameTitle = (game: Game) => { - if (game.status === "paused") return t("paused", { title: game.title }); + if (game.status === GameStatus.Paused) return t("paused", { title: game.title }); if (gameDownloading?.id === game.id) { - const isVerifying = ["downloading_metadata", "checking_files"].includes( - gameDownloading?.status - ); + const isVerifying = GameStatus.isVerifying(gameDownloading.status); if (isVerifying) return t(gameDownloading.status, { @@ -203,7 +200,7 @@ export function Sidebar() { className={styles.menuItem({ active: location.pathname === `/game/${game.shop}/${game.objectID}`, - muted: game.status === "cancelled", + muted: game.status === GameStatus.Cancelled, })} > +
+ + + + {downloaderName[game?.downloader]} + +
{getGameInfo(game)} diff --git a/src/renderer/src/pages/game-details/installation-guides/constants.ts b/src/renderer/src/pages/game-details/installation-guides/constants.ts index e20f7714..f9d00c15 100644 --- a/src/renderer/src/pages/game-details/installation-guides/constants.ts +++ b/src/renderer/src/pages/game-details/installation-guides/constants.ts @@ -1,3 +1,4 @@ export const DONT_SHOW_ONLINE_FIX_INSTRUCTIONS_KEY = "dontShowOnlineFixInstructions"; + export const DONT_SHOW_DODI_INSTRUCTIONS_KEY = "dontShowDodiInstructions"; diff --git a/yarn.lock b/yarn.lock index ed341af3..553fd402 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"7zip-bin@~5.2.0": + version "5.2.0" + resolved "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.2.0.tgz" + integrity sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A== + "@ampproject/remapping@^2.2.0": version "2.3.0" resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz" @@ -23,7 +28,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz" integrity sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ== -"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.18.5", "@babel/core@^7.21.3", "@babel/core@^7.23.5", "@babel/core@^7.23.9": +"@babel/core@^7.18.5", "@babel/core@^7.21.3", "@babel/core@^7.23.5", "@babel/core@^7.23.9": version "7.24.5" resolved "https://registry.npmjs.org/@babel/core/-/core-7.24.5.tgz" integrity sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA== @@ -230,7 +235,7 @@ "@babel/helper-validator-identifier" "^7.24.5" to-fast-properties "^2.0.0" -"@colors/colors@^1.6.0", "@colors/colors@1.6.0": +"@colors/colors@1.6.0", "@colors/colors@^1.6.0": version "1.6.0" resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz" integrity sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA== @@ -346,6 +351,226 @@ resolved "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz" integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== +"@esbuild/aix-ppc64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" + integrity sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA== + +"@esbuild/aix-ppc64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537" + integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g== + +"@esbuild/android-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz#7ad65a36cfdb7e0d429c353e00f680d737c2aed4" + integrity sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA== + +"@esbuild/android-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9" + integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg== + +"@esbuild/android-arm@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz#b0c26536f37776162ca8bde25e42040c203f2824" + integrity sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w== + +"@esbuild/android-arm@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995" + integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w== + +"@esbuild/android-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz#cb13e2211282012194d89bf3bfe7721273473b3d" + integrity sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew== + +"@esbuild/android-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98" + integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg== + +"@esbuild/darwin-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz#cbee41e988020d4b516e9d9e44dd29200996275e" + integrity sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g== + +"@esbuild/darwin-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz#6e8517a045ddd86ae30c6608c8475ebc0c4000bb" + integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA== + +"@esbuild/darwin-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz#e37d9633246d52aecf491ee916ece709f9d5f4cd" + integrity sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A== + +"@esbuild/darwin-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0" + integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA== + +"@esbuild/freebsd-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz#1ee4d8b682ed363b08af74d1ea2b2b4dbba76487" + integrity sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA== + +"@esbuild/freebsd-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911" + integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw== + +"@esbuild/freebsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz#37a693553d42ff77cd7126764b535fb6cc28a11c" + integrity sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg== + +"@esbuild/freebsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c" + integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw== + +"@esbuild/linux-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz#be9b145985ec6c57470e0e051d887b09dddb2d4b" + integrity sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA== + +"@esbuild/linux-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5" + integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A== + +"@esbuild/linux-arm@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz#207ecd982a8db95f7b5279207d0ff2331acf5eef" + integrity sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w== + +"@esbuild/linux-arm@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c" + integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg== + +"@esbuild/linux-ia32@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz#d0d86b5ca1562523dc284a6723293a52d5860601" + integrity sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA== + +"@esbuild/linux-ia32@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa" + integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig== + +"@esbuild/linux-loong64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz#9a37f87fec4b8408e682b528391fa22afd952299" + integrity sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA== + +"@esbuild/linux-loong64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5" + integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ== + +"@esbuild/linux-mips64el@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz#4ddebd4e6eeba20b509d8e74c8e30d8ace0b89ec" + integrity sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w== + +"@esbuild/linux-mips64el@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa" + integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA== + +"@esbuild/linux-ppc64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz#adb67dadb73656849f63cd522f5ecb351dd8dee8" + integrity sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg== + +"@esbuild/linux-ppc64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20" + integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg== + +"@esbuild/linux-riscv64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz#11bc0698bf0a2abf8727f1c7ace2112612c15adf" + integrity sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg== + +"@esbuild/linux-riscv64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300" + integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg== + +"@esbuild/linux-s390x@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz#e86fb8ffba7c5c92ba91fc3b27ed5a70196c3cc8" + integrity sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg== + +"@esbuild/linux-s390x@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685" + integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ== + +"@esbuild/linux-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz#5f37cfdc705aea687dfe5dfbec086a05acfe9c78" + integrity sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg== + +"@esbuild/linux-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff" + integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw== + +"@esbuild/netbsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz#29da566a75324e0d0dd7e47519ba2f7ef168657b" + integrity sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA== + +"@esbuild/netbsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6" + integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ== + +"@esbuild/openbsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz#306c0acbdb5a99c95be98bdd1d47c916e7dc3ff0" + integrity sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw== + +"@esbuild/openbsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf" + integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ== + +"@esbuild/sunos-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz#0933eaab9af8b9b2c930236f62aae3fc593faf30" + integrity sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA== + +"@esbuild/sunos-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f" + integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w== + +"@esbuild/win32-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz#773bdbaa1971b36db2f6560088639ccd1e6773ae" + integrity sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A== + +"@esbuild/win32-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90" + integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ== + +"@esbuild/win32-ia32@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz#000516cad06354cc84a73f0943a4aa690ef6fd67" + integrity sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ== + +"@esbuild/win32-ia32@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23" + integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ== + "@esbuild/win32-x64@0.19.12": version "0.19.12" resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz" @@ -486,7 +711,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -538,6 +763,81 @@ estree-walker "^2.0.2" picomatch "^2.3.1" +"@rollup/rollup-android-arm-eabi@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz#1a32112822660ee104c5dd3a7c595e26100d4c2d" + integrity sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ== + +"@rollup/rollup-android-arm64@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz#5aeef206d65ff4db423f3a93f71af91b28662c5b" + integrity sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw== + +"@rollup/rollup-darwin-arm64@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz#6b66aaf003c70454c292cd5f0236ebdc6ffbdf1a" + integrity sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw== + +"@rollup/rollup-darwin-x64@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz#f64fc51ed12b19f883131ccbcea59fc68cbd6c0b" + integrity sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ== + +"@rollup/rollup-linux-arm-gnueabihf@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz#1a7641111be67c10111f7122d1e375d1226cbf14" + integrity sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A== + +"@rollup/rollup-linux-arm-musleabihf@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz#c93fd632923e0fee25aacd2ae414288d0b7455bb" + integrity sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg== + +"@rollup/rollup-linux-arm64-gnu@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz#fa531425dd21d058a630947527b4612d9d0b4a4a" + integrity sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A== + +"@rollup/rollup-linux-arm64-musl@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz#8acc16f095ceea5854caf7b07e73f7d1802ac5af" + integrity sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA== + +"@rollup/rollup-linux-powerpc64le-gnu@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz#94e69a8499b5cf368911b83a44bb230782aeb571" + integrity sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ== + +"@rollup/rollup-linux-riscv64-gnu@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz#7ef1c781c7e59e85a6ce261cc95d7f1e0b56db0f" + integrity sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg== + +"@rollup/rollup-linux-s390x-gnu@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz#f15775841c3232fca9b78cd25a7a0512c694b354" + integrity sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g== + +"@rollup/rollup-linux-x64-gnu@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz#b521d271798d037ad70c9f85dd97d25f8a52e811" + integrity sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ== + +"@rollup/rollup-linux-x64-musl@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz#9254019cc4baac35800991315d133cc9fd1bf385" + integrity sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q== + +"@rollup/rollup-win32-arm64-msvc@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz#27f65a89f6f52ee9426ec11e3571038e4671790f" + integrity sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA== + +"@rollup/rollup-win32-ia32-msvc@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz#a2fbf8246ed0bb014f078ca34ae6b377a90cb411" + integrity sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ== + "@rollup/rollup-win32-x64-msvc@4.17.2": version "4.17.2" resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz" @@ -646,6 +946,36 @@ magic-string "0.30.8" unplugin "1.0.1" +"@sentry/cli-darwin@2.31.2": + version "2.31.2" + resolved "https://registry.yarnpkg.com/@sentry/cli-darwin/-/cli-darwin-2.31.2.tgz#faeb87d09d8b21b8b8dd2e2aa848b538f01ddd26" + integrity sha512-BHA/JJXj1dlnoZQdK4efRCtHRnbBfzbIZUKAze7oRR1RfNqERI84BVUQeKateD3jWSJXQfEuclIShc61KOpbKw== + +"@sentry/cli-linux-arm64@2.31.2": + version "2.31.2" + resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.31.2.tgz#669c9c3f7f9130d26f5db732f793378863d58869" + integrity sha512-FLVKkJ/rWvPy/ka7OrUdRW63a/z8HYI1Gt8Pr6rWs50hb7YJja8lM8IO10tYmcFE/tODICsnHO9HTeUg2g2d1w== + +"@sentry/cli-linux-arm@2.31.2": + version "2.31.2" + resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm/-/cli-linux-arm-2.31.2.tgz#3e36ed7db09e922f00221281252e58dfd8755ea5" + integrity sha512-W8k5mGYYZz/I/OxZH65YAK7dCkQAl+wbuoASGOQjUy5VDgqH0QJ8kGJufXvFPM+f3ZQGcKAnVsZ6tFqZXETBAw== + +"@sentry/cli-linux-i686@2.31.2": + version "2.31.2" + resolved "https://registry.yarnpkg.com/@sentry/cli-linux-i686/-/cli-linux-i686-2.31.2.tgz#02b7da274369b78a5676c20bb26cc37caed5244b" + integrity sha512-A64QtzaPi3MYFpZ+Fwmi0mrSyXgeLJ0cWr4jdeTGrzNpeowSteKgd6tRKU+LVq0k5shKE7wdnHk+jXnoajulMA== + +"@sentry/cli-linux-x64@2.31.2": + version "2.31.2" + resolved "https://registry.yarnpkg.com/@sentry/cli-linux-x64/-/cli-linux-x64-2.31.2.tgz#54f74a9e5925db9ddafebc0efd4056c5377be5fd" + integrity sha512-YL/r+15R4mOEiU3mzn7iFQOeFEUB6KxeKGTTrtpeOGynVUGIdq4nV5rHow5JDbIzOuBS3SpOmcIMluvo1NCh0g== + +"@sentry/cli-win32-i686@2.31.2": + version "2.31.2" + resolved "https://registry.yarnpkg.com/@sentry/cli-win32-i686/-/cli-win32-i686-2.31.2.tgz#5dab845a824be0927566171aa05f015e887fe82d" + integrity sha512-Az/2bmW+TFI059RE0mSBIxTBcoShIclz7BDebmIoCkZ+retrwAzpmBnBCDAHow+Yi43utOow+3/4idGa2OxcLw== + "@sentry/cli-win32-x64@2.31.2": version "2.31.2" resolved "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.31.2.tgz" @@ -857,7 +1187,7 @@ "@svgr/babel-plugin-transform-react-native-svg" "8.1.0" "@svgr/babel-plugin-transform-svg-component" "8.0.0" -"@svgr/core@*", "@svgr/core@^8.1.0": +"@svgr/core@^8.1.0": version "8.1.0" resolved "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz" integrity sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA== @@ -886,12 +1216,57 @@ "@svgr/hast-util-to-babel-ast" "8.0.0" svg-parser "^2.0.4" +"@swc/core-darwin-arm64@1.4.17": + version "1.4.17" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.17.tgz#e62fa7f247bdd1c0c50a3f99722da4dd098c7c67" + integrity sha512-HVl+W4LezoqHBAYg2JCqR+s9ife9yPfgWSj37iIawLWzOmuuJ7jVdIB7Ee2B75bEisSEKyxRlTl6Y1Oq3owBgw== + +"@swc/core-darwin-x64@1.4.17": + version "1.4.17" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.4.17.tgz#1145cbb7575e317204ed3a7d0274bd26fe9ffab6" + integrity sha512-WYRO9Fdzq4S/he8zjW5I95G1zcvyd9yyD3Tgi4/ic84P5XDlSMpBDpBLbr/dCPjmSg7aUXxNQqKqGkl6dQxYlA== + +"@swc/core-linux-arm-gnueabihf@1.4.17": + version "1.4.17" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.17.tgz#7145b3ada5cf9b748eaacbc9a7c7037ba0fb26bb" + integrity sha512-cgbvpWOvtMH0XFjvwppUCR+Y+nf6QPaGu6AQ5hqCP+5Lv2zO5PG0RfasC4zBIjF53xgwEaaWmGP5/361P30X8Q== + +"@swc/core-linux-arm64-gnu@1.4.17": + version "1.4.17" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.17.tgz#5c0833ef132af17bd3cbdf2253f35b57c0cf62bb" + integrity sha512-l7zHgaIY24cF9dyQ/FOWbmZDsEj2a9gRFbmgx2u19e3FzOPuOnaopFj0fRYXXKCmtdx+anD750iBIYnTR+pq/Q== + +"@swc/core-linux-arm64-musl@1.4.17": + version "1.4.17" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.17.tgz#5bfe81eb23c905f04b669a7d2b060a147a263483" + integrity sha512-qhH4gr9gAlVk8MBtzXbzTP3BJyqbAfUOATGkyUtohh85fPXQYuzVlbExix3FZXTwFHNidGHY8C+ocscI7uDaYw== + +"@swc/core-linux-x64-gnu@1.4.17": + version "1.4.17" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.17.tgz#a0c19bc9635e86ebd1c7f8e9e026503d1a1bf83d" + integrity sha512-vRDFATL1oN5oZMImkwbgSHEkp8xG1ofEASBypze01W1Tqto8t+yo6gsp69wzCZBlxldsvPpvFZW55Jq0Rn+UnA== + +"@swc/core-linux-x64-musl@1.4.17": + version "1.4.17" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.17.tgz#2179b9536235a3b02a46997ddb1c178dfadf1667" + integrity sha512-zQNPXAXn3nmPqv54JVEN8k2JMEcMTQ6veVuU0p5O+A7KscJq+AGle/7ZQXzpXSfUCXlLMX4wvd+rwfGhh3J4cw== + +"@swc/core-win32-arm64-msvc@1.4.17": + version "1.4.17" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.17.tgz#3004a431c836c6b16b4660ea2425dde467a8ee36" + integrity sha512-z86n7EhOwyzxwm+DLE5NoLkxCTme2lq7QZlDjbQyfCxOt6isWz8rkW5QowTX8w9Rdmk34ncrjSLvnHOeLY17+w== + +"@swc/core-win32-ia32-msvc@1.4.17": + version "1.4.17" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.17.tgz#59155485d5307fb2a267e5acb215e0f440b6f48f" + integrity sha512-JBwuSTJIgiJJX6wtr4wmXbfvOswHFj223AumUrK544QV69k60FJ9q2adPW9Csk+a8wm1hLxq4HKa2K334UHJ/g== + "@swc/core-win32-x64-msvc@1.4.17": version "1.4.17" resolved "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.17.tgz" integrity sha512-jFkOnGQamtVDBm3MF5Kq1lgW8vx4Rm1UvJWRUfg+0gx7Uc3Jp3QMFeMNw/rDNQYRDYPG3yunCC+2463ycd5+dg== -"@swc/core@^1.0.0", "@swc/core@^1.4.16": +"@swc/core@^1.4.16": version "1.4.17" resolved "https://registry.npmjs.org/@swc/core/-/core-1.4.17.tgz" integrity sha512-tq+mdWvodMBNBBZbwFIMTVGYHe9N7zvEaycVVjfvAx20k1XozHbHhRv+9pEVFJjwRxLdXmtvFZd3QZHRAOpoNQ== @@ -991,12 +1366,12 @@ dependencies: "@types/ms" "*" -"@types/estree@^1.0.0", "@types/estree@1.0.5": +"@types/estree@1.0.5", "@types/estree@^1.0.0": version "1.0.5" resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== -"@types/fs-extra@^9.0.11", "@types/fs-extra@9.0.13": +"@types/fs-extra@9.0.13", "@types/fs-extra@^9.0.11": version "9.0.13" resolved "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz" integrity sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA== @@ -1053,7 +1428,7 @@ resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz" integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== -"@types/node@*", "@types/node@^18.0.0 || >=20.0.0", "@types/node@^20.12.7": +"@types/node@*", "@types/node@^20.12.7": version "20.12.8" resolved "https://registry.npmjs.org/@types/node/-/node-20.12.8.tgz" integrity sha512-NU0rJLJnshZWdE/097cdCBbyW1h4hEg0xpovcoAQYHl8dnEyp/NAOiE45pvc+Bd1Dt+2r94v2eGFpQJ4R7g+2w== @@ -1083,6 +1458,14 @@ "@types/node" "*" "@types/parse-torrent-file" "*" +"@types/plist@^3.0.1": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/plist/-/plist-3.0.5.tgz#9a0c49c0f9886c8c8696a7904dd703f6284036e0" + integrity sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA== + dependencies: + "@types/node" "*" + xmlbuilder ">=11.0.1" + "@types/prop-types@*": version "15.7.12" resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz" @@ -1095,7 +1478,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^18.2.25", "@types/react@^18.2.48": +"@types/react@*", "@types/react@^18.2.48": version "18.3.1" resolved "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz" integrity sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw== @@ -1130,6 +1513,11 @@ resolved "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz" integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA== +"@types/verror@^1.10.3": + version "1.10.10" + resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.10.tgz#d5a4b56abac169bfbc8b23d291363a682e6fa087" + integrity sha512-l4MM0Jppn18hb9xmM6wwD1uTdShpf9Pn80aXTStnK1C94gtPvJcV2FrDmbOQUAQfJ1cKZHktkQUDwEqaAKXMMg== + "@types/yauzl@^2.9.1": version "2.10.3" resolved "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz" @@ -1154,7 +1542,7 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/parser@^6.0.0 || ^6.0.0-alpha", "@typescript-eslint/parser@^6.14.0": +"@typescript-eslint/parser@^6.14.0": version "6.21.0" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz" integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== @@ -1235,7 +1623,7 @@ dependencies: "@babel/core" "^7.23.9" -"@vanilla-extract/css@^1.0.0", "@vanilla-extract/css@^1.14.2", "@vanilla-extract/css@^1.15.1": +"@vanilla-extract/css@^1.14.2", "@vanilla-extract/css@^1.15.1": version "1.15.1" resolved "https://registry.npmjs.org/@vanilla-extract/css/-/css-1.15.1.tgz" integrity sha512-puAfTKAUtsMr2+D+grQNjU5umsdw9zdVgQflUlbzS/tGORaAHdgaYz7jfKPmz1c4ZcpJ6uFNOiI50NDOAzzhyg== @@ -1303,11 +1691,6 @@ resolved "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz" integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw== -"7zip-bin@~5.2.0": - version "5.2.0" - resolved "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.2.0.tgz" - integrity sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A== - abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz" @@ -1320,18 +1703,11 @@ acorn-jsx@^5.3.2: resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.11.3, acorn@^8.8.1, acorn@^8.9.0: +acorn@^8.11.3, acorn@^8.8.1, acorn@^8.9.0: version "8.11.3" resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== -agent-base@^7.0.2, agent-base@^7.1.0: - version "7.1.1" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz" - integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA== - dependencies: - debug "^4.3.4" - agent-base@6: version "6.0.2" resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" @@ -1339,12 +1715,19 @@ agent-base@6: dependencies: debug "4" +agent-base@^7.0.2, agent-base@^7.1.0: + version "7.1.1" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz" + integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA== + dependencies: + debug "^4.3.4" + ajv-keywords@^3.4.1: version "3.5.2" resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.12.0, ajv@^6.12.4, ajv@^6.9.1: +ajv@^6.10.0, ajv@^6.12.0, ajv@^6.12.4: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1371,14 +1754,7 @@ ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.0.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^4.1.0: +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== @@ -1446,51 +1822,6 @@ app-root-path@^3.1.0: resolved "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz" integrity sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA== -archiver-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz" - integrity sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw== - dependencies: - glob "^7.1.4" - graceful-fs "^4.2.0" - lazystream "^1.0.0" - lodash.defaults "^4.2.0" - lodash.difference "^4.5.0" - lodash.flatten "^4.4.0" - lodash.isplainobject "^4.0.6" - lodash.union "^4.6.0" - normalize-path "^3.0.0" - readable-stream "^2.0.0" - -archiver-utils@^3.0.4: - version "3.0.4" - resolved "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz" - integrity sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw== - dependencies: - glob "^7.2.3" - graceful-fs "^4.2.0" - lazystream "^1.0.0" - lodash.defaults "^4.2.0" - lodash.difference "^4.5.0" - lodash.flatten "^4.4.0" - lodash.isplainobject "^4.0.6" - lodash.union "^4.6.0" - normalize-path "^3.0.0" - readable-stream "^3.6.0" - -archiver@^5.3.1: - version "5.3.2" - resolved "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz" - integrity sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw== - dependencies: - archiver-utils "^2.1.0" - async "^3.2.4" - buffer-crc32 "^0.2.1" - readable-stream "^3.6.0" - readdir-glob "^1.1.2" - tar-stream "^2.2.0" - zip-stream "^4.1.0" - argparse@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" @@ -1588,12 +1919,22 @@ arraybuffer.prototype.slice@^1.0.3: is-array-buffer "^3.0.4" is-shared-array-buffer "^1.0.2" +assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + async-exit-hook@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz" integrity sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw== -async@^3.2.3, async@^3.2.4: +async@^3.2.3: version "3.2.5" resolved "https://registry.npmjs.org/async/-/async-3.2.5.tgz" integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== @@ -1651,7 +1992,7 @@ bep53-range@^2.0.0: resolved "https://registry.npmjs.org/bep53-range/-/bep53-range-2.0.0.tgz" integrity sha512-sMm2sV5PRs0YOVk0LTKtjuIprVzxgTQUsrGX/7Yph2Rm4FO2Fqqtq7hNjsOB5xezM4v4+5rljCgK++UeQJZguA== -"better-sqlite3@^7.1.2 || ^8.0.0 || ^9.0.0", better-sqlite3@^9.5.0: +better-sqlite3@^9.5.0: version "9.6.0" resolved "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-9.6.0.tgz" integrity sha512-yR5HATnqeYNVnkaUTf4bOP2dJSnyhP4puJN/QPRyx4YkBEEUxib422n2XzPqDEHjQQqazoYoADdAm5vE15+dAQ== @@ -1719,7 +2060,7 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.22.2, "browserslist@>= 4.21.0": +browserslist@^4.22.2: version "4.23.0" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz" integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== @@ -1729,7 +2070,7 @@ browserslist@^4.22.2, "browserslist@>= 4.21.0": node-releases "^2.0.14" update-browserslist-db "^1.0.13" -buffer-crc32@^0.2.1, buffer-crc32@^0.2.13, buffer-crc32@~0.2.3: +buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== @@ -1744,7 +2085,7 @@ buffer-from@^1.0.0: resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer@^5.5.0: +buffer@^5.1.0, buffer@^5.5.0: version "5.7.1" resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -1773,8 +2114,8 @@ builder-util@24.13.1: resolved "https://registry.npmjs.org/builder-util/-/builder-util-24.13.1.tgz" integrity sha512-NhbCSIntruNDTOVI9fdXz0dihaqX2YuE1D6zZMrwiErzH4ELZHE6mdiB40wEgZNprDia+FghRFgKoAqMZRRjSA== dependencies: - "@types/debug" "^4.1.6" "7zip-bin" "~5.2.0" + "@types/debug" "^4.1.6" app-builder-bin "4.0.0" bluebird-lst "^1.0.9" builder-util-runtime "9.2.4" @@ -1848,23 +2189,7 @@ chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^4.0.2: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -1929,6 +2254,14 @@ cli-highlight@^2.1.11: parse5-htmlparser2-tree-adapter "^6.0.0" yargs "^16.0.0" +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + cliui@^7.0.2: version "7.0.4" resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" @@ -1968,7 +2301,7 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@^1.0.0, color-name@1.1.3: +color-name@1.1.3, color-name@^1.0.0: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== @@ -1978,7 +2311,7 @@ color-name@~1.1.4: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^1.6.0: +color-string@^1.6.0, color-string@^1.9.0: version "1.9.1" resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz" integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== @@ -1999,6 +2332,14 @@ color@^3.1.3: color-convert "^1.9.3" color-string "^1.6.0" +color@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a" + integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== + dependencies: + color-convert "^2.0.1" + color-string "^1.9.0" + colorspace@1.1.x: version "1.1.4" resolved "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz" @@ -2024,16 +2365,6 @@ compare-version@^0.1.2: resolved "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz" integrity sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A== -compress-commons@^4.1.2: - version "4.1.2" - resolved "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz" - integrity sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg== - dependencies: - buffer-crc32 "^0.2.13" - crc32-stream "^4.0.2" - normalize-path "^3.0.0" - readable-stream "^3.6.0" - concat-map@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" @@ -2057,9 +2388,9 @@ convert-source-map@^2.0.0: resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== -core-util-is@~1.0.0: +core-util-is@1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== cosmiconfig@^8.1.3: @@ -2072,18 +2403,12 @@ cosmiconfig@^8.1.3: parse-json "^5.2.0" path-type "^4.0.0" -crc-32@^1.2.0: - version "1.2.2" - resolved "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz" - integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== - -crc32-stream@^4.0.2: - version "4.0.3" - resolved "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz" - integrity sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw== +crc@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/crc/-/crc-3.8.0.tgz#ad60269c2c856f8c299e2c4cc0de4556914056c6" + integrity sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ== dependencies: - crc-32 "^1.2.0" - readable-stream "^3.4.0" + buffer "^5.1.0" cross-fetch-ponyfill@^1.0.3: version "1.0.3" @@ -2174,7 +2499,7 @@ dayjs@^1.11.9: resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz" integrity sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg== -debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@4: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -2213,7 +2538,7 @@ deep-object-diff@^1.1.9: resolved "https://registry.npmjs.org/deep-object-diff/-/deep-object-diff-1.1.9.tgz" integrity sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA== -deepmerge@^4.2.2, deepmerge@4.3.0: +deepmerge@4.3.0, deepmerge@^4.2.2: version "4.3.0" resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz" integrity sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og== @@ -2285,6 +2610,20 @@ dmg-builder@24.13.3: optionalDependencies: dmg-license "^1.0.11" +dmg-license@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/dmg-license/-/dmg-license-1.0.11.tgz#7b3bc3745d1b52be7506b4ee80cb61df6e4cd79a" + integrity sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q== + 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" + doctrine@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" @@ -2339,16 +2678,6 @@ ejs@^3.1.8: dependencies: jake "^10.8.5" -electron-builder-squirrel-windows@24.13.3: - version "24.13.3" - resolved "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-24.13.3.tgz" - integrity sha512-oHkV0iogWfyK+ah9ZIvMDpei1m9ZRpdXcvde1wTpra2U8AFDNNpqJdnin5z+PM1GbQ5BoaKCWas2HSjtR0HwMg== - dependencies: - app-builder-lib "24.13.3" - archiver "^5.3.1" - builder-util "24.13.1" - fs-extra "^10.1.0" - electron-builder@^24.9.1: version "24.13.3" resolved "https://registry.npmjs.org/electron-builder/-/electron-builder-24.13.3.tgz" @@ -2396,7 +2725,7 @@ electron-vite@^2.0.0: magic-string "^0.30.5" picocolors "^1.0.0" -electron@^28.2.0, electron@>=13.0.0: +electron@^28.2.0: version "28.3.1" resolved "https://registry.npmjs.org/electron/-/electron-28.3.1.tgz" integrity sha512-aF9fONuhVDJlctJS7YOw76ynxVAQdfIWmlhRMKits24tDcdSL0eMHUS0wWYiRfGWbQnUKB6V49Rf17o32f4/fg== @@ -2643,7 +2972,7 @@ escape-string-regexp@^4.0.0: resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-config-prettier@*, eslint-config-prettier@^9.1.0: +eslint-config-prettier@^9.1.0: version "9.1.0" resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz" integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== @@ -2698,7 +3027,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -"eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", eslint@^8.56.0, "eslint@>= 8.0.0", eslint@>=7.0.0, eslint@>=8.0.0: +eslint@^8.56.0: version "8.57.0" resolved "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz" integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== @@ -2809,6 +3138,11 @@ extract-zip@^2.0.1: optionalDependencies: "@types/yauzl" "^2.9.1" +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" @@ -2974,16 +3308,7 @@ fs-constants@^1.0.0: resolved "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@^10.0.0: - 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== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^10.1.0: +fs-extra@^10.0.0, fs-extra@^10.1.0: 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== @@ -3001,17 +3326,7 @@ fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^9.0.0: - version "9.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^9.0.1: +fs-extra@^9.0.0, fs-extra@^9.0.1: version "9.1.0" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -3033,6 +3348,11 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" @@ -3100,7 +3420,7 @@ github-from-package@0.0.0: resolved "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz" integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== -glob-parent@^5.1.2: +glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -3114,13 +3434,6 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - glob@^10.3.10: version "10.3.12" resolved "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz" @@ -3132,43 +3445,7 @@ glob@^10.3.10: minipass "^7.0.4" path-scurry "^1.10.2" -glob@^7.1.3: - version "7.2.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.4: - version "7.2.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.6: - version "7.2.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.2.3: +glob@^7.1.3, glob@^7.1.6: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -3400,14 +3677,22 @@ i18next-browser-languagedetector@^7.2.1: dependencies: "@babel/runtime" "^7.23.2" -i18next@^23.11.2, "i18next@>= 23.2.3": +i18next@^23.11.2: version "23.11.3" resolved "https://registry.npmjs.org/i18next/-/i18next-23.11.3.tgz" integrity sha512-Pq/aSKowir7JM0rj+Wa23Kb6KKDUGno/HjG+wRQu0PxoTbpQ4N89MAT0rFGvXmLkRLNMb1BbBOKGozl01dabzg== dependencies: "@babel/runtime" "^7.23.2" -iconv-lite@^0.6.2, iconv-lite@0.6.3: +iconv-corefoundation@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz#31065e6ab2c9272154c8b0821151e2c88f1b002a" + integrity sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ== + dependencies: + cli-truncate "^2.1.0" + node-addon-api "^1.6.3" + +iconv-lite@0.6.3, iconv-lite@^0.6.2: version "0.6.3" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -3455,7 +3740,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@2: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -3688,11 +3973,6 @@ isarray@^2.0.5: resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - isbinaryfile@^4.0.8: version "4.0.10" resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz" @@ -3860,13 +4140,6 @@ lazy-val@^1.0.4, lazy-val@^1.0.5: resolved "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz" integrity sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q== -lazystream@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz" - integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw== - dependencies: - readable-stream "^2.0.5" - levn@^0.4.1: version "0.4.1" resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" @@ -3911,36 +4184,11 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz" integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== -lodash.defaults@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz" - integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== - -lodash.difference@^4.5.0: - version "4.5.0" - resolved "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz" - integrity sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA== - -lodash.flatten@^4.4.0: - version "4.4.0" - resolved "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz" - integrity sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g== - -lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz" - integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== - lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.union@^4.6.0: - version "4.6.0" - resolved "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz" - integrity sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw== - lodash@^4.17.15: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" @@ -4008,7 +4256,7 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -magic-string@^0.30.5, magic-string@0.30.8: +magic-string@0.30.8, magic-string@^0.30.5: version "0.30.8" resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz" integrity sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ== @@ -4078,42 +4326,21 @@ mimic-response@^3.1.0: resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== -minimatch@^3.0.4, minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.0.5: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^5.0.1: - version "5.1.6" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== +minimatch@9.0.3, minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== dependencies: brace-expansion "^2.0.1" -minimatch@^5.1.0: - version "5.1.6" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: - brace-expansion "^2.0.1" + brace-expansion "^1.1.7" -minimatch@^5.1.1: +minimatch@^5.0.1, minimatch@^5.1.1: version "5.1.6" resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== @@ -4127,13 +4354,6 @@ minimatch@^8.0.2: dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.1, minimatch@9.0.3: - version "9.0.3" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: version "1.2.8" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" @@ -4151,17 +4371,12 @@ minipass@^4.2.4: resolved "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz" integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ== -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": - version "7.0.4" - resolved "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz" - integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== - minipass@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz" integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== -minipass@^7.0.4: +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.4: version "7.0.4" resolved "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz" integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== @@ -4204,7 +4419,7 @@ modern-ahocorasick@^1.0.0: resolved "https://registry.npmjs.org/modern-ahocorasick/-/modern-ahocorasick-1.0.1.tgz" integrity sha512-yoe+JbhTClckZ67b2itRtistFKf8yPYelHLc7e5xAwtNAXxM6wJTUx2C7QeVSJFDzKT7bCIFyBVybPMKvmB9AA== -ms@^2.1.1, ms@2.1.2: +ms@2.1.2, ms@^2.1.1: version "2.1.2" resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== @@ -4248,6 +4463,11 @@ node-abi@^3.3.0: dependencies: semver "^7.3.5" +node-addon-api@^1.6.3: + version "1.7.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.7.2.tgz#3df30b95720b53c24e59948b49532b662444f54d" + integrity sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg== + node-domexception@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz" @@ -4274,11 +4494,6 @@ node-releases@^2.0.14: resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz" integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== -node-unrar-js@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/node-unrar-js/-/node-unrar-js-2.0.2.tgz" - integrity sha512-hLNmoJzqaKJnod8yiTVGe9hnlNRHotUi0CreSv/8HtfRi/3JnRC8DvsmKfeGGguRjTEulhZK6zXX5PXoVuDZ2w== - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" @@ -4569,16 +4784,11 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^3.2.4, "prettier@>= 3.0.0", prettier@>=3.0.0: +prettier@^3.2.4: version "3.2.5" resolved "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz" integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - progress@^2.0.3: version "2.0.3" resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" @@ -4654,7 +4864,7 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -"react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", react-dom@^18.2.0, react-dom@>=16.8: +react-dom@^18.2.0: version "18.3.1" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== @@ -4680,7 +4890,7 @@ react-loading-skeleton@^3.4.0: resolved "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.4.0.tgz" integrity sha512-1oJEBc9+wn7BbkQQk7YodlYEIjgeR+GrRjD+QXkVjwZN7LGIcAFHrx4NhT7UHGBxNY1+zax3c+Fo6XQM4R7CgA== -"react-redux@^7.2.1 || ^8.1.3 || ^9.0.0", react-redux@^9.1.1: +react-redux@^9.1.1: version "9.1.2" resolved "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz" integrity sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w== @@ -4708,7 +4918,7 @@ react-router@6.23.0: dependencies: "@remix-run/router" "1.16.0" -"react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.9.0 || ^17.0.0 || ^18", react@^18.0, react@^18.2.0, react@^18.3.1, "react@>= 16.8.0", react@>=16.3, react@>=16.8, react@>=16.8.0, "react@15.x || 16.x || 17.x || 18.x": +react@^18.2.0: version "18.3.1" resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== @@ -4727,32 +4937,6 @@ read-config-file@6.3.2: json5 "^2.2.0" lazy-val "^1.0.4" -readable-stream@^2.0.0: - version "2.3.8" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^2.0.5: - version "2.3.8" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.2" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" @@ -4762,13 +4946,6 @@ readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readdir-glob@^1.1.2: - version "1.1.3" - resolved "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz" - integrity sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA== - dependencies: - minimatch "^5.1.0" - readdirp@~3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" @@ -4781,7 +4958,7 @@ redux-thunk@^3.1.0: resolved "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz" integrity sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw== -redux@^5.0.0, redux@^5.0.1: +redux@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz" integrity sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w== @@ -4894,7 +5071,7 @@ roarr@^2.15.3: semver-compare "^1.0.0" sprintf-js "^1.1.2" -rollup@^1.20.0||^2.0.0||^3.0.0||^4.0.0, rollup@^4.13.0: +rollup@^4.13.0: version "4.17.2" resolved "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz" integrity sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ== @@ -4946,11 +5123,6 @@ safe-buffer@^5.0.1, safe-buffer@~5.2.0: resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - safe-regex-test@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz" @@ -5006,35 +5178,7 @@ semver@^6.2.0, semver@^6.3.1: resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.2: - 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" - -semver@^7.3.5: - 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" - -semver@^7.3.8: - 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" - -semver@^7.5.3: - 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" - -semver@^7.5.4: +semver@^7.3.2, semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: version "7.6.0" resolved "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz" integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== @@ -5143,6 +5287,20 @@ slash@^3.0.0: resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +smart-buffer@^4.0.2: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + snake-case@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz" @@ -5184,20 +5342,6 @@ stat-mode@^1.0.0: resolved "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz" integrity sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg== -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - "string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" @@ -5271,6 +5415,13 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + "strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -5356,7 +5507,7 @@ tar-fs@^2.0.0: pump "^3.0.0" tar-stream "^2.1.4" -tar-stream@^2.1.4, tar-stream@^2.2.0: +tar-stream@^2.1.4: version "2.2.0" resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz" integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== @@ -5568,7 +5719,7 @@ typeorm@^0.3.20: uuid "^9.0.0" yargs "^17.6.2" -typescript@*, typescript@^5.3.3, typescript@>=4.2.0, typescript@>=4.9.5: +typescript@^5.3.3: version "5.4.5" resolved "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz" integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== @@ -5665,7 +5816,7 @@ utf8-byte-length@^1.0.1: resolved "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz" integrity sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA== -util-deprecate@^1.0.1, util-deprecate@~1.0.1: +util-deprecate@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== @@ -5675,6 +5826,15 @@ uuid@^9.0.0: resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz" integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== +verror@^1.10.0: + version "1.10.1" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.1.tgz#4bf09eeccf4563b109ed4b3d458380c972b0cdeb" + integrity sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + vite-node@^1.2.0: version "1.6.0" resolved "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz" @@ -5695,7 +5855,7 @@ vite-plugin-svgr@^4.2.0: "@svgr/core" "^8.1.0" "@svgr/plugin-jsx" "^8.1.0" -"vite@^2.6.0 || 3 || 4 || 5", "vite@^4.0.0 || ^5.0.0", "vite@^4.0.3 || ^5.0.0", "vite@^4.2.0 || ^5.0.0", vite@^5.0.0, vite@^5.0.11, vite@^5.0.12: +vite@^5.0.0, vite@^5.0.11, vite@^5.0.12: version "5.2.11" resolved "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz" integrity sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ== @@ -5901,7 +6061,7 @@ xml-name-validator@^5.0.0: resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz" integrity sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg== -xmlbuilder@^15.1.1: +xmlbuilder@>=11.0.1, xmlbuilder@^15.1.1: version "15.1.1" resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz" integrity sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg== @@ -5979,12 +6139,3 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -zip-stream@^4.1.0: - version "4.1.1" - resolved "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz" - integrity sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ== - dependencies: - archiver-utils "^3.0.4" - compress-commons "^4.1.2" - readable-stream "^3.6.0" From 072b4dc4d3e79831e51ea03e64bbda5b739fc347 Mon Sep 17 00:00:00 2001 From: Hydra Date: Tue, 7 May 2024 09:40:51 +0100 Subject: [PATCH 40/52] chore: updating yarn.lock --- src/locales/ru/translation.json | 2 +- src/main/events/misc/show-open-dialog.ts | 4 +- .../src/pages/game-details/gallery-slider.tsx | 89 +++++++++++-------- .../pages/game-details/game-details.css.ts | 15 ++-- yarn.lock | 3 - 5 files changed, 62 insertions(+), 51 deletions(-) diff --git a/src/locales/ru/translation.json b/src/locales/ru/translation.json index 2f5244ff..5372420d 100644 --- a/src/locales/ru/translation.json +++ b/src/locales/ru/translation.json @@ -138,7 +138,7 @@ "telemetry": "Телеметрия", "telemetry_description": "Включить анонимную статистику использования", "behavior": "Поведение", - "quit_app_instead_hiding": "Закрывать приложение вместо того, чтобы сворачивать его в трей" + "quit_app_instead_hiding": "Закрывать приложение вместо того, чтобы сворачивать его в трей", "launch_with_system": "Запуск приложения при запуске системы" }, "notifications": { diff --git a/src/main/events/misc/show-open-dialog.ts b/src/main/events/misc/show-open-dialog.ts index baa6a016..b107409a 100644 --- a/src/main/events/misc/show-open-dialog.ts +++ b/src/main/events/misc/show-open-dialog.ts @@ -7,8 +7,10 @@ const showOpenDialog = async ( options: Electron.OpenDialogOptions ) => { if (WindowManager.mainWindow) { - dialog.showOpenDialog(WindowManager.mainWindow, options); + return dialog.showOpenDialog(WindowManager.mainWindow, options); } + + throw new Error("Main window is not available"); }; registerEvent(showOpenDialog, { diff --git a/src/renderer/src/pages/game-details/gallery-slider.tsx b/src/renderer/src/pages/game-details/gallery-slider.tsx index 87eafb8f..d506103c 100644 --- a/src/renderer/src/pages/game-details/gallery-slider.tsx +++ b/src/renderer/src/pages/game-details/gallery-slider.tsx @@ -1,4 +1,4 @@ -import { RefObject, useEffect, useRef, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { ShopDetails, SteamMovies, SteamScreenshot } from "@types"; import { ChevronRightIcon, ChevronLeftIcon } from "@primer/octicons-react"; import * as styles from "./game-details.css"; @@ -8,8 +8,8 @@ export interface GallerySliderProps { } export function GallerySlider({ gameDetails }: GallerySliderProps) { - const scrollContainerRef: RefObject = - useRef(null); + const scrollContainerRef = useRef(null); + const [mediaCount] = useState(() => { if (gameDetails) { if (gameDetails.screenshots && gameDetails.movies) { @@ -25,16 +25,6 @@ export function GallerySlider({ gameDetails }: GallerySliderProps) { const [mediaIndex, setMediaIndex] = useState(0); const [arrowShow, setArrowShow] = useState(false); - const scrollHorizontallyToPercentage = () => { - if (scrollContainerRef.current) { - const container = scrollContainerRef.current; - const totalWidth = container.scrollWidth - container.clientWidth; - const itemWidth = totalWidth / (mediaCount - 1); - const scrollLeft = mediaIndex * itemWidth; - container.scrollLeft = scrollLeft; - } - }; - const showNextImage = () => { setMediaIndex((index: number) => { if (index === mediaCount - 1) return 0; @@ -42,6 +32,7 @@ export function GallerySlider({ gameDetails }: GallerySliderProps) { return index + 1; }); }; + const showPrevImage = () => { setMediaIndex((index: number) => { if (index === 0) return mediaCount - 1; @@ -51,11 +42,21 @@ export function GallerySlider({ gameDetails }: GallerySliderProps) { }; useEffect(() => { - scrollHorizontallyToPercentage(); - }, [mediaIndex]); + if (scrollContainerRef.current) { + const container = scrollContainerRef.current; + const totalWidth = container.scrollWidth - container.clientWidth; + const itemWidth = totalWidth / (mediaCount - 1); + const scrollLeft = mediaIndex * itemWidth; + container.scrollLeft = scrollLeft; + } + }, [mediaIndex, mediaCount]); + + const hasScreenshots = gameDetails && gameDetails.screenshots.length > 0; + const hasMovies = gameDetails && gameDetails.movies.length > 0; + return ( <> - {gameDetails?.screenshots && ( + {hasScreenshots && (
setArrowShow(true)} @@ -65,33 +66,41 @@ export function GallerySlider({ gameDetails }: GallerySliderProps) { {gameDetails.movies && gameDetails.movies.map((video: SteamMovies) => ( ))} - {gameDetails.screenshots && - gameDetails.screenshots.map((image: SteamScreenshot) => ( - - ))} + + {gameDetails.screenshots.map((image: SteamScreenshot) => ( + + ))} + {arrowShow && ( <> +
- {gameDetails.movies && + {hasMovies && gameDetails.movies.map((video: SteamMovies, i: number) => ( setMediaIndex(i)} src={video.thumbnail} className={`${styles.gallerySliderMediaPreview} ${mediaIndex === i ? styles.gallerySliderMediaPreviewActive : ""}`} /> ))} - {gameDetails.screenshots && - gameDetails.screenshots.map( - (image: SteamScreenshot, i: number) => ( - - setMediaIndex( - i + (gameDetails.movies ? gameDetails.movies.length : 0) - ) - } - className={`${styles.gallerySliderMediaPreview} ${mediaIndex === i + (gameDetails.movies ? gameDetails.movies.length : 0) ? styles.gallerySliderMediaPreviewActive : ""}`} - src={image.path_full} - /> - ) - )} + + {gameDetails.screenshots.map( + (image: SteamScreenshot, i: number) => ( + + setMediaIndex( + i + (gameDetails.movies ? gameDetails.movies.length : 0) + ) + } + className={`${styles.gallerySliderMediaPreview} ${mediaIndex === i + (gameDetails.movies ? gameDetails.movies.length : 0) ? styles.gallerySliderMediaPreviewActive : ""}`} + src={image.path_full} + /> + ) + )}
)} diff --git a/src/renderer/src/pages/game-details/game-details.css.ts b/src/renderer/src/pages/game-details/game-details.css.ts index 647fc0ec..8b331480 100644 --- a/src/renderer/src/pages/game-details/game-details.css.ts +++ b/src/renderer/src/pages/game-details/game-details.css.ts @@ -92,8 +92,9 @@ export const gallerySliderMedia = style({ height: "100%", display: "block", flexShrink: 0, - flexGrow: 0, - transition: "translate 300ms ease-in-out", + flexGrow: "0", + transition: "translate 0.3s ease-in-out", + borderRadius: "4px", }); export const gallerySliderAnimationContainer = style({ @@ -123,8 +124,8 @@ export const gallerySliderPreview = style({ }, }, "::-webkit-scrollbar-thumb": { - width: "20%" - } + width: "20%", + }, }); export const gallerySliderMediaPreview = style({ @@ -137,6 +138,7 @@ export const gallerySliderMediaPreview = style({ opacity: 0.3, paddingRight: "5px", transition: "translate 300ms ease-in-out", + borderRadius: "4px", ":hover": { opacity: 1, }, @@ -156,13 +158,12 @@ export const gallerySliderButton = style({ cursor: "pointer", transition: "background-color 100ms ease-in-out", ":hover": { - backgroundColor: "rgb(0,0,0, 0.2)", + backgroundColor: "rgb(0, 0, 0, 0.2)", }, }); export const gallerySliderIcons = style({ - stroke: "white", - fill: "black", + fill: vars.color.muted, width: "2rem", height: "2rem", }); diff --git a/yarn.lock b/yarn.lock index fa415f5a..cdb52ab7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1827,14 +1827,11 @@ app-root-path@^3.1.0: resolved "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz" integrity sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA== -<<<<<<< HEAD -======= applescript@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/applescript/-/applescript-1.0.0.tgz#bb87af568cad034a4e48c4bdaf6067a3a2701317" integrity sha512-yvtNHdWvtbYEiIazXAdp/NY+BBb65/DAseqlNiJQjOx9DynuzOYDbVLBJvuc0ve0VL9x6B3OHF6eH52y9hCBtQ== ->>>>>>> 53e5d2938c050ead27fdc8883d58f75920d63923 argparse@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" From 023e5ebb3e4d4f159b967a54c05890c7703bf84b Mon Sep 17 00:00:00 2001 From: Hydra Date: Tue, 7 May 2024 15:42:16 +0100 Subject: [PATCH 41/52] feat: adding proper path for real debrid downloads --- .../pages/game-details/gallery-slider.css.ts | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/renderer/src/pages/game-details/gallery-slider.css.ts diff --git a/src/renderer/src/pages/game-details/gallery-slider.css.ts b/src/renderer/src/pages/game-details/gallery-slider.css.ts new file mode 100644 index 00000000..c7e0b7c2 --- /dev/null +++ b/src/renderer/src/pages/game-details/gallery-slider.css.ts @@ -0,0 +1,95 @@ +import { SPACING_UNIT, vars } from "../../theme.css"; +import { style } from "@vanilla-extract/css"; + +export const gallerySliderContainer = style({ + padding: `${SPACING_UNIT * 3}px ${SPACING_UNIT * 2}px`, + width: "100%", + display: "flex", + flexDirection: "column", + alignItems: "center", +}); + +export const gallerySliderMedia = style({ + width: "100%", + height: "100%", + display: "block", + flexShrink: 0, + flexGrow: "0", + transition: "translate 0.3s ease-in-out", + borderRadius: "4px", +}); + +export const gallerySliderAnimationContainer = style({ + width: "100%", + height: "100%", + display: "flex", + position: "relative", + overflow: "hidden", + "@media": { + "(min-width: 1280px)": { + width: "60%", + }, + }, +}); + +export const gallerySliderPreview = style({ + width: "100%", + padding: `${SPACING_UNIT}px 0`, + height: "100%", + display: "flex", + position: "relative", + overflowX: "auto", + overflowY: "hidden", + gap: `${SPACING_UNIT / 2}px`, + "@media": { + "(min-width: 1280px)": { + width: "60%", + }, + }, + "::-webkit-scrollbar-thumb": { + width: "20%", + }, + "::-webkit-scrollbar": { + height: "10px", + }, +}); + +export const gallerySliderMediaPreview = style({ + cursor: "pointer", + width: "20%", + height: "20%", + display: "block", + flexShrink: 0, + flexGrow: 0, + opacity: 0.3, + transition: "translate 0.3s ease-in-out, opacity 0.2s ease", + borderRadius: "4px", + border: `solid 1px ${vars.color.border}`, + ":hover": { + opacity: "1", + }, +}); + +export const gallerySliderMediaPreviewActive = style({ + opacity: 1, +}); + +export const gallerySliderButton = style({ + all: "unset", + display: "block", + position: "absolute", + top: 0, + bottom: 0, + padding: "1rem", + cursor: "pointer", + transition: "background-color 100ms ease-in-out", + ":hover": { + backgroundColor: "rgb(0, 0, 0, 0.2)", + }, +}); + +export const gallerySliderIcons = style({ + fill: vars.color.muted, + width: "2rem", + height: "2rem", +}); From 11921099c2cf7c78e94f152c9ed55be1845c2fd4 Mon Sep 17 00:00:00 2001 From: Hydra Date: Tue, 7 May 2024 15:42:41 +0100 Subject: [PATCH 42/52] fix: removing steam disclaimer --- src/renderer/src/pages/game-details/game-details.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/renderer/src/pages/game-details/game-details.tsx b/src/renderer/src/pages/game-details/game-details.tsx index 119adcde..02c880d8 100644 --- a/src/renderer/src/pages/game-details/game-details.tsx +++ b/src/renderer/src/pages/game-details/game-details.tsx @@ -257,13 +257,6 @@ export function GameDetails() { }} className={styles.description} /> - - - All screenshots and movies displayed on this page are the - property of Steam and/or their respective owners. We do not - claim ownership of any content unless otherwise stated. All - content is used for informational and promotional purposes only. -
From 9dc9f120538b5e8cc2ea239126784159009f68de Mon Sep 17 00:00:00 2001 From: Hydra Date: Thu, 9 May 2024 09:40:05 +0100 Subject: [PATCH 43/52] fix: removing translations for real debrid --- src/locales/en/translation.json | 2 +- src/locales/es/translation.json | 3 +-- src/locales/fr/translation.json | 3 +-- src/locales/hu/translation.json | 3 +-- src/locales/it/translation.json | 3 +-- src/locales/pt/translation.json | 1 - src/main/services/window-manager.ts | 2 +- 7 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 1e441854..a766d58b 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -139,7 +139,7 @@ "enable_repack_list_notifications": "When a new repack is added", "telemetry": "Telemetry", "telemetry_description": "Enable anonymous usage statistics", - "real_debrid_api_token_description": "(Optional) Real Debrid API token", + "real_debrid_api_token_description": "Real Debrid API token", "quit_app_instead_hiding": "Quit Hydra instead of minimizing to tray", "launch_with_system": "Launch Hydra on system start-up", "general": "General", diff --git a/src/locales/es/translation.json b/src/locales/es/translation.json index 380f7849..dfc9a5d2 100644 --- a/src/locales/es/translation.json +++ b/src/locales/es/translation.json @@ -130,8 +130,7 @@ "enable_download_notifications": "Cuando se completa una descarga", "enable_repack_list_notifications": "Cuando se añade un repack nuevo", "telemetry": "Telemetría", - "telemetry_description": "Habilitar recopilación de datos de manera anónima", - "real_debrid_api_token_description": "(Opcional) Real Debrid API token" + "telemetry_description": "Habilitar recopilación de datos de manera anónima" }, "notifications": { "download_complete": "Descarga completada", diff --git a/src/locales/fr/translation.json b/src/locales/fr/translation.json index 5cc7632b..2e17f492 100644 --- a/src/locales/fr/translation.json +++ b/src/locales/fr/translation.json @@ -115,8 +115,7 @@ "enable_download_notifications": "Quand un téléchargement est terminé", "enable_repack_list_notifications": "Quand un nouveau repack est ajouté", "telemetry": "Télémétrie", - "telemetry_description": "Activer les statistiques d'utilisation anonymes", - "real_debrid_api_token_description": "(Facultatif) Real Debrid API token" + "telemetry_description": "Activer les statistiques d'utilisation anonymes" }, "notifications": { "download_complete": "Téléchargement terminé", diff --git a/src/locales/hu/translation.json b/src/locales/hu/translation.json index 61a86b6e..8a370fb2 100644 --- a/src/locales/hu/translation.json +++ b/src/locales/hu/translation.json @@ -124,8 +124,7 @@ "enable_download_notifications": "Amikor egy letöltés befejeződik", "enable_repack_list_notifications": "Amikor egy új repack hozzáadásra kerül", "telemetry": "Telemetria", - "telemetry_description": "Névtelen felhasználási statisztikák engedélyezése", - "real_debrid_api_token_description": "(Választható) Real Debrid API token" + "telemetry_description": "Névtelen felhasználási statisztikák engedélyezése" }, "notifications": { "download_complete": "Letöltés befejeződött", diff --git a/src/locales/it/translation.json b/src/locales/it/translation.json index ca2a83f5..b4ff3723 100644 --- a/src/locales/it/translation.json +++ b/src/locales/it/translation.json @@ -136,8 +136,7 @@ "enable_download_notifications": "Quando un download è completo", "enable_repack_list_notifications": "Quando viene aggiunto un nuovo repack", "telemetry": "Telemetria", - "telemetry_description": "Abilita statistiche di utilizzo anonime", - "real_debrid_api_token_description": "(Facoltativo) Real Debrid API token" + "telemetry_description": "Abilita statistiche di utilizzo anonime" }, "notifications": { "download_complete": "Download completato", diff --git a/src/locales/pt/translation.json b/src/locales/pt/translation.json index a23aa995..c5e66c02 100644 --- a/src/locales/pt/translation.json +++ b/src/locales/pt/translation.json @@ -133,7 +133,6 @@ "enable_repack_list_notifications": "Quando a lista de repacks for atualizada", "telemetry": "Telemetria", "telemetry_description": "Habilitar estatísticas de uso anônimas", - "real_debrid_api_token_description": "(Opcional) Real Debrid API token", "behavior": "Comportamento", "quit_app_instead_hiding": "Fechar o aplicativo em vez de minimizá-lo", "launch_with_system": "Iniciar aplicativo na inicialização do sistema" diff --git a/src/main/services/window-manager.ts b/src/main/services/window-manager.ts index f810acd5..cf846daf 100644 --- a/src/main/services/window-manager.ts +++ b/src/main/services/window-manager.ts @@ -105,7 +105,7 @@ export class WindowManager { tray.setToolTip("Hydra"); tray.setContextMenu(contextMenu); - if (process.platform === "win32") { + if (process.platform === "win32" || process.platform === "linux") { tray.addListener("click", () => { if (this.mainWindow) { if (WindowManager.mainWindow?.isMinimized()) From 655af0b8634da2ed7167af9df11cf618520513fc Mon Sep 17 00:00:00 2001 From: v1mkss <155435591+v1mkss@users.noreply.github.com> Date: Sun, 12 May 2024 10:52:06 +0300 Subject: [PATCH 44/52] fix readme --- README.uk-UA.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.uk-UA.md b/README.uk-UA.md index 82ae7261..0c259c87 100644 --- a/README.uk-UA.md +++ b/README.uk-UA.md @@ -64,7 +64,7 @@ ## Встановлення -Follow the steps below to install: +Щоб встановити, виконайте наведені нижче кроки: 1. Завантажте останню версію Hydra зі сторінки [Releases](https://github.com/hydralauncher/hydra/releases/latest). - Завантажте лише .exe, якщо ви хочете встановити Hydra на Windows. @@ -92,8 +92,8 @@ Follow the steps below to install: ### Як ви можете зробити свій внесок -- Translation: We want Hydra to be available to as many people as possible. Feel free to help translate to new languages or update and improve the ones that are already available on Hydra. -- Code: Hydra is built with Typescript, Electron and a little bit of Python. If you want to contribute, join our Telegram! +- Переклад: Ми хочемо, щоб Hydra була доступна якомога більшій кількості людей. Не соромтеся допомагати перекладати на нові мови або оновлювати і покращувати ті, які вже доступні на Hydra. +- Код: Hydra створена за допомогою Typescript, Electron і трохи Python. Якщо ви хочете зробити свій внесок, приєднуйтесь до нашого Telegram! ### Структура проекту From b413c673fd5155c43b8fd68bb1e6ded85c5875a0 Mon Sep 17 00:00:00 2001 From: Antecess <59663394+xxDRV@users.noreply.github.com> Date: Sun, 12 May 2024 16:40:26 +0500 Subject: [PATCH 45/52] Changed "Telegram server" to "Telegram channel" in uk-UA --- README.uk-UA.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.uk-UA.md b/README.uk-UA.md index 0c259c87..cd49eca9 100644 --- a/README.uk-UA.md +++ b/README.uk-UA.md @@ -76,7 +76,7 @@ ### Приєднуйтесь до нашого Telegram -Ми зосереджуємо наші дискусії на нашому сервері [Telegram](https://t.me/hydralauncher). +Ми зосереджуємо наші дискусії на нашому каналі [Telegram](https://t.me/hydralauncher). 1. Приєднуйтесь до нашого сервера 2. Перейдіть на канал ролей і виберіть роль Співробітник From d7c68073708f2c0fd57041957bea43e97397ba80 Mon Sep 17 00:00:00 2001 From: Antecess <59663394+xxDRV@users.noreply.github.com> Date: Sun, 12 May 2024 16:45:05 +0500 Subject: [PATCH 46/52] Update README.uk-UA.md --- README.uk-UA.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.uk-UA.md b/README.uk-UA.md index cd49eca9..3b77009a 100644 --- a/README.uk-UA.md +++ b/README.uk-UA.md @@ -78,7 +78,7 @@ Ми зосереджуємо наші дискусії на нашому каналі [Telegram](https://t.me/hydralauncher). -1. Приєднуйтесь до нашого сервера +1. Приєднуйтесь до нашого канала 2. Перейдіть на канал ролей і виберіть роль Співробітник 3. Заходьте на dev-канал, спілкуйтеся з нами та діліться своїми ідеями. From 081823cd8ce0037ed5ae70b16f3465d291af9ab9 Mon Sep 17 00:00:00 2001 From: Antecess <59663394+xxDRV@users.noreply.github.com> Date: Sun, 12 May 2024 16:45:41 +0500 Subject: [PATCH 47/52] Update README.ru.md --- README.ru.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.ru.md b/README.ru.md index 5c0a5c6d..78220ad4 100644 --- a/README.ru.md +++ b/README.ru.md @@ -89,7 +89,7 @@ ### Способы внести свой вклад - Перевод: Мы хотим, чтобы Hydra была доступна как можно большему количеству людей. Не стесняйтесь помогать переводить на новые языки или обновлять и улучшать те, которые уже доступны в Hydra. -- Код: Hydra создан с использованием TypeScript, Electron и немного Python. Если хотите внести свой вклад, присоединяйтесь к нашему серверу [Telegram](https://t.me/hydralauncher)! +- Код: Hydra создан с использованием TypeScript, Electron и немного Python. Если хотите внести свой вклад, присоединяйтесь к нашему каналу [Telegram](https://t.me/hydralauncher)! ### Структура проекта From c29f28dbdd93557592599f87a3d1f2fc93b42031 Mon Sep 17 00:00:00 2001 From: Hydra Date: Sun, 12 May 2024 13:29:12 +0100 Subject: [PATCH 48/52] fix: fixing tsc errors --- src/locales/en/translation.json | 3 ++- src/locales/pt/translation.json | 9 +++++-- src/main/constants.ts | 2 -- .../events/helpers/generate-lutris-yaml.ts | 4 +-- .../events/library/open-game-installer.ts | 2 +- .../downloaders/real-debrid.downloader.ts | 7 ++--- src/main/services/real-debrid.ts | 1 + src/main/services/repack-tracker/1337x.ts | 26 +++++-------------- .../services/repack-tracker/cpg-repacks.ts | 18 ++++++------- src/main/services/repack-tracker/gog.ts | 10 +++---- .../services/repack-tracker/online-fix.ts | 20 +++++++------- src/main/services/repack-tracker/xatab.ts | 26 ++++++++----------- src/renderer/src/assets/telegram-icon.svg | 2 +- src/renderer/src/assets/x-icon.svg | 2 +- src/renderer/src/hooks/use-download.ts | 3 +-- .../src/pages/downloads/downloads.tsx | 3 +-- .../pages/game-details/hero/hero-panel.tsx | 3 +-- .../game-details/select-folder-modal.tsx | 4 +-- .../pages/settings/settings-real-debrid.tsx | 2 +- src/renderer/src/utils/format-bytes.ts | 15 ----------- src/renderer/src/utils/index.ts | 1 - src/shared/index.ts | 16 ++++++++++++ 22 files changed, 79 insertions(+), 100 deletions(-) delete mode 100644 src/renderer/src/utils/format-bytes.ts delete mode 100644 src/renderer/src/utils/index.ts diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 167eb0be..0674d1b5 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -146,7 +146,8 @@ "behavior": "Behavior", "enable_real_debrid": "Enable Real Debrid", "real_debrid": "Real Debrid", - "real_debrid_api_token_hint": "You can get your API key <0>here" + "real_debrid_api_token_hint": "You can get your API key <0>here.", + "save_changes": "Save changes" }, "notifications": { "download_complete": "Download complete", diff --git a/src/locales/pt/translation.json b/src/locales/pt/translation.json index 2ee0d827..dda53065 100644 --- a/src/locales/pt/translation.json +++ b/src/locales/pt/translation.json @@ -133,9 +133,14 @@ "enable_repack_list_notifications": "Quando a lista de repacks for atualizada", "telemetry": "Telemetria", "telemetry_description": "Habilitar estatísticas de uso anônimas", - "behavior": "Comportamento", "quit_app_instead_hiding": "Fechar o aplicativo em vez de minimizá-lo", - "launch_with_system": "Iniciar aplicativo na inicialização do sistema" + "launch_with_system": "Iniciar aplicativo na inicialização do sistema", + "general": "Geral", + "behavior": "Comportamento", + "enable_real_debrid": "Habilitar Real Debrid", + "real_debrid": "Real Debrid", + "real_debrid_api_token_hint": "Você pode obter sua chave de API <0>aqui.", + "save_changes": "Salvar mudanças" }, "notifications": { "download_complete": "Download concluído", diff --git a/src/main/constants.ts b/src/main/constants.ts index 6c61f0b5..a229cb31 100644 --- a/src/main/constants.ts +++ b/src/main/constants.ts @@ -41,7 +41,5 @@ export const databasePath = path.join( "hydra.db" ); -console.log(databasePath); - export const INSTALLATION_ID_LENGTH = 6; export const ACTIVATION_KEY_MULTIPLIER = 7; diff --git a/src/main/events/helpers/generate-lutris-yaml.ts b/src/main/events/helpers/generate-lutris-yaml.ts index 75c9786b..f47a2a68 100644 --- a/src/main/events/helpers/generate-lutris-yaml.ts +++ b/src/main/events/helpers/generate-lutris-yaml.ts @@ -28,8 +28,8 @@ export const generateYML = (game: Game) => { { task: { executable: path.join( - game.downloadPath, - game.folderName, + game.downloadPath!, + game.folderName!, "setup.exe" ), name: "wineexec", diff --git a/src/main/events/library/open-game-installer.ts b/src/main/events/library/open-game-installer.ts index 27f110e5..2621d1f1 100644 --- a/src/main/events/library/open-game-installer.ts +++ b/src/main/events/library/open-game-installer.ts @@ -21,7 +21,7 @@ const openGameInstaller = async ( const gamePath = path.join( game.downloadPath ?? (await getDownloadsPath()), - game.folderName + game.folderName! ); if (!fs.existsSync(gamePath)) { diff --git a/src/main/services/downloaders/real-debrid.downloader.ts b/src/main/services/downloaders/real-debrid.downloader.ts index 38b27931..4c8e2691 100644 --- a/src/main/services/downloaders/real-debrid.downloader.ts +++ b/src/main/services/downloaders/real-debrid.downloader.ts @@ -38,12 +38,9 @@ export class RealDebridDownloader extends Downloader { const updatePayload: QueryDeepPartialEntity = { status: GameStatus.Finished, - progress: 1, }; - await this.updateGameProgress(game.id, updatePayload, { - timeRemaining: 0, - }); + await this.updateGameProgress(game.id, updatePayload, {}); } static destroy() { @@ -100,7 +97,7 @@ export class RealDebridDownloader extends Downloader { this.download.on("end", async () => { const updatePayload: QueryDeepPartialEntity = { status: GameStatus.Decompressing, - progress: 0.99, + progress: 1, }; await this.updateGameProgress(game.id, updatePayload, { diff --git a/src/main/services/real-debrid.ts b/src/main/services/real-debrid.ts index 7fa12e86..44798062 100644 --- a/src/main/services/real-debrid.ts +++ b/src/main/services/real-debrid.ts @@ -1,3 +1,4 @@ +import { Game } from "@main/entity"; import type { RealDebridAddMagnet, RealDebridTorrentInfo, diff --git a/src/main/services/repack-tracker/1337x.ts b/src/main/services/repack-tracker/1337x.ts index 8573079b..5e6ae527 100644 --- a/src/main/services/repack-tracker/1337x.ts +++ b/src/main/services/repack-tracker/1337x.ts @@ -33,9 +33,9 @@ const getTorrentDetails = async (path: string) => { return { magnet: $a?.href, - fileSize: $totalSize.querySelector("span").textContent ?? undefined, + fileSize: $totalSize.querySelector("span")!.textContent, uploadDate: formatUploadDate( - $dateUploaded.querySelector("span").textContent! + $dateUploaded.querySelector("span")!.textContent! ), }; }; @@ -65,8 +65,7 @@ export const getTorrentListLastPage = async (user: string) => { export const extractTorrentsFromDocument = async ( page: number, user: string, - document: Document, - existingRepacks: Repack[] = [] + document: Document ) => { const $trs = Array.from(document.querySelectorAll("tbody tr")); @@ -78,24 +77,13 @@ export const extractTorrentsFromDocument = async ( const url = $name.href; const title = $name.textContent ?? ""; - if (existingRepacks.some((repack) => repack.title === title)) { - return { - title, - magnet: "", - fileSize: null, - uploadDate: null, - repacker: user, - page, - }; - } - const details = await getTorrentDetails(url); return { title, magnet: details.magnet, - fileSize: details.fileSize ?? null, - uploadDate: details.uploadDate ?? null, + fileSize: details.fileSize ?? "N/A", + uploadDate: details.uploadDate ?? new Date(), repacker: user, page, }; @@ -114,13 +102,11 @@ export const getNewRepacksFromUser = async ( const repacks = await extractTorrentsFromDocument( page, user, - window.document, - existingRepacks + window.document ); const newRepacks = repacks.filter( (repack) => - repack.uploadDate && !existingRepacks.some( (existingRepack) => existingRepack.title === repack.title ) diff --git a/src/main/services/repack-tracker/cpg-repacks.ts b/src/main/services/repack-tracker/cpg-repacks.ts index 2b939d08..d1ba6cc4 100644 --- a/src/main/services/repack-tracker/cpg-repacks.ts +++ b/src/main/services/repack-tracker/cpg-repacks.ts @@ -4,6 +4,7 @@ import { Repack } from "@main/entity"; import { requestWebPage, savePage } from "./helpers"; import { logger } from "../logger"; +import type { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity"; export const getNewRepacksFromCPG = async ( existingRepacks: Repack[] = [], @@ -13,11 +14,11 @@ export const getNewRepacksFromCPG = async ( const { window } = new JSDOM(data); - const repacks = []; + const repacks: QueryDeepPartialEntity[] = []; try { Array.from(window.document.querySelectorAll(".post")).forEach(($post) => { - const $title = $post.querySelector(".entry-title"); + const $title = $post.querySelector(".entry-title")!; const uploadDate = $post.querySelector("time")?.getAttribute("datetime"); const $downloadInfo = Array.from( @@ -31,26 +32,25 @@ export const getNewRepacksFromCPG = async ( $a.textContent?.startsWith("Magent") ); - const fileSize = $downloadInfo.textContent + const fileSize = ($downloadInfo?.textContent ?? "") .split("Download link => ") .at(1); repacks.push({ - title: $title.textContent, + title: $title.textContent!, fileSize: fileSize ?? "N/A", - magnet: $magnet.href, + magnet: $magnet!.href, repacker: "CPG", page, - uploadDate: new Date(uploadDate), + uploadDate: uploadDate ? new Date(uploadDate) : new Date(), }); }); - } catch (err) { - logger.error(err.message, { method: "getNewRepacksFromCPG" }); + } catch (err: unknown) { + logger.error((err as Error).message, { method: "getNewRepacksFromCPG" }); } const newRepacks = repacks.filter( (repack) => - repack.uploadDate && !existingRepacks.some( (existingRepack) => existingRepack.title === repack.title ) diff --git a/src/main/services/repack-tracker/gog.ts b/src/main/services/repack-tracker/gog.ts index 00c78e36..aa22ee5c 100644 --- a/src/main/services/repack-tracker/gog.ts +++ b/src/main/services/repack-tracker/gog.ts @@ -16,14 +16,14 @@ const getGOGGame = async (url: string) => { const $em = window.document.querySelector( "p:not(.lightweight-accordion *) em" - ); - const fileSize = $em.textContent.split("Size: ").at(1); + )!; + const fileSize = $em.textContent!.split("Size: ").at(1); const $downloadButton = window.document.querySelector( ".download-btn:not(.lightweight-accordion *)" ) as HTMLAnchorElement; const { searchParams } = new URL($downloadButton.href); - const magnet = Buffer.from(searchParams.get("url"), "base64").toString( + const magnet = Buffer.from(searchParams.get("url")!, "base64").toString( "utf-8" ); @@ -50,10 +50,10 @@ export const getNewGOGGames = async (existingRepacks: Repack[] = []) => { const $lis = Array.from($ul.querySelectorAll("li")); for (const $li of $lis) { - const $a = $li.querySelector("a"); + const $a = $li.querySelector("a")!; const href = $a.href; - const title = $a.textContent.trim(); + const title = $a.textContent!.trim(); const gameExists = existingRepacks.some( (existingRepack) => existingRepack.title === title diff --git a/src/main/services/repack-tracker/online-fix.ts b/src/main/services/repack-tracker/online-fix.ts index a473679f..e73c6cc6 100644 --- a/src/main/services/repack-tracker/online-fix.ts +++ b/src/main/services/repack-tracker/online-fix.ts @@ -13,6 +13,9 @@ import { ru } from "date-fns/locale"; import { onlinefixFormatter } from "@main/helpers"; import makeFetchCookie from "fetch-cookie"; import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity"; +import { formatBytes } from "@shared"; + +const ONLINE_FIX_URL = "https://online-fix.me/"; export const getNewRepacksFromOnlineFix = async ( existingRepacks: Repack[] = [], @@ -27,14 +30,14 @@ export const getNewRepacksFromOnlineFix = async ( const http = makeFetchCookie(fetch, cookieJar); if (page === 1) { - await http("https://online-fix.me/"); + await http(ONLINE_FIX_URL); const preLogin = ((await http("https://online-fix.me/engine/ajax/authtoken.php", { method: "GET", headers: { "X-Requested-With": "XMLHttpRequest", - Referer: "https://online-fix.me/", + Referer: ONLINE_FIX_URL, }, }).then((res) => res.json())) as { field: string; @@ -50,11 +53,11 @@ export const getNewRepacksFromOnlineFix = async ( [preLogin.field]: preLogin.value, }); - await http("https://online-fix.me/", { + await http(ONLINE_FIX_URL, { method: "POST", headers: { - Referer: "https://online-fix.me", - Origin: "https://online-fix.me", + Referer: ONLINE_FIX_URL, + Origin: ONLINE_FIX_URL, "Content-Type": "application/x-www-form-urlencoded", }, body: params.toString(), @@ -149,13 +152,8 @@ export const getNewRepacksFromOnlineFix = async ( const torrentSizeInBytes = torrent.length; if (!torrentSizeInBytes) return; - const fileSizeFormatted = - torrentSizeInBytes >= 1024 ** 3 - ? `${(torrentSizeInBytes / 1024 ** 3).toFixed(1)}GBs` - : `${(torrentSizeInBytes / 1024 ** 2).toFixed(1)}MBs`; - repacks.push({ - fileSize: fileSizeFormatted, + fileSize: formatBytes(torrentSizeInBytes), magnet: magnetLink, page: 1, repacker: "onlinefix", diff --git a/src/main/services/repack-tracker/xatab.ts b/src/main/services/repack-tracker/xatab.ts index df075e88..1c43327b 100644 --- a/src/main/services/repack-tracker/xatab.ts +++ b/src/main/services/repack-tracker/xatab.ts @@ -7,6 +7,8 @@ import { requestWebPage, savePage } from "./helpers"; import createWorker from "@main/workers/torrent-parser.worker?nodeWorker"; import { toMagnetURI } from "parse-torrent"; import type { Instance } from "parse-torrent"; +import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity"; +import { formatBytes } from "@shared"; const worker = createWorker({}); @@ -23,10 +25,9 @@ const formatXatabDate = (str: string) => { return date; }; -const formatXatabDownloadSize = (str: string) => - str.replace(",", ".").replace(/Гб/g, "GB").replace(/Мб/g, "MB"); - -const getXatabRepack = (url: string) => { +const getXatabRepack = ( + url: string +): Promise<{ fileSize: string; magnet: string; uploadDate: Date }> => { return new Promise((resolve) => { (async () => { const data = await requestWebPage(url); @@ -34,7 +35,6 @@ const getXatabRepack = (url: string) => { const { document } = window; const $uploadDate = document.querySelector(".entry__date"); - const $size = document.querySelector(".entry__info-size"); const $downloadButton = document.querySelector( ".download-torrent" @@ -42,17 +42,13 @@ const getXatabRepack = (url: string) => { if (!$downloadButton) throw new Error("Download button not found"); - const onMessage = (torrent: Instance) => { + worker.once("message", (torrent: Instance) => { resolve({ - fileSize: formatXatabDownloadSize($size.textContent).toUpperCase(), + fileSize: formatBytes(torrent.length ?? 0), magnet: toMagnetURI(torrent), - uploadDate: formatXatabDate($uploadDate.textContent), + uploadDate: formatXatabDate($uploadDate!.textContent!), }); - - worker.removeListener("message", onMessage); - }; - - worker.once("message", onMessage); + }); })(); }); }; @@ -65,7 +61,7 @@ export const getNewRepacksFromXatab = async ( const { window } = new JSDOM(data); - const repacks = []; + const repacks: QueryDeepPartialEntity[] = []; for (const $a of Array.from( window.document.querySelectorAll(".entry__title a") @@ -74,7 +70,7 @@ export const getNewRepacksFromXatab = async ( const repack = await getXatabRepack(($a as HTMLAnchorElement).href); repacks.push({ - title: $a.textContent, + title: $a.textContent!, repacker: "Xatab", ...repack, page, diff --git a/src/renderer/src/assets/telegram-icon.svg b/src/renderer/src/assets/telegram-icon.svg index 35521851..962ab45f 100644 --- a/src/renderer/src/assets/telegram-icon.svg +++ b/src/renderer/src/assets/telegram-icon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/renderer/src/assets/x-icon.svg b/src/renderer/src/assets/x-icon.svg index f594427b..c394d154 100644 --- a/src/renderer/src/assets/x-icon.svg +++ b/src/renderer/src/assets/x-icon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/renderer/src/hooks/use-download.ts b/src/renderer/src/hooks/use-download.ts index f5033738..f0773533 100644 --- a/src/renderer/src/hooks/use-download.ts +++ b/src/renderer/src/hooks/use-download.ts @@ -11,8 +11,7 @@ import { } from "@renderer/features"; import type { GameShop, TorrentProgress } from "@types"; import { useDate } from "./use-date"; -import { formatBytes } from "@renderer/utils"; -import { GameStatus, GameStatusHelper } from "@shared"; +import { GameStatus, GameStatusHelper, formatBytes } from "@shared"; export function useDownload() { const { updateLibrary } = useLibrary(); diff --git a/src/renderer/src/pages/downloads/downloads.tsx b/src/renderer/src/pages/downloads/downloads.tsx index d8a4aec2..b95083dc 100644 --- a/src/renderer/src/pages/downloads/downloads.tsx +++ b/src/renderer/src/pages/downloads/downloads.tsx @@ -10,8 +10,7 @@ import { useEffect, useMemo, useRef, useState } from "react"; import { BinaryNotFoundModal } from "../shared-modals/binary-not-found-modal"; import * as styles from "./downloads.css"; import { DeleteModal } from "./delete-modal"; -import { formatBytes } from "@renderer/utils"; -import { Downloader, GameStatus, GameStatusHelper } from "@shared"; +import { Downloader, GameStatus, GameStatusHelper, formatBytes } from "@shared"; export function Downloads() { const { library, updateLibrary } = useLibrary(); diff --git a/src/renderer/src/pages/game-details/hero/hero-panel.tsx b/src/renderer/src/pages/game-details/hero/hero-panel.tsx index f156e5d2..138f27ec 100644 --- a/src/renderer/src/pages/game-details/hero/hero-panel.tsx +++ b/src/renderer/src/pages/game-details/hero/hero-panel.tsx @@ -6,9 +6,8 @@ import { useDownload } from "@renderer/hooks"; import type { Game, ShopDetails } from "@types"; import { formatDownloadProgress } from "@renderer/helpers"; -import { formatBytes } from "@renderer/utils"; import { HeroPanelActions } from "./hero-panel-actions"; -import { Downloader, GameStatus, GameStatusHelper } from "@shared"; +import { Downloader, GameStatus, GameStatusHelper, formatBytes } from "@shared"; import { BinaryNotFoundModal } from "../../shared-modals/binary-not-found-modal"; import * as styles from "./hero-panel.css"; diff --git a/src/renderer/src/pages/game-details/select-folder-modal.tsx b/src/renderer/src/pages/game-details/select-folder-modal.tsx index 0e3ae000..97567c98 100644 --- a/src/renderer/src/pages/game-details/select-folder-modal.tsx +++ b/src/renderer/src/pages/game-details/select-folder-modal.tsx @@ -3,10 +3,10 @@ import { GameRepack, ShopDetails } from "@types"; import { useEffect, useState } from "react"; import { Trans, useTranslation } from "react-i18next"; -import { formatBytes } from "@renderer/utils"; import { DiskSpace } from "check-disk-space"; import * as styles from "./select-folder-modal.css"; import { DownloadIcon } from "@primer/octicons-react"; +import { formatBytes } from "@shared"; export interface SelectFolderModalProps { visible: boolean; @@ -74,7 +74,7 @@ export function SelectFolderModal({ return ( - Save changes + {t("save_changes")} ); diff --git a/src/renderer/src/utils/format-bytes.ts b/src/renderer/src/utils/format-bytes.ts deleted file mode 100644 index b052b43b..00000000 --- a/src/renderer/src/utils/format-bytes.ts +++ /dev/null @@ -1,15 +0,0 @@ -const FORMAT = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; - -export const formatBytes = (bytes: number): string => { - if (!Number.isFinite(bytes) || isNaN(bytes) || bytes <= 0) { - return `0 ${FORMAT[0]}`; - } - - const byteKBase = 1024; - - const base = Math.floor(Math.log(bytes) / Math.log(byteKBase)); - - const formatedByte = bytes / byteKBase ** base; - - return `${Math.trunc(formatedByte * 10) / 10} ${FORMAT[base]}`; -}; diff --git a/src/renderer/src/utils/index.ts b/src/renderer/src/utils/index.ts deleted file mode 100644 index 7a828a7f..00000000 --- a/src/renderer/src/utils/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./format-bytes"; diff --git a/src/shared/index.ts b/src/shared/index.ts index bedf98fb..71021c13 100644 --- a/src/shared/index.ts +++ b/src/shared/index.ts @@ -14,6 +14,22 @@ export enum Downloader { Torrent, } +const FORMAT = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; + +export const formatBytes = (bytes: number): string => { + if (!Number.isFinite(bytes) || isNaN(bytes) || bytes <= 0) { + return `0 ${FORMAT[0]}`; + } + + const byteKBase = 1024; + + const base = Math.floor(Math.log(bytes) / Math.log(byteKBase)); + + const formatedByte = bytes / byteKBase ** base; + + return `${Math.trunc(formatedByte * 10) / 10} ${FORMAT[base]}`; +}; + export class GameStatusHelper { public static isDownloading(status: GameStatus | null) { return ( From 50a2185ad7e6cb7c830175db1d7a66f74c112742 Mon Sep 17 00:00:00 2001 From: Hydra Date: Sun, 12 May 2024 13:34:06 +0100 Subject: [PATCH 49/52] fix: removing decompression --- .../downloaders/real-debrid.downloader.ts | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/main/services/downloaders/real-debrid.downloader.ts b/src/main/services/downloaders/real-debrid.downloader.ts index 4c8e2691..8a44f934 100644 --- a/src/main/services/downloaders/real-debrid.downloader.ts +++ b/src/main/services/downloaders/real-debrid.downloader.ts @@ -4,7 +4,7 @@ import path from "node:path"; import fs from "node:fs"; import EasyDL from "easydl"; import { GameStatus } from "@shared"; -import { fullArchive } from "node-7z-archive"; +// import { fullArchive } from "node-7z-archive"; import { Downloader } from "./downloader"; import { RealDebridClient } from "../real-debrid"; @@ -29,19 +29,19 @@ export class RealDebridDownloader extends Downloader { } } - private static async startDecompression( - rarFile: string, - dest: string, - game: Game - ) { - await fullArchive(rarFile, dest); + // private static async startDecompression( + // rarFile: string, + // dest: string, + // game: Game + // ) { + // await fullArchive(rarFile, dest); - const updatePayload: QueryDeepPartialEntity = { - status: GameStatus.Finished, - }; + // const updatePayload: QueryDeepPartialEntity = { + // status: GameStatus.Finished, + // }; - await this.updateGameProgress(game.id, updatePayload, {}); - } + // await this.updateGameProgress(game.id, updatePayload, {}); + // } static destroy() { if (this.download) { @@ -96,7 +96,7 @@ export class RealDebridDownloader extends Downloader { this.download.on("end", async () => { const updatePayload: QueryDeepPartialEntity = { - status: GameStatus.Decompressing, + status: GameStatus.Finished, progress: 1, }; @@ -104,11 +104,12 @@ export class RealDebridDownloader extends Downloader { timeRemaining: 0, }); - this.startDecompression( - path.join(downloadPath, filename), - downloadPath, - game - ); + /* This has to be improved */ + // this.startDecompression( + // path.join(downloadPath, filename), + // downloadPath, + // game + // ); }); } } From 4a7b7ea04a619c4a3a7f93e611319f119c570b81 Mon Sep 17 00:00:00 2001 From: Hydra Date: Sun, 12 May 2024 14:05:51 +0100 Subject: [PATCH 50/52] ci: fixing lint trigger --- .github/workflows/lint.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 743c12dc..ca65198b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,8 +1,6 @@ name: Lint -on: - push: - branches: "**" +on: [pull_request] jobs: lint: From 2f77d881c4ebd69ff97a782b1ad55c6f1705f3d9 Mon Sep 17 00:00:00 2001 From: Hydra Date: Sun, 12 May 2024 14:06:17 +0100 Subject: [PATCH 51/52] ci: fixing lint trigger --- .github/workflows/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ca65198b..9a274ced 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,6 +1,6 @@ name: Lint -on: [pull_request] +on: [pull_request, push] jobs: lint: From 62cff6ce84ea17d3480e13be78859a69ba84a815 Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Sun, 12 May 2024 12:41:56 -0300 Subject: [PATCH 52/52] fix: playtime not showing on UI --- src/renderer/src/pages/game-details/hero/hero-panel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/src/pages/game-details/hero/hero-panel.tsx b/src/renderer/src/pages/game-details/hero/hero-panel.tsx index 138f27ec..9dafc720 100644 --- a/src/renderer/src/pages/game-details/hero/hero-panel.tsx +++ b/src/renderer/src/pages/game-details/hero/hero-panel.tsx @@ -106,7 +106,7 @@ export function HeroPanel({ ); } - if (game && GameStatusHelper.isReady(game?.status ?? null)) { + if (game && GameStatusHelper.isReady(game?.status ?? GameStatus.Finished)) { return ; }