feat(app): support cache limit and clean cache
Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
parent
1d0eca1ca1
commit
dee294dda5
|
|
@ -34,6 +34,7 @@
|
|||
"electron-log": "5.2.0",
|
||||
"electron-squirrel-startup": "1.0.1",
|
||||
"electron-updater": "^6.3.9",
|
||||
"fast-folder-size": "2.3.0",
|
||||
"font-list": "1.5.1",
|
||||
"i18next": "^23.16.4",
|
||||
"linkedom": "^0.18.5",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { app, nativeTheme, Notification, shell } from "electron"
|
|||
import contextMenu from "electron-context-menu"
|
||||
|
||||
import { getIconPath } from "./helper"
|
||||
import { clearCacheCronJob } from "./lib/cleaner"
|
||||
import { t } from "./lib/i18n"
|
||||
import { store } from "./lib/store"
|
||||
import { updateNotificationsToken } from "./lib/user"
|
||||
|
|
@ -59,6 +60,7 @@ export const initializeAppStage1 = () => {
|
|||
registerMenuAndContextMenu()
|
||||
|
||||
registerPushNotifications()
|
||||
clearCacheCronJob()
|
||||
}
|
||||
|
||||
let contextMenuDisposer: () => void
|
||||
|
|
|
|||
|
|
@ -1,9 +1,20 @@
|
|||
import { callWindowExpose } from "@follow/shared/bridge"
|
||||
import { dialog } from "electron"
|
||||
import { statSync } from "node:fs"
|
||||
import fsp from "node:fs/promises"
|
||||
import { createRequire } from "node:module"
|
||||
import path from "node:path"
|
||||
import { promisify } from "node:util"
|
||||
|
||||
import { callWindowExpose } from "@follow/shared/bridge"
|
||||
import { app, dialog } from "electron"
|
||||
|
||||
import { logger } from "~/logger"
|
||||
import { getMainWindow } from "~/window"
|
||||
|
||||
import { t } from "./i18n"
|
||||
import { store, StoreKey } from "./store"
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const fastFolderSize = require("fast-folder-size") as any as typeof import("fast-folder-size")
|
||||
|
||||
export const clearAllDataAndConfirm = async () => {
|
||||
const win = getMainWindow()
|
||||
|
|
@ -53,3 +64,75 @@ export const clearAllData = async () => {
|
|||
caller.toast.error(`Error resetting app data: ${error.message}`)
|
||||
}
|
||||
}
|
||||
const fastFolderSizeAsync = promisify(fastFolderSize)
|
||||
export const getCacheSize = async () => {
|
||||
const cachePath = path.join(app.getPath("userData"), "cache")
|
||||
|
||||
// Size is in bytes
|
||||
const sizeInBytes = await fastFolderSizeAsync(cachePath)
|
||||
return sizeInBytes || 0
|
||||
}
|
||||
|
||||
const getCachedFilesRecursive = async (dir: string, result: string[] = []) => {
|
||||
const files = await fsp.readdir(dir)
|
||||
|
||||
for (const file of files) {
|
||||
const filePath = path.join(dir, file)
|
||||
const stat = await fsp.stat(filePath)
|
||||
if (stat.isDirectory()) {
|
||||
const files = await getCachedFilesRecursive(filePath)
|
||||
result.push(...files)
|
||||
} else {
|
||||
result.push(filePath)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
let timer: any = null
|
||||
export const clearCacheCronJob = () => {
|
||||
if (timer) {
|
||||
timer = clearInterval(timer)
|
||||
}
|
||||
timer = setInterval(
|
||||
async () => {
|
||||
const hasLimit = store.get(StoreKey.CacheSizeLimit)
|
||||
|
||||
if (!hasLimit) {
|
||||
return
|
||||
}
|
||||
|
||||
const cacheSize = await getCacheSize()
|
||||
|
||||
const limitByteSize = hasLimit * 1024 * 1024
|
||||
if (cacheSize > limitByteSize) {
|
||||
const shouldCleanSize = cacheSize - limitByteSize - 1024 * 1024 * 50 // 50MB
|
||||
|
||||
const cachePath = path.join(app.getPath("userData"), "cache")
|
||||
const files = await getCachedFilesRecursive(cachePath)
|
||||
// Sort by last modified
|
||||
files.sort((a, b) => {
|
||||
const aStat = statSync(a)
|
||||
const bStat = statSync(b)
|
||||
return bStat.mtime.getTime() - aStat.mtime.getTime()
|
||||
})
|
||||
|
||||
let cleanedSize = 0
|
||||
for (const file of files) {
|
||||
const fileSize = statSync(file).size
|
||||
cleanedSize += fileSize
|
||||
if (cleanedSize >= shouldCleanSize) {
|
||||
logger.info(`Cleaned ${cleanedSize} bytes cache`)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
10 * 60 * 1000,
|
||||
) // 10 min
|
||||
|
||||
return () => {
|
||||
if (!timer) return
|
||||
timer = clearInterval(timer)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,11 @@ const createOrGetDb = () => {
|
|||
}
|
||||
return db
|
||||
}
|
||||
|
||||
export enum StoreKey {
|
||||
CacheSizeLimit = "cacheSizeLimit",
|
||||
}
|
||||
|
||||
export const store = {
|
||||
get: (key: string) => {
|
||||
const db = createOrGetDb()
|
||||
|
|
@ -26,4 +31,9 @@ export const store = {
|
|||
db.data[key] = value
|
||||
db.write()
|
||||
},
|
||||
delete: (key: string) => {
|
||||
const db = createOrGetDb()
|
||||
delete db.data[key]
|
||||
db.write()
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ import type { BrowserWindow } from "electron"
|
|||
import { app, clipboard, dialog, screen } from "electron"
|
||||
|
||||
import { registerMenuAndContextMenu } from "~/init"
|
||||
import { clearAllData } from "~/lib/cleaner"
|
||||
import { clearAllData, getCacheSize } from "~/lib/cleaner"
|
||||
import { store, StoreKey } from "~/lib/store"
|
||||
import { logger } from "~/logger"
|
||||
|
||||
import { isWindows11 } from "../env"
|
||||
import { downloadFile } from "../lib/download"
|
||||
|
|
@ -267,6 +269,27 @@ ${content}
|
|||
return { success: false, error: errorMessage }
|
||||
}
|
||||
}),
|
||||
|
||||
getCacheSize: t.procedure.action(async () => {
|
||||
return getCacheSize()
|
||||
}),
|
||||
getCacheLimit: t.procedure.action(async () => {
|
||||
return store.get(StoreKey.CacheSizeLimit)
|
||||
}),
|
||||
|
||||
clearCache: t.procedure.action(async () => {
|
||||
const cachePath = path.join(app.getPath("userData"), "cache")
|
||||
await fsp.rm(cachePath, { recursive: true, force: true })
|
||||
}),
|
||||
|
||||
limitCacheSize: t.procedure.input<number>().action(async ({ input }) => {
|
||||
logger.info("set limitCacheSize", input)
|
||||
if (input === 0) {
|
||||
store.delete(StoreKey.CacheSizeLimit)
|
||||
} else {
|
||||
store.set(StoreKey.CacheSizeLimit, input)
|
||||
}
|
||||
}),
|
||||
}
|
||||
|
||||
interface Sender extends Electron.WebContents {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ function getSettings() {
|
|||
|
||||
const settings = [] as {
|
||||
name: I18nKeysForSettings
|
||||
iconName: string
|
||||
icon: string | React.ReactNode
|
||||
path: string
|
||||
Component: () => JSX.Element
|
||||
priority: number
|
||||
|
|
|
|||
|
|
@ -0,0 +1,192 @@
|
|||
import { CarbonInfinitySymbol } from "@follow/components/icons/infinify.jsx"
|
||||
import { Button } from "@follow/components/ui/button/index.js"
|
||||
import { Label } from "@follow/components/ui/label/index.jsx"
|
||||
import { Slider } from "@follow/components/ui/slider/index.js"
|
||||
import { env } from "@follow/shared/env"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { useEffect } from "react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
import { setGeneralSetting, useGeneralSettingValue } from "~/atoms/settings/general"
|
||||
import { useModalStack } from "~/components/ui/modal/stacked/hooks"
|
||||
import { exportDB } from "~/database"
|
||||
import { initAnalytics } from "~/initialize/analytics"
|
||||
import { tipcClient } from "~/lib/client"
|
||||
import { queryClient } from "~/lib/query-client"
|
||||
import { clearLocalPersistStoreData } from "~/store/utils/clear"
|
||||
|
||||
import { SettingDescription } from "../control"
|
||||
import { createSetting } from "../helper/builder"
|
||||
import { SettingItemGroup } from "../section"
|
||||
|
||||
const { defineSettingItem, SettingBuilder } = createSetting(
|
||||
useGeneralSettingValue,
|
||||
setGeneralSetting,
|
||||
)
|
||||
export const SettingDataControl = () => {
|
||||
const { t } = useTranslation("settings")
|
||||
useEffect(() => {
|
||||
tipcClient?.getLoginItemSettings().then((settings) => {
|
||||
setGeneralSetting("appLaunchOnStartup", settings.openAtLogin)
|
||||
})
|
||||
}, [])
|
||||
|
||||
const { present } = useModalStack()
|
||||
|
||||
return (
|
||||
<div className="mt-4">
|
||||
<SettingBuilder
|
||||
settings={[
|
||||
{
|
||||
type: "title",
|
||||
value: t("general.privacy"),
|
||||
},
|
||||
defineSettingItem("sendAnonymousData", {
|
||||
label: t("general.send_anonymous_data.label"),
|
||||
description: t("general.send_anonymous_data.description"),
|
||||
onChange(value) {
|
||||
setGeneralSetting("sendAnonymousData", value)
|
||||
if (value) {
|
||||
initAnalytics()
|
||||
} else {
|
||||
window.analytics?.reset()
|
||||
delete window.analytics
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
{
|
||||
type: "title",
|
||||
value: t("general.data"),
|
||||
},
|
||||
defineSettingItem("dataPersist", {
|
||||
label: t("general.data_persist.label"),
|
||||
description: t("general.data_persist.description"),
|
||||
}),
|
||||
|
||||
{
|
||||
label: t("general.rebuild_database.label"),
|
||||
action: () => {
|
||||
present({
|
||||
title: t("general.rebuild_database.title"),
|
||||
clickOutsideToDismiss: true,
|
||||
content: () => (
|
||||
<div className="text-sm">
|
||||
<p>{t("general.rebuild_database.warning.line1")}</p>
|
||||
<p>{t("general.rebuild_database.warning.line2")}</p>
|
||||
<div className="mt-4 flex justify-end">
|
||||
<Button
|
||||
className="bg-red-500 px-3 text-white"
|
||||
onClick={async () => {
|
||||
await clearLocalPersistStoreData()
|
||||
window.location.reload()
|
||||
}}
|
||||
>
|
||||
{t("ok", { ns: "common" })}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
})
|
||||
},
|
||||
description: t("general.rebuild_database.description"),
|
||||
buttonText: t("general.rebuild_database.button"),
|
||||
},
|
||||
{
|
||||
label: t("general.export_database.label"),
|
||||
description: t("general.export_database.description"),
|
||||
buttonText: t("general.export_database.button"),
|
||||
action: () => {
|
||||
exportDB()
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t("general.export.label"),
|
||||
description: t("general.export.description"),
|
||||
buttonText: t("general.export.button"),
|
||||
action: () => {
|
||||
const link = document.createElement("a")
|
||||
link.href = `${env.VITE_API_URL}/subscriptions/export`
|
||||
link.download = "follow.opml"
|
||||
link.click()
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: "title",
|
||||
value: t("general.cache"),
|
||||
},
|
||||
AppCacheLimit,
|
||||
{
|
||||
label: t("data_control.clean_cache.button"),
|
||||
description: t("data_control.clean_cache.description"),
|
||||
buttonText: t("data_control.clean_cache.button"),
|
||||
action: async () => {
|
||||
await tipcClient?.clearCache()
|
||||
queryClient.invalidateQueries({ queryKey: ["app", "cache", "size"] })
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
const AppCacheLimit = () => {
|
||||
const { t } = useTranslation("settings")
|
||||
const { data: cacheSize, isLoading: isLoadingCacheSize } = useQuery({
|
||||
queryKey: ["app", "cache", "size"],
|
||||
queryFn: async () => {
|
||||
const byteSize = (await tipcClient?.getCacheSize()) ?? 0
|
||||
return Math.round(byteSize / 1024 / 1024)
|
||||
},
|
||||
})
|
||||
const {
|
||||
data: cacheLimit,
|
||||
isLoading: isLoadingCacheLimit,
|
||||
refetch: refetchCacheLimit,
|
||||
} = useQuery({
|
||||
queryKey: ["app", "cache", "limit"],
|
||||
queryFn: async () => {
|
||||
const size = (await tipcClient?.getCacheLimit()) ?? 0
|
||||
return size
|
||||
},
|
||||
})
|
||||
|
||||
const onChange = (value: number[]) => {
|
||||
tipcClient?.limitCacheSize(value[0])
|
||||
refetchCacheLimit()
|
||||
}
|
||||
|
||||
if (isLoadingCacheSize || isLoadingCacheLimit) return null
|
||||
|
||||
const InfinitySymbol = <CarbonInfinitySymbol />
|
||||
return (
|
||||
<SettingItemGroup>
|
||||
<div className={"mb-3 flex items-center justify-between gap-4"}>
|
||||
<Label className="center flex">
|
||||
{t("data_control.app_cache_limit.label")}
|
||||
|
||||
<span className="center ml-2 flex shrink-0 gap-1 text-xs text-gray-500">
|
||||
<span>({cacheSize}M</span> /{" "}
|
||||
<span className="center flex shrink-0">
|
||||
{cacheLimit ? `${cacheLimit}M` : InfinitySymbol})
|
||||
</span>
|
||||
</span>
|
||||
</Label>
|
||||
|
||||
<div className="relative flex w-1/5 flex-col gap-1">
|
||||
<Slider
|
||||
min={0}
|
||||
max={500}
|
||||
step={100}
|
||||
defaultValue={[cacheLimit ?? 0]}
|
||||
onValueCommit={onChange}
|
||||
/>
|
||||
<div className="absolute bottom-[-1.5em] text-base opacity-50">{InfinitySymbol}</div>
|
||||
<div className="absolute bottom-[-1.5em] right-0 text-xs opacity-50">500M</div>
|
||||
</div>
|
||||
</div>
|
||||
<SettingDescription>{t("data_control.app_cache_limit.description")}</SettingDescription>
|
||||
</SettingItemGroup>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { Button } from "@follow/components/ui/button/index.js"
|
||||
import { LoadingCircle } from "@follow/components/ui/loading/index.jsx"
|
||||
import {
|
||||
Select,
|
||||
|
|
@ -8,7 +7,6 @@ import {
|
|||
SelectValue,
|
||||
} from "@follow/components/ui/select/index.jsx"
|
||||
import { IN_ELECTRON } from "@follow/shared/constants"
|
||||
import { env } from "@follow/shared/env"
|
||||
import { cn } from "@follow/utils/utils"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { useAtom } from "jotai"
|
||||
|
|
@ -24,13 +22,9 @@ import {
|
|||
useGeneralSettingSelector,
|
||||
useGeneralSettingValue,
|
||||
} from "~/atoms/settings/general"
|
||||
import { useModalStack } from "~/components/ui/modal/stacked/hooks"
|
||||
import { exportDB } from "~/database"
|
||||
import { useProxyValue, useSetProxy } from "~/hooks/biz/useProxySetting"
|
||||
import { fallbackLanguage } from "~/i18n"
|
||||
import { initAnalytics } from "~/initialize/analytics"
|
||||
import { tipcClient } from "~/lib/client"
|
||||
import { clearLocalPersistStoreData } from "~/store/utils/clear"
|
||||
|
||||
import { SettingDescription, SettingInput } from "../control"
|
||||
import { createSetting } from "../helper/builder"
|
||||
|
|
@ -54,8 +48,6 @@ export const SettingGeneral = () => {
|
|||
setGeneralSetting("appLaunchOnStartup", checked)
|
||||
}, [])
|
||||
|
||||
const { present } = useModalStack()
|
||||
|
||||
return (
|
||||
<div className="mt-4">
|
||||
<SettingBuilder
|
||||
|
|
@ -105,82 +97,6 @@ export const SettingGeneral = () => {
|
|||
|
||||
IN_ELECTRON && VoiceSelector,
|
||||
|
||||
// { type: "title", value: "Secure" },
|
||||
// defineSettingItem("jumpOutLinkWarn", {
|
||||
// label: "Warn when opening external links",
|
||||
// description: "When you open an untrusted external link, you need to make sure that you open the link.",
|
||||
// }),
|
||||
{
|
||||
type: "title",
|
||||
value: t("general.privacy_data"),
|
||||
},
|
||||
|
||||
defineSettingItem("dataPersist", {
|
||||
label: t("general.data_persist.label"),
|
||||
description: t("general.data_persist.description"),
|
||||
}),
|
||||
|
||||
defineSettingItem("sendAnonymousData", {
|
||||
label: t("general.send_anonymous_data.label"),
|
||||
description: t("general.send_anonymous_data.description"),
|
||||
onChange(value) {
|
||||
setGeneralSetting("sendAnonymousData", value)
|
||||
if (value) {
|
||||
initAnalytics()
|
||||
} else {
|
||||
window.analytics?.reset()
|
||||
delete window.analytics
|
||||
}
|
||||
},
|
||||
}),
|
||||
{
|
||||
label: t("general.rebuild_database.label"),
|
||||
action: () => {
|
||||
present({
|
||||
title: t("general.rebuild_database.title"),
|
||||
clickOutsideToDismiss: true,
|
||||
content: () => (
|
||||
<div className="text-sm">
|
||||
<p>{t("general.rebuild_database.warning.line1")}</p>
|
||||
<p>{t("general.rebuild_database.warning.line2")}</p>
|
||||
<div className="mt-4 flex justify-end">
|
||||
<Button
|
||||
className="bg-red-500 px-3 text-white"
|
||||
onClick={async () => {
|
||||
await clearLocalPersistStoreData()
|
||||
window.location.reload()
|
||||
}}
|
||||
>
|
||||
{t("ok", { ns: "common" })}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
})
|
||||
},
|
||||
description: t("general.rebuild_database.description"),
|
||||
buttonText: t("general.rebuild_database.button"),
|
||||
},
|
||||
{
|
||||
label: t("general.export_database.label"),
|
||||
description: t("general.export_database.description"),
|
||||
buttonText: t("general.export_database.button"),
|
||||
action: () => {
|
||||
exportDB()
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t("general.export.label"),
|
||||
description: t("general.export.description"),
|
||||
buttonText: t("general.export.button"),
|
||||
action: () => {
|
||||
const link = document.createElement("a")
|
||||
link.href = `${env.VITE_API_URL}/subscriptions/export`
|
||||
link.download = "follow.opml"
|
||||
link.click()
|
||||
},
|
||||
},
|
||||
|
||||
{ type: "title", value: t("general.network"), disabled: !IN_ELECTRON },
|
||||
IN_ELECTRON && NettingSetting,
|
||||
]}
|
||||
|
|
@ -189,7 +105,7 @@ export const SettingGeneral = () => {
|
|||
)
|
||||
}
|
||||
|
||||
export const VoiceSelector = () => {
|
||||
const VoiceSelector = () => {
|
||||
const { t } = useTranslation("settings")
|
||||
|
||||
const { data } = useQuery({
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { EllipsisHorizontalTextWithTooltip } from "@follow/components/ui/typography/index.js"
|
||||
import { cn } from "@follow/utils/utils"
|
||||
import { Slot } from "@radix-ui/react-slot"
|
||||
import { useContext } from "react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useLoaderData } from "react-router-dom"
|
||||
|
|
@ -18,7 +19,11 @@ export const SettingsSidebarTitle = ({ path, className }: { path: string; classN
|
|||
|
||||
return (
|
||||
<div className={cn("flex min-w-0 items-center gap-2 text-[0.94rem] font-medium", className)}>
|
||||
<i className={`${tab.iconName} shrink-0 text-[19px]`} />
|
||||
{typeof tab.icon === "string" ? (
|
||||
<i className={`${tab.icon} shrink-0 text-[19px]`} />
|
||||
) : (
|
||||
<Slot className="shrink-0 text-[19px]">{tab.icon}</Slot>
|
||||
)}
|
||||
<EllipsisHorizontalTextWithTooltip>{t(tab.name as any)}</EllipsisHorizontalTextWithTooltip>
|
||||
</div>
|
||||
)
|
||||
|
|
@ -33,11 +38,12 @@ export const SettingsTitle = ({
|
|||
}) => {
|
||||
const { t } = useTranslation("settings")
|
||||
const {
|
||||
iconName,
|
||||
icon: iconName,
|
||||
name: title,
|
||||
headerIcon,
|
||||
} = (useLoaderData() || loader?.() || {}) as SettingPageConfig
|
||||
|
||||
const usedIcon = headerIcon || iconName
|
||||
const isInSettingIndependentWindow = useContext(IsInSettingIndependentWindowContext)
|
||||
if (!title) {
|
||||
return null
|
||||
|
|
@ -51,7 +57,7 @@ export const SettingsTitle = ({
|
|||
className,
|
||||
)}
|
||||
>
|
||||
<i className={headerIcon || iconName} />
|
||||
{typeof usedIcon === "string" ? <i className={usedIcon} /> : usedIcon}
|
||||
<span>{t(title as any)}</span>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ export enum DisableWhy {
|
|||
}
|
||||
|
||||
export interface SettingPageConfig {
|
||||
iconName: string
|
||||
icon: string | React.ReactNode
|
||||
name: I18nKeysForSettings
|
||||
priority: number
|
||||
headerIcon?: string
|
||||
headerIcon?: string | React.ReactNode
|
||||
hideIf?: (ctx: SettingPageContext) => boolean
|
||||
disableIf?: (ctx: SettingPageContext) => [boolean, DisableWhy]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { SettingsTitle } from "~/modules/settings/title"
|
|||
import { defineSettingPageData } from "~/modules/settings/utils"
|
||||
|
||||
export const loader = defineSettingPageData({
|
||||
iconName: "i-mgc-information-cute-re",
|
||||
icon: "i-mgc-information-cute-re",
|
||||
name: "titles.about",
|
||||
priority: 9999,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const iconName = "i-mgc-magic-2-cute-re"
|
|||
const priority = 1020
|
||||
|
||||
export const loader = defineSettingPageData({
|
||||
iconName,
|
||||
icon: iconName,
|
||||
name: "titles.actions",
|
||||
priority,
|
||||
disableIf: (ctx) => [ctx.role === UserRole.Trial, DisableWhy.NotActivation],
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const iconName = "i-mgc-palette-cute-re"
|
|||
const priority = 1010
|
||||
|
||||
export const loader = defineSettingPageData({
|
||||
iconName,
|
||||
icon: iconName,
|
||||
name: "titles.appearance",
|
||||
priority,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
import { MaterialSymbolsDatabaseOutline } from "@follow/components/icons/Database.js"
|
||||
|
||||
import { SettingDataControl } from "~/modules/settings/tabs/data-control"
|
||||
import { SettingsTitle } from "~/modules/settings/title"
|
||||
import { defineSettingPageData } from "~/modules/settings/utils"
|
||||
|
||||
const priority = 1025
|
||||
|
||||
export const loader = defineSettingPageData({
|
||||
icon: <MaterialSymbolsDatabaseOutline />,
|
||||
name: "titles.data_control",
|
||||
priority,
|
||||
})
|
||||
|
||||
export function Component() {
|
||||
return (
|
||||
<>
|
||||
<SettingsTitle />
|
||||
<SettingDataControl />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ const iconName = "i-mgc-certificate-cute-re"
|
|||
const priority = 1060
|
||||
|
||||
export const loader = defineSettingPageData({
|
||||
iconName,
|
||||
icon: iconName,
|
||||
name: "titles.feeds",
|
||||
priority,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const iconName = "i-mgc-settings-7-cute-re"
|
|||
const priority = 1000
|
||||
|
||||
export const loader = defineSettingPageData({
|
||||
iconName,
|
||||
icon: iconName,
|
||||
name: "titles.general",
|
||||
priority,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const iconName = "i-mgc-department-cute-re"
|
|||
const priority = 1030
|
||||
|
||||
export const loader = defineSettingPageData({
|
||||
iconName,
|
||||
icon: iconName,
|
||||
name: "titles.integration",
|
||||
priority,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const iconName = "i-mgc-love-cute-re"
|
|||
const priority = 1070
|
||||
|
||||
export const loader = defineSettingPageData({
|
||||
iconName,
|
||||
icon: iconName,
|
||||
name: "titles.invitations",
|
||||
priority,
|
||||
disableIf: (ctx) => [ctx.role === UserRole.Trial, DisableWhy.NotActivation],
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const iconName = "i-mgc-rada-cute-re"
|
|||
const priority = 1050
|
||||
|
||||
export const loader = defineSettingPageData({
|
||||
iconName,
|
||||
icon: iconName,
|
||||
name: "titles.lists",
|
||||
priority,
|
||||
disableIf: (ctx) => [ctx.role === UserRole.Trial, DisableWhy.NotActivation],
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { defineSettingPageData } from "~/modules/settings/utils"
|
|||
const iconName = "i-mgc-user-setting-cute-re"
|
||||
const priority = 1090
|
||||
export const loader = defineSettingPageData({
|
||||
iconName,
|
||||
icon: iconName,
|
||||
name: "titles.profile",
|
||||
priority,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ const iconName = "i-mgc-hotkey-cute-re"
|
|||
const priority = 1080
|
||||
|
||||
export const loader = defineSettingPageData({
|
||||
iconName,
|
||||
icon: iconName,
|
||||
name: "titles.shortcuts",
|
||||
priority,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@
|
|||
## New Features
|
||||
|
||||
- Feed owners can now reset their feeds.
|
||||
- Now you can export the data from the local database.
|
||||
|
||||
## Improvements
|
||||
|
||||
- Optimized the Zen mode experience on macOS.
|
||||
|
||||
## Bug Fixes
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ const ymlMapsMap = {
|
|||
win32: "latest.yml",
|
||||
}
|
||||
|
||||
const keepModules = new Set(["font-list", "vscode-languagedetection"])
|
||||
const keepModules = new Set(["font-list", "vscode-languagedetection", "fast-folder-size"])
|
||||
const keepLanguages = new Set(["en", "en_GB", "en-US", "en_US"])
|
||||
|
||||
// remove folders & files not to be included in the app
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@
|
|||
"general.mark_as_read.render.label": "تحديد كمقروءة عند العرض",
|
||||
"general.mark_as_read.scroll.description": "تحديد الإدخالات تلقائيًا كمقروءة عند التمرير خارج العرض.",
|
||||
"general.mark_as_read.scroll.label": "تحديد كمقروءة عند التمرير",
|
||||
"general.privacy_data": "الخصوصية والبيانات",
|
||||
"general.rebuild_database.button": "إعادة بناء",
|
||||
"general.rebuild_database.description": "إذا كنت تواجه مشاكل في العرض، قد تحل إعادة بناء قاعدة البيانات هذه المشاكل.",
|
||||
"general.rebuild_database.label": "إعادة بناء قاعدة البيانات",
|
||||
|
|
|
|||
|
|
@ -92,7 +92,6 @@
|
|||
"general.mark_as_read.render.label": "تحديد كمقروءة عند العرض",
|
||||
"general.mark_as_read.scroll.description": "تحديد الإدخالات تلقائيًا كمقروءة عند التمرير خارج العرض.",
|
||||
"general.mark_as_read.scroll.label": "تحديد كمقروءة عند التمرير",
|
||||
"general.privacy_data": "الخصوصية والبيانات",
|
||||
"general.rebuild_database.button": "إعادة بناء",
|
||||
"general.rebuild_database.description": "إذا كنت تواجه مشاكل في العرض، قد تحل إعادة بناء قاعدة البيانات هذه المشاكل.",
|
||||
"general.rebuild_database.label": "إعادة بناء قاعدة البيانات",
|
||||
|
|
|
|||
|
|
@ -92,7 +92,6 @@
|
|||
"general.mark_as_read.render.label": "تحديد كمقروءة عند العرض",
|
||||
"general.mark_as_read.scroll.description": "تحديد المشاركات كمقروءة تلقائيًا عند التمرير خارج العرض.",
|
||||
"general.mark_as_read.scroll.label": "تحديد كمقروءة عند التمرير",
|
||||
"general.privacy_data": "الخصوصية والبيانات",
|
||||
"general.rebuild_database.button": "إعادة بناء",
|
||||
"general.rebuild_database.description": "إذا كنت تواجه مشاكل في العرض، قد تحل إعادة بناء قاعدة البيانات هذه المشاكل.",
|
||||
"general.rebuild_database.label": "إعادة بناء قاعدة البيانات",
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@
|
|||
"general.mark_as_read.render.label": "تحديد كمقروء عند العرض",
|
||||
"general.mark_as_read.scroll.description": "تحديد المدخلات كمقروءة تلقائيًا فاش كتخرج من العرض.",
|
||||
"general.mark_as_read.scroll.label": "تحديد كمقروء عند التمرير",
|
||||
"general.privacy_data": "الخصوصية والبيانات",
|
||||
"general.rebuild_database.button": "إعادة بناء",
|
||||
"general.rebuild_database.description": "إلى كنتي كتواجه مشاكل فالعرض، إعادة بناء قاعدة البيانات غادي يحلها.",
|
||||
"general.rebuild_database.label": "إعادة بناء قاعدة البيانات",
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@
|
|||
"general.mark_as_read.render.label": "وضع علامة كمقروء عند العرض",
|
||||
"general.mark_as_read.scroll.description": "وضع علامة على الإدخالات كمقروءة تلقائيًا عند التمرير خارج العرض.",
|
||||
"general.mark_as_read.scroll.label": "وضع علامة كمقروء عند التمرير",
|
||||
"general.privacy_data": "الخصوصية والبيانات",
|
||||
"general.rebuild_database.button": "إعادة بناء",
|
||||
"general.rebuild_database.description": "إذا كنت تواجه مشكلات في العرض، فقد تحل إعادة بناء قاعدة البيانات هذه المشكلة.",
|
||||
"general.rebuild_database.label": "إعادة بناء قاعدة البيانات",
|
||||
|
|
|
|||
|
|
@ -92,7 +92,6 @@
|
|||
"general.mark_as_read.render.label": "تحديد كمقروء عند العرض",
|
||||
"general.mark_as_read.scroll.description": "تحديد العناصر تلقائيًا كمقروءة عند التمرير خارج العرض.",
|
||||
"general.mark_as_read.scroll.label": "تحديد كمقروء عند التمرير",
|
||||
"general.privacy_data": "الخصوصية والبيانات",
|
||||
"general.rebuild_database.button": "إعادة بناء",
|
||||
"general.rebuild_database.description": "إذا كنت تواجه مشكلات في العرض، فقد يحل إعادة بناء قاعدة البيانات هذه المشكلات.",
|
||||
"general.rebuild_database.label": "إعادة بناء قاعدة البيانات",
|
||||
|
|
|
|||
|
|
@ -96,7 +96,6 @@
|
|||
"general.mark_as_read.scroll.description": "Einträge automatisch als gelesen markieren, wenn sie aus dem Ansichtsbereich gescrollt werden.",
|
||||
"general.mark_as_read.scroll.label": "Als gelesen markieren, wenn gescrollt wird",
|
||||
"general.network": "Netzwerk",
|
||||
"general.privacy_data": "Datenschutz & Daten",
|
||||
"general.proxy.description": "Proxy für Netzwerkverkehrsrouting einrichten, z.B. socks://proxy.beispiel.de:1080",
|
||||
"general.proxy.label": "Proxy",
|
||||
"general.rebuild_database.button": "Neu aufbauen",
|
||||
|
|
|
|||
|
|
@ -95,6 +95,10 @@
|
|||
"appearance.zen_mode.description": "Zen mode is an undisturbed reading mode that allows you to focus on the content without any interference. Enabling Zen mode will hide the sidebar.",
|
||||
"appearance.zen_mode.label": "Zen mode",
|
||||
"common.give_star": "<HeartIcon />Love our product? <Link>Give us a star on GitHub!</Link>",
|
||||
"data_control.app_cache_limit.description": "The maximum size of the app cache. Once the cache reaches this size, the oldest items will be deleted to free up space.",
|
||||
"data_control.app_cache_limit.label": "App Cache Limit",
|
||||
"data_control.clean_cache.button": "Clean Cache",
|
||||
"data_control.clean_cache.description": "Clean the app cache to free up space.",
|
||||
"feeds.claimTips": "To claim your feeds and receive tips, right-click on the feed in your subscription list and select Claim.",
|
||||
"feeds.noFeeds": "No claimed feeds",
|
||||
"feeds.tableHeaders.entryCount": "Entries",
|
||||
|
|
@ -102,6 +106,8 @@
|
|||
"feeds.tableHeaders.subscriptionCount": "Subs",
|
||||
"feeds.tableHeaders.tipAmount": "Tips",
|
||||
"general.app": "App",
|
||||
"general.cache": "Cache",
|
||||
"general.data": "Data",
|
||||
"general.data_persist.description": "Persist data locally to enable offline access and local search.",
|
||||
"general.data_persist.label": "Persist data for offline usage",
|
||||
"general.export.button": "Export",
|
||||
|
|
@ -121,7 +127,7 @@
|
|||
"general.mark_as_read.scroll.description": "Automatically mark entries as read when scrolled out of the view.",
|
||||
"general.mark_as_read.scroll.label": "Mark as read when scrolling",
|
||||
"general.network": "Network",
|
||||
"general.privacy_data": "Privacy & Data",
|
||||
"general.privacy": "Privacy",
|
||||
"general.proxy.description": "Set proxy for network traffic routing, e.g., socks://proxy.example.com:1080",
|
||||
"general.proxy.label": "Proxy",
|
||||
"general.rebuild_database.button": "Rebuild",
|
||||
|
|
@ -243,6 +249,7 @@
|
|||
"titles.about": "About",
|
||||
"titles.actions": "Actions",
|
||||
"titles.appearance": "Appearance",
|
||||
"titles.data_control": "Data Control",
|
||||
"titles.feeds": "Feeds",
|
||||
"titles.general": "General",
|
||||
"titles.integration": "Integration",
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@
|
|||
"general.mark_as_read.render.label": "Marcar como leído cuando está en vista",
|
||||
"general.mark_as_read.scroll.description": "Marcar automáticamente las entradas como leídas al desplazarse fuera de la vista.",
|
||||
"general.mark_as_read.scroll.label": "Marcar como leído al desplazarse",
|
||||
"general.privacy_data": "Privacidad y Datos",
|
||||
"general.rebuild_database.button": "Reconstruir",
|
||||
"general.rebuild_database.description": "Si experimentas problemas de renderizado, reconstruir la base de datos puede solucionarlos.",
|
||||
"general.rebuild_database.label": "Reconstruir Base de Datos",
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@
|
|||
"general.mark_as_read.render.label": "Merkitse luetuksi, kun näkyvissä",
|
||||
"general.mark_as_read.scroll.description": "Merkitse merkinnät automaattisesti luetuiksi, kun ne vieritetään pois näkymästä.",
|
||||
"general.mark_as_read.scroll.label": "Merkitse luetuksi vierittäessä",
|
||||
"general.privacy_data": "Yksityisyys ja data",
|
||||
"general.rebuild_database.button": "Rakenna uudelleen",
|
||||
"general.rebuild_database.description": "Jos kohtaat renderöintiongelmia, tietokannan uudelleenrakentaminen saattaa ratkaista ne.",
|
||||
"general.rebuild_database.label": "Rakenna tietokanta uudelleen",
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@
|
|||
"general.mark_as_read.render.label": "Marquer comme lu lors de l'affichage",
|
||||
"general.mark_as_read.scroll.description": "Marquer automatiquement les entrées comme lues lorsqu'elles sortent de la vue.",
|
||||
"general.mark_as_read.scroll.label": "Marquer comme lu lors du défilement",
|
||||
"general.privacy_data": "Confidentialité & Données",
|
||||
"general.rebuild_database.button": "Reconstruire",
|
||||
"general.rebuild_database.description": "Si vous rencontrez des problèmes d'affichage, la reconstruction de la base de données peut les résoudre.",
|
||||
"general.rebuild_database.label": "Reconstruire la base de données",
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@
|
|||
"general.mark_as_read.render.label": "Segna come letto quando è in visualizzazione",
|
||||
"general.mark_as_read.scroll.description": "Segna automaticamente le voci come lette quando scorri fuori dalla visualizzazione.",
|
||||
"general.mark_as_read.scroll.label": "Segna come letto durante lo scorrimento",
|
||||
"general.privacy_data": "Privacy e Dati",
|
||||
"general.rebuild_database.button": "Ricostruisci",
|
||||
"general.rebuild_database.description": "Se riscontri problemi di visualizzazione, la ricostruzione del database potrebbe risolverli.",
|
||||
"general.rebuild_database.label": "Ricostruisci Database",
|
||||
|
|
|
|||
|
|
@ -118,7 +118,6 @@
|
|||
"general.mark_as_read.scroll.description": "表示からスクロールアウトしたときにエントリを自動的に既読にします。",
|
||||
"general.mark_as_read.scroll.label": "スクロール時に既読にする",
|
||||
"general.network": "ネットワーク",
|
||||
"general.privacy_data": "プライバシーとデータ",
|
||||
"general.proxy.description": "ネットワークリクエストを代理します。例: socks://proxy.example.com:1080",
|
||||
"general.proxy.label": "プロキシ",
|
||||
"general.rebuild_database.button": "再構築",
|
||||
|
|
|
|||
|
|
@ -96,7 +96,6 @@
|
|||
"general.mark_as_read.scroll.description": "스크롤하여 보기에서 벗어날 때 자동으로 항목을 읽음으로 표시합니다.",
|
||||
"general.mark_as_read.scroll.label": "스크롤 시 읽음으로 표시",
|
||||
"general.network": "네트워크",
|
||||
"general.privacy_data": "개인정보 및 데이터",
|
||||
"general.proxy.description": "네트워크 트래픽 라우팅을 위한 프록시 설정, 예: socks://proxy.example.com:1080",
|
||||
"general.proxy.label": "프록시",
|
||||
"general.rebuild_database.button": "재구축",
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@
|
|||
"general.mark_as_read.render.label": "Marcar como lido ao visualizar",
|
||||
"general.mark_as_read.scroll.description": "Marcar automaticamente as entradas como lidas quando saem do campo de visão.",
|
||||
"general.mark_as_read.scroll.label": "Marcar como lido ao rolar a página",
|
||||
"general.privacy_data": "Privacidade & Dados",
|
||||
"general.rebuild_database.button": "Reconstruir",
|
||||
"general.rebuild_database.description": "Se estiver a ter problemas de renderização, reconstruir a base de dados pode resolver.",
|
||||
"general.rebuild_database.label": "Reconstruir Base de Dados",
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@
|
|||
"general.mark_as_read.render.label": "Отметить как прочитанное при отображении",
|
||||
"general.mark_as_read.scroll.description": "Автоматически отмечать записи как прочитанные при прокрутке.",
|
||||
"general.mark_as_read.scroll.label": "Отметить как прочитанное при прокрутке",
|
||||
"general.privacy_data": "Конфиденциальность и данные",
|
||||
"general.rebuild_database.button": "Перестроить",
|
||||
"general.rebuild_database.description": "Если у вас возникают проблемы с отображением, перестроение базы данных может их решить.",
|
||||
"general.rebuild_database.label": "Перестроить базу данных",
|
||||
|
|
|
|||
|
|
@ -96,7 +96,6 @@
|
|||
"general.mark_as_read.scroll.description": "Görünümden kaydırıldığında girdileri otomatik olarak okundu olarak işaretle.",
|
||||
"general.mark_as_read.scroll.label": "Kaydırıldığında okundu olarak işaretle",
|
||||
"general.network": "Ağ",
|
||||
"general.privacy_data": "Gizlilik ve Veri",
|
||||
"general.proxy.description": "Ağ trafiği yönlendirmesi için proxy ayarla, örn., socks://proxy.example.com:1080",
|
||||
"general.proxy.label": "Proxy",
|
||||
"general.rebuild_database.button": "Yeniden Oluştur",
|
||||
|
|
|
|||
|
|
@ -117,7 +117,6 @@
|
|||
"general.mark_as_read.scroll.description": "当条目滚动出窗口时自动标记为已读",
|
||||
"general.mark_as_read.scroll.label": "滚动时标记为已读",
|
||||
"general.network": "网络",
|
||||
"general.privacy_data": "隐私与数据",
|
||||
"general.proxy.description": "代理网络请求,示例:socks://proxy.example.com:1080",
|
||||
"general.proxy.label": "代理",
|
||||
"general.rebuild_database.button": "重建",
|
||||
|
|
|
|||
|
|
@ -106,7 +106,6 @@
|
|||
"general.mark_as_read.scroll.description": "當滾動出視圖時,自動標記條目為已讀。",
|
||||
"general.mark_as_read.scroll.label": "滾動時標記為已讀",
|
||||
"general.network": "網絡",
|
||||
"general.privacy_data": "隱私與數據",
|
||||
"general.proxy.description": "代理網絡流量,例如:socks://proxy.example.com:1080",
|
||||
"general.proxy.label": "代理",
|
||||
"general.rebuild_database.button": "重建",
|
||||
|
|
|
|||
|
|
@ -106,7 +106,6 @@
|
|||
"general.mark_as_read.scroll.description": "當條目捲動離開視圖時自動標記為已讀。",
|
||||
"general.mark_as_read.scroll.label": "捲動時標記為已讀",
|
||||
"general.network": "網路",
|
||||
"general.privacy_data": "隱私與資料",
|
||||
"general.proxy.description": "設定代理伺服器來處理網路流量,例如:socks://proxy.example.com:1080",
|
||||
"general.proxy.label": "代理伺服器",
|
||||
"general.rebuild_database.button": "重置",
|
||||
|
|
|
|||
|
|
@ -131,7 +131,8 @@
|
|||
"prettier --ignore-unknown --write"
|
||||
],
|
||||
"locales/**/*.json": [
|
||||
"npm run dedupe:locales"
|
||||
"npm run dedupe:locales",
|
||||
"git add locales"
|
||||
]
|
||||
},
|
||||
"bump": {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
import type { SVGProps } from "react"
|
||||
|
||||
export function MaterialSymbolsDatabaseOutline(props: SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...props}>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M12 21q-3.775 0-6.387-1.162T3 17V7q0-1.65 2.638-2.825T12 3t6.363 1.175T21 7v10q0 1.675-2.613 2.838T12 21m0-11.975q2.225 0 4.475-.638T19 7.025q-.275-.725-2.512-1.375T12 5q-2.275 0-4.462.638T5 7.025q.35.75 2.538 1.375T12 9.025M12 14q1.05 0 2.025-.1t1.863-.288t1.675-.462T19 12.525v-3q-.65.35-1.437.625t-1.675.463t-1.863.287T12 11t-2.05-.1t-1.888-.288T6.4 10.15T5 9.525v3q.625.35 1.4.625t1.663.463t1.887.287T12 14m0 5q1.15 0 2.338-.175t2.187-.462t1.675-.65t.8-.738v-2.45q-.65.35-1.437.625t-1.675.463t-1.863.287T12 16t-2.05-.1t-1.888-.288T6.4 15.15T5 14.525V17q.125.375.788.725t1.662.638t2.2.462T12 19"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import type { SVGProps } from "react"
|
||||
|
||||
export function CarbonInfinitySymbol(props: SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32" {...props}>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M23 23c-5.656 0-7.858-6.41-7.949-6.684C15.034 16.265 13.208 11 9 11c-2.757 0-5 2.243-5 5s2.243 5 5 5c1.588 0 3.013-.732 4.237-2.176l1.526 1.293C13.164 22.003 11.172 23 9 23c-3.86 0-7-3.14-7-7s3.14-7 7-7c5.656 0 7.858 6.41 7.949 6.684C16.966 15.735 18.792 21 23 21c2.757 0 5-2.243 5-5s-2.243-5-5-5c-1.588 0-3.013.732-4.237 2.176l-1.526-1.293C18.836 9.997 20.828 9 23 9c3.86 0 7 3.14 7 7s-3.14 7-7 7"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import { cn } from "@follow/utils/utils"
|
||||
import * as SliderPrimitive from "@radix-ui/react-slider"
|
||||
import * as React from "react"
|
||||
|
||||
export const Slider = React.forwardRef<
|
||||
React.ElementRef<typeof SliderPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SliderPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn("relative flex w-full touch-none select-none items-center", className)}
|
||||
{...props}
|
||||
>
|
||||
<SliderPrimitive.Track className="relative h-1.5 w-full grow overflow-hidden rounded-full bg-accent/20">
|
||||
<SliderPrimitive.Range className="absolute h-full bg-accent" />
|
||||
</SliderPrimitive.Track>
|
||||
<SliderPrimitive.Thumb className="block size-4 rounded-full border border-accent/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-accent disabled:pointer-events-none disabled:opacity-50" />
|
||||
</SliderPrimitive.Root>
|
||||
))
|
||||
Slider.displayName = SliderPrimitive.Root.displayName
|
||||
209
pnpm-lock.yaml
209
pnpm-lock.yaml
|
|
@ -272,6 +272,9 @@ importers:
|
|||
electron-updater:
|
||||
specifier: ^6.3.9
|
||||
version: 6.3.9
|
||||
fast-folder-size:
|
||||
specifier: 2.3.0
|
||||
version: 2.3.0
|
||||
font-list:
|
||||
specifier: 1.5.1
|
||||
version: 1.5.1
|
||||
|
|
@ -3343,8 +3346,8 @@ packages:
|
|||
'@radix-ui/react-avatar@1.1.1':
|
||||
resolution: {integrity: sha512-eoOtThOmxeoizxpX6RiEsQZ2wj5r4+zoeqAwO0cBaFQGjJwIH3dIX0OCxNrCyrrdxG+vBweMETh3VziQG7c1kw==}
|
||||
peerDependencies:
|
||||
'@types/react': npm:types-react@19.0.0-rc.1
|
||||
'@types/react-dom': npm:types-react-dom@19.0.0-rc.1
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
peerDependenciesMeta:
|
||||
|
|
@ -4859,6 +4862,9 @@ packages:
|
|||
birecord@0.1.1:
|
||||
resolution: {integrity: sha512-VUpsf/qykW0heRlC8LooCq28Kxn3mAqKohhDG/49rrsQ1dT1CXyj/pgXS+5BSRzFTR/3DyIBOqQOrGyZOh71Aw==}
|
||||
|
||||
bl@1.2.3:
|
||||
resolution: {integrity: sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==}
|
||||
|
||||
bl@4.1.0:
|
||||
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
|
||||
|
||||
|
|
@ -4936,6 +4942,12 @@ packages:
|
|||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
hasBin: true
|
||||
|
||||
buffer-alloc-unsafe@1.1.0:
|
||||
resolution: {integrity: sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==}
|
||||
|
||||
buffer-alloc@1.2.0:
|
||||
resolution: {integrity: sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==}
|
||||
|
||||
buffer-crc32@0.2.13:
|
||||
resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
|
||||
|
||||
|
|
@ -4946,6 +4958,9 @@ packages:
|
|||
resolution: {integrity: sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==}
|
||||
engines: {node: '>=0.4'}
|
||||
|
||||
buffer-fill@1.0.0:
|
||||
resolution: {integrity: sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==}
|
||||
|
||||
buffer-from@1.1.2:
|
||||
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
|
||||
|
||||
|
|
@ -5542,6 +5557,26 @@ packages:
|
|||
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
decompress-tar@4.1.1:
|
||||
resolution: {integrity: sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
decompress-tarbz2@4.1.1:
|
||||
resolution: {integrity: sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
decompress-targz@4.1.1:
|
||||
resolution: {integrity: sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
decompress-unzip@4.0.1:
|
||||
resolution: {integrity: sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
decompress@4.2.1:
|
||||
resolution: {integrity: sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
deep-eql@5.0.2:
|
||||
resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
|
||||
engines: {node: '>=6'}
|
||||
|
|
@ -6233,6 +6268,10 @@ packages:
|
|||
fast-deep-equal@3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
|
||||
fast-folder-size@2.3.0:
|
||||
resolution: {integrity: sha512-W3HuQYdZ1GaOAdIqKR/guqxvlHW0f8ZFknYfnsTBuL+9QokVARUBNt/kFE8hkyZd/yQ/mYnKmrtWmFyTLRfX3A==}
|
||||
hasBin: true
|
||||
|
||||
fast-glob@3.3.2:
|
||||
resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
|
|
@ -6293,6 +6332,18 @@ packages:
|
|||
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
|
||||
file-type@3.9.0:
|
||||
resolution: {integrity: sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
file-type@5.2.0:
|
||||
resolution: {integrity: sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
file-type@6.2.0:
|
||||
resolution: {integrity: sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
filelist@1.0.4:
|
||||
resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==}
|
||||
|
||||
|
|
@ -6499,6 +6550,10 @@ packages:
|
|||
resolution: {integrity: sha512-SCbprXGAPdIhKAXiG+Mk6yeoFH61JlYunqdFQFHDtLjJlDjFf6x07dsS8acO+xWt52jpdVo49AlVDnUVK1sDNw==}
|
||||
engines: {node: '>= 4.0'}
|
||||
|
||||
get-stream@2.3.1:
|
||||
resolution: {integrity: sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
get-stream@4.1.0:
|
||||
resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==}
|
||||
engines: {node: '>=6'}
|
||||
|
|
@ -6974,6 +7029,9 @@ packages:
|
|||
is-my-json-valid@2.20.6:
|
||||
resolution: {integrity: sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==}
|
||||
|
||||
is-natural-number@4.0.1:
|
||||
resolution: {integrity: sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==}
|
||||
|
||||
is-number@7.0.0:
|
||||
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
|
||||
engines: {node: '>=0.12.0'}
|
||||
|
|
@ -7451,6 +7509,10 @@ packages:
|
|||
resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
make-dir@1.3.0:
|
||||
resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
make-fetch-happen@10.2.1:
|
||||
resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||
|
|
@ -8190,6 +8252,18 @@ packages:
|
|||
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
pify@3.0.0:
|
||||
resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
pinkie-promise@2.0.1:
|
||||
resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
pinkie@2.0.4:
|
||||
resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
pino-abstract-transport@2.0.0:
|
||||
resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==}
|
||||
|
||||
|
|
@ -9059,6 +9133,10 @@ packages:
|
|||
secure-json-parse@2.7.0:
|
||||
resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==}
|
||||
|
||||
seek-bzip@1.0.6:
|
||||
resolution: {integrity: sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==}
|
||||
hasBin: true
|
||||
|
||||
selecto@1.26.3:
|
||||
resolution: {integrity: sha512-gZHgqMy5uyB6/2YDjv3Qqaf7bd2hTDOpPdxXlrez4R3/L0GiEWDCFaUfrflomgqdb3SxHF2IXY0Jw0EamZi7cw==}
|
||||
|
||||
|
|
@ -9315,6 +9393,9 @@ packages:
|
|||
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
strip-dirs@2.1.0:
|
||||
resolution: {integrity: sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==}
|
||||
|
||||
strip-eof@1.0.0:
|
||||
resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
|
@ -9409,6 +9490,10 @@ packages:
|
|||
engines: {node: '>=14.0.0'}
|
||||
hasBin: true
|
||||
|
||||
tar-stream@1.6.2:
|
||||
resolution: {integrity: sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
||||
tar-stream@2.2.0:
|
||||
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
|
@ -9442,6 +9527,9 @@ packages:
|
|||
thread-stream@3.1.0:
|
||||
resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==}
|
||||
|
||||
through@2.3.8:
|
||||
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
|
||||
|
||||
tiny-inflate@1.0.3:
|
||||
resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
|
||||
|
||||
|
|
@ -9488,6 +9576,9 @@ packages:
|
|||
resolution: {integrity: sha512-DbplOfQFkqG5IHcDyyrs/lkvSr3mPUVsFf/RbDppOshs22yTPnSJWEe6FkYd1txAwU/zcnR905ar2fi4kwF29w==}
|
||||
engines: {node: '>=0.12'}
|
||||
|
||||
to-buffer@1.1.1:
|
||||
resolution: {integrity: sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==}
|
||||
|
||||
to-data-view@1.1.0:
|
||||
resolution: {integrity: sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==}
|
||||
|
||||
|
|
@ -9672,6 +9763,9 @@ packages:
|
|||
uhyphen@0.2.0:
|
||||
resolution: {integrity: sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==}
|
||||
|
||||
unbzip2-stream@1.4.3:
|
||||
resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==}
|
||||
|
||||
unconfig@0.5.5:
|
||||
resolution: {integrity: sha512-VQZ5PT9HDX+qag0XdgQi8tJepPhXiR/yVOkn707gJDKo31lGjRilPREiQJ9Z6zd/Ugpv6ZvO5VxVIcatldYcNQ==}
|
||||
|
||||
|
|
@ -14879,6 +14973,11 @@ snapshots:
|
|||
|
||||
birecord@0.1.1: {}
|
||||
|
||||
bl@1.2.3:
|
||||
dependencies:
|
||||
readable-stream: 2.3.8
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
bl@4.1.0:
|
||||
dependencies:
|
||||
buffer: 5.7.1
|
||||
|
|
@ -14983,12 +15082,21 @@ snapshots:
|
|||
node-releases: 2.0.18
|
||||
update-browserslist-db: 1.1.1(browserslist@4.24.0)
|
||||
|
||||
buffer-alloc-unsafe@1.1.0: {}
|
||||
|
||||
buffer-alloc@1.2.0:
|
||||
dependencies:
|
||||
buffer-alloc-unsafe: 1.1.0
|
||||
buffer-fill: 1.0.0
|
||||
|
||||
buffer-crc32@0.2.13: {}
|
||||
|
||||
buffer-equal-constant-time@1.0.1: {}
|
||||
|
||||
buffer-equal@1.0.1: {}
|
||||
|
||||
buffer-fill@1.0.0: {}
|
||||
|
||||
buffer-from@1.1.2: {}
|
||||
|
||||
buffer-xor@1.0.3: {}
|
||||
|
|
@ -15705,6 +15813,44 @@ snapshots:
|
|||
dependencies:
|
||||
mimic-response: 3.1.0
|
||||
|
||||
decompress-tar@4.1.1:
|
||||
dependencies:
|
||||
file-type: 5.2.0
|
||||
is-stream: 1.1.0
|
||||
tar-stream: 1.6.2
|
||||
|
||||
decompress-tarbz2@4.1.1:
|
||||
dependencies:
|
||||
decompress-tar: 4.1.1
|
||||
file-type: 6.2.0
|
||||
is-stream: 1.1.0
|
||||
seek-bzip: 1.0.6
|
||||
unbzip2-stream: 1.4.3
|
||||
|
||||
decompress-targz@4.1.1:
|
||||
dependencies:
|
||||
decompress-tar: 4.1.1
|
||||
file-type: 5.2.0
|
||||
is-stream: 1.1.0
|
||||
|
||||
decompress-unzip@4.0.1:
|
||||
dependencies:
|
||||
file-type: 3.9.0
|
||||
get-stream: 2.3.1
|
||||
pify: 2.3.0
|
||||
yauzl: 2.10.0
|
||||
|
||||
decompress@4.2.1:
|
||||
dependencies:
|
||||
decompress-tar: 4.1.1
|
||||
decompress-tarbz2: 4.1.1
|
||||
decompress-targz: 4.1.1
|
||||
decompress-unzip: 4.0.1
|
||||
graceful-fs: 4.2.11
|
||||
make-dir: 1.3.0
|
||||
pify: 2.3.0
|
||||
strip-dirs: 2.1.0
|
||||
|
||||
deep-eql@5.0.2: {}
|
||||
|
||||
deep-is@0.1.4: {}
|
||||
|
|
@ -16610,6 +16756,13 @@ snapshots:
|
|||
|
||||
fast-deep-equal@3.1.3: {}
|
||||
|
||||
fast-folder-size@2.3.0:
|
||||
dependencies:
|
||||
decompress: 4.2.1
|
||||
https-proxy-agent: 7.0.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
fast-glob@3.3.2:
|
||||
dependencies:
|
||||
'@nodelib/fs.stat': 2.0.5
|
||||
|
|
@ -16686,6 +16839,12 @@ snapshots:
|
|||
dependencies:
|
||||
flat-cache: 4.0.1
|
||||
|
||||
file-type@3.9.0: {}
|
||||
|
||||
file-type@5.2.0: {}
|
||||
|
||||
file-type@6.2.0: {}
|
||||
|
||||
filelist@1.0.4:
|
||||
dependencies:
|
||||
minimatch: 5.1.6
|
||||
|
|
@ -16944,6 +17103,11 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
get-stream@2.3.1:
|
||||
dependencies:
|
||||
object-assign: 4.1.1
|
||||
pinkie-promise: 2.0.1
|
||||
|
||||
get-stream@4.1.0:
|
||||
dependencies:
|
||||
pump: 3.0.2
|
||||
|
|
@ -17595,6 +17759,8 @@ snapshots:
|
|||
xtend: 4.0.2
|
||||
optional: true
|
||||
|
||||
is-natural-number@4.0.1: {}
|
||||
|
||||
is-number@7.0.0: {}
|
||||
|
||||
is-obj@2.0.0: {}
|
||||
|
|
@ -18033,6 +18199,10 @@ snapshots:
|
|||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
|
||||
make-dir@1.3.0:
|
||||
dependencies:
|
||||
pify: 3.0.0
|
||||
|
||||
make-fetch-happen@10.2.1:
|
||||
dependencies:
|
||||
agentkeepalive: 4.5.0
|
||||
|
|
@ -19039,6 +19209,14 @@ snapshots:
|
|||
|
||||
pify@2.3.0: {}
|
||||
|
||||
pify@3.0.0: {}
|
||||
|
||||
pinkie-promise@2.0.1:
|
||||
dependencies:
|
||||
pinkie: 2.0.4
|
||||
|
||||
pinkie@2.0.4: {}
|
||||
|
||||
pino-abstract-transport@2.0.0:
|
||||
dependencies:
|
||||
split2: 4.2.0
|
||||
|
|
@ -19966,6 +20144,10 @@ snapshots:
|
|||
|
||||
secure-json-parse@2.7.0: {}
|
||||
|
||||
seek-bzip@1.0.6:
|
||||
dependencies:
|
||||
commander: 2.20.3
|
||||
|
||||
selecto@1.26.3:
|
||||
dependencies:
|
||||
'@daybrush/utils': 1.13.0
|
||||
|
|
@ -20218,6 +20400,10 @@ snapshots:
|
|||
|
||||
strip-bom@3.0.0: {}
|
||||
|
||||
strip-dirs@2.1.0:
|
||||
dependencies:
|
||||
is-natural-number: 4.0.1
|
||||
|
||||
strip-eof@1.0.0: {}
|
||||
|
||||
strip-final-newline@3.0.0: {}
|
||||
|
|
@ -20332,6 +20518,16 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- ts-node
|
||||
|
||||
tar-stream@1.6.2:
|
||||
dependencies:
|
||||
bl: 1.2.3
|
||||
buffer-alloc: 1.2.0
|
||||
end-of-stream: 1.4.4
|
||||
fs-constants: 1.0.0
|
||||
readable-stream: 2.3.8
|
||||
to-buffer: 1.1.1
|
||||
xtend: 4.0.2
|
||||
|
||||
tar-stream@2.2.0:
|
||||
dependencies:
|
||||
bl: 4.1.0
|
||||
|
|
@ -20381,6 +20577,8 @@ snapshots:
|
|||
dependencies:
|
||||
real-require: 0.2.0
|
||||
|
||||
through@2.3.8: {}
|
||||
|
||||
tiny-inflate@1.0.3: {}
|
||||
|
||||
tiny-typed-emitter@2.1.0: {}
|
||||
|
|
@ -20417,6 +20615,8 @@ snapshots:
|
|||
unorm: 1.6.0
|
||||
optional: true
|
||||
|
||||
to-buffer@1.1.1: {}
|
||||
|
||||
to-data-view@1.1.0:
|
||||
optional: true
|
||||
|
||||
|
|
@ -20572,6 +20772,11 @@ snapshots:
|
|||
|
||||
uhyphen@0.2.0: {}
|
||||
|
||||
unbzip2-stream@1.4.3:
|
||||
dependencies:
|
||||
buffer: 5.7.1
|
||||
through: 2.3.8
|
||||
|
||||
unconfig@0.5.5:
|
||||
dependencies:
|
||||
'@antfu/utils': 0.7.10
|
||||
|
|
|
|||
Loading…
Reference in New Issue