From 4a4a800b0704b59c070da655472c949fd5c1095c Mon Sep 17 00:00:00 2001 From: Chubby Granny Chaser Date: Wed, 5 Jun 2024 20:15:59 +0100 Subject: [PATCH] feat: adding icon parser to download notification --- package.json | 3 +- src/locales/en/translation.json | 4 +- src/locales/pt/translation.json | 4 +- src/main/events/library/delete-game-folder.ts | 47 +++--- src/main/main.ts | 14 +- src/main/services/download-manager.ts | 16 +- src/main/services/notifications.ts | 34 +++- .../src/components/sidebar/sidebar.tsx | 2 - src/renderer/src/hooks/use-download.ts | 14 +- .../src/pages/downloads/download-group.css.ts | 38 ++--- .../src/pages/downloads/download-group.tsx | 67 ++++---- .../src/pages/downloads/downloads.css.ts | 21 +++ .../src/pages/downloads/downloads.tsx | 49 ++++-- .../pages/game-details/sidebar/sidebar.css.ts | 9 - .../pages/game-details/sidebar/sidebar.tsx | 12 +- src/renderer/src/theme.css.ts | 1 + yarn.lock | 154 +++++++++++++++++- 17 files changed, 343 insertions(+), 146 deletions(-) diff --git a/package.json b/package.json index 48741503..d7b6fb9e 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,6 @@ "@reduxjs/toolkit": "^2.2.3", "@vanilla-extract/css": "^1.14.2", "@vanilla-extract/recipes": "^0.5.2", - "iso-639-1": "3.1.2", "aria2": "^4.1.2", "auto-launch": "^5.0.6", "axios": "^1.6.8", @@ -56,6 +55,8 @@ "flexsearch": "^0.7.43", "i18next": "^23.11.2", "i18next-browser-languagedetector": "^7.2.1", + "icojs": "^0.19.3", + "iso-639-1": "3.1.2", "jsdom": "^24.0.0", "lodash-es": "^4.17.21", "lottie-react": "^2.4.0", diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 8fab29e8..d43a2323 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -133,7 +133,9 @@ "download_in_progress": "In progress", "queued_downloads": "Queued downloads", "downloads_completed": "Completed", - "queued": "Queued" + "queued": "Queued", + "no_downloads_title": "Such empty", + "no_downloads_description": "You haven't downloaded anything with Hydra yet, but it's never too late to start." }, "settings": { "downloads_path": "Downloads path", diff --git a/src/locales/pt/translation.json b/src/locales/pt/translation.json index 96705bbf..18dbe385 100644 --- a/src/locales/pt/translation.json +++ b/src/locales/pt/translation.json @@ -130,7 +130,9 @@ "download_in_progress": "Baixando agora", "queued_downloads": "Na fila", "downloads_completed": "Completo", - "queued": "Na fila" + "queued": "Na fila", + "no_downloads_title": "Nada por aqui…", + "no_downloads_description": "Você ainda não baixou nada pelo Hydra, mas nunca é tarde para começar." }, "settings": { "downloads_path": "Diretório dos downloads", diff --git a/src/main/events/library/delete-game-folder.ts b/src/main/events/library/delete-game-folder.ts index 31f3d69f..533e0063 100644 --- a/src/main/events/library/delete-game-folder.ts +++ b/src/main/events/library/delete-game-folder.ts @@ -34,33 +34,32 @@ const deleteGameFolder = async ( game.folderName ); - if (!fs.existsSync(folderPath)) { - await gameRepository.update( - { id: gameId }, - { downloadPath: null, folderName: null } - ); - } + if (fs.existsSync(folderPath)) { + await new Promise((resolve, reject) => { + fs.rm( + folderPath, + { recursive: true, force: true, maxRetries: 5, retryDelay: 200 }, + (error) => { + if (error) { + logger.error(error); + reject(); + } - return new Promise((resolve, reject) => { - fs.rm( - folderPath, - { recursive: true, force: true, maxRetries: 5, retryDelay: 200 }, - (error) => { - if (error) { - logger.error(error); - reject(); + const aria2ControlFilePath = `${folderPath}.aria2`; + if (fs.existsSync(aria2ControlFilePath)) + fs.rmSync(aria2ControlFilePath); + + resolve(); } - - resolve(); - } - ); - }).then(async () => { - await gameRepository.update( - { id: gameId }, - { downloadPath: null, folderName: null } - ); - }); + ); + }); + } } + + await gameRepository.update( + { id: gameId }, + { downloadPath: null, folderName: null, status: null, progress: 0 } + ); }; registerEvent("deleteGameFolder", deleteGameFolder); diff --git a/src/main/main.ts b/src/main/main.ts index ea4e7dd9..d5998b5a 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -1,12 +1,14 @@ import { DownloadManager, RepacksManager, startMainLoop } from "./services"; import { downloadQueueRepository, + repackRepository, userPreferencesRepository, } from "./repository"; import { UserPreferences } from "./entity"; import { RealDebridClient } from "./services/real-debrid"; import { fetchDownloadSourcesAndUpdate } from "./helpers"; import { publishNewRepacksNotifications } from "./services/notifications"; +import { MoreThan } from "typeorm"; startMainLoop(); @@ -30,8 +32,16 @@ const loadState = async (userPreferences: UserPreferences | null) => { if (nextQueueItem?.game.status === "active") DownloadManager.startDownload(nextQueueItem.game); - fetchDownloadSourcesAndUpdate().then(() => { - publishNewRepacksNotifications(300); + const now = new Date(); + + fetchDownloadSourcesAndUpdate().then(async () => { + const newRepacksCount = await repackRepository.count({ + where: { + createdAt: MoreThan(now), + }, + }); + + if (newRepacksCount > 0) publishNewRepacksNotifications(newRepacksCount); }); }; diff --git a/src/main/services/download-manager.ts b/src/main/services/download-manager.ts index 5c2c3f48..2a7532a4 100644 --- a/src/main/services/download-manager.ts +++ b/src/main/services/download-manager.ts @@ -1,5 +1,7 @@ import Aria2, { StatusResponse } from "aria2"; +import path from "node:path"; + import { downloadQueueRepository, gameRepository } from "@main/repository"; import { WindowManager } from "./window-manager"; @@ -67,7 +69,11 @@ export class DownloadManager { private static getFolderName(status: StatusResponse) { if (status.bittorrent?.info) return status.bittorrent.info.name; - return ""; + + const [file] = status.files; + if (file) return path.win32.basename(file.path); + + return null; } private static async getRealDebridDownloadUrl() { @@ -198,7 +204,7 @@ export class DownloadManager { } if (progress === 1 && this.game && !isDownloadingMetadata) { - await publishDownloadCompleteNotification(this.game); + publishDownloadCompleteNotification(this.game); await downloadQueueRepository.delete({ game: this.game }); @@ -220,7 +226,9 @@ export class DownloadManager { }, }); - this.resumeDownload(nextQueueItem!.game); + if (nextQueueItem) { + this.resumeDownload(nextQueueItem.game); + } } } @@ -237,7 +245,7 @@ export class DownloadManager { const gid = this.downloads.get(gameId); if (gid) { - await this.aria2.call("remove", gid); + await this.aria2.call("forceRemove", gid); if (this.gid === gid) { this.clearCurrentDownload(); diff --git a/src/main/services/notifications.ts b/src/main/services/notifications.ts index 127399f5..d53cc527 100644 --- a/src/main/services/notifications.ts +++ b/src/main/services/notifications.ts @@ -1,13 +1,40 @@ -import { Notification } from "electron"; +import { Notification, nativeImage } from "electron"; import { t } from "i18next"; +import { parseICO } from "icojs"; + import { Game } from "@main/entity"; -import { userPreferencesRepository } from "@main/repository"; +import { gameRepository, userPreferencesRepository } from "@main/repository"; + +const getGameIconNativeImage = async (gameId: number) => { + try { + const game = await gameRepository.findOne({ + where: { + id: gameId, + }, + }); + + if (!game?.iconUrl) return undefined; + + const images = await parseICO( + Buffer.from(game.iconUrl.split("base64,")[1], "base64") + ); + + const highResIcon = images.find((image) => image.width >= 128); + if (!highResIcon) return undefined; + + return nativeImage.createFromBuffer(Buffer.from(highResIcon.buffer)); + } catch (err) { + return undefined; + } +}; export const publishDownloadCompleteNotification = async (game: Game) => { const userPreferences = await userPreferencesRepository.findOne({ where: { id: 1 }, }); + const icon = await getGameIconNativeImage(game.id); + if (userPreferences?.downloadNotificationsEnabled) { new Notification({ title: t("download_complete", { @@ -19,6 +46,7 @@ export const publishDownloadCompleteNotification = async (game: Game) => { lng: userPreferences.language, title: game.title, }), + icon, }).show(); } }; @@ -28,7 +56,7 @@ export const publishNewRepacksNotifications = async (count: number) => { where: { id: 1 }, }); - if (count > 0 && userPreferences?.repackUpdatesNotificationsEnabled) { + if (userPreferences?.repackUpdatesNotificationsEnabled) { new Notification({ title: t("repack_list_updated", { ns: "notifications", diff --git a/src/renderer/src/components/sidebar/sidebar.tsx b/src/renderer/src/components/sidebar/sidebar.tsx index 28448555..76ab3137 100644 --- a/src/renderer/src/components/sidebar/sidebar.tsx +++ b/src/renderer/src/components/sidebar/sidebar.tsx @@ -40,8 +40,6 @@ export function Sidebar() { updateLibrary(); }, [lastPacket?.game.id, updateLibrary]); - console.log(library); - const isDownloading = library.some( (game) => game.status === "active" && game.progress !== 1 ); diff --git a/src/renderer/src/hooks/use-download.ts b/src/renderer/src/hooks/use-download.ts index d3bf2c7a..8db5fc03 100644 --- a/src/renderer/src/hooks/use-download.ts +++ b/src/renderer/src/hooks/use-download.ts @@ -41,12 +41,6 @@ export function useDownload() { return updateLibrary(); }; - const cancelDownload = async (gameId: number) => { - await window.electron.cancelGameDownload(gameId); - dispatch(clearDownload()); - updateLibrary(); - }; - const removeGameInstaller = async (gameId: number) => { dispatch(setGameDeleting(gameId)); @@ -58,6 +52,14 @@ export function useDownload() { } }; + const cancelDownload = async (gameId: number) => { + await window.electron.cancelGameDownload(gameId); + dispatch(clearDownload()); + updateLibrary(); + + removeGameInstaller(gameId); + }; + const removeGameFromLibrary = (gameId: number) => window.electron.removeGameFromLibrary(gameId).then(() => { updateLibrary(); diff --git a/src/renderer/src/pages/downloads/download-group.css.ts b/src/renderer/src/pages/downloads/download-group.css.ts index e42fb6eb..c928851b 100644 --- a/src/renderer/src/pages/downloads/download-group.css.ts +++ b/src/renderer/src/pages/downloads/download-group.css.ts @@ -1,6 +1,5 @@ import { SPACING_UNIT, vars } from "../../theme.css"; import { style } from "@vanilla-extract/css"; -import { recipe } from "@vanilla-extract/recipes"; export const downloadTitleWrapper = style({ display: "flex", @@ -28,6 +27,7 @@ export const downloads = style({ flexDirection: "column", margin: "0", padding: "0", + marginTop: `${SPACING_UNIT}px`, }); export const downloadCover = style({ @@ -64,30 +64,18 @@ export const downloadCoverImage = style({ zIndex: "-1", }); -export const download = recipe({ - base: { - width: "100%", - backgroundColor: vars.color.background, - display: "flex", - borderRadius: "8px", - border: `solid 1px ${vars.color.border}`, - overflow: "hidden", - boxShadow: "0px 0px 15px 0px #000000", - transition: "all ease 0.2s", - height: "140px", - minHeight: "140px", - maxHeight: "140px", - }, - variants: { - cancelled: { - true: { - opacity: vars.opacity.disabled, - ":hover": { - opacity: "1", - }, - }, - }, - }, +export const download = style({ + width: "100%", + backgroundColor: vars.color.background, + display: "flex", + borderRadius: "8px", + border: `solid 1px ${vars.color.border}`, + overflow: "hidden", + boxShadow: "0px 0px 15px 0px #000000", + transition: "all ease 0.2s", + height: "140px", + minHeight: "140px", + maxHeight: "140px", }); export const downloadDetails = style({ diff --git a/src/renderer/src/pages/downloads/download-group.tsx b/src/renderer/src/pages/downloads/download-group.tsx index 737e318a..d8152426 100644 --- a/src/renderer/src/pages/downloads/download-group.tsx +++ b/src/renderer/src/pages/downloads/download-group.tsx @@ -15,6 +15,7 @@ import { useAppSelector, useDownload } from "@renderer/hooks"; import * as styles from "./download-group.css"; import { useTranslation } from "react-i18next"; +import { SPACING_UNIT, vars } from "@renderer/theme.css"; export interface DownloadGroupProps { library: LibraryGame[]; @@ -42,7 +43,6 @@ export function DownloadGroup({ progress, pauseDownload, resumeDownload, - removeGameFromLibrary, cancelDownload, isGameDeleting, } = useDownload(); @@ -149,42 +149,20 @@ export function DownloadGroup({ ); } - if (game.status === "paused") { - return ( - <> - - - - ); - } - return ( <> - - ); @@ -194,17 +172,30 @@ export function DownloadGroup({ return (
-

{title}

+
+

{title}

+ +
+

{library.length}

+
    {library.map((game) => { return ( -
  • +
  • { - /* Game has been manually added to the library */ - if (!next.status) return prev; + /* Game has been manually added to the library or has been canceled */ + if (!next.status || next.status === "removed") return prev; /* Is downloading */ if (lastPacket?.game.id === next.id) @@ -94,8 +95,12 @@ export function Downloads() { }, ]; + const hasItemsInLibrary = useMemo(() => { + return Object.values(libraryGroup).some((group) => group.length > 0); + }, [libraryGroup]); + return ( -
    + <> setShowBinaryNotFoundModal(false)} @@ -107,17 +112,31 @@ export function Downloads() { deleteGame={handleDeleteGame} /> -
    - {downloadGroups.map((group) => ( - - ))} -
    -
    + {hasItemsInLibrary ? ( +
    +
    + {downloadGroups.map((group) => ( + + ))} +
    +
    + ) : ( +
    +
    + +
    +

    {t("no_downloads_title")}

    +

    + {t("no_downloads_description")} +

    +
    + )} + ); } diff --git a/src/renderer/src/pages/game-details/sidebar/sidebar.css.ts b/src/renderer/src/pages/game-details/sidebar/sidebar.css.ts index 1afb864d..e6d8b60a 100644 --- a/src/renderer/src/pages/game-details/sidebar/sidebar.css.ts +++ b/src/renderer/src/pages/game-details/sidebar/sidebar.css.ts @@ -6,7 +6,6 @@ export const contentSidebar = style({ borderLeft: `solid 1px ${vars.color.border};`, width: "100%", height: "100%", - position: "relative", "@media": { "(min-width: 768px)": { width: "100%", @@ -87,14 +86,6 @@ export const howLongToBeatCategorySkeleton = style({ height: "76px", }); -export const technicalDetailsContainer = style({ - padding: `0 ${SPACING_UNIT * 2}px`, - color: vars.color.body, - userSelect: "text", - position: "absolute", - bottom: `${SPACING_UNIT}px`, -}); - globalStyle(`${requirementsDetails} a`, { display: "flex", color: vars.color.body, diff --git a/src/renderer/src/pages/game-details/sidebar/sidebar.tsx b/src/renderer/src/pages/game-details/sidebar/sidebar.tsx index eaa5c722..780f5964 100644 --- a/src/renderer/src/pages/game-details/sidebar/sidebar.tsx +++ b/src/renderer/src/pages/game-details/sidebar/sidebar.tsx @@ -16,8 +16,7 @@ export function Sidebar() { const [activeRequirement, setActiveRequirement] = useState("minimum"); - const { gameTitle, shopDetails, shop, objectID } = - useContext(gameDetailsContext); + const { gameTitle, shopDetails, objectID } = useContext(gameDetailsContext); const { t } = useTranslation("game_details"); @@ -75,15 +74,6 @@ export function Sidebar() { }), }} /> - -
    -

    - shop: "{shop}" -

    -

    - objectID: "{objectID}" -

    -
    ); } diff --git a/src/renderer/src/theme.css.ts b/src/renderer/src/theme.css.ts index 125e1543..13fe3fae 100644 --- a/src/renderer/src/theme.css.ts +++ b/src/renderer/src/theme.css.ts @@ -18,5 +18,6 @@ export const [themeClass, vars] = createTheme({ }, size: { body: "14px", + small: "12px", }, }); diff --git a/yarn.lock b/yarn.lock index 9114d4f7..5ffbd1a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -235,6 +235,11 @@ "@babel/helper-validator-identifier" "^7.24.5" to-fast-properties "^2.0.0" +"@canvas/image-data@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@canvas/image-data/-/image-data-1.0.0.tgz#3bd2cd856e13fc9e2c25feff360a4056857b0367" + integrity sha512-BxOqI5LgsIQP1odU5KMwV9yoijleOPzHL18/YvNqF9KFSGF2K/DLlYAbDQsWqd/1nbaFuSkYD/191dpMtNh4vw== + "@commitlint/cli@^19.3.0": version "19.3.0" resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-19.3.0.tgz#44e6da9823a01f0cdcc43054bbefdd2c6c5ddf39" @@ -796,6 +801,21 @@ wrap-ansi "^8.1.0" wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" +"@jimp/bmp@^0.22.10": + version "0.22.12" + resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.22.12.tgz#0316044dc7b1a90274aef266d50349347fb864d4" + integrity sha512-aeI64HD0npropd+AR76MCcvvRaa+Qck6loCOS03CkkxGHN5/r336qTM5HPUdHKMDOGzqknuVPA8+kK1t03z12g== + dependencies: + "@jimp/utils" "^0.22.12" + bmp-js "^0.1.0" + +"@jimp/utils@^0.22.12": + version "0.22.12" + resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-0.22.12.tgz#8ffaed8f2dc2962539ccaf14727ac60793c7a537" + integrity sha512-yJ5cWUknGnilBq97ZXOyOS0HhsHOyAyjHwYfHxGbSyMTohgQI6sVyE8KPgDwH8HHW/nMKXk8TrSwAE71zt716Q== + dependencies: + regenerator-runtime "^0.13.3" + "@jridgewell/gen-mapping@^0.3.5": version "0.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" @@ -1173,6 +1193,11 @@ dependencies: uint8-util "^2.1.9" +"@tokenizer/token@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" + integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== + "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" @@ -1965,6 +1990,11 @@ bluebird@^3.5.5: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== +bmp-js@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" + integrity sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw== + boolean@^3.0.1: version "3.2.0" resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.2.0.tgz#9e5294af4e98314494cbb17979fa54ca159f116b" @@ -2484,6 +2514,23 @@ decimal.js@^10.4.3: resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== +decode-bmp@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/decode-bmp/-/decode-bmp-0.2.1.tgz#cec3e0197ec3b6c60f02220f50e8757030ff2427" + integrity sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA== + dependencies: + "@canvas/image-data" "^1.0.0" + to-data-view "^1.1.0" + +decode-ico@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/decode-ico/-/decode-ico-0.4.1.tgz#e0f7373081532c7b8495bd51fb225d354e14de25" + integrity sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA== + dependencies: + "@canvas/image-data" "^1.0.0" + decode-bmp "^0.2.0" + to-data-view "^1.1.0" + decompress-response@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" @@ -3242,6 +3289,15 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" +file-type@^18.7.0: + version "18.7.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-18.7.0.tgz#cddb16f184d6b94106cfc4bb56978726b25cb2a2" + integrity sha512-ihHtXRzXEziMrQ56VSgU7wkxh55iNchFkosu7Y9/S+tXHdKyrGjVK0ujbqNnsxzea+78MaLhN6PGmfYSAv1ACw== + dependencies: + readable-web-to-node-stream "^3.0.2" + strtok3 "^7.0.0" + token-types "^5.0.1" + file-uri-to-path@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" @@ -3728,6 +3784,18 @@ i18next@^23.11.2: dependencies: "@babel/runtime" "^7.23.2" +icojs@^0.19.3: + version "0.19.3" + resolved "https://registry.yarnpkg.com/icojs/-/icojs-0.19.3.tgz#1c0a4e593c8cb3ce61aee4aa4f4a3befb3165527" + integrity sha512-Q6syRxwoEACLRl7uTiee72038vDbq4gF6ot7JFsXmxj0WtkgGQiUxCdEJtwxd8nfADr9mPmGtpmbORJursaOsQ== + dependencies: + "@jimp/bmp" "^0.22.10" + decode-ico "^0.4.1" + file-type "^18.7.0" + jpeg-js "^0.4.4" + pngjs "^7.0.0" + to-data-view "^2.0.0" + iconv-corefoundation@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz#31065e6ab2c9272154c8b0821151e2c88f1b002a" @@ -4087,6 +4155,11 @@ jiti@^1.19.1: resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d" integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q== +jpeg-js@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.4.tgz#a9f1c6f1f9f0fa80cdb3484ed9635054d28936aa" + integrity sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -4880,6 +4953,11 @@ pathe@^1.1.1, pathe@^1.1.2: resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== +peek-readable@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.0.0.tgz#7ead2aff25dc40458c60347ea76cfdfd63efdfec" + integrity sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A== + pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" @@ -4920,6 +4998,11 @@ plist@^3.0.4, plist@^3.0.5: base64-js "^1.5.1" xmlbuilder "^15.1.1" +pngjs@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-7.0.0.tgz#a8b7446020ebbc6ac739db6c5415a65d17090e26" + integrity sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow== + possible-typed-array-names@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" @@ -5117,7 +5200,7 @@ read-config-file@6.3.2: json5 "^2.2.0" lazy-val "^1.0.4" -readable-stream@^3.1.1, readable-stream@^3.4.0: +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -5126,6 +5209,13 @@ readable-stream@^3.1.1, readable-stream@^3.4.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" +readable-web-to-node-stream@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb" + integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== + dependencies: + readable-stream "^3.6.0" + redux-thunk@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-3.1.0.tgz#94aa6e04977c30e14e892eae84978c1af6058ff3" @@ -5154,6 +5244,11 @@ reflect.getprototypeof@^1.0.4: globalthis "^1.0.3" which-builtin-type "^1.1.3" +regenerator-runtime@^0.13.3: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + regenerator-runtime@^0.14.0: version "0.14.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" @@ -5518,7 +5613,16 @@ stat-mode@^1.0.0: resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-1.0.0.tgz#68b55cb61ea639ff57136f36b216a291800d1465" integrity sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -5589,7 +5693,14 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -5618,6 +5729,14 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== +strtok3@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-7.0.0.tgz#868c428b4ade64a8fd8fee7364256001c1a4cbe5" + integrity sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ== + dependencies: + "@tokenizer/token" "^0.3.0" + peek-readable "^5.0.0" + sumchecker@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42" @@ -5749,6 +5868,16 @@ tmp@^0.2.0: resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== +to-data-view@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/to-data-view/-/to-data-view-1.1.0.tgz#08d6492b0b8deb9b29bdf1f61c23eadfa8994d00" + integrity sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ== + +to-data-view@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-data-view/-/to-data-view-2.0.0.tgz#4cc3f5c9eb59514a7436fc54c587c3c34c9b1d60" + integrity sha512-RGEM5KqlPHr+WVTPmGNAXNeFEmsBnlkxXaIfEpUYV0AST2Z5W1EGq9L/MENFrMMmL2WQr1wjkmZy/M92eKhjYA== + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -5761,6 +5890,14 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +token-types@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-5.0.1.tgz#aa9d9e6b23c420a675e55413b180635b86a093b4" + integrity sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg== + dependencies: + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + tough-cookie@^4.0.0, tough-cookie@^4.1.3: version "4.1.4" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36" @@ -6158,7 +6295,16 @@ word-wrap@^1.2.5: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==