mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-07-14 18:15:56 -04:00
feat(i18n): add RTL layout support for Arabic and other RTL locales
- Export `isLocaleRTL` from `@sofa/i18n` to detect right-to-left locales - Native: call `I18nManager.allowRTL` / `forceRTL` on locale init and on locale change; reload the app immediately if the current layout direction doesn't match the persisted locale, and prompt the user to restart when switching between LTR and RTL locales - Native: flip the `SettingsRow` chevron to `IconChevronLeft` when `I18nManager.isRTL` is true - Native: add Arabic Intl polyfill locale data (PluralRules, NumberFormat, DateTimeFormat, RelativeTimeFormat) - Web: enable `"rtl": true` in `components.json` and regenerate all shadcn UI components to use CSS logical properties (`ms-*`, `me-*`, `ps-*`, `pe-*`, `text-start`, `text-end`) instead of physical `ml-*`/`mr-*`/`text-left` equivalents - Web: apply the same logical-property conversions to non-generated components (nav-bar, settings sections, title cards, hero banner, continue-watching card) - Web: set `document.dir` based on the active locale's RTL flag in the i18n initialiser and root route - Add `../../packages/i18n/src/po.d.ts` to native `tsconfig.json` includes so TypeScript accepts `.po` imports
This commit is contained in:
+16
-1
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": ["oxc", "eslint", "typescript", "react", "import", "unicorn"],
|
||||
"jsPlugins": ["eslint-plugin-lingui"],
|
||||
"env": {
|
||||
"builtin": true
|
||||
},
|
||||
@@ -20,7 +21,21 @@
|
||||
"no-await-in-loop": "off",
|
||||
"react/no-array-index-key": "off",
|
||||
"react/jsx-no-useless-fragment": "error",
|
||||
"react/rules-of-hooks": "error"
|
||||
"react/rules-of-hooks": "error",
|
||||
"lingui/no-unlocalized-strings": "off",
|
||||
"lingui/t-call-in-function": "error",
|
||||
"lingui/no-single-variables-to-translate": "error",
|
||||
"lingui/no-expression-in-message": "error",
|
||||
"lingui/no-single-tag-to-translate": "error",
|
||||
"lingui/no-trans-inside-trans": "error"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["apps/web/src/**/*", "apps/native/src/**/*"],
|
||||
"rules": {
|
||||
"lingui/no-unlocalized-strings": "warn"
|
||||
}
|
||||
}
|
||||
],
|
||||
"ignorePatterns": ["node_modules", "dist", "build", "docs", "**/routeTree.gen.ts"]
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"expo-system-ui": "55.0.10",
|
||||
"expo-tracking-transparency": "55.0.9",
|
||||
"expo-web-browser": "55.0.10",
|
||||
"posthog-react-native": "4.37.4",
|
||||
"posthog-react-native": "4.37.5",
|
||||
"react": "19.2.0",
|
||||
"react-dom": "19.2.0",
|
||||
"react-native": "0.83.2",
|
||||
|
||||
@@ -84,34 +84,38 @@ export default function LoginScreen() {
|
||||
|
||||
return (
|
||||
<AuthScreen title="Sofa" subtitle={t`Sign in to continue`}>
|
||||
{showOidc && (
|
||||
<Animated.View entering={FadeInDown.duration(300).delay(100)} className="mb-4">
|
||||
<Button
|
||||
onPress={() => {
|
||||
authClient.signIn.oauth2({
|
||||
providerId: "oidc",
|
||||
callbackURL: "/(tabs)/(home)",
|
||||
});
|
||||
}}
|
||||
variant="secondary"
|
||||
className="w-full"
|
||||
>
|
||||
<ButtonLabel>
|
||||
<Trans>Sign in with {authConfig.data?.oidcProviderName ?? "SSO"}</Trans>
|
||||
</ButtonLabel>
|
||||
</Button>
|
||||
{showOidc &&
|
||||
(() => {
|
||||
const providerName = authConfig.data?.oidcProviderName ?? "SSO";
|
||||
return (
|
||||
<Animated.View entering={FadeInDown.duration(300).delay(100)} className="mb-4">
|
||||
<Button
|
||||
onPress={() => {
|
||||
authClient.signIn.oauth2({
|
||||
providerId: "oidc",
|
||||
callbackURL: "/(tabs)/(home)",
|
||||
});
|
||||
}}
|
||||
variant="secondary"
|
||||
className="w-full"
|
||||
>
|
||||
<ButtonLabel>
|
||||
<Trans>Sign in with {providerName}</Trans>
|
||||
</ButtonLabel>
|
||||
</Button>
|
||||
|
||||
{showPasswordLogin && (
|
||||
<View className="my-4 flex-row items-center">
|
||||
<View className="bg-border h-px flex-1" />
|
||||
<Text className="text-muted-foreground px-3 text-xs">
|
||||
<Trans>OR</Trans>
|
||||
</Text>
|
||||
<View className="bg-border h-px flex-1" />
|
||||
</View>
|
||||
)}
|
||||
</Animated.View>
|
||||
)}
|
||||
{showPasswordLogin && (
|
||||
<View className="my-4 flex-row items-center">
|
||||
<View className="bg-border h-px flex-1" />
|
||||
<Text className="text-muted-foreground px-3 text-xs">
|
||||
<Trans>OR</Trans>
|
||||
</Text>
|
||||
<View className="bg-border h-px flex-1" />
|
||||
</View>
|
||||
)}
|
||||
</Animated.View>
|
||||
);
|
||||
})()}
|
||||
|
||||
{showPasswordLogin && (
|
||||
<View className="gap-3">
|
||||
|
||||
@@ -111,7 +111,10 @@ export default function DashboardScreen() {
|
||||
<View className="gap-3">
|
||||
<View className="flex-row gap-3">
|
||||
<StatsCard
|
||||
label={t`Movies ${periodLabels[moviePeriod]}`}
|
||||
label={(() => {
|
||||
const period = periodLabels[moviePeriod];
|
||||
return t`Movies ${period}`;
|
||||
})()}
|
||||
value={movieCount}
|
||||
icon={IconMovie}
|
||||
color="text-primary"
|
||||
@@ -122,7 +125,10 @@ export default function DashboardScreen() {
|
||||
onPeriodChange={setMoviePeriod}
|
||||
/>
|
||||
<StatsCard
|
||||
label={t`Episodes ${periodLabels[episodePeriod]}`}
|
||||
label={(() => {
|
||||
const period = periodLabels[episodePeriod];
|
||||
return t`Episodes ${period}`;
|
||||
})()}
|
||||
value={episodeCount}
|
||||
icon={IconDeviceTvOld}
|
||||
color="text-status-watching"
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
IconWorld,
|
||||
} from "@tabler/icons-react-native";
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import { reloadAppAsync } from "expo";
|
||||
import * as Application from "expo-application";
|
||||
import * as ImagePicker from "expo-image-picker";
|
||||
import { useRouter } from "expo-router";
|
||||
@@ -54,7 +55,7 @@ import { isAnalyticsEnabled, setAnalyticsEnabled } from "@/lib/posthog";
|
||||
import { queryClient } from "@/lib/query-client";
|
||||
import { authClient, getServerUrl } from "@/lib/server";
|
||||
import { toast } from "@/lib/toast";
|
||||
import { activateLocale, type SupportedLocale } from "@sofa/i18n";
|
||||
import { activateLocale, isLocaleRTL, type SupportedLocale } from "@sofa/i18n";
|
||||
import { LOCALE_INFO } from "@sofa/i18n/locales";
|
||||
|
||||
const settingsContentContainerStyle = {
|
||||
@@ -421,7 +422,10 @@ export default function SettingsScreen() {
|
||||
label={t`Database`}
|
||||
value={
|
||||
systemHealth.data?.database
|
||||
? t`${plural(systemHealth.data.database.titleCount, { one: "# title", other: "# titles" })}`
|
||||
? plural(systemHealth.data.database.titleCount, {
|
||||
one: "# title",
|
||||
other: "# titles",
|
||||
})
|
||||
: "—"
|
||||
}
|
||||
icon={IconDatabase}
|
||||
@@ -435,7 +439,10 @@ export default function SettingsScreen() {
|
||||
label={t`Image Cache`}
|
||||
value={
|
||||
systemHealth.data?.imageCache
|
||||
? t`${plural(systemHealth.data.imageCache.imageCount, { one: "# image", other: "# images" })}`
|
||||
? plural(systemHealth.data.imageCache.imageCount, {
|
||||
one: "# image",
|
||||
other: "# images",
|
||||
})
|
||||
: "—"
|
||||
}
|
||||
icon={IconPhoto}
|
||||
@@ -472,13 +479,16 @@ export default function SettingsScreen() {
|
||||
/>
|
||||
}
|
||||
/>
|
||||
{updateCheck.data?.updateCheck?.updateAvailable && (
|
||||
<View className="py-3.5">
|
||||
<Text className="text-status-completed font-sans text-sm font-medium">
|
||||
<Trans>Update available: {updateCheck.data.updateCheck.latestVersion}</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
{(() => {
|
||||
const latestVersion = updateCheck.data?.updateCheck?.latestVersion;
|
||||
return updateCheck.data?.updateCheck?.updateAvailable ? (
|
||||
<View className="py-3.5">
|
||||
<Text className="text-status-completed font-sans text-sm font-medium">
|
||||
<Trans>Update available: {latestVersion}</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
) : null;
|
||||
})()}
|
||||
</SettingsSection>
|
||||
</Animated.View>
|
||||
)}
|
||||
@@ -512,8 +522,18 @@ export default function SettingsScreen() {
|
||||
}))}
|
||||
onSelect={(locale) => {
|
||||
setLanguageModalOpen(false);
|
||||
const previousLocale = i18n.locale;
|
||||
activateLocale(locale as SupportedLocale).then(
|
||||
() => setPersistedLocale(locale as SupportedLocale),
|
||||
() => {
|
||||
setPersistedLocale(locale as SupportedLocale);
|
||||
if (isLocaleRTL(locale) !== isLocaleRTL(previousLocale)) {
|
||||
Alert.alert(
|
||||
t`Restart Required`,
|
||||
t`Sofa needs to restart to apply the new layout direction.`,
|
||||
[{ text: t`Restart`, onPress: () => reloadAppAsync() }],
|
||||
);
|
||||
}
|
||||
},
|
||||
() => {},
|
||||
);
|
||||
}}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Icon } from "@tabler/icons-react-native";
|
||||
import { IconChevronRight } from "@tabler/icons-react-native";
|
||||
import { IconChevronLeft, IconChevronRight } from "@tabler/icons-react-native";
|
||||
import type { ReactNode } from "react";
|
||||
import { Pressable, View } from "react-native";
|
||||
import { I18nManager, Pressable, View } from "react-native";
|
||||
import { useCSSVariable } from "uniwind";
|
||||
|
||||
import { ScaledIcon } from "@/components/ui/scaled-icon";
|
||||
@@ -53,7 +53,12 @@ export function SettingsRow({
|
||||
</Text>
|
||||
) : null}
|
||||
{!right && onPress && (
|
||||
<ScaledIcon icon={IconChevronRight} size={16} color={mutedFgColor} accessible={false} />
|
||||
<ScaledIcon
|
||||
icon={I18nManager.isRTL ? IconChevronLeft : IconChevronRight}
|
||||
size={16}
|
||||
color={mutedFgColor}
|
||||
accessible={false}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -99,6 +99,9 @@ export function SeasonAccordion({
|
||||
[watchedEpisodeIds, unwatchEpisode, watchEpisode],
|
||||
);
|
||||
|
||||
const seasonNumber = season.seasonNumber;
|
||||
const episodeCount = episodes.length;
|
||||
|
||||
return (
|
||||
<View
|
||||
className="bg-card mb-2 overflow-hidden rounded-xl border"
|
||||
@@ -110,16 +113,16 @@ export function SeasonAccordion({
|
||||
<Pressable
|
||||
onPress={toggleExpanded}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={`${season.name ?? t`Season ${season.seasonNumber}`}, ${t`${watchedCount} of ${episodes.length} episodes watched`}`}
|
||||
accessibilityLabel={`${season.name ?? t`Season ${seasonNumber}`}, ${t`${watchedCount} of ${episodeCount} episodes watched`}`}
|
||||
accessibilityState={{ expanded }}
|
||||
className="flex-row items-center justify-between p-4"
|
||||
>
|
||||
<View className="flex-1">
|
||||
<Text className="text-foreground font-sans text-base font-medium">
|
||||
{season.name ?? t`Season ${season.seasonNumber}`}
|
||||
{season.name ?? t`Season ${seasonNumber}`}
|
||||
</Text>
|
||||
<Text className="text-muted-foreground mt-0.5 text-xs">
|
||||
{t`${watchedCount}/${episodes.length} ${plural(episodes.length, { one: "episode", other: "episodes" })}`}
|
||||
{t`${watchedCount}/${plural(episodeCount, { one: "# episode", other: "# episodes" })}`}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
|
||||
@@ -81,9 +81,10 @@ export function useTitleActions(options?: UseTitleActionsOptions) {
|
||||
const updateRating = useMutation(
|
||||
orpc.titles.updateRating.mutationOptions({
|
||||
onSuccess: (_data, input) => {
|
||||
const stars = input.stars;
|
||||
const defaultMsg =
|
||||
input.stars > 0
|
||||
? t`Rated ${input.stars} ${plural(input.stars, { one: "star", other: "stars" })}`
|
||||
stars > 0
|
||||
? t`Rated ${plural(stars, { one: "# star", other: "# stars" })}`
|
||||
: t`Rating removed`;
|
||||
toast.success(resolveToast(toastOverrides?.updateRating, defaultMsg, input));
|
||||
// Rating only invalidates title queries, not dashboard
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { reloadAppAsync } from "expo";
|
||||
import * as Localization from "expo-localization";
|
||||
import { I18nManager } from "react-native";
|
||||
|
||||
import { activateLocale, SUPPORTED_LOCALES, type SupportedLocale } from "@sofa/i18n";
|
||||
import { activateLocale, isLocaleRTL, SUPPORTED_LOCALES, type SupportedLocale } from "@sofa/i18n";
|
||||
|
||||
import { globalStorage } from "./mmkv";
|
||||
|
||||
@@ -23,10 +25,21 @@ export function getPersistedLocale(): SupportedLocale {
|
||||
|
||||
export function setPersistedLocale(locale: SupportedLocale): void {
|
||||
globalStorage.set(LOCALE_STORAGE_KEY, locale);
|
||||
const rtl = isLocaleRTL(locale);
|
||||
I18nManager.allowRTL(rtl);
|
||||
I18nManager.forceRTL(rtl);
|
||||
}
|
||||
|
||||
export function initLocale(): Promise<void> {
|
||||
const locale = getPersistedLocale();
|
||||
const rtl = isLocaleRTL(locale);
|
||||
I18nManager.allowRTL(rtl);
|
||||
I18nManager.forceRTL(rtl);
|
||||
// forceRTL only takes effect on the next launch — if the current layout
|
||||
// doesn't match (e.g. fresh install on an RTL device), reload immediately.
|
||||
if (I18nManager.isRTL !== rtl) {
|
||||
reloadAppAsync();
|
||||
}
|
||||
if (locale !== "en") {
|
||||
return activateLocale(locale);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,12 @@ import "@formatjs/intl-pluralrules/locale-data/de.js";
|
||||
import "@formatjs/intl-pluralrules/locale-data/es.js";
|
||||
import "@formatjs/intl-pluralrules/locale-data/it.js";
|
||||
import "@formatjs/intl-pluralrules/locale-data/pt.js";
|
||||
import "@formatjs/intl-pluralrules/locale-data/ar.js";
|
||||
import "@formatjs/intl-pluralrules/locale-data/nl.js";
|
||||
import "@formatjs/intl-pluralrules/locale-data/he.js";
|
||||
import "@formatjs/intl-pluralrules/locale-data/zh.js";
|
||||
import "@formatjs/intl-pluralrules/locale-data/ja.js";
|
||||
import "@formatjs/intl-pluralrules/locale-data/ko.js";
|
||||
// 4. NumberFormat (depends on PluralRules, Locale)
|
||||
import "@formatjs/intl-numberformat/polyfill.js";
|
||||
import "@formatjs/intl-numberformat/locale-data/en.js";
|
||||
@@ -28,6 +34,12 @@ import "@formatjs/intl-numberformat/locale-data/de.js";
|
||||
import "@formatjs/intl-numberformat/locale-data/es.js";
|
||||
import "@formatjs/intl-numberformat/locale-data/it.js";
|
||||
import "@formatjs/intl-numberformat/locale-data/pt.js";
|
||||
import "@formatjs/intl-numberformat/locale-data/ar.js";
|
||||
import "@formatjs/intl-numberformat/locale-data/nl.js";
|
||||
import "@formatjs/intl-numberformat/locale-data/he.js";
|
||||
import "@formatjs/intl-numberformat/locale-data/zh.js";
|
||||
import "@formatjs/intl-numberformat/locale-data/ja.js";
|
||||
import "@formatjs/intl-numberformat/locale-data/ko.js";
|
||||
// 5. DateTimeFormat (depends on Locale)
|
||||
import "@formatjs/intl-datetimeformat/polyfill.js";
|
||||
import "@formatjs/intl-datetimeformat/locale-data/en.js";
|
||||
@@ -36,6 +48,12 @@ import "@formatjs/intl-datetimeformat/locale-data/de.js";
|
||||
import "@formatjs/intl-datetimeformat/locale-data/es.js";
|
||||
import "@formatjs/intl-datetimeformat/locale-data/it.js";
|
||||
import "@formatjs/intl-datetimeformat/locale-data/pt.js";
|
||||
import "@formatjs/intl-datetimeformat/locale-data/ar.js";
|
||||
import "@formatjs/intl-datetimeformat/locale-data/nl.js";
|
||||
import "@formatjs/intl-datetimeformat/locale-data/he.js";
|
||||
import "@formatjs/intl-datetimeformat/locale-data/zh.js";
|
||||
import "@formatjs/intl-datetimeformat/locale-data/ja.js";
|
||||
import "@formatjs/intl-datetimeformat/locale-data/ko.js";
|
||||
// 6. RelativeTimeFormat (depends on PluralRules, Locale)
|
||||
import "@formatjs/intl-relativetimeformat/polyfill.js";
|
||||
import "@formatjs/intl-relativetimeformat/locale-data/en.js";
|
||||
@@ -44,3 +62,9 @@ import "@formatjs/intl-relativetimeformat/locale-data/de.js";
|
||||
import "@formatjs/intl-relativetimeformat/locale-data/es.js";
|
||||
import "@formatjs/intl-relativetimeformat/locale-data/it.js";
|
||||
import "@formatjs/intl-relativetimeformat/locale-data/pt.js";
|
||||
import "@formatjs/intl-relativetimeformat/locale-data/ar.js";
|
||||
import "@formatjs/intl-relativetimeformat/locale-data/nl.js";
|
||||
import "@formatjs/intl-relativetimeformat/locale-data/he.js";
|
||||
import "@formatjs/intl-relativetimeformat/locale-data/zh.js";
|
||||
import "@formatjs/intl-relativetimeformat/locale-data/ja.js";
|
||||
import "@formatjs/intl-relativetimeformat/locale-data/ko.js";
|
||||
|
||||
@@ -7,5 +7,12 @@
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts", "uniwind-types.d.ts"]
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".expo/types/**/*.ts",
|
||||
"expo-env.d.ts",
|
||||
"uniwind-types.d.ts",
|
||||
"../../packages/i18n/src/po.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"prefix": ""
|
||||
},
|
||||
"iconLibrary": "tabler",
|
||||
"rtl": false,
|
||||
"rtl": true,
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils",
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"@tabler/icons-react": "3.40.0",
|
||||
"@tanstack/react-hotkeys": "0.4.2",
|
||||
"@tanstack/react-query": "catalog:",
|
||||
"@tanstack/react-router": "1.167.5",
|
||||
"@tanstack/react-router": "1.168.1",
|
||||
"better-auth": "catalog:",
|
||||
"class-variance-authority": "0.7.1",
|
||||
"clsx": "2.1.1",
|
||||
@@ -37,7 +37,7 @@
|
||||
"motion": "12.38.0",
|
||||
"react": "catalog:",
|
||||
"react-dom": "catalog:",
|
||||
"shadcn": "4.0.8",
|
||||
"shadcn": "4.1.0",
|
||||
"sonner": "2.0.7",
|
||||
"tailwind-merge": "catalog:",
|
||||
"thumbhash": "catalog:",
|
||||
@@ -51,8 +51,8 @@
|
||||
"@tanstack/devtools-vite": "0.6.0",
|
||||
"@tanstack/react-devtools": "0.10.0",
|
||||
"@tanstack/react-query-devtools": "5.91.3",
|
||||
"@tanstack/react-router-devtools": "1.166.9",
|
||||
"@tanstack/router-plugin": "1.166.14",
|
||||
"@tanstack/react-router-devtools": "1.166.10",
|
||||
"@tanstack/router-plugin": "1.167.1",
|
||||
"@types/bun": "catalog:",
|
||||
"@types/node": "catalog:",
|
||||
"@types/react": "catalog:",
|
||||
|
||||
@@ -48,6 +48,7 @@ export function AuthForm({
|
||||
const isRegister = mode === "register";
|
||||
const showOidc = authConfig?.oidcEnabled ?? false;
|
||||
const showPasswordForm = !(authConfig?.passwordLoginDisabled ?? false);
|
||||
const oidcProviderName = authConfig?.oidcProviderName || "SSO";
|
||||
|
||||
async function handleSubmit(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
@@ -139,7 +140,7 @@ export function AuthForm({
|
||||
{oidcLoading ? (
|
||||
<Trans>Redirecting…</Trans>
|
||||
) : (
|
||||
<Trans>Sign in with {authConfig?.oidcProviderName || "SSO"}</Trans>
|
||||
<Trans>Sign in with {oidcProviderName}</Trans>
|
||||
)}
|
||||
</Button>
|
||||
</motion.div>
|
||||
|
||||
@@ -27,6 +27,8 @@ export function ContinueWatchingCard({ item }: { item: ContinueWatchingItemProps
|
||||
const { t } = useLingui();
|
||||
const stillUrl = item.nextEpisode?.stillPath ?? item.title.backdropPath ?? null;
|
||||
const progress = item.totalEpisodes > 0 ? (item.watchedEpisodes / item.totalEpisodes) * 100 : 0;
|
||||
const watchedEpisodes = item.watchedEpisodes;
|
||||
const totalEpisodes = item.totalEpisodes;
|
||||
|
||||
return (
|
||||
<Link
|
||||
@@ -63,7 +65,7 @@ export function ContinueWatchingCard({ item }: { item: ContinueWatchingItemProps
|
||||
{t`Up next`}
|
||||
</p>
|
||||
<p className="mt-0.5 truncate text-sm font-medium text-white">
|
||||
<span className="mr-0.5 font-mono text-xs text-white/60 [word-spacing:-0.25em]">
|
||||
<span className="me-0.5 font-mono text-xs text-white/60 [word-spacing:-0.25em]">
|
||||
S{item.nextEpisode.seasonNumber} E{item.nextEpisode.episodeNumber}
|
||||
</span>{" "}
|
||||
{item.nextEpisode.name}
|
||||
@@ -75,7 +77,7 @@ export function ContinueWatchingCard({ item }: { item: ContinueWatchingItemProps
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="truncate text-sm font-medium">{item.title.title}</p>
|
||||
<p className="text-muted-foreground text-xs">
|
||||
{t`${item.watchedEpisodes}/${item.totalEpisodes} ${plural(item.totalEpisodes, { one: "episode", other: "episodes" })}`}
|
||||
{t`${watchedEpisodes}/${plural(totalEpisodes, { one: "# episode", other: "# episodes" })}`}
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-primary/10 text-primary group-hover:bg-primary group-hover:text-primary-foreground flex h-8 w-8 shrink-0 items-center justify-center rounded-full transition-colors">
|
||||
|
||||
@@ -70,7 +70,7 @@ export function HeroBanner({
|
||||
<Trans>Trending today</Trans>
|
||||
</span>
|
||||
</div>
|
||||
<Link to="/titles/$id" params={{ id }} className="group/title text-left">
|
||||
<Link to="/titles/$id" params={{ id }} className="group/title text-start">
|
||||
<h2 className="font-display group-hover/title:text-primary text-3xl tracking-tight text-balance transition-colors sm:text-4xl">
|
||||
{title}
|
||||
</h2>
|
||||
|
||||
@@ -188,7 +188,7 @@ export function NavBar({
|
||||
>
|
||||
<IconSearch aria-hidden={true} className="size-3.5" />
|
||||
<span>{t`Search…`}</span>
|
||||
<Kbd className="ml-2.5">⌘ K</Kbd>
|
||||
<Kbd className="ms-2.5">⌘ K</Kbd>
|
||||
</button>
|
||||
<Separator
|
||||
orientation="vertical"
|
||||
@@ -219,7 +219,7 @@ export function NavBar({
|
||||
<p className="text-foreground truncate text-sm leading-tight font-medium">
|
||||
{userName}
|
||||
{userRole === "admin" && (
|
||||
<Badge className="bg-primary/10 text-primary mb-0.5 ml-1.5 rounded-md border-0 align-middle">
|
||||
<Badge className="bg-primary/10 text-primary ms-1.5 mb-0.5 rounded-md border-0 align-middle">
|
||||
<Trans>Admin</Trans>
|
||||
</Badge>
|
||||
)}
|
||||
@@ -291,7 +291,7 @@ export function MobileTabBar() {
|
||||
return (
|
||||
<nav
|
||||
aria-label="Primary"
|
||||
className="border-border/50 bg-background/90 fixed right-0 bottom-0 left-0 z-50 border-t pr-[env(safe-area-inset-right)] pl-[env(safe-area-inset-left)] backdrop-blur-xl sm:hidden"
|
||||
className="border-border/50 bg-background/90 fixed right-0 bottom-0 left-0 z-50 border-t ps-[env(safe-area-inset-left)] pe-[env(safe-area-inset-right)] backdrop-blur-xl sm:hidden"
|
||||
>
|
||||
<div ref={containerRef} className="relative flex h-14 items-stretch">
|
||||
{mobileTabs.map((tab, i) => {
|
||||
|
||||
@@ -294,7 +294,7 @@ export function AccountSection({
|
||||
transition={{ duration: 0.1 }}
|
||||
type="button"
|
||||
onClick={() => setIsEditingName(true)}
|
||||
className="group/name hover:text-primary inline-flex items-center gap-1.5 rounded-md px-0 text-left transition-colors"
|
||||
className="group/name hover:text-primary inline-flex items-center gap-1.5 rounded-md px-0 text-start transition-colors"
|
||||
>
|
||||
{displayName}
|
||||
<IconPencil className="group-hover/name:text-muted-foreground size-3 text-transparent transition-colors" />
|
||||
@@ -305,7 +305,7 @@ export function AccountSection({
|
||||
<CardDescription>
|
||||
{user.email}
|
||||
{user.role === "admin" && (
|
||||
<Badge className="bg-primary/10 text-primary ml-1.5 rounded-md border-0 align-middle">
|
||||
<Badge className="bg-primary/10 text-primary ms-1.5 rounded-md border-0 align-middle">
|
||||
<Trans>Admin</Trans>
|
||||
</Badge>
|
||||
)}
|
||||
|
||||
@@ -218,31 +218,28 @@ export function BackupScheduleSection() {
|
||||
<CardDescription>
|
||||
{enabled ? (
|
||||
<span className="inline-flex flex-wrap items-baseline" suppressHydrationWarning>
|
||||
{formatNextBackup(frequency, time, dow)}.{" "}
|
||||
<Trans>
|
||||
Keeping{" "}
|
||||
<Select
|
||||
value={String(maxRetention)}
|
||||
onValueChange={(v) => v && changeMaxRetention(Number(v))}
|
||||
modal={false}
|
||||
>
|
||||
<SelectTrigger className="decoration-muted-foreground/50 hover:text-foreground hover:decoration-foreground/50 focus-visible:decoration-foreground mr-0.5 ml-1.5 !h-auto w-auto gap-0.5 rounded-none border-0 bg-transparent p-0 underline decoration-dotted underline-offset-4 shadow-none hover:bg-transparent focus-visible:decoration-solid focus-visible:ring-0 dark:bg-transparent dark:hover:bg-transparent">
|
||||
<SelectValue>
|
||||
{(value: string | null) =>
|
||||
value === "0" ? t`unlimited` : value ? t`last ${value}` : null
|
||||
}
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent align="start" alignItemWithTrigger={false} className="p-1">
|
||||
{[3, 5, 7, 14, 30, 0].map((n) => (
|
||||
<SelectItem key={n} value={String(n)}>
|
||||
{n === 0 ? t`unlimited` : t`last ${n}`}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>{" "}
|
||||
backups.
|
||||
</Trans>
|
||||
{formatNextBackup(frequency, time, dow)}. <Trans>Keeping</Trans>{" "}
|
||||
<Select
|
||||
value={String(maxRetention)}
|
||||
onValueChange={(v) => v && changeMaxRetention(Number(v))}
|
||||
modal={false}
|
||||
>
|
||||
<SelectTrigger className="decoration-muted-foreground/50 hover:text-foreground hover:decoration-foreground/50 focus-visible:decoration-foreground ms-1.5 me-0.5 !h-auto w-auto gap-0.5 rounded-none border-0 bg-transparent p-0 underline decoration-dotted underline-offset-4 shadow-none hover:bg-transparent focus-visible:decoration-solid focus-visible:ring-0 dark:bg-transparent dark:hover:bg-transparent">
|
||||
<SelectValue>
|
||||
{(value: string | null) =>
|
||||
value === "0" ? t`unlimited` : value ? t`last ${value}` : null
|
||||
}
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent align="start" alignItemWithTrigger={false} className="p-1">
|
||||
{[3, 5, 7, 14, 30, 0].map((n) => (
|
||||
<SelectItem key={n} value={String(n)}>
|
||||
{n === 0 ? t`unlimited` : t`last ${n}`}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>{" "}
|
||||
<Trans>backups.</Trans>
|
||||
</span>
|
||||
) : (
|
||||
<Trans>Automatically back up your database on a schedule</Trans>
|
||||
|
||||
@@ -93,9 +93,10 @@ export function BackupSection() {
|
||||
const creating = createMutation.isPending;
|
||||
const deleting = deleteMutation.isPending ? (deleteMutation.variables?.filename ?? null) : null;
|
||||
|
||||
const backupCount = displayBackups.length;
|
||||
const backupCountLabel =
|
||||
displayBackups.length > 0
|
||||
? t`${displayBackups.length} ${plural(displayBackups.length, { one: "backup", other: "backups" })} stored`
|
||||
backupCount > 0
|
||||
? t`${plural(backupCount, { one: "# backup", other: "# backups" })} stored`
|
||||
: t`No backups yet`;
|
||||
|
||||
return (
|
||||
@@ -126,136 +127,136 @@ export function BackupSection() {
|
||||
{displayBackups.length > 0 && (
|
||||
<CardContent className="border-border/30 border-t pt-4">
|
||||
<div className="space-y-1.5">
|
||||
{displayBackups.map((backup: BackupInfo) => (
|
||||
<motion.div
|
||||
key={backup.filename}
|
||||
initial={{ opacity: 0, height: 0 }}
|
||||
animate={{ opacity: 1, height: "auto" }}
|
||||
exit={{ opacity: 0, height: 0 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
className="overflow-hidden"
|
||||
>
|
||||
<div className="group hover:bg-muted/40 flex items-center gap-3 rounded-md px-2.5 py-1.5 transition-colors">
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={
|
||||
<span className="text-muted-foreground flex shrink-0 items-center" />
|
||||
}
|
||||
>
|
||||
{backup.source === "scheduled" ? (
|
||||
<IconClock aria-hidden={true} className="size-3.5" />
|
||||
) : backup.source === "pre-restore" ? (
|
||||
<IconShieldCheck aria-hidden={true} className="size-3.5" />
|
||||
) : (
|
||||
<IconPointer aria-hidden={true} className="size-3.5" />
|
||||
)}
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
{backup.source === "scheduled"
|
||||
? t`Scheduled backup`
|
||||
: backup.source === "pre-restore"
|
||||
? t`Pre-restore backup`
|
||||
: t`Manual backup`}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="flex items-baseline gap-2">
|
||||
<span className="text-foreground text-xs font-medium">
|
||||
{formatBackupDate(backup.createdAt)}
|
||||
</span>
|
||||
<span className="text-muted-foreground text-[11px]">
|
||||
{formatBytesI18n(backup.sizeBytes)}
|
||||
</span>
|
||||
<span
|
||||
className="text-muted-foreground/50 text-[11px]"
|
||||
suppressHydrationWarning
|
||||
>
|
||||
{formatRelativeTime(backup.createdAt)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex shrink-0 items-center gap-0.5 opacity-0 transition-opacity group-focus-within:opacity-100 group-hover:opacity-100">
|
||||
{displayBackups.map((backup: BackupInfo) => {
|
||||
const backupDate = formatBackupDate(backup.createdAt);
|
||||
return (
|
||||
<motion.div
|
||||
key={backup.filename}
|
||||
initial={{ opacity: 0, height: 0 }}
|
||||
animate={{ opacity: 1, height: "auto" }}
|
||||
exit={{ opacity: 0, height: 0 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
className="overflow-hidden"
|
||||
>
|
||||
<div className="group hover:bg-muted/40 flex items-center gap-3 rounded-md px-2.5 py-1.5 transition-colors">
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
className="text-muted-foreground hover:text-foreground"
|
||||
nativeButton={false}
|
||||
render={
|
||||
<a
|
||||
href={`/api/backup/${backup.filename}`}
|
||||
download
|
||||
aria-label={t`Download backup`}
|
||||
>
|
||||
<IconCloudDownload />
|
||||
</a>
|
||||
}
|
||||
/>
|
||||
<span className="text-muted-foreground flex shrink-0 items-center" />
|
||||
}
|
||||
/>
|
||||
>
|
||||
{backup.source === "scheduled" ? (
|
||||
<IconClock aria-hidden={true} className="size-3.5" />
|
||||
) : backup.source === "pre-restore" ? (
|
||||
<IconShieldCheck aria-hidden={true} className="size-3.5" />
|
||||
) : (
|
||||
<IconPointer aria-hidden={true} className="size-3.5" />
|
||||
)}
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<Trans>Download</Trans>
|
||||
{backup.source === "scheduled"
|
||||
? t`Scheduled backup`
|
||||
: backup.source === "pre-restore"
|
||||
? t`Pre-restore backup`
|
||||
: t`Manual backup`}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<AlertDialog>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="flex items-baseline gap-2">
|
||||
<span className="text-foreground text-xs font-medium">{backupDate}</span>
|
||||
<span className="text-muted-foreground text-[11px]">
|
||||
{formatBytesI18n(backup.sizeBytes)}
|
||||
</span>
|
||||
<span
|
||||
className="text-muted-foreground/50 text-[11px]"
|
||||
suppressHydrationWarning
|
||||
>
|
||||
{formatRelativeTime(backup.createdAt)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex shrink-0 items-center gap-0.5 opacity-0 transition-opacity group-focus-within:opacity-100 group-hover:opacity-100">
|
||||
<Tooltip>
|
||||
<AlertDialogTrigger
|
||||
<TooltipTrigger
|
||||
render={
|
||||
<TooltipTrigger
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
className="text-muted-foreground hover:text-foreground"
|
||||
nativeButton={false}
|
||||
render={
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
aria-label={t`Delete backup`}
|
||||
className="text-muted-foreground hover:text-destructive"
|
||||
disabled={deleting === backup.filename}
|
||||
/>
|
||||
<a
|
||||
href={`/api/backup/${backup.filename}`}
|
||||
download
|
||||
aria-label={t`Download backup`}
|
||||
>
|
||||
<IconCloudDownload />
|
||||
</a>
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{deleting === backup.filename ? <Spinner /> : <IconTrash />}
|
||||
</AlertDialogTrigger>
|
||||
/>
|
||||
<TooltipContent>
|
||||
<Trans>Delete</Trans>
|
||||
<Trans>Download</Trans>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>
|
||||
<Trans>Delete backup?</Trans>
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
<Trans>
|
||||
This will permanently delete the backup from{" "}
|
||||
<strong>{formatBackupDate(backup.createdAt)}</strong>. This cannot
|
||||
be undone.
|
||||
</Trans>
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>
|
||||
<Trans>Cancel</Trans>
|
||||
</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
variant="destructive"
|
||||
onClick={() =>
|
||||
deleteMutation.mutate({
|
||||
filename: backup.filename,
|
||||
})
|
||||
<AlertDialog>
|
||||
<Tooltip>
|
||||
<AlertDialogTrigger
|
||||
render={
|
||||
<TooltipTrigger
|
||||
render={
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
aria-label={t`Delete backup`}
|
||||
className="text-muted-foreground hover:text-destructive"
|
||||
disabled={deleting === backup.filename}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{deleting === backup.filename ? <Spinner /> : <IconTrash />}
|
||||
</AlertDialogTrigger>
|
||||
<TooltipContent>
|
||||
<Trans>Delete</Trans>
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>
|
||||
<Trans>Delete backup?</Trans>
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
<Trans>
|
||||
This will permanently delete the backup from{" "}
|
||||
<strong>{backupDate}</strong>. This cannot be undone.
|
||||
</Trans>
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>
|
||||
<Trans>Cancel</Trans>
|
||||
</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
variant="destructive"
|
||||
onClick={() =>
|
||||
deleteMutation.mutate({
|
||||
filename: backup.filename,
|
||||
})
|
||||
}
|
||||
>
|
||||
<Trans>Delete</Trans>
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</CardContent>
|
||||
)}
|
||||
|
||||
@@ -277,8 +277,10 @@ function ImportSourceCard({ config }: { config: SourceConfig }) {
|
||||
warnings: event.job.warnings,
|
||||
});
|
||||
setStep("done");
|
||||
if (event.job.importedCount > 0) {
|
||||
toast.success(t`Imported ${event.job.importedCount} items from ${config.label}`);
|
||||
const importedCount = event.job.importedCount;
|
||||
const sourceLabel = config.label;
|
||||
if (importedCount > 0) {
|
||||
toast.success(t`Imported ${importedCount} items from ${sourceLabel}`);
|
||||
}
|
||||
} else if (event.type === "timeout") {
|
||||
receivedComplete = true;
|
||||
@@ -366,8 +368,9 @@ function ImportSourceCard({ config }: { config: SourceConfig }) {
|
||||
});
|
||||
if (!res.ok) {
|
||||
const err = await res.json().catch(() => ({}));
|
||||
const sourceLabel = config.label;
|
||||
throw new Error(
|
||||
(err as { error?: string }).error ?? t`Failed to start ${config.label} connection`,
|
||||
(err as { error?: string }).error ?? t`Failed to start ${sourceLabel} connection`,
|
||||
);
|
||||
}
|
||||
const data = (await res.json()) as DeviceCodeInfo;
|
||||
@@ -546,14 +549,16 @@ function ChooseStep({
|
||||
onCancel: () => void;
|
||||
}) {
|
||||
const { t } = useLingui();
|
||||
const sourceLabel = config.label;
|
||||
const acceptFormat = config.accept;
|
||||
return (
|
||||
<>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
<Trans>Import from {config.label}</Trans>
|
||||
<Trans>Import from {sourceLabel}</Trans>
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
<Trans>Choose how to import your {config.label} data.</Trans>
|
||||
<Trans>Choose how to import your {sourceLabel} data.</Trans>
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
@@ -566,7 +571,7 @@ function ChooseStep({
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="border-border/50 hover:bg-muted/50 flex w-full items-center gap-3 rounded-lg border p-4 text-left transition-colors"
|
||||
className="border-border/50 hover:bg-muted/50 flex w-full items-center gap-3 rounded-lg border p-4 text-start transition-colors"
|
||||
onClick={onConnect}
|
||||
>
|
||||
<div className="bg-primary/10 flex h-10 w-10 shrink-0 items-center justify-center rounded-lg">
|
||||
@@ -574,17 +579,17 @@ function ChooseStep({
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-medium">
|
||||
<Trans>Connect with {config.label}</Trans>
|
||||
<Trans>Connect with {sourceLabel}</Trans>
|
||||
</p>
|
||||
<p className="text-muted-foreground text-xs">
|
||||
<Trans>Authorize Sofa to read your {config.label} library. No password shared.</Trans>
|
||||
<Trans>Authorize Sofa to read your {sourceLabel} library. No password shared.</Trans>
|
||||
</p>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="border-border/50 hover:bg-muted/50 flex w-full items-center gap-3 rounded-lg border p-4 text-left transition-colors"
|
||||
className="border-border/50 hover:bg-muted/50 flex w-full items-center gap-3 rounded-lg border p-4 text-start transition-colors"
|
||||
onClick={() => {
|
||||
onCancel();
|
||||
// Small delay so the dialog closes before file picker opens
|
||||
@@ -600,7 +605,7 @@ function ChooseStep({
|
||||
<Trans>Upload export file</Trans>
|
||||
</p>
|
||||
<p className="text-muted-foreground text-xs">
|
||||
{t`Upload a ${config.accept} export from your ${config.label} account settings.`}
|
||||
{t`Upload a ${acceptFormat} export from your ${sourceLabel} account settings.`}
|
||||
</p>
|
||||
</div>
|
||||
</button>
|
||||
@@ -725,6 +730,12 @@ function PreviewStep({
|
||||
(options.importWatchlist ? stats.watchlist : 0) +
|
||||
(options.importRatings ? stats.ratings : 0);
|
||||
|
||||
const movieCount = stats.movies;
|
||||
const episodeCount = stats.episodes;
|
||||
const watchlistCount = stats.watchlist;
|
||||
const ratingCount = stats.ratings;
|
||||
const unresolvedCount = preview.diagnostics?.unresolved ?? 0;
|
||||
|
||||
return (
|
||||
<>
|
||||
<DialogHeader>
|
||||
@@ -738,18 +749,18 @@ function PreviewStep({
|
||||
|
||||
<div className="space-y-4 py-2">
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<StatBadge label={t`Movies`} count={stats.movies} />
|
||||
<StatBadge label={t`Episodes`} count={stats.episodes} />
|
||||
<StatBadge label={t`Watchlist`} count={stats.watchlist} />
|
||||
<StatBadge label={t`Ratings`} count={stats.ratings} />
|
||||
<StatBadge label={t`Movies`} count={movieCount} />
|
||||
<StatBadge label={t`Episodes`} count={episodeCount} />
|
||||
<StatBadge label={t`Watchlist`} count={watchlistCount} />
|
||||
<StatBadge label={t`Ratings`} count={ratingCount} />
|
||||
</div>
|
||||
|
||||
{preview.diagnostics && preview.diagnostics.unresolved > 0 && (
|
||||
{preview.diagnostics && unresolvedCount > 0 && (
|
||||
<div className="bg-muted/50 rounded-lg p-3">
|
||||
<p className="text-muted-foreground text-xs">
|
||||
<Trans>
|
||||
{preview.diagnostics.unresolved} items have no external IDs and will be resolved by
|
||||
title search, which may be less accurate.
|
||||
{unresolvedCount} items have no external IDs and will be resolved by title search,
|
||||
which may be less accurate.
|
||||
</Trans>
|
||||
</p>
|
||||
</div>
|
||||
@@ -761,19 +772,19 @@ function PreviewStep({
|
||||
</p>
|
||||
<OptionCheckbox
|
||||
label={t`Watch history`}
|
||||
description={t`${stats.movies} movies, ${stats.episodes} episodes`}
|
||||
description={t`${movieCount} movies, ${episodeCount} episodes`}
|
||||
checked={options.importWatches}
|
||||
onChange={(v) => setOptions({ ...options, importWatches: v })}
|
||||
/>
|
||||
<OptionCheckbox
|
||||
label={t`Watchlist`}
|
||||
description={t`${stats.watchlist} items`}
|
||||
description={t`${watchlistCount} items`}
|
||||
checked={options.importWatchlist}
|
||||
onChange={(v) => setOptions({ ...options, importWatchlist: v })}
|
||||
/>
|
||||
<OptionCheckbox
|
||||
label={t`Ratings`}
|
||||
description={t`${stats.ratings} ratings`}
|
||||
description={t`${ratingCount} ratings`}
|
||||
checked={options.importRatings}
|
||||
onChange={(v) => setOptions({ ...options, importRatings: v })}
|
||||
/>
|
||||
@@ -863,6 +874,9 @@ function DoneStep({
|
||||
onClose: () => void;
|
||||
}) {
|
||||
const { t } = useLingui();
|
||||
const errorCount = result.errors.length;
|
||||
const warningCount = result.warnings.length;
|
||||
const remainingErrors = errorCount - 50;
|
||||
return (
|
||||
<>
|
||||
<DialogHeader>
|
||||
@@ -881,28 +895,28 @@ function DoneStep({
|
||||
<StatBadge label={t`Failed`} count={result.failed} />
|
||||
</div>
|
||||
|
||||
{result.errors.length > 0 && (
|
||||
{errorCount > 0 && (
|
||||
<div className="bg-destructive/10 max-h-40 overflow-y-auto rounded-lg p-3">
|
||||
<p className="text-destructive mb-1 text-xs font-medium">
|
||||
<Trans>Errors ({result.errors.length})</Trans>
|
||||
<Trans>Errors ({errorCount})</Trans>
|
||||
</p>
|
||||
<ul className="text-destructive/80 space-y-0.5 text-xs">
|
||||
{result.errors.slice(0, 50).map((e, i) => (
|
||||
<li key={i}>{e}</li>
|
||||
))}
|
||||
{result.errors.length > 50 && (
|
||||
{errorCount > 50 && (
|
||||
<li>
|
||||
<Trans>...and {result.errors.length - 50} more</Trans>
|
||||
<Trans>...and {remainingErrors} more</Trans>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{result.warnings.length > 0 && (
|
||||
{warningCount > 0 && (
|
||||
<div className="max-h-32 overflow-y-auto rounded-lg bg-yellow-500/10 p-3">
|
||||
<p className="mb-1 text-xs font-medium text-yellow-600">
|
||||
<Trans>Warnings ({result.warnings.length})</Trans>
|
||||
<Trans>Warnings ({warningCount})</Trans>
|
||||
</p>
|
||||
<ul className="space-y-0.5 text-xs text-yellow-600/80">
|
||||
{result.warnings.slice(0, 20).map((w, i) => (
|
||||
|
||||
@@ -147,7 +147,7 @@ export function IntegrationCard({
|
||||
<div className="bg-primary/10 flex h-8 w-8 shrink-0 items-center justify-center rounded-lg">
|
||||
<Icon className="text-primary size-4" />
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<div className="text-start">
|
||||
<CardTitle>{config.label}</CardTitle>
|
||||
<CardDescription>
|
||||
{connection ? config.connectedStatus(connection.lastEventAt) : t`Not configured`}
|
||||
@@ -172,7 +172,7 @@ export function IntegrationCard({
|
||||
size="lg"
|
||||
className="w-full"
|
||||
>
|
||||
{connecting ? <Trans>Connecting...</Trans> : <Trans>Connect {config.label}</Trans>}
|
||||
{connecting ? <Trans>Connecting...</Trans> : <Trans>Connect {label}</Trans>}
|
||||
</Button>
|
||||
) : (
|
||||
<AnimatePresence>
|
||||
@@ -251,10 +251,10 @@ export function IntegrationCard({
|
||||
<div className="border-border/50 bg-muted/30 text-muted-foreground mt-2 rounded-lg border p-3 text-xs leading-relaxed">
|
||||
<ol className="list-inside list-decimal space-y-1.5">{config.setupSteps}</ol>
|
||||
{config.docsUrl && (
|
||||
<p className="mt-2 -ml-0.5">
|
||||
<p className="-ms-0.5 mt-2">
|
||||
<IconBook2
|
||||
aria-hidden={true}
|
||||
className="mr-1 inline-block size-3 translate-y-[-1px]"
|
||||
className="me-1 inline-block size-3 translate-y-[-1px]"
|
||||
/>
|
||||
<Trans>Need more help?</Trans>{" "}
|
||||
<a
|
||||
@@ -285,14 +285,18 @@ export function IntegrationCard({
|
||||
|
||||
/** Status line for webhook integrations (shows last event time). */
|
||||
export function webhookStatus(lastEventAt: string | null): string {
|
||||
return lastEventAt
|
||||
? i18n._(msg`Last event ${formatRelativeTime(lastEventAt)}`)
|
||||
: i18n._(msg`Ready — nothing received yet`);
|
||||
if (lastEventAt) {
|
||||
const relativeTime = formatRelativeTime(lastEventAt);
|
||||
return i18n._(msg`Last event ${relativeTime}`);
|
||||
}
|
||||
return i18n._(msg`Ready — nothing received yet`);
|
||||
}
|
||||
|
||||
/** Status line for list integrations (shows last event time). */
|
||||
export function listStatus(lastEventAt: string | null): string {
|
||||
return lastEventAt
|
||||
? i18n._(msg`Last polled ${formatRelativeTime(lastEventAt)}`)
|
||||
: i18n._(msg`Ready — not polled yet`);
|
||||
if (lastEventAt) {
|
||||
const relativeTime = formatRelativeTime(lastEventAt);
|
||||
return i18n._(msg`Last polled ${relativeTime}`);
|
||||
}
|
||||
return i18n._(msg`Ready — not polled yet`);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ export function LanguageSection() {
|
||||
<div className="bg-primary/10 flex h-8 w-8 shrink-0 items-center justify-center rounded-lg">
|
||||
<IconLanguage className="text-primary size-4" />
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<div className="text-start">
|
||||
<CardTitle>
|
||||
<Trans>Language</Trans>
|
||||
</CardTitle>
|
||||
@@ -46,28 +46,31 @@ export function LanguageSection() {
|
||||
<CollapsibleContent className="h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-200 ease-out data-[ending-style]:h-0 data-[starting-style]:h-0">
|
||||
<CardContent className="border-border/30 border-t pt-4">
|
||||
<div className="grid grid-cols-2 gap-2 sm:grid-cols-3">
|
||||
{LOCALE_INFO.map((info) => (
|
||||
<button
|
||||
key={info.code}
|
||||
type="button"
|
||||
onClick={() => handleLocaleChange(info.code)}
|
||||
className={`relative flex items-center gap-2 rounded-lg border px-3 py-2 text-left text-sm transition-colors ${
|
||||
currentLocale === info.code
|
||||
? "border-primary bg-primary/5 text-foreground"
|
||||
: "border-border hover:border-primary/40 hover:bg-primary/5"
|
||||
}`}
|
||||
aria-label={t`Switch to ${info.name}`}
|
||||
aria-pressed={currentLocale === info.code}
|
||||
>
|
||||
<div className="min-w-0">
|
||||
<div className="truncate font-medium">{info.nativeName}</div>
|
||||
<div className="text-muted-foreground truncate text-xs">{info.name}</div>
|
||||
</div>
|
||||
{currentLocale === info.code && (
|
||||
<IconCheck className="text-primary ml-auto size-4 shrink-0" />
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
{LOCALE_INFO.map((info) => {
|
||||
const name = info.name;
|
||||
return (
|
||||
<button
|
||||
key={info.code}
|
||||
type="button"
|
||||
onClick={() => handleLocaleChange(info.code)}
|
||||
className={`relative flex items-center gap-2 rounded-lg border px-3 py-2 text-start text-sm transition-colors ${
|
||||
currentLocale === info.code
|
||||
? "border-primary bg-primary/5 text-foreground"
|
||||
: "border-border hover:border-primary/40 hover:bg-primary/5"
|
||||
}`}
|
||||
aria-label={t`Switch to ${name}`}
|
||||
aria-pressed={currentLocale === info.code}
|
||||
>
|
||||
<div className="min-w-0">
|
||||
<div className="truncate font-medium">{info.nativeName}</div>
|
||||
<div className="text-muted-foreground truncate text-xs">{info.name}</div>
|
||||
</div>
|
||||
{currentLocale === info.code && (
|
||||
<IconCheck className="text-primary ml-auto size-4 shrink-0" />
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</CardContent>
|
||||
</CollapsibleContent>
|
||||
|
||||
@@ -80,7 +80,7 @@ export function SkeletonCards() {
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
{["status", "jobs", "storage"].map((s) => (
|
||||
<Card key={s} className="border-l-primary/30 border-l-2">
|
||||
<Card key={s} className="border-s-primary/30 border-s-2">
|
||||
<CardContent>
|
||||
<div className="flex items-start gap-3">
|
||||
<Skeleton className="mt-0.5 h-8 w-8 rounded-lg" />
|
||||
@@ -181,7 +181,7 @@ function SystemStatusCard({
|
||||
onRefresh: () => void;
|
||||
}) {
|
||||
return (
|
||||
<Card className="border-l-primary/30 border-l-2">
|
||||
<Card className="border-s-primary/30 border-s-2">
|
||||
<CardContent>
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<div className="flex items-start gap-3">
|
||||
@@ -313,7 +313,8 @@ function BackgroundJobsCard({
|
||||
const triggerJobMutation = useMutation(
|
||||
orpc.admin.triggerJob.mutationOptions({
|
||||
onSuccess: (_, { name }) => {
|
||||
toast.success(t`${JOB_LABELS[name] ?? name} triggered`);
|
||||
const jobLabel = JOB_LABELS[name] ?? name;
|
||||
toast.success(t`${jobLabel} triggered`);
|
||||
setTimeout(onRefresh, 1500);
|
||||
},
|
||||
onError: (err) => {
|
||||
@@ -334,9 +335,10 @@ function BackgroundJobsCard({
|
||||
});
|
||||
const activeJobs = jobs.filter((j) => !j.disabled);
|
||||
const healthyCount = activeJobs.filter((j) => j.lastStatus === "success").length;
|
||||
const activeJobCount = activeJobs.length;
|
||||
|
||||
return (
|
||||
<Card className="border-l-primary/30 border-l-2">
|
||||
<Card className="border-s-primary/30 border-s-2">
|
||||
<CardContent>
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<div className="flex items-start gap-3">
|
||||
@@ -349,7 +351,7 @@ function BackgroundJobsCard({
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
<Trans>
|
||||
{healthyCount} of {activeJobs.length} jobs healthy
|
||||
{healthyCount} of {activeJobCount} jobs healthy
|
||||
</Trans>
|
||||
</CardDescription>
|
||||
</div>
|
||||
@@ -361,7 +363,7 @@ function BackgroundJobsCard({
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow className="border-b-border/30 hover:bg-transparent">
|
||||
<TableHead className="text-muted-foreground h-8 pl-5 text-[10px] font-medium tracking-wider uppercase">
|
||||
<TableHead className="text-muted-foreground h-8 ps-5 text-[10px] font-medium tracking-wider uppercase">
|
||||
<Trans>Job</Trans>
|
||||
</TableHead>
|
||||
<TableHead className="text-muted-foreground h-8 text-[10px] font-medium tracking-wider uppercase">
|
||||
@@ -373,7 +375,7 @@ function BackgroundJobsCard({
|
||||
<TableHead className="text-muted-foreground h-8 text-[10px] font-medium tracking-wider uppercase">
|
||||
<Trans>Next run</Trans>
|
||||
</TableHead>
|
||||
<TableHead className="text-muted-foreground h-8 pr-5 text-right text-[10px] font-medium tracking-wider uppercase">
|
||||
<TableHead className="text-muted-foreground h-8 pe-5 text-end text-[10px] font-medium tracking-wider uppercase">
|
||||
<span className="sr-only">
|
||||
<Trans>Actions</Trans>
|
||||
</span>
|
||||
@@ -388,7 +390,7 @@ function BackgroundJobsCard({
|
||||
return (
|
||||
<TableRow key={job.jobName} className="border-b-border/20 hover:bg-muted/30">
|
||||
{/* Job name + status */}
|
||||
<TableCell className="pl-5">
|
||||
<TableCell className="ps-5">
|
||||
<div className="flex items-center gap-2">
|
||||
{job.disabled ? (
|
||||
<StatusDot status="inactive" label={t`Disabled`} />
|
||||
@@ -472,7 +474,7 @@ function BackgroundJobsCard({
|
||||
</TableCell>
|
||||
|
||||
{/* Trigger button */}
|
||||
<TableCell className="pr-5 text-right">
|
||||
<TableCell className="pe-5 text-end">
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={
|
||||
@@ -524,8 +526,11 @@ function StorageCard({
|
||||
onRefresh: () => void;
|
||||
}) {
|
||||
const { t } = useLingui();
|
||||
const cachedImageCount = imageCache.imageCount.toLocaleString();
|
||||
const backupCount = backups.backupCount;
|
||||
const lastBackupAt = backups.lastBackupAt;
|
||||
return (
|
||||
<Card className="border-l-primary/30 border-l-2">
|
||||
<Card className="border-s-primary/30 border-s-2">
|
||||
<CardContent>
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<div className="flex items-start gap-3">
|
||||
@@ -560,7 +565,7 @@ function StorageCard({
|
||||
{imageCache.enabled ? (
|
||||
<>
|
||||
<p className="text-muted-foreground mt-1 text-xs">
|
||||
{t`${imageCache.imageCount.toLocaleString()} cached images`}
|
||||
{t`${cachedImageCount} cached images`}
|
||||
</p>
|
||||
<p className="text-muted-foreground/50 mt-0.5 text-[10px] leading-relaxed">
|
||||
{Object.entries(imageCache.categories)
|
||||
@@ -582,17 +587,16 @@ function StorageCard({
|
||||
<span className="text-muted-foreground/70 text-[11px] font-medium tracking-wider uppercase">
|
||||
<Trans>Backups</Trans>
|
||||
</span>
|
||||
{backups.backupCount > 0 && (
|
||||
{backupCount > 0 && (
|
||||
<span className="text-muted-foreground/50 font-mono text-[11px]">
|
||||
{formatBytes(backups.totalSizeBytes)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{backups.backupCount > 0 ? (
|
||||
{backupCount > 0 ? (
|
||||
<p className="text-muted-foreground mt-1 text-xs">
|
||||
<Trans>
|
||||
{backups.backupCount} backups · last{" "}
|
||||
<LiveTimeAgo date={backups.lastBackupAt} fallback={t`unknown`} />
|
||||
{backupCount} backups · last <LiveTimeAgo date={lastBackupAt} fallback={t`unknown`} />
|
||||
</Trans>
|
||||
</p>
|
||||
) : (
|
||||
|
||||
@@ -115,7 +115,7 @@ function QuickAddButton({ id, userStatus }: { id: string; userStatus?: TitleStat
|
||||
return (
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
className="absolute top-2 right-2 z-10 flex size-8 cursor-default items-center justify-center rounded-full bg-black/50 text-white backdrop-blur-sm"
|
||||
className="absolute end-2 top-2 z-10 flex size-8 cursor-default items-center justify-center rounded-full bg-black/50 text-white backdrop-blur-sm"
|
||||
render={<div />}
|
||||
>
|
||||
<StatusIcon className="size-4" />
|
||||
@@ -129,7 +129,7 @@ function QuickAddButton({ id, userStatus }: { id: string; userStatus?: TitleStat
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
onClick={handleClick}
|
||||
className="absolute top-2 right-2 z-10 flex size-8 items-center justify-center rounded-full bg-black/50 text-white opacity-60 backdrop-blur-sm transition-opacity hover:bg-black/70 focus-visible:opacity-100 sm:opacity-0 sm:group-hover:opacity-100"
|
||||
className="absolute end-2 top-2 z-10 flex size-8 items-center justify-center rounded-full bg-black/50 text-white opacity-60 backdrop-blur-sm transition-opacity hover:bg-black/70 focus-visible:opacity-100 sm:opacity-0 sm:group-hover:opacity-100"
|
||||
render={<button type="button" />}
|
||||
>
|
||||
{!quickAddMutation.isPending && <IconPlus className="size-4" />}
|
||||
|
||||
@@ -6,13 +6,18 @@ import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import { thumbHashToUrl } from "@/lib/thumbhash";
|
||||
import type { CastMember } from "@sofa/api/schemas";
|
||||
|
||||
function EpisodeCountLabel({ count }: { count: number }) {
|
||||
const { t } = useLingui();
|
||||
const suffix = count !== 1 ? "s" : "";
|
||||
return <p className="text-muted-foreground/70 text-[10px]">{t`${count} ep${suffix}`}</p>;
|
||||
}
|
||||
|
||||
interface CastCarouselProps {
|
||||
actors: CastMember[];
|
||||
titleType: "movie" | "tv";
|
||||
}
|
||||
|
||||
export function CastCarousel({ actors, titleType }: CastCarouselProps) {
|
||||
const { t } = useLingui();
|
||||
return (
|
||||
<section className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -74,9 +79,7 @@ export function CastCarousel({ actors, titleType }: CastCarouselProps) {
|
||||
</p>
|
||||
)}
|
||||
{titleType === "tv" && member.episodeCount && (
|
||||
<p className="text-muted-foreground/70 text-[10px]">
|
||||
{t`${member.episodeCount} ep${member.episodeCount !== 1 ? "s" : ""}`}
|
||||
</p>
|
||||
<EpisodeCountLabel count={member.episodeCount} />
|
||||
)}
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
@@ -161,7 +161,7 @@ export function TitleSeasons({
|
||||
setOpenSeason(isOpen ? null : season.seasonNumber);
|
||||
}
|
||||
}}
|
||||
className="group/season hover:bg-accent/50 flex w-full cursor-pointer items-center justify-between p-4 text-left transition-colors"
|
||||
className="group/season hover:bg-accent/50 flex w-full cursor-pointer items-center justify-between p-4 text-start transition-colors"
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="font-medium">
|
||||
@@ -253,7 +253,7 @@ export function TitleSeasons({
|
||||
className="h-full w-full object-cover"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black/40 via-transparent to-transparent" />
|
||||
<span className="absolute bottom-2 left-3 font-mono text-[10px] text-white/70">
|
||||
<span className="absolute start-3 bottom-2 font-mono text-[10px] text-white/70">
|
||||
E{String(ep.episodeNumber).padStart(2, "0")}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -65,8 +65,9 @@ export function useTitleActions() {
|
||||
try {
|
||||
await batchWatchMutation.mutateAsync({ episodeIds });
|
||||
await queryClient.invalidateQueries({ queryKey: userInfoKey });
|
||||
const count = episodeIds.length;
|
||||
toast.success(
|
||||
t`Caught up — marked ${episodeIds.length} ${plural(episodeIds.length, { one: "episode", other: "episodes" })} as watched`,
|
||||
t`Caught up — marked ${plural(count, { one: "# episode", other: "# episodes" })} as watched`,
|
||||
);
|
||||
} catch {
|
||||
setUserInfo((old) => ({
|
||||
@@ -112,7 +113,7 @@ export function useTitleActions() {
|
||||
});
|
||||
toast.success(
|
||||
ratingStars > 0
|
||||
? t`Rated ${ratingStars} ${plural(ratingStars, { one: "star", other: "stars" })}`
|
||||
? t`Rated ${plural(ratingStars, { one: "# star", other: "# stars" })}`
|
||||
: t`Rating removed`,
|
||||
);
|
||||
} catch {
|
||||
@@ -195,7 +196,7 @@ export function useTitleActions() {
|
||||
if (previousUnwatched.length > 0) {
|
||||
const count = previousUnwatched.length;
|
||||
toast.success(t`Watched S${seasonNum} E${epNum}`, {
|
||||
description: t`${count} earlier ${plural(count, { one: "episode", other: "episodes" })} unwatched`,
|
||||
description: t`${plural(count, { one: "# earlier episode", other: "# earlier episodes" })} unwatched`,
|
||||
action: {
|
||||
label: t`Catch up`,
|
||||
onClick: () => catchUp(previousUnwatched),
|
||||
@@ -263,11 +264,12 @@ export function useTitleActions() {
|
||||
}
|
||||
}
|
||||
|
||||
const seasonLabel = season.name ?? t`Season ${season.seasonNumber}`;
|
||||
const seasonNumber = season.seasonNumber;
|
||||
const seasonLabel = season.name ?? t`Season ${seasonNumber}`;
|
||||
if (previousUnwatched.length > 0) {
|
||||
const count = previousUnwatched.length;
|
||||
toast.success(t`Watched all of ${seasonLabel}`, {
|
||||
description: t`${count} earlier ${plural(count, { one: "episode", other: "episodes" })} unwatched`,
|
||||
description: t`${plural(count, { one: "# earlier episode", other: "# earlier episodes" })} unwatched`,
|
||||
action: {
|
||||
label: t`Catch up`,
|
||||
onClick: () => catchUp(previousUnwatched),
|
||||
@@ -302,7 +304,9 @@ export function useTitleActions() {
|
||||
|
||||
try {
|
||||
await unwatchSeasonMutation.mutateAsync({ id: season.id });
|
||||
toast.success(t`Unwatched all of ${season.name ?? t`Season ${season.seasonNumber}`}`);
|
||||
const seasonNumber = season.seasonNumber;
|
||||
const seasonLabel = season.name ?? t`Season ${seasonNumber}`;
|
||||
toast.success(t`Unwatched all of ${seasonLabel}`);
|
||||
} catch {
|
||||
setUserInfo((old) => ({
|
||||
...old,
|
||||
|
||||
@@ -29,7 +29,7 @@ function AccordionTrigger({ className, children, ...props }: AccordionPrimitive.
|
||||
<AccordionPrimitive.Trigger
|
||||
data-slot="accordion-trigger"
|
||||
className={cn(
|
||||
"group/accordion-trigger **:data-[slot=accordion-trigger-icon]:text-muted-foreground relative flex flex-1 items-start justify-between gap-6 border border-transparent p-2 text-left text-xs/relaxed font-medium transition-all outline-none hover:underline aria-disabled:pointer-events-none aria-disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4",
|
||||
"group/accordion-trigger **:data-[slot=accordion-trigger-icon]:text-muted-foreground relative flex flex-1 items-start justify-between gap-6 border border-transparent p-2 text-start text-xs/relaxed font-medium transition-all outline-none hover:underline aria-disabled:pointer-events-none aria-disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ms-auto **:data-[slot=accordion-trigger-icon]:size-4",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -43,7 +43,7 @@ function AlertDialogContent({
|
||||
data-slot="alert-dialog-content"
|
||||
data-size={size}
|
||||
className={cn(
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 group/alert-dialog-content bg-background ring-foreground/10 data-closed:animate-out data-open:animate-in fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-3 rounded-xl p-4 ring-1 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-64 data-[size=default]:sm:max-w-sm",
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 group/alert-dialog-content bg-background ring-foreground/10 data-closed:animate-out data-open:animate-in fixed start-1/2 top-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-3 rounded-xl p-4 ring-1 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-64 data-[size=default]:sm:max-w-sm rtl:translate-x-1/2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -57,7 +57,7 @@ function AlertDialogHeader({ className, ...props }: React.ComponentProps<"div">)
|
||||
<div
|
||||
data-slot="alert-dialog-header"
|
||||
className={cn(
|
||||
"grid grid-rows-[auto_1fr] place-items-center gap-1 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]",
|
||||
"grid grid-rows-[auto_1fr] place-items-center gap-1 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-start sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -4,7 +4,7 @@ import type * as React from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const alertVariants = cva(
|
||||
"group/alert relative grid w-full gap-0.5 rounded-lg border px-2 py-1.5 text-left text-xs/relaxed has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-1.5 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-3.5",
|
||||
"group/alert relative grid w-full gap-0.5 rounded-lg border px-2 py-1.5 text-start text-xs/relaxed has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pe-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-1.5 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-3.5",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
@@ -62,11 +62,7 @@ function AlertDescription({ className, ...props }: React.ComponentProps<"div">)
|
||||
|
||||
function AlertAction({ className, ...props }: React.ComponentProps<"div">) {
|
||||
return (
|
||||
<div
|
||||
data-slot="alert-action"
|
||||
className={cn("absolute top-1.5 right-2", className)}
|
||||
{...props}
|
||||
/>
|
||||
<div data-slot="alert-action" className={cn("absolute end-2 top-1.5", className)} {...props} />
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ function AvatarBadge({ className, ...props }: React.ComponentProps<"span">) {
|
||||
<span
|
||||
data-slot="avatar-badge"
|
||||
className={cn(
|
||||
"bg-primary text-primary-foreground ring-background absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-blend-color ring-2 select-none",
|
||||
"bg-primary text-primary-foreground ring-background absolute end-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-blend-color ring-2 select-none",
|
||||
"group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden",
|
||||
"group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
|
||||
"group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
|
||||
|
||||
@@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const badgeVariants = cva(
|
||||
"group/badge focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-[0.625rem] font-medium whitespace-nowrap transition-all focus-visible:ring-[3px] has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:pointer-events-none [&>svg]:size-2.5!",
|
||||
"group/badge focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-[0.625rem] font-medium whitespace-nowrap transition-all focus-visible:ring-[3px] has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&>svg]:pointer-events-none [&>svg]:size-2.5!",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
|
||||
@@ -6,12 +6,12 @@ import { Separator } from "@/components/ui/separator";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const buttonGroupVariants = cva(
|
||||
"flex w-fit items-stretch *:focus-visible:relative *:focus-visible:z-10 has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
|
||||
"flex w-fit items-stretch *:focus-visible:relative *:focus-visible:z-10 has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-e-md [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
|
||||
{
|
||||
variants: {
|
||||
orientation: {
|
||||
horizontal:
|
||||
"*:data-slot:rounded-r-none [&>[data-slot]:not(:has(~[data-slot]))]:rounded-r-md! [&>[data-slot]~[data-slot]]:rounded-l-none [&>[data-slot]~[data-slot]]:border-l-0",
|
||||
"*:data-slot:rounded-e-none [&>[data-slot]:not(:has(~[data-slot]))]:rounded-e-md! [&>[data-slot]~[data-slot]]:rounded-s-none [&>[data-slot]~[data-slot]]:border-s-0",
|
||||
vertical:
|
||||
"flex-col *:data-slot:rounded-b-none [&>[data-slot]:not(:has(~[data-slot]))]:rounded-b-md! [&>[data-slot]~[data-slot]]:rounded-t-none [&>[data-slot]~[data-slot]]:border-t-0",
|
||||
},
|
||||
|
||||
@@ -21,10 +21,10 @@ const buttonVariants = cva(
|
||||
},
|
||||
size: {
|
||||
default:
|
||||
"h-7 gap-1 px-2 text-xs/relaxed has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
xs: "h-5 gap-1 rounded-sm px-2 text-[0.625rem] has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-2.5",
|
||||
sm: "h-6 gap-1 px-2 text-xs/relaxed has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
|
||||
lg: "h-8 gap-1 px-2.5 text-xs/relaxed has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-4",
|
||||
"h-7 gap-1 px-2 text-xs/relaxed has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
xs: "h-5 gap-1 rounded-sm px-2 text-[0.625rem] has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-2.5",
|
||||
sm: "h-6 gap-1 px-2 text-xs/relaxed has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-3",
|
||||
lg: "h-8 gap-1 px-2.5 text-xs/relaxed has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2 [&_svg:not([class*='size-'])]:size-4",
|
||||
icon: "size-7 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
"icon-xs": "size-5 rounded-sm [&_svg:not([class*='size-'])]:size-2.5",
|
||||
"icon-sm": "size-6 [&_svg:not([class*='size-'])]:size-3",
|
||||
|
||||
@@ -102,7 +102,7 @@ function ComboboxContent({
|
||||
data-slot="combobox-content"
|
||||
data-chips={!!anchor}
|
||||
className={cn(
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 group/combobox-content bg-popover text-popover-foreground ring-foreground/10 data-closed:animate-out data-open:animate-in *:data-[slot=input-group]:bg-input/20 dark:bg-popover relative max-h-(--available-height) w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) overflow-hidden rounded-lg shadow-md ring-1 duration-100 data-[chips=true]:min-w-(--anchor-width) *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-7 *:data-[slot=input-group]:border-none *:data-[slot=input-group]:shadow-none",
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-end-2 data-[side=inline-end]:slide-in-from-start-2 group/combobox-content bg-popover text-popover-foreground ring-foreground/10 data-closed:animate-out data-open:animate-in *:data-[slot=input-group]:bg-input/20 dark:bg-popover relative max-h-(--available-height) w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) overflow-hidden rounded-lg shadow-md ring-1 duration-100 data-[chips=true]:min-w-(--anchor-width) *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-7 *:data-[slot=input-group]:border-none *:data-[slot=input-group]:shadow-none",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -138,7 +138,7 @@ function ComboboxItem({ className, children, ...props }: ComboboxPrimitive.Item.
|
||||
{children}
|
||||
<ComboboxPrimitive.ItemIndicator
|
||||
render={
|
||||
<span className="pointer-events-none absolute right-2 flex items-center justify-center" />
|
||||
<span className="pointer-events-none absolute end-2 flex items-center justify-center" />
|
||||
}
|
||||
>
|
||||
<IconCheck className="pointer-events-none" />
|
||||
@@ -218,7 +218,7 @@ function ComboboxChip({
|
||||
<ComboboxPrimitive.Chip
|
||||
data-slot="combobox-chip"
|
||||
className={cn(
|
||||
"bg-muted-foreground/10 text-foreground flex h-[calc(--spacing(4.75))] w-fit items-center justify-center gap-1 rounded-[calc(var(--radius-sm)-2px)] px-1.5 text-xs/relaxed font-medium whitespace-nowrap has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-data-[slot=combobox-chip-remove]:pr-0",
|
||||
"bg-muted-foreground/10 text-foreground flex h-[calc(--spacing(4.75))] w-fit items-center justify-center gap-1 rounded-[calc(var(--radius-sm)-2px)] px-1.5 text-xs/relaxed font-medium whitespace-nowrap has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-data-[slot=combobox-chip-remove]:pe-0",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -227,7 +227,7 @@ function ComboboxChip({
|
||||
{showRemove && (
|
||||
<ComboboxPrimitive.ChipRemove
|
||||
render={<Button variant="ghost" size="icon-xs" />}
|
||||
className="-ml-1 opacity-50 hover:opacity-100"
|
||||
className="-ms-1 opacity-50 hover:opacity-100"
|
||||
data-slot="combobox-chip-remove"
|
||||
>
|
||||
<IconX className="pointer-events-none" />
|
||||
|
||||
@@ -148,7 +148,7 @@ function CommandItem({
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<IconCheck className="ml-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100" />
|
||||
<IconCheck className="ms-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100" />
|
||||
</CommandPrimitive.Item>
|
||||
);
|
||||
}
|
||||
@@ -158,7 +158,7 @@ function CommandShortcut({ className, ...props }: React.ComponentProps<"span">)
|
||||
<span
|
||||
data-slot="command-shortcut"
|
||||
className={cn(
|
||||
"text-muted-foreground group-data-selected/command-item:text-foreground ml-auto text-[0.625rem] tracking-widest",
|
||||
"text-muted-foreground group-data-selected/command-item:text-foreground ms-auto text-[0.625rem] tracking-widest",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -26,7 +26,7 @@ function ContextMenuContent({
|
||||
className,
|
||||
align = "start",
|
||||
alignOffset = 4,
|
||||
side = "right",
|
||||
side = "inline-end",
|
||||
sideOffset = 0,
|
||||
...props
|
||||
}: ContextMenuPrimitive.Popup.Props &
|
||||
@@ -43,7 +43,7 @@ function ContextMenuContent({
|
||||
<ContextMenuPrimitive.Popup
|
||||
data-slot="context-menu-content"
|
||||
className={cn(
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 bg-popover text-popover-foreground ring-foreground/10 data-closed:animate-out data-open:animate-in z-50 max-h-(--available-height) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg p-1 shadow-md ring-1 duration-100 outline-none",
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-end-2 data-[side=inline-end]:slide-in-from-start-2 bg-popover text-popover-foreground ring-foreground/10 data-closed:animate-out data-open:animate-in z-50 max-h-(--available-height) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg p-1 shadow-md ring-1 duration-100 outline-none",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -68,7 +68,7 @@ function ContextMenuLabel({
|
||||
<ContextMenuPrimitive.GroupLabel
|
||||
data-slot="context-menu-label"
|
||||
data-inset={inset}
|
||||
className={cn("text-muted-foreground px-2 py-1.5 text-xs data-inset:pl-7.5", className)}
|
||||
className={cn("text-muted-foreground px-2 py-1.5 text-xs data-inset:ps-7.5", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
@@ -89,7 +89,7 @@ function ContextMenuItem({
|
||||
data-inset={inset}
|
||||
data-variant={variant}
|
||||
className={cn(
|
||||
"group/context-menu-item focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:*:[svg]:text-destructive relative flex min-h-7 cursor-default items-center gap-2 rounded-md px-2 py-1 text-xs/relaxed outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
"group/context-menu-item focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:*:[svg]:text-destructive relative flex min-h-7 cursor-default items-center gap-2 rounded-md px-2 py-1 text-xs/relaxed outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:ps-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -114,13 +114,13 @@ function ContextMenuSubTrigger({
|
||||
data-slot="context-menu-sub-trigger"
|
||||
data-inset={inset}
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground flex min-h-7 cursor-default items-center gap-2 rounded-md px-2 py-1 text-xs outline-hidden select-none data-inset:pl-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
"focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground flex min-h-7 cursor-default items-center gap-2 rounded-md px-2 py-1 text-xs outline-hidden select-none data-inset:ps-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<IconChevronRight className="ml-auto" />
|
||||
<IconChevronRight className="ms-auto" />
|
||||
</ContextMenuPrimitive.SubmenuTrigger>
|
||||
);
|
||||
}
|
||||
@@ -130,7 +130,7 @@ function ContextMenuSubContent({ ...props }: React.ComponentProps<typeof Context
|
||||
<ContextMenuContent
|
||||
data-slot="context-menu-sub-content"
|
||||
className="shadow-lg"
|
||||
side="right"
|
||||
side="inline-end"
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
@@ -150,13 +150,13 @@ function ContextMenuCheckboxItem({
|
||||
data-slot="context-menu-checkbox-item"
|
||||
data-inset={inset}
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 pr-8 pl-2 text-xs outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 ps-2 pe-8 text-xs outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:ps-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
className,
|
||||
)}
|
||||
checked={checked}
|
||||
{...props}
|
||||
>
|
||||
<span className="pointer-events-none absolute right-2 flex items-center justify-center">
|
||||
<span className="pointer-events-none absolute end-2 flex items-center justify-center">
|
||||
<ContextMenuPrimitive.CheckboxItemIndicator>
|
||||
<IconCheck />
|
||||
</ContextMenuPrimitive.CheckboxItemIndicator>
|
||||
@@ -183,12 +183,12 @@ function ContextMenuRadioItem({
|
||||
data-slot="context-menu-radio-item"
|
||||
data-inset={inset}
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 pr-8 pl-2 text-xs outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 ps-2 pe-8 text-xs outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:ps-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<span className="pointer-events-none absolute right-2 flex items-center justify-center">
|
||||
<span className="pointer-events-none absolute end-2 flex items-center justify-center">
|
||||
<ContextMenuPrimitive.RadioItemIndicator>
|
||||
<IconCheck />
|
||||
</ContextMenuPrimitive.RadioItemIndicator>
|
||||
@@ -213,7 +213,7 @@ function ContextMenuShortcut({ className, ...props }: React.ComponentProps<"span
|
||||
<span
|
||||
data-slot="context-menu-shortcut"
|
||||
className={cn(
|
||||
"text-muted-foreground group-focus/context-menu-item:text-accent-foreground ml-auto text-[0.625rem] tracking-widest",
|
||||
"text-muted-foreground group-focus/context-menu-item:text-accent-foreground ms-auto text-[0.625rem] tracking-widest",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -48,7 +48,7 @@ function DialogContent({
|
||||
<DialogPrimitive.Popup
|
||||
data-slot="dialog-content"
|
||||
className={cn(
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 bg-background ring-foreground/10 data-closed:animate-out data-open:animate-in fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl p-4 text-xs/relaxed ring-1 duration-100 outline-none sm:max-w-sm",
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 bg-background ring-foreground/10 data-closed:animate-out data-open:animate-in fixed start-1/2 top-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl p-4 text-xs/relaxed ring-1 duration-100 outline-none sm:max-w-sm rtl:translate-x-1/2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -57,7 +57,7 @@ function DialogContent({
|
||||
{showCloseButton && (
|
||||
<DialogPrimitive.Close
|
||||
data-slot="dialog-close"
|
||||
render={<Button variant="ghost" className="absolute top-2 right-2" size="icon-sm" />}
|
||||
render={<Button variant="ghost" className="absolute end-2 top-2" size="icon-sm" />}
|
||||
>
|
||||
<IconX />
|
||||
<span className="sr-only">Close</span>
|
||||
|
||||
@@ -37,7 +37,7 @@ function DropdownMenuContent({
|
||||
<MenuPrimitive.Popup
|
||||
data-slot="dropdown-menu-content"
|
||||
className={cn(
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 bg-popover text-popover-foreground ring-foreground/10 data-closed:animate-out data-open:animate-in z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg p-1 shadow-md ring-1 duration-100 outline-none data-closed:overflow-hidden",
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-end-2 data-[side=inline-end]:slide-in-from-start-2 bg-popover text-popover-foreground ring-foreground/10 data-closed:animate-out data-open:animate-in z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg p-1 shadow-md ring-1 duration-100 outline-none data-closed:overflow-hidden",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -62,7 +62,7 @@ function DropdownMenuLabel({
|
||||
<MenuPrimitive.GroupLabel
|
||||
data-slot="dropdown-menu-label"
|
||||
data-inset={inset}
|
||||
className={cn("text-muted-foreground px-2 py-1.5 text-xs data-inset:pl-7.5", className)}
|
||||
className={cn("text-muted-foreground px-2 py-1.5 text-xs data-inset:ps-7.5", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
@@ -83,7 +83,7 @@ function DropdownMenuItem({
|
||||
data-inset={inset}
|
||||
data-variant={variant}
|
||||
className={cn(
|
||||
"group/dropdown-menu-item focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:*:[svg]:text-destructive relative flex min-h-7 cursor-default items-center gap-2 rounded-md px-2 py-1 text-xs/relaxed outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
"group/dropdown-menu-item focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:*:[svg]:text-destructive relative flex min-h-7 cursor-default items-center gap-2 rounded-md px-2 py-1 text-xs/relaxed outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:ps-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -108,13 +108,13 @@ function DropdownMenuSubTrigger({
|
||||
data-slot="dropdown-menu-sub-trigger"
|
||||
data-inset={inset}
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-open:bg-accent data-popup-open:bg-accent data-open:text-accent-foreground data-popup-open:text-accent-foreground flex min-h-7 cursor-default items-center gap-2 rounded-md px-2 py-1 text-xs outline-hidden select-none data-inset:pl-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
"focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-open:bg-accent data-popup-open:bg-accent data-open:text-accent-foreground data-popup-open:text-accent-foreground flex min-h-7 cursor-default items-center gap-2 rounded-md px-2 py-1 text-xs outline-hidden select-none data-inset:ps-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<IconChevronRight className="ml-auto" />
|
||||
<IconChevronRight className="ms-auto" />
|
||||
</MenuPrimitive.SubmenuTrigger>
|
||||
);
|
||||
}
|
||||
@@ -122,7 +122,7 @@ function DropdownMenuSubTrigger({
|
||||
function DropdownMenuSubContent({
|
||||
align = "start",
|
||||
alignOffset = -3,
|
||||
side = "right",
|
||||
side = "inline-end",
|
||||
sideOffset = 0,
|
||||
className,
|
||||
...props
|
||||
@@ -157,14 +157,14 @@ function DropdownMenuCheckboxItem({
|
||||
data-slot="dropdown-menu-checkbox-item"
|
||||
data-inset={inset}
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 pr-8 pl-2 text-xs outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 ps-2 pe-8 text-xs outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:ps-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
className,
|
||||
)}
|
||||
checked={checked}
|
||||
{...props}
|
||||
>
|
||||
<span
|
||||
className="pointer-events-none absolute right-2 flex items-center justify-center"
|
||||
className="pointer-events-none absolute end-2 flex items-center justify-center"
|
||||
data-slot="dropdown-menu-checkbox-item-indicator"
|
||||
>
|
||||
<MenuPrimitive.CheckboxItemIndicator>
|
||||
@@ -193,13 +193,13 @@ function DropdownMenuRadioItem({
|
||||
data-slot="dropdown-menu-radio-item"
|
||||
data-inset={inset}
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 pr-8 pl-2 text-xs outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 ps-2 pe-8 text-xs outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:ps-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<span
|
||||
className="pointer-events-none absolute right-2 flex items-center justify-center"
|
||||
className="pointer-events-none absolute end-2 flex items-center justify-center"
|
||||
data-slot="dropdown-menu-radio-item-indicator"
|
||||
>
|
||||
<MenuPrimitive.RadioItemIndicator>
|
||||
@@ -226,7 +226,7 @@ function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<"spa
|
||||
<span
|
||||
data-slot="dropdown-menu-shortcut"
|
||||
className={cn(
|
||||
"text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground ml-auto text-[0.625rem] tracking-widest",
|
||||
"text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground ms-auto text-[0.625rem] tracking-widest",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -122,7 +122,7 @@ function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
|
||||
<p
|
||||
data-slot="field-description"
|
||||
className={cn(
|
||||
"text-muted-foreground text-left text-xs/relaxed leading-normal font-normal group-has-data-horizontal/field:text-balance [[data-variant=legend]+&]:-mt-1.5",
|
||||
"text-muted-foreground text-start text-xs/relaxed leading-normal font-normal group-has-data-horizontal/field:text-balance [[data-variant=legend]+&]:-mt-1.5",
|
||||
"last:mt-0 nth-last-2:-mt-1",
|
||||
"[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
|
||||
className,
|
||||
@@ -186,7 +186,7 @@ function FieldError({
|
||||
}
|
||||
|
||||
return (
|
||||
<ul className="ml-4 flex list-disc flex-col gap-1">
|
||||
<ul className="ms-4 flex list-disc flex-col gap-1">
|
||||
{uniqueErrors.map((error, index) => error?.message && <li key={index}>{error.message}</li>)}
|
||||
</ul>
|
||||
);
|
||||
|
||||
@@ -31,7 +31,7 @@ function HoverCardContent({
|
||||
<PreviewCardPrimitive.Popup
|
||||
data-slot="hover-card-content"
|
||||
className={cn(
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 bg-popover text-popover-foreground ring-foreground/10 data-closed:animate-out data-open:animate-in z-50 w-72 origin-(--transform-origin) rounded-lg p-2.5 text-xs/relaxed shadow-md ring-1 outline-hidden duration-100",
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-end-2 data-[side=inline-end]:slide-in-from-start-2 bg-popover text-popover-foreground ring-foreground/10 data-closed:animate-out data-open:animate-in z-50 w-72 origin-(--transform-origin) rounded-lg p-2.5 text-xs/relaxed shadow-md ring-1 outline-hidden duration-100",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -12,7 +12,7 @@ function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
|
||||
data-slot="input-group"
|
||||
role="group"
|
||||
className={cn(
|
||||
"group/input-group border-input bg-input/20 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot=input-group-control]:focus-visible]:ring-ring/30 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 dark:bg-input/30 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 relative flex h-7 w-full min-w-0 items-center rounded-md border transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-data-[align=block-end]:rounded-md has-data-[align=block-start]:rounded-md has-[[data-slot=input-group-control]:focus-visible]:ring-2 has-[[data-slot][aria-invalid=true]]:ring-2 has-[textarea]:rounded-md has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5",
|
||||
"group/input-group border-input bg-input/20 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot=input-group-control]:focus-visible]:ring-ring/30 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 dark:bg-input/30 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 relative flex h-7 w-full min-w-0 items-center rounded-md border transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-data-[align=block-end]:rounded-md has-data-[align=block-start]:rounded-md has-[[data-slot=input-group-control]:focus-visible]:ring-2 has-[[data-slot][aria-invalid=true]]:ring-2 has-[textarea]:rounded-md has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pe-1.5 has-[>[data-align=inline-start]]:[&>input]:ps-1.5",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -25,8 +25,8 @@ const inputGroupAddonVariants = cva(
|
||||
{
|
||||
variants: {
|
||||
align: {
|
||||
"inline-start": "order-first pl-2 has-[>button]:ml-[-0.275rem] has-[>kbd]:ml-[-0.275rem]",
|
||||
"inline-end": "order-last pr-2 has-[>button]:mr-[-0.275rem] has-[>kbd]:mr-[-0.275rem]",
|
||||
"inline-start": "order-first ps-2 has-[>button]:ms-[-0.275rem] has-[>kbd]:ms-[-0.275rem]",
|
||||
"inline-end": "order-last pe-2 has-[>button]:me-[-0.275rem] has-[>kbd]:me-[-0.275rem]",
|
||||
"block-start":
|
||||
"order-first w-full justify-start px-2 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2",
|
||||
"block-end":
|
||||
|
||||
@@ -140,7 +140,7 @@ function ItemDescription({ className, ...props }: React.ComponentProps<"p">) {
|
||||
<p
|
||||
data-slot="item-description"
|
||||
className={cn(
|
||||
"text-muted-foreground [&>a:hover]:text-primary line-clamp-2 text-left text-xs/relaxed font-normal [&>a]:underline [&>a]:underline-offset-4",
|
||||
"text-muted-foreground [&>a:hover]:text-primary line-clamp-2 text-start text-xs/relaxed font-normal [&>a]:underline [&>a]:underline-offset-4",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -69,7 +69,7 @@ function MenubarContent({
|
||||
alignOffset={alignOffset}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"data-open:fade-in-0 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 bg-popover text-popover-foreground ring-foreground/10 data-open:animate-in min-w-32 rounded-lg p-1 shadow-md ring-1 duration-100",
|
||||
"data-open:fade-in-0 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-end-2 data-[side=inline-end]:slide-in-from-start-2 bg-popover text-popover-foreground ring-foreground/10 data-open:animate-in min-w-32 rounded-lg p-1 shadow-md ring-1 duration-100",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -89,7 +89,7 @@ function MenubarItem({
|
||||
data-inset={inset}
|
||||
data-variant={variant}
|
||||
className={cn(
|
||||
"group/menubar-item focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:*:[svg]:text-destructive! min-h-7 gap-2 rounded-md px-2 py-1 text-xs/relaxed data-disabled:opacity-50 data-inset:pl-7.5 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
"group/menubar-item focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:*:[svg]:text-destructive! min-h-7 gap-2 rounded-md px-2 py-1 text-xs/relaxed data-disabled:opacity-50 data-inset:ps-7.5 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -111,13 +111,13 @@ function MenubarCheckboxItem({
|
||||
data-slot="menubar-checkbox-item"
|
||||
data-inset={inset}
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 pr-2 pl-7.5 text-xs outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 ps-7.5 pe-2 text-xs outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:ps-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
className,
|
||||
)}
|
||||
checked={checked}
|
||||
{...props}
|
||||
>
|
||||
<span className="pointer-events-none absolute left-2 flex size-4 items-center justify-center [&_svg:not([class*='size-'])]:size-4">
|
||||
<span className="pointer-events-none absolute start-2 flex size-4 items-center justify-center [&_svg:not([class*='size-'])]:size-4">
|
||||
<MenuPrimitive.CheckboxItemIndicator>
|
||||
<IconCheck />
|
||||
</MenuPrimitive.CheckboxItemIndicator>
|
||||
@@ -144,12 +144,12 @@ function MenubarRadioItem({
|
||||
data-slot="menubar-radio-item"
|
||||
data-inset={inset}
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 pr-2 pl-7.5 text-xs outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 ps-7.5 pe-2 text-xs outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:ps-7.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<span className="pointer-events-none absolute left-2 flex size-4 items-center justify-center [&_svg:not([class*='size-'])]:size-4">
|
||||
<span className="pointer-events-none absolute start-2 flex size-4 items-center justify-center [&_svg:not([class*='size-'])]:size-4">
|
||||
<MenuPrimitive.RadioItemIndicator>
|
||||
<IconCheck />
|
||||
</MenuPrimitive.RadioItemIndicator>
|
||||
@@ -170,7 +170,7 @@ function MenubarLabel({
|
||||
<DropdownMenuLabel
|
||||
data-slot="menubar-label"
|
||||
data-inset={inset}
|
||||
className={cn("text-muted-foreground px-2 py-1.5 text-xs data-inset:pl-7.5", className)}
|
||||
className={cn("text-muted-foreground px-2 py-1.5 text-xs data-inset:ps-7.5", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
@@ -197,7 +197,7 @@ function MenubarShortcut({
|
||||
<DropdownMenuShortcut
|
||||
data-slot="menubar-shortcut"
|
||||
className={cn(
|
||||
"text-muted-foreground group-focus/menubar-item:text-accent-foreground ml-auto text-[0.625rem] tracking-widest",
|
||||
"text-muted-foreground group-focus/menubar-item:text-accent-foreground ms-auto text-[0.625rem] tracking-widest",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -221,7 +221,7 @@ function MenubarSubTrigger({
|
||||
data-slot="menubar-sub-trigger"
|
||||
data-inset={inset}
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground min-h-7 gap-2 rounded-md px-2 py-1 text-xs data-inset:pl-7.5 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
"focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground min-h-7 gap-2 rounded-md px-2 py-1 text-xs data-inset:ps-7.5 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -68,7 +68,7 @@ function NavigationMenuTrigger({
|
||||
>
|
||||
{children}{" "}
|
||||
<IconChevronDown
|
||||
className="relative top-px ml-1 size-3 transition duration-300 group-data-open/navigation-menu-trigger:rotate-180 group-data-popup-open/navigation-menu-trigger:rotate-180"
|
||||
className="relative top-px ms-1 size-3 transition duration-300 group-data-open/navigation-menu-trigger:rotate-180 group-data-popup-open/navigation-menu-trigger:rotate-180"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</NavigationMenuPrimitive.Trigger>
|
||||
@@ -80,7 +80,7 @@ function NavigationMenuContent({ className, ...props }: NavigationMenuPrimitive.
|
||||
<NavigationMenuPrimitive.Content
|
||||
data-slot="navigation-menu-content"
|
||||
className={cn(
|
||||
"data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 group-data-[viewport=false]/navigation-menu:data-closed:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-open:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-open:fade-in-0 group-data-[viewport=false]/navigation-menu:data-closed:fade-out-0 data-ending-style:data-activation-direction=left:translate-x-[50%] data-ending-style:data-activation-direction=right:translate-x-[-50%] data-starting-style:data-activation-direction=left:translate-x-[-50%] data-starting-style:data-activation-direction=right:translate-x-[50%] data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:ring-foreground/10 group-data-[viewport=false]/navigation-menu:data-closed:animate-out group-data-[viewport=false]/navigation-menu:data-open:animate-in h-full w-auto p-1.5 transition-[opacity,transform,translate] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] group-data-[viewport=false]/navigation-menu:rounded-xl group-data-[viewport=false]/navigation-menu:shadow-md group-data-[viewport=false]/navigation-menu:ring-1 group-data-[viewport=false]/navigation-menu:duration-300 data-ending-style:opacity-0 data-starting-style:opacity-0 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none",
|
||||
"data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 group-data-[viewport=false]/navigation-menu:data-closed:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-open:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-open:fade-in-0 group-data-[viewport=false]/navigation-menu:data-closed:fade-out-0 data-ending-style:data-activation-direction=left:translate-x-[50%] rtl:data-ending-style:data-activation-direction=left:-translate-x-[50%] data-ending-style:data-activation-direction=right:translate-x-[-50%] rtl:data-ending-style:data-activation-direction=right:-translate-x-[-50%] data-starting-style:data-activation-direction=left:translate-x-[-50%] rtl:data-starting-style:data-activation-direction=left:-translate-x-[-50%] data-starting-style:data-activation-direction=right:translate-x-[50%] rtl:data-starting-style:data-activation-direction=right:-translate-x-[50%] data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:ring-foreground/10 group-data-[viewport=false]/navigation-menu:data-closed:animate-out group-data-[viewport=false]/navigation-menu:data-open:animate-in h-full w-auto p-1.5 transition-[opacity,transform,translate] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] group-data-[viewport=false]/navigation-menu:rounded-xl group-data-[viewport=false]/navigation-menu:shadow-md group-data-[viewport=false]/navigation-menu:ring-1 group-data-[viewport=false]/navigation-menu:duration-300 data-ending-style:opacity-0 data-starting-style:opacity-0 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -104,7 +104,7 @@ function NavigationMenuPositioner({
|
||||
align={align}
|
||||
alignOffset={alignOffset}
|
||||
className={cn(
|
||||
"isolate z-50 h-(--positioner-height) w-(--positioner-width) max-w-(--available-width) transition-[top,left,right,bottom] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] data-instant:transition-none data-[side=bottom]:before:top-[-10px] data-[side=bottom]:before:right-0 data-[side=bottom]:before:left-0",
|
||||
"isolate z-50 h-(--positioner-height) w-(--positioner-width) max-w-(--available-width) transition-[top,left,right,bottom] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] data-instant:transition-none data-[side=bottom]:before:start-0 data-[side=bottom]:before:end-0 data-[side=bottom]:before:top-[-10px]",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -143,7 +143,7 @@ function NavigationMenuIndicator({
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<div className="bg-border relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm shadow-md" />
|
||||
<div className="bg-border relative top-[60%] h-2 w-2 rotate-45 rounded-ss-sm shadow-md" />
|
||||
</NavigationMenuPrimitive.Icon>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ function PaginationPrevious({
|
||||
<PaginationLink
|
||||
aria-label="Go to previous page"
|
||||
size="default"
|
||||
className={cn("pl-2!", className)}
|
||||
className={cn("ps-2!", className)}
|
||||
{...props}
|
||||
>
|
||||
<IconChevronLeft data-icon="inline-start" />
|
||||
@@ -80,7 +80,7 @@ function PaginationNext({
|
||||
<PaginationLink
|
||||
aria-label="Go to next page"
|
||||
size="default"
|
||||
className={cn("pr-2!", className)}
|
||||
className={cn("pe-2!", className)}
|
||||
{...props}
|
||||
>
|
||||
<span className="hidden sm:block">{text}</span>
|
||||
|
||||
@@ -32,7 +32,7 @@ function PopoverContent({
|
||||
<PopoverPrimitive.Popup
|
||||
data-slot="popover-content"
|
||||
className={cn(
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 bg-popover text-popover-foreground ring-foreground/10 data-closed:animate-out data-open:animate-in z-50 flex w-72 origin-(--transform-origin) flex-col gap-4 rounded-lg p-2.5 text-xs shadow-md ring-1 outline-hidden duration-100",
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-end-2 data-[side=inline-end]:slide-in-from-start-2 bg-popover text-popover-foreground ring-foreground/10 data-closed:animate-out data-open:animate-in z-50 flex w-72 origin-(--transform-origin) flex-col gap-4 rounded-lg p-2.5 text-xs shadow-md ring-1 outline-hidden duration-100",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -54,7 +54,7 @@ function ProgressLabel({ className, ...props }: ProgressPrimitive.Label.Props) {
|
||||
function ProgressValue({ className, ...props }: ProgressPrimitive.Value.Props) {
|
||||
return (
|
||||
<ProgressPrimitive.Value
|
||||
className={cn("text-muted-foreground ml-auto text-xs/relaxed tabular-nums", className)}
|
||||
className={cn("text-muted-foreground ms-auto text-xs/relaxed tabular-nums", className)}
|
||||
data-slot="progress-value"
|
||||
{...props}
|
||||
/>
|
||||
|
||||
@@ -27,7 +27,7 @@ function RadioGroupItem({ className, ...props }: RadioPrimitive.Root.Props) {
|
||||
data-slot="radio-group-indicator"
|
||||
className="flex size-4 items-center justify-center"
|
||||
>
|
||||
<span className="bg-primary-foreground absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full" />
|
||||
<span className="bg-primary-foreground absolute start-1/2 top-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full rtl:translate-x-1/2" />
|
||||
</RadioPrimitive.Indicator>
|
||||
</RadioPrimitive.Root>
|
||||
);
|
||||
|
||||
@@ -36,7 +36,7 @@ function ScrollArea({
|
||||
"no-scrollbar focus-visible:ring-ring/50 flex-1 rounded-[inherit] outline-none focus-visible:ring-[3px] focus-visible:outline-1 data-has-overflow-x:overscroll-x-contain",
|
||||
scrollFade &&
|
||||
"mask-t-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-y-start)))] mask-r-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-x-end)))] mask-b-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-y-end)))] mask-l-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-x-start)))] [--fade-size:1.5rem]",
|
||||
scrollbarGutter && "data-has-overflow-x:pb-2.5 data-has-overflow-y:pr-2.5",
|
||||
scrollbarGutter && "data-has-overflow-x:pb-2.5 data-has-overflow-y:pe-2.5",
|
||||
)}
|
||||
>
|
||||
<ScrollAreaPrimitive.Content data-slot="scroll-area-content" ref={contentRef}>
|
||||
|
||||
@@ -20,7 +20,7 @@ function SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {
|
||||
return (
|
||||
<SelectPrimitive.Value
|
||||
data-slot="select-value"
|
||||
className={cn("flex flex-1 text-left", className)}
|
||||
className={cn("flex flex-1 text-start", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
@@ -80,7 +80,7 @@ function SelectContent({
|
||||
data-slot="select-content"
|
||||
data-align-trigger={alignItemWithTrigger}
|
||||
className={cn(
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 bg-popover text-popover-foreground ring-foreground/10 data-closed:animate-out data-open:animate-in relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg shadow-md ring-1 duration-100 data-[align-trigger=true]:animate-none",
|
||||
"data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-end-2 data-[side=inline-end]:slide-in-from-start-2 bg-popover text-popover-foreground ring-foreground/10 data-closed:animate-out data-open:animate-in relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg shadow-md ring-1 duration-100 data-[align-trigger=true]:animate-none",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -119,7 +119,7 @@ function SelectItem({ className, children, ...props }: SelectPrimitive.Item.Prop
|
||||
</SelectPrimitive.ItemText>
|
||||
<SelectPrimitive.ItemIndicator
|
||||
render={
|
||||
<span className="pointer-events-none absolute right-2 flex items-center justify-center" />
|
||||
<span className="pointer-events-none absolute end-2 flex items-center justify-center" />
|
||||
}
|
||||
>
|
||||
<IconCheck className="pointer-events-none" />
|
||||
|
||||
@@ -51,7 +51,7 @@ function SheetContent({
|
||||
data-slot="sheet-content"
|
||||
data-side={side}
|
||||
className={cn(
|
||||
"data-[side=right]:data-closed:slide-out-to-right-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=top]:data-closed:slide-out-to-top-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:fade-out-0 data-open:fade-in-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=bottom]:data-open:slide-in-from-bottom-10 bg-background data-closed:animate-out data-open:animate-in fixed z-50 flex flex-col bg-clip-padding text-xs/relaxed shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",
|
||||
"data-[side=right]:data-closed:slide-out-to-right-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=top]:data-closed:slide-out-to-top-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:fade-out-0 data-open:fade-in-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=bottom]:data-open:slide-in-from-bottom-10 bg-background data-closed:animate-out data-open:animate-in fixed z-50 flex flex-col bg-clip-padding text-xs/relaxed shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-e data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-s data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -60,7 +60,7 @@ function SheetContent({
|
||||
{showCloseButton && (
|
||||
<SheetPrimitive.Close
|
||||
data-slot="sheet-close"
|
||||
render={<Button variant="ghost" className="absolute top-4 right-4" size="icon-sm" />}
|
||||
render={<Button variant="ghost" className="absolute end-4 top-4" size="icon-sm" />}
|
||||
>
|
||||
<IconX />
|
||||
<span className="sr-only">Close</span>
|
||||
|
||||
@@ -225,7 +225,7 @@ function Sidebar({
|
||||
// Adjust the padding for floating and inset variants.
|
||||
variant === "floating" || variant === "inset"
|
||||
? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]"
|
||||
: "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
|
||||
: "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-e group-data-[side=right]:border-s",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -277,11 +277,11 @@ function SidebarRail({ className, ...props }: React.ComponentProps<"button">) {
|
||||
title="Toggle Sidebar"
|
||||
className={cn(
|
||||
"hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:start-1/2 after:w-[2px] sm:flex ltr:-translate-x-1/2 rtl:-translate-x-1/2",
|
||||
"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize",
|
||||
"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
|
||||
"hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full",
|
||||
"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
|
||||
"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",
|
||||
"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize rtl:in-data-[side=left]:cursor-e-resize rtl:in-data-[side=right]:cursor-w-resize",
|
||||
"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize rtl:[[data-side=left][data-state=collapsed]_&]:cursor-w-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize rtl:[[data-side=right][data-state=collapsed]_&]:cursor-e-resize",
|
||||
"hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:start-full rtl:group-data-[collapsible=offcanvas]:-translate-x-0",
|
||||
"[[data-side=left][data-collapsible=offcanvas]_&]:-end-2",
|
||||
"[[data-side=right][data-collapsible=offcanvas]_&]:-start-2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -294,7 +294,7 @@ function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
|
||||
<main
|
||||
data-slot="sidebar-inset"
|
||||
className={cn(
|
||||
"bg-background relative flex w-full flex-1 flex-col md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2",
|
||||
"bg-background relative flex w-full flex-1 flex-col md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ms-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ms-2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -405,7 +405,7 @@ function SidebarGroupAction({
|
||||
props: mergeProps<"button">(
|
||||
{
|
||||
className: cn(
|
||||
"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute end-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
className,
|
||||
),
|
||||
},
|
||||
@@ -453,7 +453,7 @@ function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) {
|
||||
}
|
||||
|
||||
const sidebarMenuButtonVariants = cva(
|
||||
"peer/menu-button group/menu-button ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground flex w-full items-center gap-2 overflow-hidden rounded-[calc(var(--radius-sm)+2px)] p-2 text-left text-xs outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-active:font-medium [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate",
|
||||
"peer/menu-button group/menu-button ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground flex w-full items-center gap-2 overflow-hidden rounded-[calc(var(--radius-sm)+2px)] p-2 text-start text-xs outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pe-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-active:font-medium [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
@@ -542,7 +542,7 @@ function SidebarMenuAction({
|
||||
props: mergeProps<"button">(
|
||||
{
|
||||
className: cn(
|
||||
"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-[calc(var(--radius-sm)-2px)] p-0 outline-hidden transition-transform group-data-[collapsible=icon]:hidden peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 after:absolute after:-inset-2 focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute end-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-[calc(var(--radius-sm)-2px)] p-0 outline-hidden transition-transform group-data-[collapsible=icon]:hidden peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 after:absolute after:-inset-2 focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
showOnHover &&
|
||||
"peer-data-active/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 aria-expanded:opacity-100 md:opacity-0",
|
||||
className,
|
||||
@@ -564,7 +564,7 @@ function SidebarMenuBadge({ className, ...props }: React.ComponentProps<"div">)
|
||||
data-slot="sidebar-menu-badge"
|
||||
data-sidebar="menu-badge"
|
||||
className={cn(
|
||||
"text-sidebar-foreground peer-hover/menu-button:text-sidebar-accent-foreground peer-data-active/menu-button:text-sidebar-accent-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-[calc(var(--radius-sm)-2px)] px-1 text-xs font-medium tabular-nums select-none group-data-[collapsible=icon]:hidden peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1",
|
||||
"text-sidebar-foreground peer-hover/menu-button:text-sidebar-accent-foreground peer-data-active/menu-button:text-sidebar-accent-foreground pointer-events-none absolute end-1 flex h-5 min-w-5 items-center justify-center rounded-[calc(var(--radius-sm)-2px)] px-1 text-xs font-medium tabular-nums select-none group-data-[collapsible=icon]:hidden peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -611,7 +611,7 @@ function SidebarMenuSub({ className, ...props }: React.ComponentProps<"ul">) {
|
||||
data-slot="sidebar-menu-sub"
|
||||
data-sidebar="menu-sub"
|
||||
className={cn(
|
||||
"border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5 group-data-[collapsible=icon]:hidden",
|
||||
"border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-s px-2.5 py-0.5 group-data-[collapsible=icon]:hidden rtl:-translate-x-px",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -646,7 +646,7 @@ function SidebarMenuSubButton({
|
||||
props: mergeProps<"a">(
|
||||
{
|
||||
className: cn(
|
||||
"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden group-data-[collapsible=icon]:hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[size=md]:text-xs data-[size=sm]:text-xs [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden group-data-[collapsible=icon]:hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[size=md]:text-xs data-[size=sm]:text-xs rtl:translate-x-px [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
|
||||
className,
|
||||
),
|
||||
},
|
||||
|
||||
@@ -21,7 +21,7 @@ function Switch({
|
||||
>
|
||||
<SwitchPrimitive.Thumb
|
||||
data-slot="switch-thumb"
|
||||
className="bg-background dark:data-checked:bg-primary-foreground dark:data-unchecked:bg-foreground pointer-events-none block rounded-full ring-0 transition-transform group-data-[size=default]/switch:size-3.5 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-1px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-1px)] group-data-[size=default]/switch:data-unchecked:translate-x-px group-data-[size=sm]/switch:data-unchecked:translate-x-px"
|
||||
className="bg-background dark:data-checked:bg-primary-foreground dark:data-unchecked:bg-foreground pointer-events-none block rounded-full ring-0 transition-transform group-data-[size=default]/switch:size-3.5 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-1px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-1px)] group-data-[size=default]/switch:data-unchecked:translate-x-px group-data-[size=sm]/switch:data-unchecked:translate-x-px rtl:group-data-[size=default]/switch:data-checked:-translate-x-[calc(100%-1px)] rtl:group-data-[size=sm]/switch:data-checked:-translate-x-[calc(100%-1px)] rtl:group-data-[size=default]/switch:data-unchecked:-translate-x-px rtl:group-data-[size=sm]/switch:data-unchecked:-translate-x-px"
|
||||
/>
|
||||
</SwitchPrimitive.Root>
|
||||
);
|
||||
|
||||
@@ -56,7 +56,7 @@ function TableHead({ className, ...props }: React.ComponentProps<"th">) {
|
||||
<th
|
||||
data-slot="table-head"
|
||||
className={cn(
|
||||
"text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0",
|
||||
"text-foreground h-10 px-2 text-start align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pe-0",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -68,7 +68,7 @@ function TableCell({ className, ...props }: React.ComponentProps<"td">) {
|
||||
return (
|
||||
<td
|
||||
data-slot="table-cell"
|
||||
className={cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0", className)}
|
||||
className={cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pe-0", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -52,7 +52,7 @@ function TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {
|
||||
"text-foreground/60 hover:text-foreground focus-visible:border-ring focus-visible:outline-ring focus-visible:ring-ring/50 dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-xs font-medium whitespace-nowrap transition-colors group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start group-data-vertical/tabs:py-[calc(--spacing(1.25))] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent",
|
||||
"data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground",
|
||||
"after:bg-foreground after:absolute after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
|
||||
"after:bg-foreground after:absolute after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-end-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -70,7 +70,7 @@ function ToggleGroupItem({
|
||||
data-size={context.size || size}
|
||||
data-spacing={context.spacing}
|
||||
className={cn(
|
||||
"shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-md group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-md group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-md group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-md group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t",
|
||||
"shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-s-md group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-md group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-e-md group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-md group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-s-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-s group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t",
|
||||
toggleVariants({
|
||||
variant: context.variant || variant,
|
||||
size: context.size || size,
|
||||
|
||||
@@ -36,13 +36,13 @@ function TooltipContent({
|
||||
<TooltipPrimitive.Popup
|
||||
data-slot="tooltip-content"
|
||||
className={cn(
|
||||
"data-open:fade-in-0 data-open:zoom-in-95 data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-closed:fade-out-0 data-closed:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 bg-foreground text-background data-[state=delayed-open]:animate-in data-closed:animate-out data-open:animate-in z-50 w-fit max-w-xs origin-(--transform-origin) rounded-md px-3 py-1.5 text-xs **:data-[slot=kbd]:rounded-md",
|
||||
"data-open:fade-in-0 data-open:zoom-in-95 data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-closed:fade-out-0 data-closed:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-end-2 data-[side=inline-end]:slide-in-from-start-2 bg-foreground text-background data-[state=delayed-open]:animate-in data-closed:animate-out data-open:animate-in z-50 w-fit max-w-xs origin-(--transform-origin) rounded-md px-3 py-1.5 text-xs **:data-[slot=kbd]:rounded-md",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<TooltipPrimitive.Arrow className="bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5" />
|
||||
<TooltipPrimitive.Arrow className="bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] data-[side=bottom]:top-1 data-[side=inline-end]:-start-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:-end-1 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5" />
|
||||
</TooltipPrimitive.Popup>
|
||||
</TooltipPrimitive.Positioner>
|
||||
</TooltipPrimitive.Portal>
|
||||
|
||||
@@ -15,8 +15,10 @@ export function UpdateToast({ data }: { data: UpdateCheckResult | null }) {
|
||||
if (dismissedVersion === data.latestVersion) return;
|
||||
|
||||
setDismissedVersion(data.latestVersion);
|
||||
toast.info(t`Sofa v${data.latestVersion} is available`, {
|
||||
description: t`You're running v${data.currentVersion}.`,
|
||||
const latestVersion = data.latestVersion;
|
||||
const currentVersion = data.currentVersion;
|
||||
toast.info(t`Sofa v${latestVersion} is available`, {
|
||||
description: t`You're running v${currentVersion}.`,
|
||||
duration: 15_000,
|
||||
action: data.releaseUrl
|
||||
? {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { activateLocale, SUPPORTED_LOCALES, type SupportedLocale } from "@sofa/i18n";
|
||||
import { activateLocale, getDirection, SUPPORTED_LOCALES, type SupportedLocale } from "@sofa/i18n";
|
||||
|
||||
const LOCALE_STORAGE_KEY = "sofa:locale";
|
||||
|
||||
@@ -17,6 +17,7 @@ export function getPersistedLocale(): SupportedLocale {
|
||||
export function setPersistedLocale(locale: SupportedLocale): void {
|
||||
localStorage.setItem(LOCALE_STORAGE_KEY, locale);
|
||||
document.documentElement.lang = locale;
|
||||
document.documentElement.dir = getDirection(locale);
|
||||
}
|
||||
|
||||
let initialized = false;
|
||||
@@ -26,6 +27,7 @@ export async function initLocale(): Promise<void> {
|
||||
initialized = true;
|
||||
const locale = getPersistedLocale();
|
||||
document.documentElement.lang = locale;
|
||||
document.documentElement.dir = getDirection(locale);
|
||||
if (locale !== "en") {
|
||||
await activateLocale(locale);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { I18nProvider } from "@lingui/react";
|
||||
import { Trans } from "@lingui/react/macro";
|
||||
import { Trans, useLingui } from "@lingui/react/macro";
|
||||
import { IconAlertTriangle } from "@tabler/icons-react";
|
||||
import { TanStackDevtools } from "@tanstack/react-devtools";
|
||||
import type { QueryClient } from "@tanstack/react-query";
|
||||
@@ -11,11 +11,12 @@ import { MotionConfig } from "motion/react";
|
||||
|
||||
import { NavigationProgress } from "@/components/navigation-progress";
|
||||
import { SofaLogo } from "@/components/sofa-logo";
|
||||
import { DirectionProvider } from "@/components/ui/direction";
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { initLocale } from "@/lib/i18n";
|
||||
import type { orpc } from "@/lib/orpc/client";
|
||||
import { i18n } from "@sofa/i18n";
|
||||
import { getDirection, i18n } from "@sofa/i18n";
|
||||
|
||||
import "@/styles/globals.css";
|
||||
|
||||
@@ -53,13 +54,7 @@ function RootComponent() {
|
||||
<HeadContent />
|
||||
<StoreProvider>
|
||||
<I18nProvider i18n={i18n}>
|
||||
<MotionConfig reducedMotion="user">
|
||||
<NavigationProgress />
|
||||
<TooltipProvider>
|
||||
<Outlet />
|
||||
</TooltipProvider>
|
||||
<Toaster position="bottom-right" />
|
||||
</MotionConfig>
|
||||
<AppShell />
|
||||
</I18nProvider>
|
||||
</StoreProvider>
|
||||
<TanStackDevtools
|
||||
@@ -78,6 +73,23 @@ function RootComponent() {
|
||||
);
|
||||
}
|
||||
|
||||
function AppShell() {
|
||||
const { i18n: linguiI18n } = useLingui();
|
||||
const direction = getDirection(linguiI18n.locale);
|
||||
|
||||
return (
|
||||
<DirectionProvider direction={direction}>
|
||||
<MotionConfig reducedMotion="user">
|
||||
<NavigationProgress />
|
||||
<TooltipProvider>
|
||||
<Outlet />
|
||||
</TooltipProvider>
|
||||
<Toaster position={direction === "rtl" ? "bottom-left" : "bottom-right"} />
|
||||
</MotionConfig>
|
||||
</DirectionProvider>
|
||||
);
|
||||
}
|
||||
|
||||
function GlobalNotFound() {
|
||||
return (
|
||||
<div className="relative flex min-h-screen flex-col items-center justify-center overflow-hidden px-6">
|
||||
|
||||
@@ -41,7 +41,7 @@ function AppLayout() {
|
||||
<div className="bg-primary/3 pointer-events-none fixed top-1/4 left-1/2 h-[600px] w-[800px] -translate-x-1/2 -translate-y-1/2 rounded-full blur-[200px]" />
|
||||
<main
|
||||
id="main-content"
|
||||
className="relative mx-auto max-w-6xl py-6 pr-[max(1rem,env(safe-area-inset-right))] pl-[max(1rem,env(safe-area-inset-left))] sm:pr-[max(1.5rem,env(safe-area-inset-right))] sm:pl-[max(1.5rem,env(safe-area-inset-left))]"
|
||||
className="relative mx-auto max-w-6xl py-6 ps-[max(1rem,env(safe-area-inset-left))] pe-[max(1rem,env(safe-area-inset-right))] sm:ps-[max(1.5rem,env(safe-area-inset-left))] sm:pe-[max(1.5rem,env(safe-area-inset-right))]"
|
||||
>
|
||||
<Outlet />
|
||||
</main>
|
||||
|
||||
@@ -173,10 +173,10 @@ function SettingsPage() {
|
||||
</span>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<Card className="border-l-primary/30 border-l-2">
|
||||
<Card className="border-s-primary/30 border-s-2">
|
||||
<RegistrationSection />
|
||||
</Card>
|
||||
<Card className="border-l-primary/30 border-l-2">
|
||||
<Card className="border-s-primary/30 border-s-2">
|
||||
<UpdateCheckSection />
|
||||
</Card>
|
||||
</div>
|
||||
@@ -196,13 +196,13 @@ function SettingsPage() {
|
||||
</span>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<Card className="border-l-primary/30 border-l-2">
|
||||
<Card className="border-s-primary/30 border-s-2">
|
||||
<BackupSection />
|
||||
</Card>
|
||||
<Card className="border-l-primary/30 border-l-2">
|
||||
<Card className="border-s-primary/30 border-s-2">
|
||||
<BackupScheduleSection />
|
||||
</Card>
|
||||
<Card className="border-l-primary/30 border-l-2">
|
||||
<Card className="border-s-primary/30 border-s-2">
|
||||
<BackupRestoreSection />
|
||||
</Card>
|
||||
</div>
|
||||
@@ -221,7 +221,7 @@ function SettingsPage() {
|
||||
Admin only
|
||||
</span>
|
||||
</div>
|
||||
<Card className="border-l-primary/30 border-l-2">
|
||||
<Card className="border-s-primary/30 border-s-2">
|
||||
<CacheSection />
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
@@ -14,6 +14,6 @@
|
||||
},
|
||||
"types": ["bun"]
|
||||
},
|
||||
"include": ["src", "vite.config.ts"],
|
||||
"include": ["src", "vite.config.ts", "../../packages/i18n/src/po.d.ts"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"@lingui/cli": "catalog:",
|
||||
"@lingui/conf": "catalog:",
|
||||
"@lingui/format-po": "catalog:",
|
||||
"eslint-plugin-lingui": "0.11.0",
|
||||
"oxfmt": "0.41.0",
|
||||
"oxlint": "1.56.0",
|
||||
"turbo": "2.8.20",
|
||||
@@ -67,7 +68,7 @@
|
||||
"expo-system-ui": "55.0.10",
|
||||
"expo-tracking-transparency": "55.0.9",
|
||||
"expo-web-browser": "55.0.10",
|
||||
"posthog-react-native": "4.37.4",
|
||||
"posthog-react-native": "4.37.5",
|
||||
"react": "19.2.0",
|
||||
"react-dom": "19.2.0",
|
||||
"react-native": "0.83.2",
|
||||
@@ -156,7 +157,7 @@
|
||||
"@tabler/icons-react": "3.40.0",
|
||||
"@tanstack/react-hotkeys": "0.4.2",
|
||||
"@tanstack/react-query": "catalog:",
|
||||
"@tanstack/react-router": "1.167.5",
|
||||
"@tanstack/react-router": "1.168.1",
|
||||
"better-auth": "catalog:",
|
||||
"class-variance-authority": "0.7.1",
|
||||
"clsx": "2.1.1",
|
||||
@@ -165,7 +166,7 @@
|
||||
"motion": "12.38.0",
|
||||
"react": "catalog:",
|
||||
"react-dom": "catalog:",
|
||||
"shadcn": "4.0.8",
|
||||
"shadcn": "4.1.0",
|
||||
"sonner": "2.0.7",
|
||||
"tailwind-merge": "catalog:",
|
||||
"thumbhash": "catalog:",
|
||||
@@ -179,8 +180,8 @@
|
||||
"@tanstack/devtools-vite": "0.6.0",
|
||||
"@tanstack/react-devtools": "0.10.0",
|
||||
"@tanstack/react-query-devtools": "5.91.3",
|
||||
"@tanstack/react-router-devtools": "1.166.9",
|
||||
"@tanstack/router-plugin": "1.166.14",
|
||||
"@tanstack/react-router-devtools": "1.166.10",
|
||||
"@tanstack/router-plugin": "1.167.1",
|
||||
"@types/bun": "catalog:",
|
||||
"@types/node": "catalog:",
|
||||
"@types/react": "catalog:",
|
||||
@@ -315,7 +316,7 @@
|
||||
"@orpc/client": "1.13.9",
|
||||
"@orpc/contract": "1.13.9",
|
||||
"@orpc/tanstack-query": "1.13.9",
|
||||
"@tanstack/react-query": "5.91.2",
|
||||
"@tanstack/react-query": "5.91.3",
|
||||
"@types/bun": "1.3.11",
|
||||
"@types/node": "25.5.0",
|
||||
"@types/react": "19.2.14",
|
||||
@@ -641,6 +642,24 @@
|
||||
|
||||
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
|
||||
|
||||
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="],
|
||||
|
||||
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="],
|
||||
|
||||
"@eslint/config-array": ["@eslint/config-array@0.21.2", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.5" } }, "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw=="],
|
||||
|
||||
"@eslint/config-helpers": ["@eslint/config-helpers@0.4.2", "", { "dependencies": { "@eslint/core": "^0.17.0" } }, "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw=="],
|
||||
|
||||
"@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="],
|
||||
|
||||
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.5", "", { "dependencies": { "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" } }, "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg=="],
|
||||
|
||||
"@eslint/js": ["@eslint/js@9.39.4", "", {}, "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw=="],
|
||||
|
||||
"@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="],
|
||||
|
||||
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="],
|
||||
|
||||
"@expo-google-fonts/material-symbols": ["@expo-google-fonts/material-symbols@0.4.27", "", {}, "sha512-cnb3DZnWUWpezGFkJ8y4MT5f/lw6FcgDzeJzic+T+vpQHLHG1cg3SC3i1w1i8Bk4xKR4HPY3t9iIRNvtr5ml8A=="],
|
||||
|
||||
"@expo/cli": ["@expo/cli@55.0.18", "", { "dependencies": { "@expo/code-signing-certificates": "^0.0.6", "@expo/config": "~55.0.10", "@expo/config-plugins": "~55.0.7", "@expo/devcert": "^1.2.1", "@expo/env": "~2.1.1", "@expo/image-utils": "^0.8.12", "@expo/json-file": "^10.0.12", "@expo/log-box": "55.0.7", "@expo/metro": "~54.2.0", "@expo/metro-config": "~55.0.11", "@expo/osascript": "^2.4.2", "@expo/package-manager": "^1.10.3", "@expo/plist": "^0.5.2", "@expo/prebuild-config": "^55.0.10", "@expo/require-utils": "^55.0.3", "@expo/router-server": "^55.0.11", "@expo/schema-utils": "^55.0.2", "@expo/spawn-async": "^1.7.2", "@expo/ws-tunnel": "^1.0.1", "@expo/xcpretty": "^4.4.0", "@react-native/dev-middleware": "0.83.2", "accepts": "^1.3.8", "arg": "^5.0.2", "better-opn": "~3.0.2", "bplist-creator": "0.1.0", "bplist-parser": "^0.3.1", "chalk": "^4.0.0", "ci-info": "^3.3.0", "compression": "^1.7.4", "connect": "^3.7.0", "debug": "^4.3.4", "dnssd-advertise": "^1.1.3", "expo-server": "^55.0.6", "fetch-nodeshim": "^0.4.6", "getenv": "^2.0.0", "glob": "^13.0.0", "lan-network": "^0.2.0", "multitars": "^0.2.3", "node-forge": "^1.3.3", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", "picomatch": "^4.0.3", "pretty-format": "^29.7.0", "progress": "^2.0.3", "prompts": "^2.3.2", "resolve-from": "^5.0.0", "semver": "^7.6.0", "send": "^0.19.0", "slugify": "^1.3.4", "source-map-support": "~0.5.21", "stacktrace-parser": "^0.1.10", "structured-headers": "^0.4.1", "terminal-link": "^2.1.1", "toqr": "^0.1.1", "wrap-ansi": "^7.0.0", "ws": "^8.12.1", "zod": "^3.25.76" }, "peerDependencies": { "expo": "*", "expo-router": "*", "react-native": "*" }, "optionalPeers": ["expo-router", "react-native"], "bin": { "expo-internal": "build/bin/cli" } }, "sha512-3sJwu8KvCvQIXBnhUlHgLBZBe+ZK4Da9R5rgI4znaowJavYWMqzRClLzyE6Kri66WVoMX7Q4HUVIh8prRlO0XA=="],
|
||||
@@ -745,6 +764,14 @@
|
||||
|
||||
"@hono/zod-validator": ["@hono/zod-validator@0.7.6", "", { "peerDependencies": { "hono": ">=3.9.0", "zod": "^3.25.0 || ^4.0.0" } }, "sha512-Io1B6d011Gj1KknV4rXYz4le5+5EubcWEU/speUjuw9XMMIaP3n78yXLhjd2A3PXaXaUwEAluOiAyLqhBEJgsw=="],
|
||||
|
||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||
|
||||
"@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
|
||||
|
||||
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
|
||||
|
||||
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
|
||||
|
||||
"@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="],
|
||||
|
||||
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="],
|
||||
@@ -1023,7 +1050,7 @@
|
||||
|
||||
"@player.style/sutro": ["@player.style/sutro@0.2.1", "", { "peerDependencies": { "media-chrome": ">=1.0.0" } }, "sha512-vWtFAdu4z3+1HcDPAriX+41q+bYSOgM898XO4TxEgoNyeaBq/Aoz2cRgWFpsWaK368+n7uWCbO5n2vAszN5fhw=="],
|
||||
|
||||
"@posthog/core": ["@posthog/core@1.24.0", "", { "dependencies": { "cross-spawn": "^7.0.6" } }, "sha512-Wkp9mgNfgdf6+G4C1VMKakm2RXKQFf4bb5/CPQRAjpqv9l6BY36zZrD1+X5Y2XIAzZqbMKRxsDu3V1r6uKu7/A=="],
|
||||
"@posthog/core": ["@posthog/core@1.24.1", "", { "dependencies": { "cross-spawn": "^7.0.6" } }, "sha512-e8AciAnc6MRFws89ux8lJKFAaI03yEon0ASDoUO7yS91FVqbUGXYekObUUR3LHplcg+pmyiJBI0jolY0SFbGRA=="],
|
||||
|
||||
"@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
|
||||
|
||||
@@ -1275,25 +1302,25 @@
|
||||
|
||||
"@tanstack/react-hotkeys": ["@tanstack/react-hotkeys@0.4.2", "", { "dependencies": { "@tanstack/hotkeys": "0.4.2", "@tanstack/react-store": "^0.9.2" }, "peerDependencies": { "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-7AMAmX+l1k0tHCaDgT5lHHF0cmtrmK0aaKxR6DliSdAVVjfmyraPZQapLwpyNKoTKNYIROj+2Wg+OvWYP52Oog=="],
|
||||
|
||||
"@tanstack/react-query": ["@tanstack/react-query@5.91.2", "", { "dependencies": { "@tanstack/query-core": "5.91.2" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-GClLPzbM57iFXv+FlvOUL56XVe00PxuTaVEyj1zAObhRiKF008J5vedmaq7O6ehs+VmPHe8+PUQhMuEyv8d9wQ=="],
|
||||
"@tanstack/react-query": ["@tanstack/react-query@5.91.3", "", { "dependencies": { "@tanstack/query-core": "5.91.2" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-D8jsCexxS5crZxAeiH6VlLHOUzmHOxeW5c11y8rZu0c34u/cy18hUKQXA/gn1Ila3ZIFzP+Pzv76YnliC0EtZQ=="],
|
||||
|
||||
"@tanstack/react-query-devtools": ["@tanstack/react-query-devtools@5.91.3", "", { "dependencies": { "@tanstack/query-devtools": "5.93.0" }, "peerDependencies": { "@tanstack/react-query": "^5.90.20", "react": "^18 || ^19" } }, "sha512-nlahjMtd/J1h7IzOOfqeyDh5LNfG0eULwlltPEonYy0QL+nqrBB+nyzJfULV+moL7sZyxc2sHdNJki+vLA9BSA=="],
|
||||
|
||||
"@tanstack/react-query-persist-client": ["@tanstack/react-query-persist-client@5.90.27", "", { "dependencies": { "@tanstack/query-persist-client-core": "5.92.4" }, "peerDependencies": { "@tanstack/react-query": "^5.91.2", "react": "^18 || ^19" } }, "sha512-rKiCZ2C0kzmyDoLfrPHz2UdEDKHo/oXkKVRbhgtHya/bWH6jWDFX5cSFc1SLB33FDrgR8uOG1MwVohBrI4+F8A=="],
|
||||
|
||||
"@tanstack/react-router": ["@tanstack/react-router@1.167.5", "", { "dependencies": { "@tanstack/history": "1.161.6", "@tanstack/react-store": "^0.9.1", "@tanstack/router-core": "1.167.5", "isbot": "^5.1.22", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-s1nP6l/7BYZfSwhoNbB7/rUmZ07q/AvkmhBoiDQl3tgy5dpb9Q1qjtIapYdvCOrao1aA/QCaWqxcbGc2Ct1bvQ=="],
|
||||
"@tanstack/react-router": ["@tanstack/react-router@1.168.1", "", { "dependencies": { "@tanstack/history": "1.161.6", "@tanstack/react-store": "^0.9.2", "@tanstack/router-core": "1.168.1", "isbot": "^5.1.22", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-DsQzbfwcr2Xugqs4G8yShUO9hVQ/tbWhIiLNJSxmZZOgaZCB3JP+ngN1EJBYZz+JBQdvyVHfiEsPXy0P1h3yVA=="],
|
||||
|
||||
"@tanstack/react-router-devtools": ["@tanstack/react-router-devtools@1.166.9", "", { "dependencies": { "@tanstack/router-devtools-core": "1.166.9" }, "peerDependencies": { "@tanstack/react-router": "^1.167.2", "@tanstack/router-core": "^1.167.2", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" }, "optionalPeers": ["@tanstack/router-core"] }, "sha512-O49eZmaeEKB5YnKH/qd61AbxV/lW8ICm4stfZ4GNQNpzQQ6rhPIB0p3PMZDIgX+6DoMivdNvLRmXAOOpzpIpDg=="],
|
||||
"@tanstack/react-router-devtools": ["@tanstack/react-router-devtools@1.166.10", "", { "dependencies": { "@tanstack/router-devtools-core": "1.167.0" }, "peerDependencies": { "@tanstack/react-router": "^1.168.0", "@tanstack/router-core": "^1.168.0", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" }, "optionalPeers": ["@tanstack/router-core"] }, "sha512-+C4doh9D+ag8yA4WjR3Og4RGvuwvwwqN0j67Pg+Hu1I1ebZAKowtUREH8iT4acUxgtH6hzt8pAuzMVskdLc4SQ=="],
|
||||
|
||||
"@tanstack/react-store": ["@tanstack/react-store@0.9.2", "", { "dependencies": { "@tanstack/store": "0.9.2", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Vt5usJE5sHG/cMechQfmwvwne6ktGCELe89Lmvoxe3LKRoFrhPa8OCKWs0NliG8HTJElEIj7PLtaBQIcux5pAQ=="],
|
||||
|
||||
"@tanstack/router-core": ["@tanstack/router-core@1.167.5", "", { "dependencies": { "@tanstack/history": "1.161.6", "@tanstack/store": "^0.9.1", "cookie-es": "^2.0.0", "seroval": "^1.4.2", "seroval-plugins": "^1.4.2", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "bin": { "intent": "bin/intent.js" } }, "sha512-8fRgJ0zNJf77R4grCaJQ5Imatjyc4YT5v8rlsPkYYYeUlcFNLbuFRhLlAMdND9gRUMznpnbRDXngpTPgx2K7HQ=="],
|
||||
"@tanstack/router-core": ["@tanstack/router-core@1.168.1", "", { "dependencies": { "@tanstack/history": "1.161.6", "cookie-es": "^2.0.0", "seroval": "^1.4.2", "seroval-plugins": "^1.4.2", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "bin": { "intent": "bin/intent.js" } }, "sha512-RtpshTLZsMOkwW7rI52WFWGZSSfMAyDR1zWP9kVm91UX28gedc+LXih1CTP6TchS+TvxK4q8oW7ApMTvnpiY1w=="],
|
||||
|
||||
"@tanstack/router-devtools-core": ["@tanstack/router-devtools-core@1.166.9", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16", "tiny-invariant": "^1.3.3" }, "peerDependencies": { "@tanstack/router-core": "^1.167.2", "csstype": "^3.0.10" }, "optionalPeers": ["csstype"] }, "sha512-PNlA7GmOUX9wY7LUG709Pk3Lg33dfHBztQwzjzrOiOsuf4ggp2R6bwarF8nYGNjG79z/MaB5PN+5yvkCVk8jGw=="],
|
||||
"@tanstack/router-devtools-core": ["@tanstack/router-devtools-core@1.167.0", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16", "tiny-invariant": "^1.3.3" }, "peerDependencies": { "@tanstack/router-core": "^1.168.0", "csstype": "^3.0.10" }, "optionalPeers": ["csstype"] }, "sha512-icgcpE7CQqOzZs4hbFfmICvwk4k7R8ErhUUuUHIKbAYioowQWKm1F3oJhkv6CtoTiofzplUrv9Jy8KE+U/sTKA=="],
|
||||
|
||||
"@tanstack/router-generator": ["@tanstack/router-generator@1.166.13", "", { "dependencies": { "@tanstack/router-core": "1.167.5", "@tanstack/router-utils": "1.161.6", "@tanstack/virtual-file-routes": "1.161.7", "prettier": "^3.5.0", "recast": "^0.23.11", "source-map": "^0.7.4", "tsx": "^4.19.2", "zod": "^3.24.2" } }, "sha512-ALxSs6OzimiSgpOuIm+AXmc7eUx/oGPwSPpdQbpZ/kX7WHRh6qM7lv8DAN0K3jWcBpzF8eeOIdryWryX8gH+Yg=="],
|
||||
"@tanstack/router-generator": ["@tanstack/router-generator@1.166.15", "", { "dependencies": { "@tanstack/router-core": "1.168.1", "@tanstack/router-utils": "1.161.6", "@tanstack/virtual-file-routes": "1.161.7", "prettier": "^3.5.0", "recast": "^0.23.11", "source-map": "^0.7.4", "tsx": "^4.19.2", "zod": "^3.24.2" } }, "sha512-W8ybCktgN/45fc7ohWJKAyG5Al1pnTg7V8Z6RiG8NkSrN7Igo4BqanUmXULnhnkdCID5XhMbkhP84r2hzkXbPw=="],
|
||||
|
||||
"@tanstack/router-plugin": ["@tanstack/router-plugin@1.166.14", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@tanstack/router-core": "1.167.5", "@tanstack/router-generator": "1.166.13", "@tanstack/router-utils": "1.161.6", "@tanstack/virtual-file-routes": "1.161.7", "chokidar": "^3.6.0", "unplugin": "^2.1.2", "zod": "^3.24.2" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2", "@tanstack/react-router": "^1.167.5", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0", "vite-plugin-solid": "^2.11.10", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"], "bin": { "intent": "bin/intent.js" } }, "sha512-hypyj0qlsAbJf60/glmVYqSVwnRB4hKRrMCUsSXjrPdO2g6gs3z6xHmcWsHQ831C4G9+bSFEK9Uy5EjO3A4THQ=="],
|
||||
"@tanstack/router-plugin": ["@tanstack/router-plugin@1.167.1", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@tanstack/router-core": "1.168.1", "@tanstack/router-generator": "1.166.15", "@tanstack/router-utils": "1.161.6", "@tanstack/virtual-file-routes": "1.161.7", "chokidar": "^3.6.0", "unplugin": "^2.1.2", "zod": "^3.24.2" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2", "@tanstack/react-router": "^1.168.1", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0", "vite-plugin-solid": "^2.11.10", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"], "bin": { "intent": "bin/intent.js" } }, "sha512-bPDdwvpoznjyCUWd+w2ss+y9GemXvF3R6Zzi36rxiWUGwuqDhQbvs1fWkjsx2oBqXSG8vkF74yFdUxFEX90o4g=="],
|
||||
|
||||
"@tanstack/router-utils": ["@tanstack/router-utils@1.161.6", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/generator": "^7.28.5", "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "ansis": "^4.1.0", "babel-dead-code-elimination": "^1.0.12", "diff": "^8.0.2", "pathe": "^2.0.3", "tinyglobby": "^0.2.15" } }, "sha512-nRcYw+w2OEgK6VfjirYvGyPLOK+tZQz1jkYcmH5AjMamQ9PycnlxZF2aEZtPpNoUsaceX2bHptn6Ub5hGXqNvw=="],
|
||||
|
||||
@@ -1333,6 +1360,8 @@
|
||||
|
||||
"@types/bun": ["@types/bun@1.3.11", "", { "dependencies": { "bun-types": "1.3.11" } }, "sha512-5vPne5QvtpjGpsGYXiFyycfpDF2ECyPcTSsFBMa0fraoxiQyMJ3SmuQIGhzPg2WJuWxVBoxWJ2kClYTcw/4fAg=="],
|
||||
|
||||
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
||||
|
||||
"@types/graceful-fs": ["@types/graceful-fs@4.1.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ=="],
|
||||
|
||||
"@types/hammerjs": ["@types/hammerjs@2.0.46", "", {}, "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw=="],
|
||||
@@ -1343,6 +1372,8 @@
|
||||
|
||||
"@types/istanbul-reports": ["@types/istanbul-reports@3.0.4", "", { "dependencies": { "@types/istanbul-lib-report": "*" } }, "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ=="],
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/mssql": ["@types/mssql@9.1.9", "", { "dependencies": { "@types/node": "*", "tarn": "^3.0.1", "tedious": "*" } }, "sha512-P0nCgw6vzY23UxZMnbI4N7fnLGANt4LI4yvxze1paPj+LuN28cFv5EI+QidP8udnId/BKhkcRhm/BleNsjK65A=="],
|
||||
|
||||
"@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="],
|
||||
@@ -1367,6 +1398,20 @@
|
||||
|
||||
"@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="],
|
||||
|
||||
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.57.1", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.57.1", "@typescript-eslint/types": "^8.57.1", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg=="],
|
||||
|
||||
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.57.1", "", { "dependencies": { "@typescript-eslint/types": "8.57.1", "@typescript-eslint/visitor-keys": "8.57.1" } }, "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg=="],
|
||||
|
||||
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.57.1", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg=="],
|
||||
|
||||
"@typescript-eslint/types": ["@typescript-eslint/types@8.57.1", "", {}, "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.57.1", "", { "dependencies": { "@typescript-eslint/project-service": "8.57.1", "@typescript-eslint/tsconfig-utils": "8.57.1", "@typescript-eslint/types": "8.57.1", "@typescript-eslint/visitor-keys": "8.57.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g=="],
|
||||
|
||||
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.57.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.57.1", "@typescript-eslint/types": "8.57.1", "@typescript-eslint/typescript-estree": "8.57.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ=="],
|
||||
|
||||
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.57.1", "", { "dependencies": { "@typescript-eslint/types": "8.57.1", "eslint-visitor-keys": "^5.0.0" } }, "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A=="],
|
||||
|
||||
"@typespec/ts-http-runtime": ["@typespec/ts-http-runtime@0.3.4", "", { "dependencies": { "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "tslib": "^2.6.2" } }, "sha512-CI0NhTrz4EBaa0U+HaaUZrJhPoso8sG7ZFya8uQoBA57fjzrjRSv87ekCjLZOFExN+gXE/z0xuN2QfH4H2HrLQ=="],
|
||||
|
||||
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
|
||||
@@ -1405,11 +1450,13 @@
|
||||
|
||||
"acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="],
|
||||
|
||||
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
|
||||
|
||||
"adm-zip": ["adm-zip@0.5.16", "", {}, "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ=="],
|
||||
|
||||
"agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
|
||||
|
||||
"ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="],
|
||||
"ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="],
|
||||
|
||||
"ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="],
|
||||
|
||||
@@ -1633,6 +1680,8 @@
|
||||
|
||||
"dedent": ["dedent@1.7.2", "", { "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, "optionalPeers": ["babel-plugin-macros"] }, "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA=="],
|
||||
|
||||
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
||||
|
||||
"deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
|
||||
|
||||
"default-browser": ["default-browser@5.5.0", "", { "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" } }, "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw=="],
|
||||
@@ -1711,10 +1760,28 @@
|
||||
|
||||
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
||||
|
||||
"eslint": ["eslint@9.39.4", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.5", "@eslint/js": "9.39.4", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ=="],
|
||||
|
||||
"eslint-plugin-lingui": ["eslint-plugin-lingui@0.11.0", "", { "dependencies": { "@typescript-eslint/utils": "^8.0.0", "micromatch": "^4.0.0" }, "peerDependencies": { "eslint": "^8.37.0 || ^9.0.0" } }, "sha512-O2Ixoapt5fa4VKZJgXhVwb6BHnzByIUDNMfZOhHWGMYk40GfGCho4MUfspLVrHAFLimgBPKXtCcJ8GC4YNZmfg=="],
|
||||
|
||||
"eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
|
||||
|
||||
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="],
|
||||
|
||||
"esm": ["esm@3.2.25", "", {}, "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA=="],
|
||||
|
||||
"espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
|
||||
|
||||
"esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
|
||||
|
||||
"esquery": ["esquery@1.7.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g=="],
|
||||
|
||||
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
|
||||
|
||||
"estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
|
||||
|
||||
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
|
||||
|
||||
"etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
|
||||
|
||||
"event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="],
|
||||
@@ -1815,6 +1882,8 @@
|
||||
|
||||
"fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
|
||||
|
||||
"fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
|
||||
|
||||
"fast-safe-stringify": ["fast-safe-stringify@2.1.1", "", {}, "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="],
|
||||
|
||||
"fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="],
|
||||
@@ -1833,6 +1902,8 @@
|
||||
|
||||
"figures": ["figures@6.1.0", "", { "dependencies": { "is-unicode-supported": "^2.0.0" } }, "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg=="],
|
||||
|
||||
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
|
||||
|
||||
"file-type": ["file-type@16.5.4", "", { "dependencies": { "readable-web-to-node-stream": "^3.0.0", "strtok3": "^6.2.4", "token-types": "^4.1.1" } }, "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw=="],
|
||||
|
||||
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
||||
@@ -1841,7 +1912,11 @@
|
||||
|
||||
"finalhandler": ["finalhandler@1.1.2", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "~2.3.0", "parseurl": "~1.3.3", "statuses": "~1.5.0", "unpipe": "~1.0.0" } }, "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA=="],
|
||||
|
||||
"find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="],
|
||||
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
|
||||
|
||||
"flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
|
||||
|
||||
"flatted": ["flatted@3.4.2", "", {}, "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA=="],
|
||||
|
||||
"flow-enums-runtime": ["flow-enums-runtime@0.0.6", "", {}, "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw=="],
|
||||
|
||||
@@ -1895,6 +1970,8 @@
|
||||
|
||||
"glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||
|
||||
"globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||
|
||||
"goober": ["goober@2.1.18", "", { "peerDependencies": { "csstype": "^3.0.10" } }, "sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw=="],
|
||||
|
||||
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
|
||||
@@ -2053,12 +2130,16 @@
|
||||
|
||||
"jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
|
||||
|
||||
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
|
||||
|
||||
"json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="],
|
||||
|
||||
"json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
|
||||
"json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
|
||||
|
||||
"json-schema-typed": ["json-schema-typed@8.0.2", "", {}, "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA=="],
|
||||
|
||||
"json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
|
||||
|
||||
"json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
|
||||
|
||||
"jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="],
|
||||
@@ -2069,6 +2150,8 @@
|
||||
|
||||
"jws": ["jws@4.0.1", "", { "dependencies": { "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA=="],
|
||||
|
||||
"keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
|
||||
|
||||
"kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
|
||||
|
||||
"kysely": ["kysely@0.28.13", "", {}, "sha512-jCkYDvlfzOyHaVsrvR4vnNZxG30oNv2jbbFBjTQAUG8n0h07HW0sZJHk4KAQIRyu9ay+Rg+L8qGa3lwt8Gve9w=="],
|
||||
@@ -2079,6 +2162,8 @@
|
||||
|
||||
"leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="],
|
||||
|
||||
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
||||
|
||||
"lighthouse-logger": ["lighthouse-logger@1.4.2", "", { "dependencies": { "debug": "^2.6.9", "marky": "^1.2.2" } }, "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g=="],
|
||||
|
||||
"lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="],
|
||||
@@ -2107,7 +2192,7 @@
|
||||
|
||||
"lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
|
||||
|
||||
"locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="],
|
||||
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
||||
|
||||
"lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="],
|
||||
|
||||
@@ -2123,6 +2208,8 @@
|
||||
|
||||
"lodash.isstring": ["lodash.isstring@4.0.1", "", {}, "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="],
|
||||
|
||||
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
|
||||
|
||||
"lodash.once": ["lodash.once@4.1.1", "", {}, "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="],
|
||||
|
||||
"lodash.throttle": ["lodash.throttle@4.1.1", "", {}, "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="],
|
||||
@@ -2235,6 +2322,8 @@
|
||||
|
||||
"native-duplexpair": ["native-duplexpair@1.0.0", "", {}, "sha512-E7QQoM+3jvNtlmyfqRZ0/U75VFgCls+fSkbml2MpgWkWyz3ox8Y58gNhfuziuQYGNNQAbFZJQck55LHCnCK6CA=="],
|
||||
|
||||
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
||||
|
||||
"negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="],
|
||||
|
||||
"node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="],
|
||||
@@ -2289,6 +2378,8 @@
|
||||
|
||||
"openapi-typescript-helpers": ["openapi-typescript-helpers@0.1.0", "", {}, "sha512-OKTGPthhivLw/fHz6c3OPtg72vi86qaMlqbJuVJ23qOvQ+53uw1n7HdmkJFibloF7QEjDrDkzJiOJuockM/ljw=="],
|
||||
|
||||
"optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
|
||||
|
||||
"ora": ["ora@5.4.1", "", { "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", "cli-cursor": "^3.1.0", "cli-spinners": "^2.5.0", "is-interactive": "^1.0.0", "is-unicode-supported": "^0.1.0", "log-symbols": "^4.1.0", "strip-ansi": "^6.0.0", "wcwidth": "^1.0.1" } }, "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ=="],
|
||||
|
||||
"outvariant": ["outvariant@1.4.3", "", {}, "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA=="],
|
||||
@@ -2297,9 +2388,9 @@
|
||||
|
||||
"oxlint": ["oxlint@1.56.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.56.0", "@oxlint/binding-android-arm64": "1.56.0", "@oxlint/binding-darwin-arm64": "1.56.0", "@oxlint/binding-darwin-x64": "1.56.0", "@oxlint/binding-freebsd-x64": "1.56.0", "@oxlint/binding-linux-arm-gnueabihf": "1.56.0", "@oxlint/binding-linux-arm-musleabihf": "1.56.0", "@oxlint/binding-linux-arm64-gnu": "1.56.0", "@oxlint/binding-linux-arm64-musl": "1.56.0", "@oxlint/binding-linux-ppc64-gnu": "1.56.0", "@oxlint/binding-linux-riscv64-gnu": "1.56.0", "@oxlint/binding-linux-riscv64-musl": "1.56.0", "@oxlint/binding-linux-s390x-gnu": "1.56.0", "@oxlint/binding-linux-x64-gnu": "1.56.0", "@oxlint/binding-linux-x64-musl": "1.56.0", "@oxlint/binding-openharmony-arm64": "1.56.0", "@oxlint/binding-win32-arm64-msvc": "1.56.0", "@oxlint/binding-win32-ia32-msvc": "1.56.0", "@oxlint/binding-win32-x64-msvc": "1.56.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.15.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-Q+5Mj5PVaH/R6/fhMMFzw4dT+KPB+kQW4kaL8FOIq7tfhlnEVp6+3lcWqFruuTNlUo9srZUW3qH7Id4pskeR6g=="],
|
||||
|
||||
"p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="],
|
||||
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
||||
|
||||
"p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
|
||||
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
|
||||
|
||||
"p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="],
|
||||
|
||||
@@ -2365,10 +2456,12 @@
|
||||
|
||||
"postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
|
||||
|
||||
"posthog-react-native": ["posthog-react-native@4.37.4", "", { "dependencies": { "@posthog/core": "1.24.0" }, "peerDependencies": { "@react-native-async-storage/async-storage": ">=1.0.0", "@react-navigation/native": ">= 5.0.0", "expo-application": ">= 4.0.0", "expo-device": ">= 4.0.0", "expo-file-system": ">= 13.0.0", "expo-localization": ">= 11.0.0", "posthog-react-native-session-replay": ">= 1.5.0", "react-native-device-info": ">= 10.0.0", "react-native-localize": ">= 3.0.0", "react-native-navigation": ">= 6.0.0", "react-native-safe-area-context": ">= 4.0.0", "react-native-svg": ">= 15.0.0" }, "optionalPeers": ["@react-native-async-storage/async-storage", "@react-navigation/native", "expo-application", "expo-device", "expo-file-system", "expo-localization", "posthog-react-native-session-replay", "react-native-device-info", "react-native-localize", "react-native-navigation", "react-native-safe-area-context"] }, "sha512-0/zHFZ1bnIlo0mDl2JvuS7EgDNs2XTol1kbR6M0R9OFn9aH7q2UVA0c9ixmIqYntKrSW7ava9TxCOO5QNIE+fw=="],
|
||||
"posthog-react-native": ["posthog-react-native@4.37.5", "", { "dependencies": { "@posthog/core": "1.24.1" }, "peerDependencies": { "@react-native-async-storage/async-storage": ">=1.0.0", "@react-navigation/native": ">= 5.0.0", "expo-application": ">= 4.0.0", "expo-device": ">= 4.0.0", "expo-file-system": ">= 13.0.0", "expo-localization": ">= 11.0.0", "posthog-react-native-session-replay": ">= 1.5.0", "react-native-device-info": ">= 10.0.0", "react-native-localize": ">= 3.0.0", "react-native-navigation": ">= 6.0.0", "react-native-safe-area-context": ">= 4.0.0", "react-native-svg": ">= 15.0.0" }, "optionalPeers": ["@react-native-async-storage/async-storage", "@react-navigation/native", "expo-application", "expo-device", "expo-file-system", "expo-localization", "posthog-react-native-session-replay", "react-native-device-info", "react-native-localize", "react-native-navigation", "react-native-safe-area-context"] }, "sha512-5q5cFcu7541nXrsoWaRtCbmYrbd0IqYPm8FhRO3uMquPj2900+2777Xhwi89HuXLpq5XsrPEr2hR/8SL1MZttA=="],
|
||||
|
||||
"powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="],
|
||||
|
||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||
|
||||
"prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="],
|
||||
|
||||
"pretty-format": ["pretty-format@29.7.0", "", { "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } }, "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ=="],
|
||||
@@ -2547,7 +2640,7 @@
|
||||
|
||||
"sf-symbols-typescript": ["sf-symbols-typescript@2.2.0", "", {}, "sha512-TPbeg0b7ylrswdGCji8FRGFAKuqbpQlLbL8SOle3j1iHSs5Ob5mhvMAxWN2UItOjgALAB5Zp3fmMfj8mbWvXKw=="],
|
||||
|
||||
"shadcn": ["shadcn@4.0.8", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/plugin-transform-typescript": "^7.28.0", "@babel/preset-typescript": "^7.27.1", "@dotenvx/dotenvx": "^1.48.4", "@modelcontextprotocol/sdk": "^1.26.0", "@types/validate-npm-package-name": "^4.0.2", "browserslist": "^4.26.2", "commander": "^14.0.0", "cosmiconfig": "^9.0.0", "dedent": "^1.6.0", "deepmerge": "^4.3.1", "diff": "^8.0.2", "execa": "^9.6.0", "fast-glob": "^3.3.3", "fs-extra": "^11.3.1", "fuzzysort": "^3.1.0", "https-proxy-agent": "^7.0.6", "kleur": "^4.1.5", "msw": "^2.10.4", "node-fetch": "^3.3.2", "open": "^11.0.0", "ora": "^8.2.0", "postcss": "^8.5.6", "postcss-selector-parser": "^7.1.0", "prompts": "^2.4.2", "recast": "^0.23.11", "stringify-object": "^5.0.0", "tailwind-merge": "^3.0.1", "ts-morph": "^26.0.0", "tsconfig-paths": "^4.2.0", "validate-npm-package-name": "^7.0.1", "zod": "^3.24.1", "zod-to-json-schema": "^3.24.6" }, "bin": { "shadcn": "dist/index.js" } }, "sha512-DVAyeo95TQ/OvaHugLm5V0Dqz3al+dnoP3mZdWWxKJ33IYG1jN5B3sGZyNaYsfzm7JsWokfksSzDl83LnmMing=="],
|
||||
"shadcn": ["shadcn@4.1.0", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/plugin-transform-typescript": "^7.28.0", "@babel/preset-typescript": "^7.27.1", "@dotenvx/dotenvx": "^1.48.4", "@modelcontextprotocol/sdk": "^1.26.0", "@types/validate-npm-package-name": "^4.0.2", "browserslist": "^4.26.2", "commander": "^14.0.0", "cosmiconfig": "^9.0.0", "dedent": "^1.6.0", "deepmerge": "^4.3.1", "diff": "^8.0.2", "execa": "^9.6.0", "fast-glob": "^3.3.3", "fs-extra": "^11.3.1", "fuzzysort": "^3.1.0", "https-proxy-agent": "^7.0.6", "kleur": "^4.1.5", "msw": "^2.10.4", "node-fetch": "^3.3.2", "open": "^11.0.0", "ora": "^8.2.0", "postcss": "^8.5.6", "postcss-selector-parser": "^7.1.0", "prompts": "^2.4.2", "recast": "^0.23.11", "stringify-object": "^5.0.0", "tailwind-merge": "^3.0.1", "ts-morph": "^26.0.0", "tsconfig-paths": "^4.2.0", "validate-npm-package-name": "^7.0.1", "zod": "^3.24.1", "zod-to-json-schema": "^3.24.6" }, "bin": { "shadcn": "dist/index.js" } }, "sha512-3zETJ+0Ezj69FS6RL0HOkLKKAR5yXisXx1iISJdfLQfrUqj/VIQlanQi1Ukk+9OE+XHZVj4FQNTBSfbr2CyCYg=="],
|
||||
|
||||
"shallowequal": ["shallowequal@1.1.0", "", {}, "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="],
|
||||
|
||||
@@ -2699,6 +2792,8 @@
|
||||
|
||||
"tr46": ["tr46@5.1.1", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="],
|
||||
|
||||
"ts-api-utils": ["ts-api-utils@2.5.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA=="],
|
||||
|
||||
"ts-morph": ["ts-morph@26.0.0", "", { "dependencies": { "@ts-morph/common": "~0.27.0", "code-block-writer": "^13.0.3" } }, "sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug=="],
|
||||
|
||||
"tsconfig-paths": ["tsconfig-paths@4.2.0", "", { "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg=="],
|
||||
@@ -2711,6 +2806,8 @@
|
||||
|
||||
"tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="],
|
||||
|
||||
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
||||
|
||||
"type-detect": ["type-detect@4.0.8", "", {}, "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="],
|
||||
|
||||
"type-fest": ["type-fest@5.5.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g=="],
|
||||
@@ -2745,6 +2842,8 @@
|
||||
|
||||
"update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
|
||||
|
||||
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
||||
|
||||
"use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="],
|
||||
|
||||
"use-latest-callback": ["use-latest-callback@0.2.6", "", { "peerDependencies": { "react": ">=16.8" } }, "sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg=="],
|
||||
@@ -2793,6 +2892,8 @@
|
||||
|
||||
"wildcard-match": ["wildcard-match@5.1.4", "", {}, "sha512-wldeCaczs8XXq7hj+5d/F38JE2r7EXgb6WQDM84RVwxy81T/sxB5e9+uZLK9Q9oNz1mlvjut+QtvgaOQFPVq/g=="],
|
||||
|
||||
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
|
||||
|
||||
"wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
|
||||
|
||||
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
|
||||
@@ -2819,6 +2920,8 @@
|
||||
|
||||
"yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
|
||||
|
||||
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
||||
|
||||
"yoctocolors": ["yoctocolors@2.1.2", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="],
|
||||
|
||||
"yoctocolors-cjs": ["yoctocolors-cjs@2.1.3", "", {}, "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw=="],
|
||||
@@ -2851,6 +2954,14 @@
|
||||
|
||||
"@ecies/ciphers/@noble/ciphers": ["@noble/ciphers@1.3.0", "", {}, "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw=="],
|
||||
|
||||
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
||||
|
||||
"@eslint/config-array/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
|
||||
|
||||
"@eslint/eslintrc/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
|
||||
|
||||
"@eslint/eslintrc/strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
|
||||
|
||||
"@expo/cli/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
"@expo/cli/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
|
||||
@@ -2903,12 +3014,16 @@
|
||||
|
||||
"@istanbuljs/load-nyc-config/camelcase": ["camelcase@5.3.1", "", {}, "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="],
|
||||
|
||||
"@istanbuljs/load-nyc-config/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="],
|
||||
|
||||
"@istanbuljs/load-nyc-config/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="],
|
||||
|
||||
"@jest/transform/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
"@jest/types/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
"@modelcontextprotocol/sdk/ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="],
|
||||
|
||||
"@noble/curves/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
|
||||
|
||||
"@orpc/zod/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
|
||||
@@ -2979,6 +3094,10 @@
|
||||
|
||||
"@tanstack/router-plugin/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||
|
||||
"@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="],
|
||||
|
||||
"ajv-formats/ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="],
|
||||
|
||||
"ansi-escapes/type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="],
|
||||
|
||||
"anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||
@@ -3013,6 +3132,12 @@
|
||||
|
||||
"eciesjs/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
|
||||
|
||||
"eslint/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
"eslint/glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||
|
||||
"eslint/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
|
||||
|
||||
"expo-modules-autolinking/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
"expo-modules-autolinking/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
|
||||
@@ -3197,6 +3322,10 @@
|
||||
|
||||
"@dotenvx/dotenvx/execa/strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="],
|
||||
|
||||
"@eslint/config-array/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
||||
|
||||
"@eslint/eslintrc/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
||||
|
||||
"@expo/cli/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"@expo/cli/ora/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="],
|
||||
@@ -3259,12 +3388,16 @@
|
||||
|
||||
"@inquirer/core/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"@istanbuljs/load-nyc-config/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="],
|
||||
|
||||
"@istanbuljs/load-nyc-config/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
|
||||
|
||||
"@jest/transform/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"@jest/types/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"@modelcontextprotocol/sdk/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
|
||||
|
||||
"@radix-ui/react-arrow/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
||||
|
||||
"@radix-ui/react-context-menu/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
||||
@@ -3341,6 +3474,8 @@
|
||||
|
||||
"@tanstack/router-plugin/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
|
||||
|
||||
"ajv-formats/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
|
||||
|
||||
"babel-jest/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"babel-plugin-syntax-hermes-parser/hermes-parser/hermes-estree": ["hermes-estree@0.32.0", "", {}, "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ=="],
|
||||
@@ -3361,6 +3496,10 @@
|
||||
|
||||
"cross-spawn/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
||||
|
||||
"eslint/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"eslint/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
||||
|
||||
"expo-modules-autolinking/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"express/accepts/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
|
||||
@@ -3499,6 +3638,10 @@
|
||||
|
||||
"vite/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="],
|
||||
|
||||
"@eslint/config-array/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||
|
||||
"@eslint/eslintrc/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||
|
||||
"@expo/cli/ora/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="],
|
||||
|
||||
"@expo/cli/ora/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="],
|
||||
@@ -3519,6 +3662,8 @@
|
||||
|
||||
"@expo/package-manager/ora/strip-ansi/ansi-regex": ["ansi-regex@4.1.1", "", {}, "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g=="],
|
||||
|
||||
"@istanbuljs/load-nyc-config/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
|
||||
|
||||
"@istanbuljs/load-nyc-config/js-yaml/argparse/sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="],
|
||||
|
||||
"@react-native/codegen/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
||||
@@ -3557,6 +3702,8 @@
|
||||
|
||||
"@tanstack/router-plugin/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||
|
||||
"eslint/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||
|
||||
"isomorphic-fetch/node-fetch/whatwg-url/tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="],
|
||||
|
||||
"isomorphic-fetch/node-fetch/whatwg-url/webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
|
||||
@@ -3591,6 +3738,8 @@
|
||||
|
||||
"@expo/package-manager/ora/cli-cursor/restore-cursor/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
|
||||
|
||||
"@istanbuljs/load-nyc-config/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="],
|
||||
|
||||
"@react-native/codegen/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||
|
||||
"react-native/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||
|
||||
+6
-6
@@ -7,10 +7,10 @@
|
||||
"dependencies": {
|
||||
"@takumi-rs/image-response": "^0.73.1",
|
||||
"@vercel/analytics": "^2.0.1",
|
||||
"fumadocs-core": "^16.7.0",
|
||||
"fumadocs-core": "^16.7.2",
|
||||
"fumadocs-mdx": "^14.2.11",
|
||||
"fumadocs-openapi": "^10.4.0",
|
||||
"fumadocs-ui": "^16.7.0",
|
||||
"fumadocs-openapi": "^10.4.1",
|
||||
"fumadocs-ui": "^16.7.2",
|
||||
"lucide-react": "^0.577.0",
|
||||
"next": "16.2.0",
|
||||
"react": "19.2.4",
|
||||
@@ -568,13 +568,13 @@
|
||||
|
||||
"framer-motion": ["framer-motion@12.38.0", "", { "dependencies": { "motion-dom": "^12.38.0", "motion-utils": "^12.36.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g=="],
|
||||
|
||||
"fumadocs-core": ["fumadocs-core@16.7.0", "", { "dependencies": { "@formatjs/intl-localematcher": "^0.8.2", "@orama/orama": "^3.1.18", "@shikijs/rehype": "^4.0.2", "@shikijs/transformers": "^4.0.2", "estree-util-value-to-estree": "^3.5.0", "github-slugger": "^2.0.0", "hast-util-to-estree": "^3.1.3", "hast-util-to-jsx-runtime": "^2.3.6", "image-size": "^2.0.2", "mdast-util-mdx": "^3.0.0", "mdast-util-to-markdown": "^2.1.2", "negotiator": "^1.0.0", "npm-to-yarn": "^3.0.1", "path-to-regexp": "^8.3.0", "remark": "^15.0.1", "remark-gfm": "^4.0.1", "remark-rehype": "^11.1.2", "scroll-into-view-if-needed": "^3.1.0", "shiki": "^4.0.2", "tinyglobby": "^0.2.15", "unified": "^11.0.5", "unist-util-visit": "^5.1.0", "vfile": "^6.0.3" }, "peerDependencies": { "@mdx-js/mdx": "*", "@mixedbread/sdk": "^0.46.0", "@orama/core": "1.x.x", "@oramacloud/client": "2.x.x", "@tanstack/react-router": "1.x.x", "@types/estree-jsx": "*", "@types/hast": "*", "@types/mdast": "*", "@types/react": "*", "algoliasearch": "5.x.x", "flexsearch": "*", "lucide-react": "*", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0", "react-router": "7.x.x", "waku": "^0.26.0 || ^0.27.0 || ^1.0.0", "zod": "4.x.x" }, "optionalPeers": ["@mdx-js/mdx", "@mixedbread/sdk", "@orama/core", "@oramacloud/client", "@tanstack/react-router", "@types/estree-jsx", "@types/hast", "@types/mdast", "@types/react", "algoliasearch", "flexsearch", "lucide-react", "next", "react", "react-dom", "react-router", "waku", "zod"] }, "sha512-6QkOLy3LZfVin5/SOYMnVoKHJRO8vGtGbG4seWTYlaLj3jAhlRiefxIUilP+px1tpDTr6G6jGv6TeWtU0aP71Q=="],
|
||||
"fumadocs-core": ["fumadocs-core@16.7.2", "", { "dependencies": { "@formatjs/intl-localematcher": "^0.8.2", "@orama/orama": "^3.1.18", "@shikijs/rehype": "^4.0.2", "@shikijs/transformers": "^4.0.2", "estree-util-value-to-estree": "^3.5.0", "github-slugger": "^2.0.0", "hast-util-to-estree": "^3.1.3", "hast-util-to-jsx-runtime": "^2.3.6", "image-size": "^2.0.2", "mdast-util-mdx": "^3.0.0", "mdast-util-to-markdown": "^2.1.2", "negotiator": "^1.0.0", "npm-to-yarn": "^3.0.1", "path-to-regexp": "^8.3.0", "remark": "^15.0.1", "remark-gfm": "^4.0.1", "remark-rehype": "^11.1.2", "scroll-into-view-if-needed": "^3.1.0", "shiki": "^4.0.2", "tinyglobby": "^0.2.15", "unified": "^11.0.5", "unist-util-visit": "^5.1.0", "vfile": "^6.0.3" }, "peerDependencies": { "@mdx-js/mdx": "*", "@mixedbread/sdk": "^0.46.0", "@orama/core": "1.x.x", "@oramacloud/client": "2.x.x", "@tanstack/react-router": "1.x.x", "@types/estree-jsx": "*", "@types/hast": "*", "@types/mdast": "*", "@types/react": "*", "algoliasearch": "5.x.x", "flexsearch": "*", "lucide-react": "*", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0", "react-router": "7.x.x", "waku": "^0.26.0 || ^0.27.0 || ^1.0.0", "zod": "4.x.x" }, "optionalPeers": ["@mdx-js/mdx", "@mixedbread/sdk", "@orama/core", "@oramacloud/client", "@tanstack/react-router", "@types/estree-jsx", "@types/hast", "@types/mdast", "@types/react", "algoliasearch", "flexsearch", "lucide-react", "next", "react", "react-dom", "react-router", "waku", "zod"] }, "sha512-dPOp4KdaqKVTnCvwMp5XKAushq1rb9IeH20Nbtp8ocG0RhtL7QtE17UC6qXEbmcCFL5NgxRhG+MW2RS7kFFKGw=="],
|
||||
|
||||
"fumadocs-mdx": ["fumadocs-mdx@14.2.11", "", { "dependencies": { "@mdx-js/mdx": "^3.1.1", "@standard-schema/spec": "^1.1.0", "chokidar": "^5.0.0", "esbuild": "^0.27.3", "estree-util-value-to-estree": "^3.5.0", "js-yaml": "^4.1.1", "mdast-util-mdx": "^3.0.0", "mdast-util-to-markdown": "^2.1.2", "picocolors": "^1.1.1", "picomatch": "^4.0.3", "tinyexec": "^1.0.4", "tinyglobby": "^0.2.15", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.1.0", "vfile": "^6.0.3", "zod": "^4.3.6" }, "peerDependencies": { "@fumadocs/mdx-remote": "^1.4.0", "@types/mdast": "*", "@types/mdx": "*", "@types/react": "*", "fumadocs-core": "^15.0.0 || ^16.0.0", "mdast-util-directive": "*", "next": "^15.3.0 || ^16.0.0", "react": "*", "vite": "6.x.x || 7.x.x || 8.x.x" }, "optionalPeers": ["@fumadocs/mdx-remote", "@types/mdast", "@types/mdx", "@types/react", "mdast-util-directive", "next", "react", "vite"], "bin": { "fumadocs-mdx": "dist/bin.js" } }, "sha512-j0gHKs45c62ARteE8/yBM2Nu2I8AE2Cs37ktPEdc/8EX7TL66XP74un5OpHp6itLyWTu8Jur0imOiiIDq8+rDg=="],
|
||||
|
||||
"fumadocs-openapi": ["fumadocs-openapi@10.4.0", "", { "dependencies": { "@fastify/deepmerge": "^3.2.1", "@fumari/json-schema-ts": "^0.0.2", "@fumari/stf": "1.0.3", "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slot": "^1.2.4", "@scalar/json-magic": "^0.12.4", "@scalar/openapi-upgrader": "^0.2.1", "ajv": "^8.18.0", "class-variance-authority": "^0.7.1", "dereference-json-schema": "^0.2.2", "github-slugger": "^2.0.0", "hast-util-to-jsx-runtime": "^2.3.6", "js-yaml": "^4.1.1", "lucide-react": "^0.577.0", "next-themes": "^0.4.6", "openapi-sampler": "^1.7.2", "react-hook-form": "^7.71.2", "remark": "^15.0.1", "remark-rehype": "^11.1.2", "tailwind-merge": "^3.5.0", "xml-js": "^1.6.11" }, "peerDependencies": { "@scalar/api-client-react": "*", "@types/react": "*", "fumadocs-core": "^16.7.0", "fumadocs-ui": "^16.7.0", "json-schema-typed": "*", "react": "^19.2.0", "react-dom": "^19.2.0", "shiki": "*" }, "optionalPeers": ["@scalar/api-client-react", "@types/react", "json-schema-typed", "shiki"] }, "sha512-DI5C1N3MHmKyegPebgnD1/ULzBtdnhOC2bj3J3LgQ7gqC+WEql+UYKfqVr1CoM7WRfn0vQ4sGfZhfjA42+mmPQ=="],
|
||||
"fumadocs-openapi": ["fumadocs-openapi@10.4.1", "", { "dependencies": { "@fastify/deepmerge": "^3.2.1", "@fumari/json-schema-ts": "^0.0.2", "@fumari/stf": "1.0.3", "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slot": "^1.2.4", "@scalar/json-magic": "^0.12.4", "@scalar/openapi-upgrader": "^0.2.1", "ajv": "^8.18.0", "class-variance-authority": "^0.7.1", "dereference-json-schema": "^0.2.2", "github-slugger": "^2.0.0", "hast-util-to-jsx-runtime": "^2.3.6", "js-yaml": "^4.1.1", "lucide-react": "^0.577.0", "next-themes": "^0.4.6", "openapi-sampler": "^1.7.2", "react-hook-form": "^7.71.2", "remark": "^15.0.1", "remark-rehype": "^11.1.2", "tailwind-merge": "^3.5.0", "xml-js": "^1.6.11" }, "peerDependencies": { "@scalar/api-client-react": "*", "@types/react": "*", "fumadocs-core": "^16.7.0", "fumadocs-ui": "^16.7.0", "json-schema-typed": "*", "react": "^19.2.0", "react-dom": "^19.2.0", "shiki": "*" }, "optionalPeers": ["@scalar/api-client-react", "@types/react", "json-schema-typed", "shiki"] }, "sha512-iMEDyANcikDePUFlBE5sffjTbrUI5LELuIla+6kTZJYEuoQMLUK+plOnXq1iacPBMeCS7cSFadvE/Vp/h7oA+g=="],
|
||||
|
||||
"fumadocs-ui": ["fumadocs-ui@16.7.0", "", { "dependencies": { "@fumadocs/tailwind": "0.0.3", "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-direction": "^1.1.1", "@radix-ui/react-navigation-menu": "^1.2.14", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-presence": "^1.1.5", "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-tabs": "^1.1.13", "class-variance-authority": "^0.7.1", "lucide-react": "^0.577.0", "motion": "^12.38.0", "next-themes": "^0.4.6", "react-medium-image-zoom": "^5.4.1", "react-remove-scroll": "^2.7.2", "rehype-raw": "^7.0.0", "scroll-into-view-if-needed": "^3.1.0", "tailwind-merge": "^3.5.0", "unist-util-visit": "^5.1.0" }, "peerDependencies": { "@takumi-rs/image-response": "*", "@types/mdx": "*", "@types/react": "*", "fumadocs-core": "16.7.0", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0", "shiki": "*" }, "optionalPeers": ["@takumi-rs/image-response", "@types/mdx", "@types/react", "next", "shiki"] }, "sha512-EHxijMwafP96sVDPh+8x2yrolcC9VCz/Xnm8a8pY/fjzO8i2gEXwnQ3Fy2KiiBji/ClRp5XjmnYo1uQO35hzLQ=="],
|
||||
"fumadocs-ui": ["fumadocs-ui@16.7.2", "", { "dependencies": { "@fumadocs/tailwind": "0.0.3", "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-direction": "^1.1.1", "@radix-ui/react-navigation-menu": "^1.2.14", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-presence": "^1.1.5", "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-tabs": "^1.1.13", "class-variance-authority": "^0.7.1", "lucide-react": "^0.577.0", "motion": "^12.38.0", "next-themes": "^0.4.6", "react-medium-image-zoom": "^5.4.1", "react-remove-scroll": "^2.7.2", "rehype-raw": "^7.0.0", "scroll-into-view-if-needed": "^3.1.0", "tailwind-merge": "^3.5.0", "unist-util-visit": "^5.1.0" }, "peerDependencies": { "@takumi-rs/image-response": "*", "@types/mdx": "*", "@types/react": "*", "fumadocs-core": "16.7.2", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0", "shiki": "*" }, "optionalPeers": ["@takumi-rs/image-response", "@types/mdx", "@types/react", "next", "shiki"] }, "sha512-k4/QlWUMEL3WuzdO36gyrVSrr7ePGMhvD5/Zqaoqb8PMun8HWn8sAzg0FnHtWwn4kO6YrIw1puaA2U5vUCH6iA=="],
|
||||
|
||||
"get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="],
|
||||
|
||||
|
||||
@@ -7,11 +7,17 @@ icon: Languages
|
||||
Sofa supports multiple languages for the web and mobile apps. The current supported locales are:
|
||||
|
||||
- English (source)
|
||||
- Arabic
|
||||
- Chinese
|
||||
- Dutch
|
||||
- French
|
||||
- German
|
||||
- Spanish
|
||||
- Hebrew
|
||||
- Italian
|
||||
- Japanese
|
||||
- Korean
|
||||
- Portuguese
|
||||
- Spanish
|
||||
|
||||
You can switch languages in **Settings > Language** on web or the mobile app. Sofa detects your browser or device language on first launch and defaults to it if supported. This setting is **not** saved to the server — it is only persisted to the current browser or device.
|
||||
|
||||
|
||||
+3
-3
@@ -16,10 +16,10 @@
|
||||
"dependencies": {
|
||||
"@takumi-rs/image-response": "^0.73.1",
|
||||
"@vercel/analytics": "^2.0.1",
|
||||
"fumadocs-core": "^16.7.0",
|
||||
"fumadocs-core": "^16.7.2",
|
||||
"fumadocs-mdx": "^14.2.11",
|
||||
"fumadocs-openapi": "^10.4.0",
|
||||
"fumadocs-ui": "^16.7.0",
|
||||
"fumadocs-openapi": "^10.4.1",
|
||||
"fumadocs-ui": "^16.7.2",
|
||||
"lucide-react": "^0.577.0",
|
||||
"next": "16.2.0",
|
||||
"react": "19.2.4",
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { defineConfig } from "@lingui/conf";
|
||||
import { formatter } from "@lingui/format-po";
|
||||
|
||||
export default defineConfig({
|
||||
locales: ["en", "fr", "de", "es", "it", "pt"],
|
||||
locales: ["en", "fr", "de", "es", "it", "pt", "nl", "ar", "he", "zh", "ja", "ko"],
|
||||
sourceLocale: "en",
|
||||
catalogs: [
|
||||
{
|
||||
|
||||
+2
-1
@@ -11,7 +11,7 @@
|
||||
"@orpc/client": "1.13.9",
|
||||
"@orpc/contract": "1.13.9",
|
||||
"@orpc/tanstack-query": "1.13.9",
|
||||
"@tanstack/react-query": "5.91.2",
|
||||
"@tanstack/react-query": "5.91.3",
|
||||
"@types/bun": "1.3.11",
|
||||
"@types/node": "25.5.0",
|
||||
"@types/react": "19.2.14",
|
||||
@@ -52,6 +52,7 @@
|
||||
"@lingui/cli": "catalog:",
|
||||
"@lingui/conf": "catalog:",
|
||||
"@lingui/format-po": "catalog:",
|
||||
"eslint-plugin-lingui": "0.11.0",
|
||||
"oxfmt": "0.41.0",
|
||||
"oxlint": "1.56.0",
|
||||
"turbo": "2.8.20",
|
||||
|
||||
@@ -518,18 +518,18 @@ for (const locale of locales) {
|
||||
await translateLocale(locale, model, batchSize, dryRun, contextMap);
|
||||
}
|
||||
|
||||
if (!dryRun) {
|
||||
// Re-extract to restore #. placeholder comments that @lingui/format-po's
|
||||
// serialize() strips during the round-trip.
|
||||
console.log("Re-extracting to restore comments...");
|
||||
const extract = Bun.spawn(["bun", "run", "i18n:extract"], {
|
||||
stdout: "inherit",
|
||||
stderr: "inherit",
|
||||
});
|
||||
if ((await extract.exited) !== 0) {
|
||||
console.error("Extraction failed");
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
// if (!dryRun) {
|
||||
// // Re-extract to restore #. placeholder comments that @lingui/format-po's
|
||||
// // serialize() strips during the round-trip.
|
||||
// console.log("Re-extracting to restore comments...");
|
||||
// const extract = Bun.spawn(["bun", "run", "i18n:extract"], {
|
||||
// stdout: "inherit",
|
||||
// stderr: "inherit",
|
||||
// });
|
||||
// if ((await extract.exited) !== 0) {
|
||||
// console.error("Extraction failed");
|
||||
// process.exit(1);
|
||||
// }
|
||||
// }
|
||||
|
||||
console.log("Done!");
|
||||
|
||||
@@ -3,7 +3,13 @@ import { i18n, type Messages } from "@lingui/core";
|
||||
import type { SupportedLocale } from "./locales";
|
||||
import { messages as enMessages } from "./po/en.po";
|
||||
|
||||
export { SUPPORTED_LOCALES, type SupportedLocale } from "./locales";
|
||||
export {
|
||||
LOCALE_INFO,
|
||||
SUPPORTED_LOCALES,
|
||||
type SupportedLocale,
|
||||
isLocaleRTL,
|
||||
getDirection,
|
||||
} from "./locales";
|
||||
|
||||
// English always bundled — zero async on default locale
|
||||
i18n.load("en", enMessages);
|
||||
@@ -15,6 +21,12 @@ const loaders: Record<Exclude<SupportedLocale, "en">, () => Promise<{ messages:
|
||||
es: () => import("./po/es.po"),
|
||||
it: () => import("./po/it.po"),
|
||||
pt: () => import("./po/pt.po"),
|
||||
nl: () => import("./po/nl.po"),
|
||||
ar: () => import("./po/ar.po"),
|
||||
he: () => import("./po/he.po"),
|
||||
zh: () => import("./po/zh.po"),
|
||||
ja: () => import("./po/ja.po"),
|
||||
ko: () => import("./po/ko.po"),
|
||||
};
|
||||
|
||||
export async function activateLocale(locale: SupportedLocale): Promise<void> {
|
||||
|
||||
@@ -2,17 +2,57 @@ export interface LocaleInfo {
|
||||
code: string;
|
||||
name: string;
|
||||
nativeName: string;
|
||||
isRTL: boolean;
|
||||
}
|
||||
|
||||
export const LOCALE_INFO = [
|
||||
{ code: "en", name: "English", nativeName: "English" },
|
||||
{ code: "fr", name: "French", nativeName: "Fran\u00e7ais" },
|
||||
{ code: "de", name: "German", nativeName: "Deutsch" },
|
||||
{ code: "es", name: "Spanish", nativeName: "Espa\u00f1ol" },
|
||||
{ code: "it", name: "Italian", nativeName: "Italiano" },
|
||||
{ code: "pt", name: "Portuguese", nativeName: "Portugu\u00eas" },
|
||||
{ code: "en", name: "English", nativeName: "English", isRTL: false },
|
||||
{ code: "fr", name: "French", nativeName: "Fran\u00e7ais", isRTL: false },
|
||||
{ code: "de", name: "German", nativeName: "Deutsch", isRTL: false },
|
||||
{ code: "es", name: "Spanish", nativeName: "Espa\u00f1ol", isRTL: false },
|
||||
{ code: "it", name: "Italian", nativeName: "Italiano", isRTL: false },
|
||||
{ code: "pt", name: "Portuguese", nativeName: "Portugu\u00eas", isRTL: false },
|
||||
{ code: "nl", name: "Dutch", nativeName: "Nederlands", isRTL: false },
|
||||
{
|
||||
code: "ar",
|
||||
name: "Arabic",
|
||||
nativeName: "\u0627\u0644\u0639\u0631\u0628\u064a\u0629",
|
||||
isRTL: true,
|
||||
},
|
||||
{
|
||||
code: "he",
|
||||
name: "Hebrew",
|
||||
nativeName: "\u05e2\u05d1\u05e8\u05d9\u05ea",
|
||||
isRTL: true,
|
||||
},
|
||||
{
|
||||
code: "zh",
|
||||
name: "Chinese",
|
||||
nativeName: "\u4e2d\u6587",
|
||||
isRTL: false,
|
||||
},
|
||||
{
|
||||
code: "ja",
|
||||
name: "Japanese",
|
||||
nativeName: "\u65e5\u672c\u8a9e",
|
||||
isRTL: false,
|
||||
},
|
||||
{
|
||||
code: "ko",
|
||||
name: "Korean",
|
||||
nativeName: "\ud55c\uad6d\uc5b4",
|
||||
isRTL: false,
|
||||
},
|
||||
] as const satisfies readonly LocaleInfo[];
|
||||
|
||||
export type SupportedLocale = (typeof LOCALE_INFO)[number]["code"];
|
||||
|
||||
export const SUPPORTED_LOCALES = LOCALE_INFO.map((l) => l.code) as SupportedLocale[];
|
||||
|
||||
export function isLocaleRTL(code: string): boolean {
|
||||
return LOCALE_INFO.find((l) => l.code === code)?.isRTL ?? false;
|
||||
}
|
||||
|
||||
export function getDirection(code: string): "ltr" | "rtl" {
|
||||
return isLocaleRTL(code) ? "rtl" : "ltr";
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+285
-161
@@ -8,20 +8,23 @@ msgstr ""
|
||||
"Language: de\n"
|
||||
"Project-Id-Version: sofa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-03-19 00:35\n"
|
||||
"PO-Revision-Date: 2026-03-20 23:13\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: German\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Crowdin-Project: sofa\n"
|
||||
"X-Crowdin-Project-ID: 881052\n"
|
||||
"X-Crowdin-Language: de\n"
|
||||
"X-Crowdin-File: en.po\n"
|
||||
"X-Crowdin-File-ID: 14\n"
|
||||
"X-Crowdin-File: /packages/i18n/src/po/en.po\n"
|
||||
"X-Crowdin-File-ID: 26\n"
|
||||
|
||||
#. placeholder {0}: result.errors.length - 50
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "...and {0} more"
|
||||
msgstr "...und {0} weitere"
|
||||
#~ msgid "...and {0} more"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
@@ -33,86 +36,99 @@ msgstr "{0, plural, one {# Bild} other {# Bilder}}"
|
||||
msgid "{0, plural, one {# title} other {# titles}}"
|
||||
msgstr "{0, plural, one {# Titel} other {# Titel}}"
|
||||
|
||||
#. placeholder {0}: displayBackups.length
|
||||
#. placeholder {1}: displayBackups.length
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "{0} {1, plural, one {backup} other {backups}} stored"
|
||||
msgstr "{0} {1, plural, one {Backup} other {Backups}} gespeichert"
|
||||
#~ msgid "{0} {1, plural, one {backup} other {backups}} stored"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
#~ msgid "{0} backup{1} stored"
|
||||
#~ msgstr "{0} backup{1} stored"
|
||||
|
||||
#. placeholder {0}: backups.backupCount
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} backups · last <0/>"
|
||||
msgstr "{0} Backups · zuletzt <0/>"
|
||||
#~ msgid "{0} backups · last <0/>"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: imageCache.imageCount.toLocaleString()
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} cached images"
|
||||
msgstr "{0} gecachte Bilder"
|
||||
#~ msgid "{0} cached images"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: member.episodeCount
|
||||
#. placeholder {1}: member.episodeCount !== 1 ? "s" : ""
|
||||
#: apps/web/src/components/titles/cast-carousel.tsx
|
||||
msgid "{0} ep{1}"
|
||||
msgstr "{0} Ep{1}"
|
||||
#~ msgid "{0} ep{1}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#~ msgid "{0} images"
|
||||
#~ msgstr "{0} images"
|
||||
|
||||
#. placeholder {0}: stats.watchlist
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} items"
|
||||
msgstr "{0} Einträge"
|
||||
#~ msgid "{0} items"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: preview.diagnostics.unresolved
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
msgstr "{0} Einträge haben keine externen IDs und werden über die Titelsuche gefunden, was weniger genau sein kann."
|
||||
#~ msgid "{0} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: stats.movies
|
||||
#. placeholder {1}: stats.episodes
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} movies, {1} episodes"
|
||||
msgstr "{0} Filme, {1} Episoden"
|
||||
#~ msgid "{0} movies, {1} episodes"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: stats.ratings
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} ratings"
|
||||
msgstr "{0} Bewertungen"
|
||||
#~ msgid "{0} ratings"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#~ msgid "{0} titles"
|
||||
#~ msgstr "{0} titles"
|
||||
|
||||
#. placeholder {0}: JOB_LABELS[name] ?? name
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} triggered"
|
||||
msgstr "{0} ausgelöst"
|
||||
#~ msgid "{0} triggered"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: item.watchedEpisodes
|
||||
#. placeholder {1}: item.totalEpisodes
|
||||
#. placeholder {2}: item.totalEpisodes
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
msgid "{0}/{1} {2, plural, one {episode} other {episodes}}"
|
||||
msgstr "{0}/{1} {2, plural, one {Episode} other {Episoden}}"
|
||||
#~ msgid "{0}/{1} {2, plural, one {episode} other {episodes}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
#~ msgid "{0}/{1} episodes"
|
||||
#~ msgstr "{0}/{1} episodes"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "{count} earlier {count, plural, one {episode} other {episodes}} unwatched"
|
||||
msgstr "{count} {count, plural, one {frühere Episode} other {frühere Episoden}} noch ungesehen"
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "{backupCount, plural, one {# backup} other {# backups}} stored"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: activeJobs.length
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{healthyCount} of {0} jobs healthy"
|
||||
msgstr "{healthyCount} von {0} Jobs fehlerfrei"
|
||||
msgid "{backupCount} backups · last <0/>"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{cachedImageCount} cached images"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "{count, plural, one {# earlier episode} other {# earlier episodes}} unwatched"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#~ msgid "{count} earlier {count, plural, one {episode} other {episodes}} unwatched"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/cast-carousel.tsx
|
||||
msgid "{count} ep{suffix}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
#~ msgid "{healthyCount} of {0} jobs healthy"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{healthyCount} of {activeJobCount} jobs healthy"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{jobLabel} triggered"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-card.tsx
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
@@ -129,25 +145,50 @@ msgstr "{label} getrennt"
|
||||
msgid "{label} URL regenerated"
|
||||
msgstr "{label}-URL neu generiert"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{movieCount} movies, {episodeCount} episodes"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{ratingCount} ratings"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{unresolvedCount} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/title-card.tsx
|
||||
msgid "{watched}/{total} episodes"
|
||||
msgstr "{watched}/{total} Episoden"
|
||||
|
||||
#. placeholder {0}: episodes.length
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount} of {0} episodes watched"
|
||||
msgstr "{watchedCount} von {0} Episoden gesehen"
|
||||
#~ msgid "{watchedCount} of {0} episodes watched"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: episodes.length
|
||||
#. placeholder {1}: episodes.length
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount}/{0} {1, plural, one {episode} other {episodes}}"
|
||||
msgstr "{watchedCount}/{0} {1, plural, one {Episode} other {Episoden}}"
|
||||
msgid "{watchedCount} of {episodeCount} episodes watched"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#~ msgid "{watchedCount}/{0} {1, plural, one {episode} other {episodes}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#~ msgid "{watchedCount}/{0} episodes"
|
||||
#~ msgstr "{watchedCount}/{0} episodes"
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount}/{episodeCount, plural, one {# episode} other {# episodes}}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
msgid "{watchedEpisodes}/{totalEpisodes, plural, one {# episode} other {# episodes}}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{watchlistCount} items"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
msgid "Account"
|
||||
@@ -207,7 +248,7 @@ msgstr "Zur Merkliste hinzugefügt"
|
||||
#: apps/web/src/components/nav-bar.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
msgid "Admin"
|
||||
msgstr "Admin"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/routes/_app/settings.tsx
|
||||
msgid "Admin only"
|
||||
@@ -268,10 +309,13 @@ msgstr "Autorisierung erfolgreich, aber die Bibliothek konnte nicht abgerufen we
|
||||
msgid "Authorization was denied. Please try again."
|
||||
msgstr "Autorisierung wurde verweigert. Bitte versuche es erneut."
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Authorize Sofa to read your {0} library. No password shared."
|
||||
msgstr "Sofa autorisieren, deine {0}-Bibliothek zu lesen. Kein Passwort wird geteilt."
|
||||
#~ msgid "Authorize Sofa to read your {0} library. No password shared."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Authorize Sofa to read your {sourceLabel} library. No password shared."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/update-check-section.tsx
|
||||
msgid "Automatic update checks"
|
||||
@@ -295,7 +339,7 @@ msgstr "Hintergrundaufgaben"
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Backup"
|
||||
msgstr "Backup"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "Backup created"
|
||||
@@ -312,11 +356,11 @@ msgstr "Backup-Zeitplan"
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
#: apps/web/src/routes/_app/settings.tsx
|
||||
msgid "Backups"
|
||||
msgstr "Backups"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
#~ msgid "backups."
|
||||
#~ msgstr "backups."
|
||||
msgid "backups."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Buy"
|
||||
@@ -374,11 +418,13 @@ msgstr "Aufholen"
|
||||
msgid "Caught Up"
|
||||
msgstr "Auf dem Laufenden"
|
||||
|
||||
#. placeholder {0}: episodeIds.length
|
||||
#. placeholder {1}: episodeIds.length
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Caught up — marked {0} {1, plural, one {episode} other {episodes}} as watched"
|
||||
msgstr "Aufgeholt - {0} {1, plural, one {Episode} other {Episoden}} als gesehen markiert"
|
||||
#~ msgid "Caught up — marked {0} {1, plural, one {episode} other {episodes}} as watched"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Caught up — marked {count, plural, one {# episode} other {# episodes}} as watched"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
@@ -414,10 +460,13 @@ msgstr "Geprüft <0/>"
|
||||
msgid "Checking…"
|
||||
msgstr "Prüfe..."
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Choose how to import your {0} data."
|
||||
msgstr "Wähle aus, wie du deine {0}-Daten importieren möchtest."
|
||||
#~ msgid "Choose how to import your {0} data."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Choose how to import your {sourceLabel} data."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
#~ msgid "Choose your preferred display language"
|
||||
@@ -480,12 +529,12 @@ msgstr "Neues Passwort bestätigen"
|
||||
msgid "Connect"
|
||||
msgstr "Verbinden"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Connect {0}"
|
||||
msgstr "{0} verbinden"
|
||||
#~ msgid "Connect {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-card.tsx
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Connect {label}"
|
||||
msgstr "{label} verbinden"
|
||||
|
||||
@@ -497,10 +546,13 @@ msgstr "Mit {source} verbinden"
|
||||
msgid "Connect to TMDB"
|
||||
msgstr "Mit TMDB verbinden"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Connect with {0}"
|
||||
msgstr "Mit {0} verbinden"
|
||||
#~ msgid "Connect with {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Connect with {sourceLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/server-url.tsx
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
@@ -596,7 +648,7 @@ msgstr "Gefahrenzone"
|
||||
#: apps/web/src/routes/_app/titles.$id.tsx
|
||||
#: apps/web/src/routes/_app/titles.$id.tsx
|
||||
msgid "Dashboard"
|
||||
msgstr "Dashboard"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
@@ -740,11 +792,11 @@ msgstr "Umgebung"
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#~ msgid "Episode {0}"
|
||||
#~ msgstr "Folge {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#~ msgid "Episode {0}, {episodeLabel}"
|
||||
#~ msgstr "Folge {0}, {episodeLabel}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
@@ -770,10 +822,13 @@ msgstr "Episode als gesehen markiert"
|
||||
msgid "Episodes"
|
||||
msgstr "Episoden"
|
||||
|
||||
#. placeholder {0}: periodLabels[episodePeriod]
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Episodes {0}"
|
||||
msgstr "Folgen {0}"
|
||||
#~ msgid "Episodes {0}"
|
||||
#~ msgstr "Episodes {0}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Episodes {period}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/stats-display.tsx
|
||||
#~ msgid "Episodes {periodSelect}"
|
||||
@@ -785,17 +840,20 @@ msgstr "Episoden {select}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
#~ msgid "Episodes this week"
|
||||
#~ msgstr "Episoden diese Woche"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/change-password.tsx
|
||||
#: apps/native/src/app/change-password.tsx
|
||||
msgid "Error"
|
||||
msgstr "Fehler"
|
||||
|
||||
#. placeholder {0}: result.errors.length
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Errors ({0})"
|
||||
msgstr "Fehler ({0})"
|
||||
#~ msgid "Errors ({0})"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Errors ({errorCount})"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(explore)/_layout.tsx
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
@@ -923,10 +981,13 @@ msgstr "Profilbild konnte nicht entfernt werden"
|
||||
msgid "Failed to sign in"
|
||||
msgstr "Anmeldung fehlgeschlagen"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Failed to start {0} connection"
|
||||
msgstr "{0}-Verbindung konnte nicht gestartet werden"
|
||||
#~ msgid "Failed to start {0} connection"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Failed to start {sourceLabel} connection"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Failed to trigger job"
|
||||
@@ -1072,7 +1133,7 @@ msgstr "Speichernutzung für Bild-Cache und Backups"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import"
|
||||
msgstr "Import"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import {totalItems} items"
|
||||
@@ -1086,15 +1147,18 @@ msgstr "Import abgeschlossen"
|
||||
msgid "Import failed"
|
||||
msgstr "Import fehlgeschlagen"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {0}"
|
||||
msgstr "Von {0} importieren"
|
||||
#~ msgid "Import from {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {source}"
|
||||
msgstr "Von {source} importieren"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {sourceLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import is still running in the background. Check back later."
|
||||
@@ -1108,11 +1172,13 @@ msgstr "Importoptionen"
|
||||
msgid "Imported"
|
||||
msgstr "Importiert"
|
||||
|
||||
#. placeholder {0}: event.job.importedCount
|
||||
#. placeholder {1}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Imported {0} items from {1}"
|
||||
msgstr "{0} Einträge von {1} importiert"
|
||||
#~ msgid "Imported {0} items from {1}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Imported {importedCount} items from {sourceLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Importing from {source}"
|
||||
@@ -1158,14 +1224,12 @@ msgid "Job"
|
||||
msgstr "Aufgabe"
|
||||
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
#~ msgid "Keeping"
|
||||
#~ msgstr "Keeping"
|
||||
msgid "Keeping"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: (value: string | null) => value === "0" ? t`unlimited` : value ? t`last ${value}` : null
|
||||
#. placeholder {1}: [3, 5, 7, 14, 30, 0].map((n) => ( <SelectItem key={n} value={String(n)}> {n === 0 ? t`unlimited` : t`last ${n}`} </SelectItem> ))
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
msgid "Keeping <0><1><2>{0}</2></1><3>{1}</3></0> backups."
|
||||
msgstr "<0><1><2>{0}</2></1><3>{1}</3></0> Backups werden aufbewahrt."
|
||||
#~ msgid "Keeping <0><1><2>{0}</2></1><3>{1}</3></0> backups."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/command-palette.tsx
|
||||
#: apps/web/src/components/command-palette.tsx
|
||||
@@ -1186,19 +1250,25 @@ msgstr "letzte {n}"
|
||||
msgid "last {value}"
|
||||
msgstr "letzte {value}"
|
||||
|
||||
#. placeholder {0}: formatRelativeTime(lastEventAt)
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last event {0}"
|
||||
msgstr "Letztes Ereignis {0}"
|
||||
#~ msgid "Last event {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last event {relativeTime}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
msgid "Last event {timeAgo}"
|
||||
msgstr "Letztes Ereignis {timeAgo}"
|
||||
|
||||
#. placeholder {0}: formatRelativeTime(lastEventAt)
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last polled {0}"
|
||||
msgstr "Zuletzt abgefragt {0}"
|
||||
#~ msgid "Last polled {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last polled {relativeTime}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
msgid "Last polled {timeAgo}"
|
||||
@@ -1249,7 +1319,7 @@ msgstr "Alle als gesehen markieren"
|
||||
|
||||
#: apps/native/src/components/dashboard/continue-watching-card.tsx
|
||||
#~ msgid "Mark as Completed"
|
||||
#~ msgstr "Als abgeschlossen markieren"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/ui/poster-card.tsx
|
||||
msgid "Mark as Watched"
|
||||
@@ -1257,7 +1327,7 @@ msgstr "Als gesehen markieren"
|
||||
|
||||
#: apps/native/src/components/ui/poster-card.tsx
|
||||
#~ msgid "Mark as Watching"
|
||||
#~ msgstr "Als am Schauen markieren"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/title/[id].tsx
|
||||
#: apps/web/src/components/titles/title-actions.tsx
|
||||
@@ -1266,7 +1336,7 @@ msgstr "Als gesehen markieren"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#~ msgid "Marked \"{titleName}\" as completed"
|
||||
#~ msgstr "\"{titleName}\" als abgeschlossen markiert"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
@@ -1285,7 +1355,7 @@ msgstr "Alle Folgen von \"{titleName}\" als gesehen markiert"
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#~ msgid "Marked as completed"
|
||||
#~ msgstr "Als abgeschlossen markiert"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
@@ -1295,7 +1365,7 @@ msgstr "Als gesehen markiert"
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#~ msgid "Marked as watching"
|
||||
#~ msgstr "Als am Schauen markiert"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
msgid "Member since {memberSince}"
|
||||
@@ -1327,10 +1397,13 @@ msgstr "Film"
|
||||
msgid "Movies"
|
||||
msgstr "Filme"
|
||||
|
||||
#. placeholder {0}: periodLabels[moviePeriod]
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Movies {0}"
|
||||
msgstr "Filme {0}"
|
||||
#~ msgid "Movies {0}"
|
||||
#~ msgstr "Movies {0}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Movies {period}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/stats-display.tsx
|
||||
#~ msgid "Movies {periodSelect}"
|
||||
@@ -1342,12 +1415,12 @@ msgstr "Filme {select}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
#~ msgid "Movies this month"
|
||||
#~ msgstr "Filme diesen Monat"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/register.tsx
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
@@ -1540,7 +1613,7 @@ msgstr "GitHub regelmäßig auf neue Sofa-Versionen prüfen"
|
||||
#: apps/native/src/components/search/search-result-row.tsx
|
||||
#: apps/native/src/components/search/search-result-row.tsx
|
||||
msgid "Person"
|
||||
msgstr "Person"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/person/[id].tsx
|
||||
#: apps/web/src/routes/_app/people.$id.tsx
|
||||
@@ -1635,20 +1708,23 @@ msgstr "Schnellaktionen"
|
||||
msgid "Radarr List URL"
|
||||
msgstr "Radarr-Listen-URL"
|
||||
|
||||
#. placeholder {0}: input.stars
|
||||
#. placeholder {1}: input.stars
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
msgid "Rated {0} {1, plural, one {star} other {stars}}"
|
||||
msgstr "{0} {1, plural, one {Stern} other {Sterne}} bewertet"
|
||||
#~ msgid "Rated {0} {1, plural, one {star} other {stars}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#~ msgid "Rated {0} star{1}"
|
||||
#~ msgstr "Rated {0} star{1}"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Rated {ratingStars} {ratingStars, plural, one {star} other {stars}}"
|
||||
msgstr "{ratingStars} {ratingStars, plural, one {Stern} other {Sterne}} bewertet"
|
||||
msgid "Rated {ratingStars, plural, one {# star} other {# stars}}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#~ msgid "Rated {ratingStars} {ratingStars, plural, one {star} other {stars}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Rated {stars, plural, one {# star} other {# stars}}"
|
||||
msgstr "{stars, plural, one {# Stern} other {# Sterne}} vergeben"
|
||||
@@ -1810,6 +1886,14 @@ msgstr "Erfordert ein aktives Plex Pass-Abonnement."
|
||||
msgid "Requires Emby Server 4.7.9+ and an active Emby Premiere license."
|
||||
msgstr "Erfordert Emby Server 4.7.9+ und eine aktive Emby Premiere-Lizenz."
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Restart"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Restart Required"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-restore-section.tsx
|
||||
#: apps/web/src/components/settings/backup-restore-section.tsx
|
||||
msgid "Restore"
|
||||
@@ -1921,13 +2005,19 @@ msgstr "Filme, Serien, Personen suchen..."
|
||||
msgid "Search…"
|
||||
msgstr "Suchen..."
|
||||
|
||||
#. placeholder {0}: season.seasonNumber
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Season {0}"
|
||||
msgstr "Staffel {0}"
|
||||
#~ msgid "Season {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Season {seasonNumber}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
@@ -1949,7 +2039,7 @@ msgstr "Selbstgehosteter Film- & Serien-Tracker"
|
||||
|
||||
#: apps/web/src/routes/_app/settings.tsx
|
||||
msgid "Server"
|
||||
msgstr "Server"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Server Health"
|
||||
@@ -2018,12 +2108,18 @@ msgstr "Stattdessen anmelden"
|
||||
msgid "Sign in to continue"
|
||||
msgstr "Anmelden, um fortzufahren"
|
||||
|
||||
#. placeholder {0}: authConfig.data?.oidcProviderName ?? "SSO"
|
||||
#. placeholder {0}: authConfig?.oidcProviderName || "SSO"
|
||||
#: apps/native/src/app/(auth)/login.tsx
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
msgid "Sign in with {0}"
|
||||
msgstr "Mit {0} anmelden"
|
||||
#~ msgid "Sign in with {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
msgid "Sign in with {oidcProviderName}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/login.tsx
|
||||
msgid "Sign in with {providerName}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/native/src/components/header-avatar.tsx
|
||||
@@ -2048,10 +2144,17 @@ msgstr "Von anderen Sitzungen abmelden"
|
||||
msgid "Skipped"
|
||||
msgstr "Übersprungen"
|
||||
|
||||
#. placeholder {0}: data.latestVersion
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Sofa needs to restart to apply the new layout direction."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "Sofa v{0} is available"
|
||||
msgstr "Sofa v{0} ist verfügbar"
|
||||
#~ msgid "Sofa v{0} is available"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "Sofa v{latestVersion} is available"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
@@ -2118,10 +2221,13 @@ msgstr "Streamen"
|
||||
msgid "Sunday"
|
||||
msgstr "Sonntag"
|
||||
|
||||
#. placeholder {0}: info.name
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
msgid "Switch to {0}"
|
||||
msgstr "Zu {0} wechseln"
|
||||
#~ msgid "Switch to {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
msgid "Switch to {name}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/+not-found.tsx
|
||||
msgid "The page you're looking for doesn't exist."
|
||||
@@ -2192,10 +2298,13 @@ msgstr "Dadurch wird die aktuelle {label}-URL ungültig. Du musst sie in {label}
|
||||
msgid "This will mark every episode of this show as watched. You can undo this later by unmarking individual seasons."
|
||||
msgstr "Dadurch werden alle Episoden dieser Serie als gesehen markiert. Du kannst dies später rückgängig machen, indem du einzelne Staffeln abwählst."
|
||||
|
||||
#. placeholder {0}: formatBackupDate(backup.createdAt)
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "This will permanently delete the backup from <0>{0}</0>. This cannot be undone."
|
||||
msgstr "Dadurch wird das Backup vom <0>{0}</0> dauerhaft gelöscht. Dies kann nicht rückgängig gemacht werden."
|
||||
#~ msgid "This will permanently delete the backup from <0>{0}</0>. This cannot be undone."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "This will permanently delete the backup from <0>{backupDate}</0>. This cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/search/recently-viewed-list.ios.tsx
|
||||
#: apps/native/src/components/search/recently-viewed-list.tsx
|
||||
@@ -2266,7 +2375,7 @@ msgstr "Verfolge, was du schaust. Wisse, was als Nächstes kommt.<0/>Deine Bibli
|
||||
#: apps/web/src/components/titles/trailer-dialog.tsx
|
||||
#: apps/web/src/components/titles/trailer-dialog.tsx
|
||||
msgid "Trailer"
|
||||
msgstr "Trailer"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/explore/hero-banner.tsx
|
||||
msgid "Trending today"
|
||||
@@ -2327,10 +2436,13 @@ msgstr "Ohne Titel"
|
||||
msgid "Unwatch all"
|
||||
msgstr "Alle als ungesehen markieren"
|
||||
|
||||
#. placeholder {0}: season.name ?? t`Season ${season.seasonNumber}`
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched all of {0}"
|
||||
msgstr "Alle Episoden von {0} als ungesehen markiert"
|
||||
#~ msgid "Unwatched all of {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched all of {seasonLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched S{seasonNum} E{epNum}"
|
||||
@@ -2341,10 +2453,13 @@ msgstr "S{seasonNum} E{epNum} als ungesehen markiert"
|
||||
msgid "Up next"
|
||||
msgstr "Als Nächstes"
|
||||
|
||||
#. placeholder {0}: updateCheck.data.updateCheck.latestVersion
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Update available: {0}"
|
||||
msgstr "Update verfügbar: {0}"
|
||||
#~ msgid "Update available: {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Update available: {latestVersion}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Update check"
|
||||
@@ -2381,11 +2496,13 @@ msgstr "Hochladen"
|
||||
msgid "Upload a .db file to replace the current database. A safety backup is created first."
|
||||
msgstr "Lade eine .db-Datei hoch, um die aktuelle Datenbank zu ersetzen. Zuerst wird ein Sicherheits-Backup erstellt."
|
||||
|
||||
#. placeholder {0}: config.accept
|
||||
#. placeholder {1}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload a {0} export from your {1} account settings."
|
||||
msgstr "Lade einen {0}-Export aus deinen {1}-Kontoeinstellungen hoch."
|
||||
#~ msgid "Upload a {0} export from your {1} account settings."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload a {acceptFormat} export from your {sourceLabel} account settings."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload export file"
|
||||
@@ -2419,10 +2536,13 @@ msgstr "Warte auf Autorisierung..."
|
||||
msgid "Warnings"
|
||||
msgstr "Warnungen"
|
||||
|
||||
#. placeholder {0}: result.warnings.length
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Warnings ({0})"
|
||||
msgstr "Warnungen ({0})"
|
||||
#~ msgid "Warnings ({0})"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Warnings ({warningCount})"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-seasons.tsx
|
||||
msgid "Watch all"
|
||||
@@ -2465,7 +2585,7 @@ msgstr "Merkliste"
|
||||
|
||||
#: apps/native/src/components/titles/status-action-button.tsx
|
||||
#~ msgid "Watchlisted"
|
||||
#~ msgstr "Auf Merkliste"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
@@ -2505,10 +2625,13 @@ msgstr "Autor"
|
||||
msgid "You'll be signed out to change the server URL."
|
||||
msgstr "Du wirst abgemeldet, um die Server-URL zu ändern."
|
||||
|
||||
#. placeholder {0}: data.currentVersion
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "You're running v{0}."
|
||||
msgstr "Du verwendest v{0}."
|
||||
#~ msgid "You're running v{0}."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "You're running v{currentVersion}."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Your code:"
|
||||
@@ -2522,3 +2645,4 @@ msgstr "Deine Bibliothek ist leer"
|
||||
#: apps/native/src/app/(auth)/register.tsx
|
||||
msgid "Your name"
|
||||
msgstr "Dein Name"
|
||||
|
||||
|
||||
+262
-139
@@ -18,10 +18,13 @@ msgstr ""
|
||||
"X-Crowdin-File: /packages/i18n/src/po/en.po\n"
|
||||
"X-Crowdin-File-ID: 12\n"
|
||||
|
||||
#. placeholder {0}: result.errors.length - 50
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "...and {0} more"
|
||||
msgstr ""
|
||||
#~ msgid "...and {0} more"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr "...and {remainingErrors} more"
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
@@ -33,86 +36,99 @@ msgstr ""
|
||||
msgid "{0, plural, one {# title} other {# titles}}"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: displayBackups.length
|
||||
#. placeholder {1}: displayBackups.length
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "{0} {1, plural, one {backup} other {backups}} stored"
|
||||
msgstr ""
|
||||
#~ msgid "{0} {1, plural, one {backup} other {backups}} stored"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
#~ msgid "{0} backup{1} stored"
|
||||
#~ msgstr "{0} backup{1} stored"
|
||||
|
||||
#. placeholder {0}: backups.backupCount
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} backups · last <0/>"
|
||||
msgstr ""
|
||||
#~ msgid "{0} backups · last <0/>"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: imageCache.imageCount.toLocaleString()
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} cached images"
|
||||
msgstr ""
|
||||
#~ msgid "{0} cached images"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: member.episodeCount
|
||||
#. placeholder {1}: member.episodeCount !== 1 ? "s" : ""
|
||||
#: apps/web/src/components/titles/cast-carousel.tsx
|
||||
msgid "{0} ep{1}"
|
||||
msgstr ""
|
||||
#~ msgid "{0} ep{1}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#~ msgid "{0} images"
|
||||
#~ msgstr "{0} images"
|
||||
|
||||
#. placeholder {0}: stats.watchlist
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} items"
|
||||
msgstr ""
|
||||
#~ msgid "{0} items"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: preview.diagnostics.unresolved
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
msgstr ""
|
||||
#~ msgid "{0} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: stats.movies
|
||||
#. placeholder {1}: stats.episodes
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} movies, {1} episodes"
|
||||
msgstr ""
|
||||
#~ msgid "{0} movies, {1} episodes"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: stats.ratings
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} ratings"
|
||||
msgstr ""
|
||||
#~ msgid "{0} ratings"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#~ msgid "{0} titles"
|
||||
#~ msgstr "{0} titles"
|
||||
|
||||
#. placeholder {0}: JOB_LABELS[name] ?? name
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} triggered"
|
||||
msgstr ""
|
||||
#~ msgid "{0} triggered"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: item.watchedEpisodes
|
||||
#. placeholder {1}: item.totalEpisodes
|
||||
#. placeholder {2}: item.totalEpisodes
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
msgid "{0}/{1} {2, plural, one {episode} other {episodes}}"
|
||||
msgstr ""
|
||||
#~ msgid "{0}/{1} {2, plural, one {episode} other {episodes}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
#~ msgid "{0}/{1} episodes"
|
||||
#~ msgstr "{0}/{1} episodes"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "{count} earlier {count, plural, one {episode} other {episodes}} unwatched"
|
||||
msgstr ""
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "{backupCount, plural, one {# backup} other {# backups}} stored"
|
||||
msgstr "{backupCount, plural, one {# backup} other {# backups}} stored"
|
||||
|
||||
#. placeholder {0}: activeJobs.length
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{healthyCount} of {0} jobs healthy"
|
||||
msgstr ""
|
||||
msgid "{backupCount} backups · last <0/>"
|
||||
msgstr "{backupCount} backups · last <0/>"
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{cachedImageCount} cached images"
|
||||
msgstr "{cachedImageCount} cached images"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "{count, plural, one {# earlier episode} other {# earlier episodes}} unwatched"
|
||||
msgstr "{count, plural, one {# earlier episode} other {# earlier episodes}} unwatched"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#~ msgid "{count} earlier {count, plural, one {episode} other {episodes}} unwatched"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/cast-carousel.tsx
|
||||
msgid "{count} ep{suffix}"
|
||||
msgstr "{count} ep{suffix}"
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
#~ msgid "{healthyCount} of {0} jobs healthy"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{healthyCount} of {activeJobCount} jobs healthy"
|
||||
msgstr "{healthyCount} of {activeJobCount} jobs healthy"
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{jobLabel} triggered"
|
||||
msgstr "{jobLabel} triggered"
|
||||
|
||||
#: apps/native/src/components/settings/integration-card.tsx
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
@@ -129,25 +145,50 @@ msgstr ""
|
||||
msgid "{label} URL regenerated"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{movieCount} movies, {episodeCount} episodes"
|
||||
msgstr "{movieCount} movies, {episodeCount} episodes"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{ratingCount} ratings"
|
||||
msgstr "{ratingCount} ratings"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{unresolvedCount} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
msgstr "{unresolvedCount} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
|
||||
#: apps/web/src/components/title-card.tsx
|
||||
msgid "{watched}/{total} episodes"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: episodes.length
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount} of {0} episodes watched"
|
||||
msgstr ""
|
||||
#~ msgid "{watchedCount} of {0} episodes watched"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: episodes.length
|
||||
#. placeholder {1}: episodes.length
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount}/{0} {1, plural, one {episode} other {episodes}}"
|
||||
msgstr ""
|
||||
msgid "{watchedCount} of {episodeCount} episodes watched"
|
||||
msgstr "{watchedCount} of {episodeCount} episodes watched"
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#~ msgid "{watchedCount}/{0} {1, plural, one {episode} other {episodes}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#~ msgid "{watchedCount}/{0} episodes"
|
||||
#~ msgstr "{watchedCount}/{0} episodes"
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount}/{episodeCount, plural, one {# episode} other {# episodes}}"
|
||||
msgstr "{watchedCount}/{episodeCount, plural, one {# episode} other {# episodes}}"
|
||||
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
msgid "{watchedEpisodes}/{totalEpisodes, plural, one {# episode} other {# episodes}}"
|
||||
msgstr "{watchedEpisodes}/{totalEpisodes, plural, one {# episode} other {# episodes}}"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{watchlistCount} items"
|
||||
msgstr "{watchlistCount} items"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
msgid "Account"
|
||||
@@ -268,10 +309,13 @@ msgstr ""
|
||||
msgid "Authorization was denied. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Authorize Sofa to read your {0} library. No password shared."
|
||||
msgstr ""
|
||||
#~ msgid "Authorize Sofa to read your {0} library. No password shared."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Authorize Sofa to read your {sourceLabel} library. No password shared."
|
||||
msgstr "Authorize Sofa to read your {sourceLabel} library. No password shared."
|
||||
|
||||
#: apps/web/src/components/settings/update-check-section.tsx
|
||||
msgid "Automatic update checks"
|
||||
@@ -315,8 +359,8 @@ msgid "Backups"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
#~ msgid "backups."
|
||||
#~ msgstr "backups."
|
||||
msgid "backups."
|
||||
msgstr "backups."
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Buy"
|
||||
@@ -374,11 +418,13 @@ msgstr ""
|
||||
msgid "Caught Up"
|
||||
msgstr "Caught Up"
|
||||
|
||||
#. placeholder {0}: episodeIds.length
|
||||
#. placeholder {1}: episodeIds.length
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Caught up — marked {0} {1, plural, one {episode} other {episodes}} as watched"
|
||||
msgstr ""
|
||||
#~ msgid "Caught up — marked {0} {1, plural, one {episode} other {episodes}} as watched"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Caught up — marked {count, plural, one {# episode} other {# episodes}} as watched"
|
||||
msgstr "Caught up — marked {count, plural, one {# episode} other {# episodes}} as watched"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
@@ -414,10 +460,13 @@ msgstr ""
|
||||
msgid "Checking…"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Choose how to import your {0} data."
|
||||
msgstr ""
|
||||
#~ msgid "Choose how to import your {0} data."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Choose how to import your {sourceLabel} data."
|
||||
msgstr "Choose how to import your {sourceLabel} data."
|
||||
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
#~ msgid "Choose your preferred display language"
|
||||
@@ -480,12 +529,12 @@ msgstr ""
|
||||
msgid "Connect"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Connect {0}"
|
||||
msgstr ""
|
||||
#~ msgid "Connect {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-card.tsx
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Connect {label}"
|
||||
msgstr ""
|
||||
|
||||
@@ -497,10 +546,13 @@ msgstr ""
|
||||
msgid "Connect to TMDB"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Connect with {0}"
|
||||
msgstr ""
|
||||
#~ msgid "Connect with {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Connect with {sourceLabel}"
|
||||
msgstr "Connect with {sourceLabel}"
|
||||
|
||||
#: apps/native/src/app/(auth)/server-url.tsx
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
@@ -770,10 +822,13 @@ msgstr ""
|
||||
msgid "Episodes"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: periodLabels[episodePeriod]
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Episodes {0}"
|
||||
msgstr "Episodes {0}"
|
||||
#~ msgid "Episodes {0}"
|
||||
#~ msgstr "Episodes {0}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Episodes {period}"
|
||||
msgstr "Episodes {period}"
|
||||
|
||||
#: apps/web/src/components/dashboard/stats-display.tsx
|
||||
#~ msgid "Episodes {periodSelect}"
|
||||
@@ -792,10 +847,13 @@ msgstr ""
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: result.errors.length
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Errors ({0})"
|
||||
msgstr ""
|
||||
#~ msgid "Errors ({0})"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Errors ({errorCount})"
|
||||
msgstr "Errors ({errorCount})"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(explore)/_layout.tsx
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
@@ -923,10 +981,13 @@ msgstr ""
|
||||
msgid "Failed to sign in"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Failed to start {0} connection"
|
||||
msgstr ""
|
||||
#~ msgid "Failed to start {0} connection"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Failed to start {sourceLabel} connection"
|
||||
msgstr "Failed to start {sourceLabel} connection"
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Failed to trigger job"
|
||||
@@ -1086,15 +1147,18 @@ msgstr ""
|
||||
msgid "Import failed"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {0}"
|
||||
msgstr ""
|
||||
#~ msgid "Import from {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {source}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {sourceLabel}"
|
||||
msgstr "Import from {sourceLabel}"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import is still running in the background. Check back later."
|
||||
@@ -1108,11 +1172,13 @@ msgstr ""
|
||||
msgid "Imported"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: event.job.importedCount
|
||||
#. placeholder {1}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Imported {0} items from {1}"
|
||||
msgstr ""
|
||||
#~ msgid "Imported {0} items from {1}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Imported {importedCount} items from {sourceLabel}"
|
||||
msgstr "Imported {importedCount} items from {sourceLabel}"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Importing from {source}"
|
||||
@@ -1158,14 +1224,12 @@ msgid "Job"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
#~ msgid "Keeping"
|
||||
#~ msgstr "Keeping"
|
||||
msgid "Keeping"
|
||||
msgstr "Keeping"
|
||||
|
||||
#. placeholder {0}: (value: string | null) => value === "0" ? t`unlimited` : value ? t`last ${value}` : null
|
||||
#. placeholder {1}: [3, 5, 7, 14, 30, 0].map((n) => ( <SelectItem key={n} value={String(n)}> {n === 0 ? t`unlimited` : t`last ${n}`} </SelectItem> ))
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
msgid "Keeping <0><1><2>{0}</2></1><3>{1}</3></0> backups."
|
||||
msgstr ""
|
||||
#~ msgid "Keeping <0><1><2>{0}</2></1><3>{1}</3></0> backups."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/command-palette.tsx
|
||||
#: apps/web/src/components/command-palette.tsx
|
||||
@@ -1186,19 +1250,25 @@ msgstr ""
|
||||
msgid "last {value}"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: formatRelativeTime(lastEventAt)
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last event {0}"
|
||||
msgstr ""
|
||||
#~ msgid "Last event {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last event {relativeTime}"
|
||||
msgstr "Last event {relativeTime}"
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
msgid "Last event {timeAgo}"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: formatRelativeTime(lastEventAt)
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last polled {0}"
|
||||
msgstr ""
|
||||
#~ msgid "Last polled {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last polled {relativeTime}"
|
||||
msgstr "Last polled {relativeTime}"
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
msgid "Last polled {timeAgo}"
|
||||
@@ -1327,10 +1397,13 @@ msgstr ""
|
||||
msgid "Movies"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: periodLabels[moviePeriod]
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Movies {0}"
|
||||
msgstr "Movies {0}"
|
||||
#~ msgid "Movies {0}"
|
||||
#~ msgstr "Movies {0}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Movies {period}"
|
||||
msgstr "Movies {period}"
|
||||
|
||||
#: apps/web/src/components/dashboard/stats-display.tsx
|
||||
#~ msgid "Movies {periodSelect}"
|
||||
@@ -1635,20 +1708,23 @@ msgstr ""
|
||||
msgid "Radarr List URL"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: input.stars
|
||||
#. placeholder {1}: input.stars
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
msgid "Rated {0} {1, plural, one {star} other {stars}}"
|
||||
msgstr ""
|
||||
#~ msgid "Rated {0} {1, plural, one {star} other {stars}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#~ msgid "Rated {0} star{1}"
|
||||
#~ msgstr "Rated {0} star{1}"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Rated {ratingStars} {ratingStars, plural, one {star} other {stars}}"
|
||||
msgstr ""
|
||||
msgid "Rated {ratingStars, plural, one {# star} other {# stars}}"
|
||||
msgstr "Rated {ratingStars, plural, one {# star} other {# stars}}"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#~ msgid "Rated {ratingStars} {ratingStars, plural, one {star} other {stars}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Rated {stars, plural, one {# star} other {# stars}}"
|
||||
msgstr ""
|
||||
@@ -1810,6 +1886,14 @@ msgstr ""
|
||||
msgid "Requires Emby Server 4.7.9+ and an active Emby Premiere license."
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Restart"
|
||||
msgstr "Restart"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Restart Required"
|
||||
msgstr "Restart Required"
|
||||
|
||||
#: apps/web/src/components/settings/backup-restore-section.tsx
|
||||
#: apps/web/src/components/settings/backup-restore-section.tsx
|
||||
msgid "Restore"
|
||||
@@ -1921,13 +2005,19 @@ msgstr ""
|
||||
msgid "Search…"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: season.seasonNumber
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Season {0}"
|
||||
msgstr ""
|
||||
#~ msgid "Season {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Season {seasonNumber}"
|
||||
msgstr "Season {seasonNumber}"
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
@@ -2018,12 +2108,18 @@ msgstr ""
|
||||
msgid "Sign in to continue"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: authConfig.data?.oidcProviderName ?? "SSO"
|
||||
#. placeholder {0}: authConfig?.oidcProviderName || "SSO"
|
||||
#: apps/native/src/app/(auth)/login.tsx
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
msgid "Sign in with {0}"
|
||||
msgstr ""
|
||||
#~ msgid "Sign in with {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
msgid "Sign in with {oidcProviderName}"
|
||||
msgstr "Sign in with {oidcProviderName}"
|
||||
|
||||
#: apps/native/src/app/(auth)/login.tsx
|
||||
msgid "Sign in with {providerName}"
|
||||
msgstr "Sign in with {providerName}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/native/src/components/header-avatar.tsx
|
||||
@@ -2048,10 +2144,17 @@ msgstr ""
|
||||
msgid "Skipped"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: data.latestVersion
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Sofa needs to restart to apply the new layout direction."
|
||||
msgstr "Sofa needs to restart to apply the new layout direction."
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "Sofa v{0} is available"
|
||||
msgstr ""
|
||||
#~ msgid "Sofa v{0} is available"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "Sofa v{latestVersion} is available"
|
||||
msgstr "Sofa v{latestVersion} is available"
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
@@ -2118,10 +2221,13 @@ msgstr ""
|
||||
msgid "Sunday"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: info.name
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
msgid "Switch to {0}"
|
||||
msgstr ""
|
||||
#~ msgid "Switch to {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
msgid "Switch to {name}"
|
||||
msgstr "Switch to {name}"
|
||||
|
||||
#: apps/native/src/app/+not-found.tsx
|
||||
msgid "The page you're looking for doesn't exist."
|
||||
@@ -2192,10 +2298,13 @@ msgstr ""
|
||||
msgid "This will mark every episode of this show as watched. You can undo this later by unmarking individual seasons."
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: formatBackupDate(backup.createdAt)
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "This will permanently delete the backup from <0>{0}</0>. This cannot be undone."
|
||||
msgstr ""
|
||||
#~ msgid "This will permanently delete the backup from <0>{0}</0>. This cannot be undone."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "This will permanently delete the backup from <0>{backupDate}</0>. This cannot be undone."
|
||||
msgstr "This will permanently delete the backup from <0>{backupDate}</0>. This cannot be undone."
|
||||
|
||||
#: apps/native/src/components/search/recently-viewed-list.ios.tsx
|
||||
#: apps/native/src/components/search/recently-viewed-list.tsx
|
||||
@@ -2327,10 +2436,13 @@ msgstr ""
|
||||
msgid "Unwatch all"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: season.name ?? t`Season ${season.seasonNumber}`
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched all of {0}"
|
||||
msgstr ""
|
||||
#~ msgid "Unwatched all of {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched all of {seasonLabel}"
|
||||
msgstr "Unwatched all of {seasonLabel}"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched S{seasonNum} E{epNum}"
|
||||
@@ -2341,10 +2453,13 @@ msgstr ""
|
||||
msgid "Up next"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: updateCheck.data.updateCheck.latestVersion
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Update available: {0}"
|
||||
msgstr ""
|
||||
#~ msgid "Update available: {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Update available: {latestVersion}"
|
||||
msgstr "Update available: {latestVersion}"
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Update check"
|
||||
@@ -2381,11 +2496,13 @@ msgstr ""
|
||||
msgid "Upload a .db file to replace the current database. A safety backup is created first."
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: config.accept
|
||||
#. placeholder {1}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload a {0} export from your {1} account settings."
|
||||
msgstr ""
|
||||
#~ msgid "Upload a {0} export from your {1} account settings."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload a {acceptFormat} export from your {sourceLabel} account settings."
|
||||
msgstr "Upload a {acceptFormat} export from your {sourceLabel} account settings."
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload export file"
|
||||
@@ -2419,10 +2536,13 @@ msgstr ""
|
||||
msgid "Warnings"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: result.warnings.length
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Warnings ({0})"
|
||||
msgstr ""
|
||||
#~ msgid "Warnings ({0})"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Warnings ({warningCount})"
|
||||
msgstr "Warnings ({warningCount})"
|
||||
|
||||
#: apps/web/src/components/titles/title-seasons.tsx
|
||||
msgid "Watch all"
|
||||
@@ -2505,10 +2625,13 @@ msgstr ""
|
||||
msgid "You'll be signed out to change the server URL."
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: data.currentVersion
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "You're running v{0}."
|
||||
msgstr ""
|
||||
#~ msgid "You're running v{0}."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "You're running v{currentVersion}."
|
||||
msgstr "You're running v{currentVersion}."
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Your code:"
|
||||
|
||||
+281
-157
@@ -8,20 +8,23 @@ msgstr ""
|
||||
"Language: es\n"
|
||||
"Project-Id-Version: sofa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-03-19 00:35\n"
|
||||
"PO-Revision-Date: 2026-03-20 23:13\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Spanish\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Crowdin-Project: sofa\n"
|
||||
"X-Crowdin-Project-ID: 881052\n"
|
||||
"X-Crowdin-Language: es-ES\n"
|
||||
"X-Crowdin-File: en.po\n"
|
||||
"X-Crowdin-File-ID: 14\n"
|
||||
"X-Crowdin-File: /packages/i18n/src/po/en.po\n"
|
||||
"X-Crowdin-File-ID: 26\n"
|
||||
|
||||
#. placeholder {0}: result.errors.length - 50
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "...and {0} more"
|
||||
msgstr "...y {0} más"
|
||||
#~ msgid "...and {0} more"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
@@ -33,86 +36,99 @@ msgstr "{0, plural, one {# imagen} other {# imágenes}}"
|
||||
msgid "{0, plural, one {# title} other {# titles}}"
|
||||
msgstr "{0, plural, one {# título} other {# títulos}}"
|
||||
|
||||
#. placeholder {0}: displayBackups.length
|
||||
#. placeholder {1}: displayBackups.length
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "{0} {1, plural, one {backup} other {backups}} stored"
|
||||
msgstr "{0} {1, plural, one {backup almacenado} other {backups almacenados}}"
|
||||
#~ msgid "{0} {1, plural, one {backup} other {backups}} stored"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
#~ msgid "{0} backup{1} stored"
|
||||
#~ msgstr "{0} backup{1} stored"
|
||||
|
||||
#. placeholder {0}: backups.backupCount
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} backups · last <0/>"
|
||||
msgstr "{0} backups · último <0/>"
|
||||
#~ msgid "{0} backups · last <0/>"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: imageCache.imageCount.toLocaleString()
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} cached images"
|
||||
msgstr "{0} imágenes en caché"
|
||||
#~ msgid "{0} cached images"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: member.episodeCount
|
||||
#. placeholder {1}: member.episodeCount !== 1 ? "s" : ""
|
||||
#: apps/web/src/components/titles/cast-carousel.tsx
|
||||
msgid "{0} ep{1}"
|
||||
msgstr "{0} ep{1}"
|
||||
#~ msgid "{0} ep{1}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#~ msgid "{0} images"
|
||||
#~ msgstr "{0} images"
|
||||
|
||||
#. placeholder {0}: stats.watchlist
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} items"
|
||||
msgstr "{0} elementos"
|
||||
#~ msgid "{0} items"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: preview.diagnostics.unresolved
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
msgstr "{0} elementos no tienen IDs externos y se resolverán por búsqueda de título, lo que puede ser menos preciso."
|
||||
#~ msgid "{0} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: stats.movies
|
||||
#. placeholder {1}: stats.episodes
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} movies, {1} episodes"
|
||||
msgstr "{0} películas, {1} episodios"
|
||||
#~ msgid "{0} movies, {1} episodes"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: stats.ratings
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} ratings"
|
||||
msgstr "{0} valoraciones"
|
||||
#~ msgid "{0} ratings"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#~ msgid "{0} titles"
|
||||
#~ msgstr "{0} titles"
|
||||
|
||||
#. placeholder {0}: JOB_LABELS[name] ?? name
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} triggered"
|
||||
msgstr "{0} iniciado"
|
||||
#~ msgid "{0} triggered"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: item.watchedEpisodes
|
||||
#. placeholder {1}: item.totalEpisodes
|
||||
#. placeholder {2}: item.totalEpisodes
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
msgid "{0}/{1} {2, plural, one {episode} other {episodes}}"
|
||||
msgstr "{0}/{1} {2, plural, one {episodio} other {episodios}}"
|
||||
#~ msgid "{0}/{1} {2, plural, one {episode} other {episodes}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
#~ msgid "{0}/{1} episodes"
|
||||
#~ msgstr "{0}/{1} episodes"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "{count} earlier {count, plural, one {episode} other {episodes}} unwatched"
|
||||
msgstr "{count} {count, plural, one {episodio anterior sin ver} other {episodios anteriores sin ver}}"
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "{backupCount, plural, one {# backup} other {# backups}} stored"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: activeJobs.length
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{healthyCount} of {0} jobs healthy"
|
||||
msgstr "{healthyCount} de {0} tareas en buen estado"
|
||||
msgid "{backupCount} backups · last <0/>"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{cachedImageCount} cached images"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "{count, plural, one {# earlier episode} other {# earlier episodes}} unwatched"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#~ msgid "{count} earlier {count, plural, one {episode} other {episodes}} unwatched"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/cast-carousel.tsx
|
||||
msgid "{count} ep{suffix}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
#~ msgid "{healthyCount} of {0} jobs healthy"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{healthyCount} of {activeJobCount} jobs healthy"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{jobLabel} triggered"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-card.tsx
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
@@ -129,25 +145,50 @@ msgstr "{label} desconectado"
|
||||
msgid "{label} URL regenerated"
|
||||
msgstr "URL de {label} regenerada"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{movieCount} movies, {episodeCount} episodes"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{ratingCount} ratings"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{unresolvedCount} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/title-card.tsx
|
||||
msgid "{watched}/{total} episodes"
|
||||
msgstr "{watched}/{total} episodios"
|
||||
|
||||
#. placeholder {0}: episodes.length
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount} of {0} episodes watched"
|
||||
msgstr "{watchedCount} de {0} episodios vistos"
|
||||
#~ msgid "{watchedCount} of {0} episodes watched"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: episodes.length
|
||||
#. placeholder {1}: episodes.length
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount}/{0} {1, plural, one {episode} other {episodes}}"
|
||||
msgstr "{watchedCount}/{0} {1, plural, one {episodio} other {episodios}}"
|
||||
msgid "{watchedCount} of {episodeCount} episodes watched"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#~ msgid "{watchedCount}/{0} {1, plural, one {episode} other {episodes}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#~ msgid "{watchedCount}/{0} episodes"
|
||||
#~ msgstr "{watchedCount}/{0} episodes"
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount}/{episodeCount, plural, one {# episode} other {# episodes}}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
msgid "{watchedEpisodes}/{totalEpisodes, plural, one {# episode} other {# episodes}}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{watchlistCount} items"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
msgid "Account"
|
||||
@@ -161,7 +202,7 @@ msgstr "Acciones"
|
||||
#: apps/native/src/components/search/recently-viewed-row-content.tsx
|
||||
#: apps/web/src/components/people/person-hero.tsx
|
||||
msgid "Actor"
|
||||
msgstr "Actor"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
msgid "Add a \"Generic Destination\" and paste the URL above"
|
||||
@@ -207,7 +248,7 @@ msgstr "Añadido a la lista"
|
||||
#: apps/web/src/components/nav-bar.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
msgid "Admin"
|
||||
msgstr "Admin"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/routes/_app/settings.tsx
|
||||
msgid "Admin only"
|
||||
@@ -268,10 +309,13 @@ msgstr "La autorización fue exitosa, pero no se pudo obtener tu biblioteca. Por
|
||||
msgid "Authorization was denied. Please try again."
|
||||
msgstr "La autorización fue denegada. Por favor, inténtalo de nuevo."
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Authorize Sofa to read your {0} library. No password shared."
|
||||
msgstr "Autoriza a Sofa a leer tu biblioteca de {0}. No se comparte ninguna contraseña."
|
||||
#~ msgid "Authorize Sofa to read your {0} library. No password shared."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Authorize Sofa to read your {sourceLabel} library. No password shared."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/update-check-section.tsx
|
||||
msgid "Automatic update checks"
|
||||
@@ -315,8 +359,8 @@ msgid "Backups"
|
||||
msgstr "Copias de seguridad"
|
||||
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
#~ msgid "backups."
|
||||
#~ msgstr "backups."
|
||||
msgid "backups."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Buy"
|
||||
@@ -374,11 +418,13 @@ msgstr "Ponerse al día"
|
||||
msgid "Caught Up"
|
||||
msgstr "Al día"
|
||||
|
||||
#. placeholder {0}: episodeIds.length
|
||||
#. placeholder {1}: episodeIds.length
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Caught up — marked {0} {1, plural, one {episode} other {episodes}} as watched"
|
||||
msgstr "Al día — {0} {1, plural, one {episodio marcado como visto} other {episodios marcados como vistos}}"
|
||||
#~ msgid "Caught up — marked {0} {1, plural, one {episode} other {episodes}} as watched"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Caught up — marked {count, plural, one {# episode} other {# episodes}} as watched"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
@@ -414,10 +460,13 @@ msgstr "Comprobado <0/>"
|
||||
msgid "Checking…"
|
||||
msgstr "Comprobando…"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Choose how to import your {0} data."
|
||||
msgstr "Elige cómo importar tus datos de {0}."
|
||||
#~ msgid "Choose how to import your {0} data."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Choose how to import your {sourceLabel} data."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
#~ msgid "Choose your preferred display language"
|
||||
@@ -480,12 +529,12 @@ msgstr "Confirmar nueva contraseña"
|
||||
msgid "Connect"
|
||||
msgstr "Conectar"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Connect {0}"
|
||||
msgstr "Conectar {0}"
|
||||
#~ msgid "Connect {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-card.tsx
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Connect {label}"
|
||||
msgstr "Conectar {label}"
|
||||
|
||||
@@ -497,10 +546,13 @@ msgstr "Conectar con {source}"
|
||||
msgid "Connect to TMDB"
|
||||
msgstr "Conectar con TMDB"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Connect with {0}"
|
||||
msgstr "Conectar con {0}"
|
||||
#~ msgid "Connect with {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Connect with {sourceLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/server-url.tsx
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
@@ -647,7 +699,7 @@ msgstr "falleció a los {age}"
|
||||
#: apps/native/src/components/search/recently-viewed-row-content.tsx
|
||||
#: apps/web/src/components/people/person-hero.tsx
|
||||
msgid "Director"
|
||||
msgstr "Director"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
@@ -697,7 +749,7 @@ msgstr "Descargar copia de seguridad"
|
||||
#: apps/native/src/components/search/recently-viewed-row-content.tsx
|
||||
#: apps/web/src/components/people/person-hero.tsx
|
||||
msgid "Editor"
|
||||
msgstr "Editor"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/login.tsx
|
||||
#: apps/native/src/app/(auth)/register.tsx
|
||||
@@ -740,11 +792,11 @@ msgstr "Entorno"
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#~ msgid "Episode {0}"
|
||||
#~ msgstr "Episodio {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#~ msgid "Episode {0}, {episodeLabel}"
|
||||
#~ msgstr "Episodio {0}, {episodeLabel}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
@@ -770,10 +822,13 @@ msgstr "Episodio marcado como visto"
|
||||
msgid "Episodes"
|
||||
msgstr "Episodios"
|
||||
|
||||
#. placeholder {0}: periodLabels[episodePeriod]
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Episodes {0}"
|
||||
msgstr "Episodios {0}"
|
||||
#~ msgid "Episodes {0}"
|
||||
#~ msgstr "Episodes {0}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Episodes {period}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/stats-display.tsx
|
||||
#~ msgid "Episodes {periodSelect}"
|
||||
@@ -785,17 +840,20 @@ msgstr "Episodios {select}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
#~ msgid "Episodes this week"
|
||||
#~ msgstr "Episodios esta semana"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/change-password.tsx
|
||||
#: apps/native/src/app/change-password.tsx
|
||||
msgid "Error"
|
||||
msgstr "Error"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: result.errors.length
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Errors ({0})"
|
||||
msgstr "Errores ({0})"
|
||||
#~ msgid "Errors ({0})"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Errors ({errorCount})"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(explore)/_layout.tsx
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
@@ -923,10 +981,13 @@ msgstr "Error al eliminar la foto de perfil"
|
||||
msgid "Failed to sign in"
|
||||
msgstr "Error al iniciar sesión"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Failed to start {0} connection"
|
||||
msgstr "Error al iniciar la conexión con {0}"
|
||||
#~ msgid "Failed to start {0} connection"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Failed to start {sourceLabel} connection"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Failed to trigger job"
|
||||
@@ -1086,15 +1147,18 @@ msgstr "Importación completada"
|
||||
msgid "Import failed"
|
||||
msgstr "Error en la importación"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {0}"
|
||||
msgstr "Importar desde {0}"
|
||||
#~ msgid "Import from {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {source}"
|
||||
msgstr "Importar desde {source}"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {sourceLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import is still running in the background. Check back later."
|
||||
@@ -1108,11 +1172,13 @@ msgstr "Opciones de importación"
|
||||
msgid "Imported"
|
||||
msgstr "Importado"
|
||||
|
||||
#. placeholder {0}: event.job.importedCount
|
||||
#. placeholder {1}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Imported {0} items from {1}"
|
||||
msgstr "{0} elementos importados desde {1}"
|
||||
#~ msgid "Imported {0} items from {1}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Imported {importedCount} items from {sourceLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Importing from {source}"
|
||||
@@ -1158,14 +1224,12 @@ msgid "Job"
|
||||
msgstr "Tarea"
|
||||
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
#~ msgid "Keeping"
|
||||
#~ msgstr "Keeping"
|
||||
msgid "Keeping"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: (value: string | null) => value === "0" ? t`unlimited` : value ? t`last ${value}` : null
|
||||
#. placeholder {1}: [3, 5, 7, 14, 30, 0].map((n) => ( <SelectItem key={n} value={String(n)}> {n === 0 ? t`unlimited` : t`last ${n}`} </SelectItem> ))
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
msgid "Keeping <0><1><2>{0}</2></1><3>{1}</3></0> backups."
|
||||
msgstr "Guardando <0><1><2>{0}</2></1><3>{1}</3></0> copias de seguridad."
|
||||
#~ msgid "Keeping <0><1><2>{0}</2></1><3>{1}</3></0> backups."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/command-palette.tsx
|
||||
#: apps/web/src/components/command-palette.tsx
|
||||
@@ -1186,19 +1250,25 @@ msgstr "últimos {n}"
|
||||
msgid "last {value}"
|
||||
msgstr "últimos {value}"
|
||||
|
||||
#. placeholder {0}: formatRelativeTime(lastEventAt)
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last event {0}"
|
||||
msgstr "Último evento {0}"
|
||||
#~ msgid "Last event {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last event {relativeTime}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
msgid "Last event {timeAgo}"
|
||||
msgstr "Último evento {timeAgo}"
|
||||
|
||||
#. placeholder {0}: formatRelativeTime(lastEventAt)
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last polled {0}"
|
||||
msgstr "Última consulta {0}"
|
||||
#~ msgid "Last polled {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last polled {relativeTime}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
msgid "Last polled {timeAgo}"
|
||||
@@ -1249,7 +1319,7 @@ msgstr "Marcar todos como vistos"
|
||||
|
||||
#: apps/native/src/components/dashboard/continue-watching-card.tsx
|
||||
#~ msgid "Mark as Completed"
|
||||
#~ msgstr "Marcar como completado"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/ui/poster-card.tsx
|
||||
msgid "Mark as Watched"
|
||||
@@ -1257,7 +1327,7 @@ msgstr "Marcar como visto"
|
||||
|
||||
#: apps/native/src/components/ui/poster-card.tsx
|
||||
#~ msgid "Mark as Watching"
|
||||
#~ msgstr "Marcar como en curso"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/title/[id].tsx
|
||||
#: apps/web/src/components/titles/title-actions.tsx
|
||||
@@ -1266,7 +1336,7 @@ msgstr "Marcar como visto"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#~ msgid "Marked \"{titleName}\" as completed"
|
||||
#~ msgstr "\"{titleName}\" marcado como completado"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
@@ -1285,7 +1355,7 @@ msgstr "Se marcaron todos los episodios de \"{titleName}\" como vistos"
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#~ msgid "Marked as completed"
|
||||
#~ msgstr "Marcado como completado"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
@@ -1295,7 +1365,7 @@ msgstr "Marcado como visto"
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#~ msgid "Marked as watching"
|
||||
#~ msgstr "Marcado como en curso"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
msgid "Member since {memberSince}"
|
||||
@@ -1327,10 +1397,13 @@ msgstr "Película"
|
||||
msgid "Movies"
|
||||
msgstr "Películas"
|
||||
|
||||
#. placeholder {0}: periodLabels[moviePeriod]
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Movies {0}"
|
||||
msgstr "Películas {0}"
|
||||
#~ msgid "Movies {0}"
|
||||
#~ msgstr "Movies {0}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Movies {period}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/stats-display.tsx
|
||||
#~ msgid "Movies {periodSelect}"
|
||||
@@ -1342,7 +1415,7 @@ msgstr "Películas {select}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
#~ msgid "Movies this month"
|
||||
#~ msgstr "Películas este mes"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/register.tsx
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
@@ -1635,20 +1708,23 @@ msgstr "Acciones rápidas"
|
||||
msgid "Radarr List URL"
|
||||
msgstr "URL de lista de Radarr"
|
||||
|
||||
#. placeholder {0}: input.stars
|
||||
#. placeholder {1}: input.stars
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
msgid "Rated {0} {1, plural, one {star} other {stars}}"
|
||||
msgstr "Valorado con {0} {1, plural, one {estrella} other {estrellas}}"
|
||||
#~ msgid "Rated {0} {1, plural, one {star} other {stars}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#~ msgid "Rated {0} star{1}"
|
||||
#~ msgstr "Rated {0} star{1}"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Rated {ratingStars} {ratingStars, plural, one {star} other {stars}}"
|
||||
msgstr "Valorado con {ratingStars} {ratingStars, plural, one {estrella} other {estrellas}}"
|
||||
msgid "Rated {ratingStars, plural, one {# star} other {# stars}}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#~ msgid "Rated {ratingStars} {ratingStars, plural, one {star} other {stars}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Rated {stars, plural, one {# star} other {# stars}}"
|
||||
msgstr "Valorado con {stars, plural, one {# estrella} other {# estrellas}}"
|
||||
@@ -1810,6 +1886,14 @@ msgstr "Requiere una suscripción activa de Plex Pass."
|
||||
msgid "Requires Emby Server 4.7.9+ and an active Emby Premiere license."
|
||||
msgstr "Requiere Emby Server 4.7.9+ y una licencia activa de Emby Premiere."
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Restart"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Restart Required"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-restore-section.tsx
|
||||
#: apps/web/src/components/settings/backup-restore-section.tsx
|
||||
msgid "Restore"
|
||||
@@ -1921,13 +2005,19 @@ msgstr "Buscar películas, series, personas..."
|
||||
msgid "Search…"
|
||||
msgstr "Buscar…"
|
||||
|
||||
#. placeholder {0}: season.seasonNumber
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Season {0}"
|
||||
msgstr "Temporada {0}"
|
||||
#~ msgid "Season {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Season {seasonNumber}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
@@ -2018,12 +2108,18 @@ msgstr "Iniciar sesión"
|
||||
msgid "Sign in to continue"
|
||||
msgstr "Inicia sesión para continuar"
|
||||
|
||||
#. placeholder {0}: authConfig.data?.oidcProviderName ?? "SSO"
|
||||
#. placeholder {0}: authConfig?.oidcProviderName || "SSO"
|
||||
#: apps/native/src/app/(auth)/login.tsx
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
msgid "Sign in with {0}"
|
||||
msgstr "Iniciar sesión con {0}"
|
||||
#~ msgid "Sign in with {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
msgid "Sign in with {oidcProviderName}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/login.tsx
|
||||
msgid "Sign in with {providerName}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/native/src/components/header-avatar.tsx
|
||||
@@ -2048,10 +2144,17 @@ msgstr "Cerrar otras sesiones"
|
||||
msgid "Skipped"
|
||||
msgstr "Omitido"
|
||||
|
||||
#. placeholder {0}: data.latestVersion
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Sofa needs to restart to apply the new layout direction."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "Sofa v{0} is available"
|
||||
msgstr "Sofa v{0} disponible"
|
||||
#~ msgid "Sofa v{0} is available"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "Sofa v{latestVersion} is available"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
@@ -2118,10 +2221,13 @@ msgstr "Streaming"
|
||||
msgid "Sunday"
|
||||
msgstr "Domingo"
|
||||
|
||||
#. placeholder {0}: info.name
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
msgid "Switch to {0}"
|
||||
msgstr "Cambiar a {0}"
|
||||
#~ msgid "Switch to {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
msgid "Switch to {name}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/+not-found.tsx
|
||||
msgid "The page you're looking for doesn't exist."
|
||||
@@ -2192,10 +2298,13 @@ msgstr "Esto invalidará la URL actual de {label}. Tendrás que actualizarla en
|
||||
msgid "This will mark every episode of this show as watched. You can undo this later by unmarking individual seasons."
|
||||
msgstr "Esto marcará todos los episodios de esta serie como vistos. Puedes deshacerlo más tarde desmarcando temporadas individuales."
|
||||
|
||||
#. placeholder {0}: formatBackupDate(backup.createdAt)
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "This will permanently delete the backup from <0>{0}</0>. This cannot be undone."
|
||||
msgstr "Esto eliminará permanentemente la copia de seguridad del <0>{0}</0>. Esta acción no se puede deshacer."
|
||||
#~ msgid "This will permanently delete the backup from <0>{0}</0>. This cannot be undone."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "This will permanently delete the backup from <0>{backupDate}</0>. This cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/search/recently-viewed-list.ios.tsx
|
||||
#: apps/native/src/components/search/recently-viewed-list.tsx
|
||||
@@ -2327,10 +2436,13 @@ msgstr "Sin título"
|
||||
msgid "Unwatch all"
|
||||
msgstr "Desmarcar todo"
|
||||
|
||||
#. placeholder {0}: season.name ?? t`Season ${season.seasonNumber}`
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched all of {0}"
|
||||
msgstr "Todo de {0} marcado como no visto"
|
||||
#~ msgid "Unwatched all of {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched all of {seasonLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched S{seasonNum} E{epNum}"
|
||||
@@ -2341,10 +2453,13 @@ msgstr "No visto T{seasonNum} E{epNum}"
|
||||
msgid "Up next"
|
||||
msgstr "A continuación"
|
||||
|
||||
#. placeholder {0}: updateCheck.data.updateCheck.latestVersion
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Update available: {0}"
|
||||
msgstr "Actualización disponible: {0}"
|
||||
#~ msgid "Update available: {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Update available: {latestVersion}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Update check"
|
||||
@@ -2381,11 +2496,13 @@ msgstr "Subir"
|
||||
msgid "Upload a .db file to replace the current database. A safety backup is created first."
|
||||
msgstr "Sube un archivo .db para reemplazar la base de datos actual. Primero se crea una copia de seguridad."
|
||||
|
||||
#. placeholder {0}: config.accept
|
||||
#. placeholder {1}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload a {0} export from your {1} account settings."
|
||||
msgstr "Sube una exportación {0} desde los ajustes de tu cuenta de {1}."
|
||||
#~ msgid "Upload a {0} export from your {1} account settings."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload a {acceptFormat} export from your {sourceLabel} account settings."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload export file"
|
||||
@@ -2419,10 +2536,13 @@ msgstr "Esperando autorización..."
|
||||
msgid "Warnings"
|
||||
msgstr "Advertencias"
|
||||
|
||||
#. placeholder {0}: result.warnings.length
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Warnings ({0})"
|
||||
msgstr "Advertencias ({0})"
|
||||
#~ msgid "Warnings ({0})"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Warnings ({warningCount})"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-seasons.tsx
|
||||
msgid "Watch all"
|
||||
@@ -2465,7 +2585,7 @@ msgstr "Lista"
|
||||
|
||||
#: apps/native/src/components/titles/status-action-button.tsx
|
||||
#~ msgid "Watchlisted"
|
||||
#~ msgstr "En lista"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
@@ -2505,10 +2625,13 @@ msgstr "Guionista"
|
||||
msgid "You'll be signed out to change the server URL."
|
||||
msgstr "Se cerrará tu sesión para cambiar la URL del servidor."
|
||||
|
||||
#. placeholder {0}: data.currentVersion
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "You're running v{0}."
|
||||
msgstr "Estás usando la v{0}."
|
||||
#~ msgid "You're running v{0}."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "You're running v{currentVersion}."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Your code:"
|
||||
@@ -2522,3 +2645,4 @@ msgstr "Tu biblioteca está vacía"
|
||||
#: apps/native/src/app/(auth)/register.tsx
|
||||
msgid "Your name"
|
||||
msgstr "Tu nombre"
|
||||
|
||||
|
||||
+280
-156
@@ -8,111 +8,127 @@ msgstr ""
|
||||
"Language: fr\n"
|
||||
"Project-Id-Version: sofa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-03-19 00:35\n"
|
||||
"PO-Revision-Date: 2026-03-20 23:13\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: French\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Crowdin-Project: sofa\n"
|
||||
"X-Crowdin-Project-ID: 881052\n"
|
||||
"X-Crowdin-Language: fr\n"
|
||||
"X-Crowdin-File: en.po\n"
|
||||
"X-Crowdin-File-ID: 14\n"
|
||||
"X-Crowdin-File: /packages/i18n/src/po/en.po\n"
|
||||
"X-Crowdin-File-ID: 26\n"
|
||||
|
||||
#. placeholder {0}: result.errors.length - 50
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "...and {0} more"
|
||||
msgstr "...et {0} de plus"
|
||||
#~ msgid "...and {0} more"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "{0, plural, one {# image} other {# images}}"
|
||||
msgstr "{0, plural, one {# image} other {# images}}"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.database.titleCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "{0, plural, one {# title} other {# titles}}"
|
||||
msgstr "{0, plural, one {# titre} other {# titres}}"
|
||||
|
||||
#. placeholder {0}: displayBackups.length
|
||||
#. placeholder {1}: displayBackups.length
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "{0} {1, plural, one {backup} other {backups}} stored"
|
||||
msgstr "{0} {1, plural, one {sauvegarde stockée} other {sauvegardes stockées}}"
|
||||
#~ msgid "{0} {1, plural, one {backup} other {backups}} stored"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
#~ msgid "{0} backup{1} stored"
|
||||
#~ msgstr "{0} backup{1} stored"
|
||||
|
||||
#. placeholder {0}: backups.backupCount
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} backups · last <0/>"
|
||||
msgstr "{0} sauvegardes · dernière <0/>"
|
||||
#~ msgid "{0} backups · last <0/>"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: imageCache.imageCount.toLocaleString()
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} cached images"
|
||||
msgstr "{0} images en cache"
|
||||
#~ msgid "{0} cached images"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: member.episodeCount
|
||||
#. placeholder {1}: member.episodeCount !== 1 ? "s" : ""
|
||||
#: apps/web/src/components/titles/cast-carousel.tsx
|
||||
msgid "{0} ep{1}"
|
||||
msgstr "{0} ép{1}"
|
||||
#~ msgid "{0} ep{1}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#~ msgid "{0} images"
|
||||
#~ msgstr "{0} images"
|
||||
|
||||
#. placeholder {0}: stats.watchlist
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} items"
|
||||
msgstr "{0} éléments"
|
||||
#~ msgid "{0} items"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: preview.diagnostics.unresolved
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
msgstr "{0} éléments n'ont pas d'identifiants externes et seront résolus par recherche de titre, ce qui peut être moins précis."
|
||||
#~ msgid "{0} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: stats.movies
|
||||
#. placeholder {1}: stats.episodes
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} movies, {1} episodes"
|
||||
msgstr "{0} films, {1} épisodes"
|
||||
#~ msgid "{0} movies, {1} episodes"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: stats.ratings
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} ratings"
|
||||
msgstr "{0} notes"
|
||||
#~ msgid "{0} ratings"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#~ msgid "{0} titles"
|
||||
#~ msgstr "{0} titles"
|
||||
|
||||
#. placeholder {0}: JOB_LABELS[name] ?? name
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} triggered"
|
||||
msgstr "{0} déclenché"
|
||||
#~ msgid "{0} triggered"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: item.watchedEpisodes
|
||||
#. placeholder {1}: item.totalEpisodes
|
||||
#. placeholder {2}: item.totalEpisodes
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
msgid "{0}/{1} {2, plural, one {episode} other {episodes}}"
|
||||
msgstr "{0}/{1} {2, plural, one {épisode} other {épisodes}}"
|
||||
#~ msgid "{0}/{1} {2, plural, one {episode} other {episodes}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
#~ msgid "{0}/{1} episodes"
|
||||
#~ msgstr "{0}/{1} episodes"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "{count} earlier {count, plural, one {episode} other {episodes}} unwatched"
|
||||
msgstr "{count} {count, plural, one {épisode précédent non visionné} other {épisodes précédents non visionnés}}"
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "{backupCount, plural, one {# backup} other {# backups}} stored"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: activeJobs.length
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{healthyCount} of {0} jobs healthy"
|
||||
msgstr "{healthyCount} sur {0} tâches en bonne santé"
|
||||
msgid "{backupCount} backups · last <0/>"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{cachedImageCount} cached images"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "{count, plural, one {# earlier episode} other {# earlier episodes}} unwatched"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#~ msgid "{count} earlier {count, plural, one {episode} other {episodes}} unwatched"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/cast-carousel.tsx
|
||||
msgid "{count} ep{suffix}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
#~ msgid "{healthyCount} of {0} jobs healthy"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{healthyCount} of {activeJobCount} jobs healthy"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{jobLabel} triggered"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-card.tsx
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
@@ -129,25 +145,50 @@ msgstr "{label} déconnecté"
|
||||
msgid "{label} URL regenerated"
|
||||
msgstr "URL {label} régénérée"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{movieCount} movies, {episodeCount} episodes"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{ratingCount} ratings"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{unresolvedCount} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/title-card.tsx
|
||||
msgid "{watched}/{total} episodes"
|
||||
msgstr "{watched}/{total} épisodes"
|
||||
|
||||
#. placeholder {0}: episodes.length
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount} of {0} episodes watched"
|
||||
msgstr "{watchedCount} sur {0} épisodes regardés"
|
||||
#~ msgid "{watchedCount} of {0} episodes watched"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: episodes.length
|
||||
#. placeholder {1}: episodes.length
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount}/{0} {1, plural, one {episode} other {episodes}}"
|
||||
msgstr "{watchedCount}/{0} {1, plural, one {épisode} other {épisodes}}"
|
||||
msgid "{watchedCount} of {episodeCount} episodes watched"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#~ msgid "{watchedCount}/{0} {1, plural, one {episode} other {episodes}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#~ msgid "{watchedCount}/{0} episodes"
|
||||
#~ msgstr "{watchedCount}/{0} episodes"
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount}/{episodeCount, plural, one {# episode} other {# episodes}}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
msgid "{watchedEpisodes}/{totalEpisodes, plural, one {# episode} other {# episodes}}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{watchlistCount} items"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
msgid "Account"
|
||||
@@ -155,7 +196,7 @@ msgstr "Compte"
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Actions"
|
||||
msgstr "Actions"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/person/[id].tsx
|
||||
#: apps/native/src/components/search/recently-viewed-row-content.tsx
|
||||
@@ -207,7 +248,7 @@ msgstr "Ajouté à la liste de suivi"
|
||||
#: apps/web/src/components/nav-bar.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
msgid "Admin"
|
||||
msgstr "Admin"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/routes/_app/settings.tsx
|
||||
msgid "Admin only"
|
||||
@@ -249,7 +290,7 @@ msgstr "Paramètres de l'application"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Application"
|
||||
msgstr "Application"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-card.tsx
|
||||
msgid "Are you sure you want to disconnect {label}? The current URL will stop working."
|
||||
@@ -268,10 +309,13 @@ msgstr "L'autorisation a réussi mais la récupération de votre bibliothèque a
|
||||
msgid "Authorization was denied. Please try again."
|
||||
msgstr "L'autorisation a été refusée. Veuillez réessayer."
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Authorize Sofa to read your {0} library. No password shared."
|
||||
msgstr "Autorisez Sofa à lire votre bibliothèque {0}. Aucun mot de passe partagé."
|
||||
#~ msgid "Authorize Sofa to read your {0} library. No password shared."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Authorize Sofa to read your {sourceLabel} library. No password shared."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/update-check-section.tsx
|
||||
msgid "Automatic update checks"
|
||||
@@ -315,8 +359,8 @@ msgid "Backups"
|
||||
msgstr "Sauvegardes"
|
||||
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
#~ msgid "backups."
|
||||
#~ msgstr "backups."
|
||||
msgid "backups."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Buy"
|
||||
@@ -374,11 +418,13 @@ msgstr "Rattraper"
|
||||
msgid "Caught Up"
|
||||
msgstr "À jour"
|
||||
|
||||
#. placeholder {0}: episodeIds.length
|
||||
#. placeholder {1}: episodeIds.length
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Caught up — marked {0} {1, plural, one {episode} other {episodes}} as watched"
|
||||
msgstr "Rattrapé — {0} {1, plural, one {épisode marqué comme visionné} other {épisodes marqués comme visionnés}}"
|
||||
#~ msgid "Caught up — marked {0} {1, plural, one {episode} other {episodes}} as watched"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Caught up — marked {count, plural, one {# episode} other {# episodes}} as watched"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
@@ -414,10 +460,13 @@ msgstr "Vérifié <0/>"
|
||||
msgid "Checking…"
|
||||
msgstr "Vérification…"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Choose how to import your {0} data."
|
||||
msgstr "Choisissez comment importer vos données {0}."
|
||||
#~ msgid "Choose how to import your {0} data."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Choose how to import your {sourceLabel} data."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
#~ msgid "Choose your preferred display language"
|
||||
@@ -480,12 +529,12 @@ msgstr "Confirmer le nouveau mot de passe"
|
||||
msgid "Connect"
|
||||
msgstr "Connecter"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Connect {0}"
|
||||
msgstr "Connecter {0}"
|
||||
#~ msgid "Connect {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-card.tsx
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Connect {label}"
|
||||
msgstr "Connecter {label}"
|
||||
|
||||
@@ -497,10 +546,13 @@ msgstr "Se connecter à {source}"
|
||||
msgid "Connect to TMDB"
|
||||
msgstr "Se connecter à TMDB"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Connect with {0}"
|
||||
msgstr "Se connecter avec {0}"
|
||||
#~ msgid "Connect with {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Connect with {sourceLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/server-url.tsx
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
@@ -740,11 +792,11 @@ msgstr "Environnement"
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#~ msgid "Episode {0}"
|
||||
#~ msgstr "Épisode {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#~ msgid "Episode {0}, {episodeLabel}"
|
||||
#~ msgstr "Épisode {0}, {episodeLabel}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
@@ -770,10 +822,13 @@ msgstr "Épisode visionné"
|
||||
msgid "Episodes"
|
||||
msgstr "Épisodes"
|
||||
|
||||
#. placeholder {0}: periodLabels[episodePeriod]
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Episodes {0}"
|
||||
msgstr "Épisodes {0}"
|
||||
#~ msgid "Episodes {0}"
|
||||
#~ msgstr "Episodes {0}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Episodes {period}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/stats-display.tsx
|
||||
#~ msgid "Episodes {periodSelect}"
|
||||
@@ -785,17 +840,20 @@ msgstr "Épisodes {select}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
#~ msgid "Episodes this week"
|
||||
#~ msgstr "Épisodes cette semaine"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/change-password.tsx
|
||||
#: apps/native/src/app/change-password.tsx
|
||||
msgid "Error"
|
||||
msgstr "Erreur"
|
||||
|
||||
#. placeholder {0}: result.errors.length
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Errors ({0})"
|
||||
msgstr "Erreurs ({0})"
|
||||
#~ msgid "Errors ({0})"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Errors ({errorCount})"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(explore)/_layout.tsx
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
@@ -923,10 +981,13 @@ msgstr "Échec de la suppression de la photo de profil"
|
||||
msgid "Failed to sign in"
|
||||
msgstr "Échec de la connexion"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Failed to start {0} connection"
|
||||
msgstr "Échec du démarrage de la connexion {0}"
|
||||
#~ msgid "Failed to start {0} connection"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Failed to start {sourceLabel} connection"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Failed to trigger job"
|
||||
@@ -1086,15 +1147,18 @@ msgstr "Importation terminée"
|
||||
msgid "Import failed"
|
||||
msgstr "Importation échouée"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {0}"
|
||||
msgstr "Importer depuis {0}"
|
||||
#~ msgid "Import from {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {source}"
|
||||
msgstr "Importer depuis {source}"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {sourceLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import is still running in the background. Check back later."
|
||||
@@ -1108,11 +1172,13 @@ msgstr "Options d'importation"
|
||||
msgid "Imported"
|
||||
msgstr "Importé"
|
||||
|
||||
#. placeholder {0}: event.job.importedCount
|
||||
#. placeholder {1}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Imported {0} items from {1}"
|
||||
msgstr "{0} éléments importés depuis {1}"
|
||||
#~ msgid "Imported {0} items from {1}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Imported {importedCount} items from {sourceLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Importing from {source}"
|
||||
@@ -1158,14 +1224,12 @@ msgid "Job"
|
||||
msgstr "Tâche"
|
||||
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
#~ msgid "Keeping"
|
||||
#~ msgstr "Keeping"
|
||||
msgid "Keeping"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: (value: string | null) => value === "0" ? t`unlimited` : value ? t`last ${value}` : null
|
||||
#. placeholder {1}: [3, 5, 7, 14, 30, 0].map((n) => ( <SelectItem key={n} value={String(n)}> {n === 0 ? t`unlimited` : t`last ${n}`} </SelectItem> ))
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
msgid "Keeping <0><1><2>{0}</2></1><3>{1}</3></0> backups."
|
||||
msgstr "Conservation de <0><1><2>{0}</2></1><3>{1}</3></0> sauvegardes."
|
||||
#~ msgid "Keeping <0><1><2>{0}</2></1><3>{1}</3></0> backups."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/command-palette.tsx
|
||||
#: apps/web/src/components/command-palette.tsx
|
||||
@@ -1186,19 +1250,25 @@ msgstr "{n} dernières"
|
||||
msgid "last {value}"
|
||||
msgstr "{value} dernières"
|
||||
|
||||
#. placeholder {0}: formatRelativeTime(lastEventAt)
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last event {0}"
|
||||
msgstr "Dernier événement {0}"
|
||||
#~ msgid "Last event {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last event {relativeTime}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
msgid "Last event {timeAgo}"
|
||||
msgstr "Dernier événement {timeAgo}"
|
||||
|
||||
#. placeholder {0}: formatRelativeTime(lastEventAt)
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last polled {0}"
|
||||
msgstr "Dernière interrogation {0}"
|
||||
#~ msgid "Last polled {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last polled {relativeTime}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
msgid "Last polled {timeAgo}"
|
||||
@@ -1249,7 +1319,7 @@ msgstr "Tout marquer comme visionné"
|
||||
|
||||
#: apps/native/src/components/dashboard/continue-watching-card.tsx
|
||||
#~ msgid "Mark as Completed"
|
||||
#~ msgstr "Marquer comme terminé"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/ui/poster-card.tsx
|
||||
msgid "Mark as Watched"
|
||||
@@ -1257,7 +1327,7 @@ msgstr "Marquer comme visionné"
|
||||
|
||||
#: apps/native/src/components/ui/poster-card.tsx
|
||||
#~ msgid "Mark as Watching"
|
||||
#~ msgstr "Marquer comme en cours"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/title/[id].tsx
|
||||
#: apps/web/src/components/titles/title-actions.tsx
|
||||
@@ -1266,7 +1336,7 @@ msgstr "Marquer comme visionné"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#~ msgid "Marked \"{titleName}\" as completed"
|
||||
#~ msgstr "« {titleName} » marqué comme terminé"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
@@ -1285,7 +1355,7 @@ msgstr "Tous les épisodes de \"{titleName}\" marqués comme vus"
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#~ msgid "Marked as completed"
|
||||
#~ msgstr "Marqué comme terminé"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
@@ -1295,7 +1365,7 @@ msgstr "Marqué comme visionné"
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#~ msgid "Marked as watching"
|
||||
#~ msgstr "Marqué comme en cours"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
msgid "Member since {memberSince}"
|
||||
@@ -1327,10 +1397,13 @@ msgstr "Film"
|
||||
msgid "Movies"
|
||||
msgstr "Films"
|
||||
|
||||
#. placeholder {0}: periodLabels[moviePeriod]
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Movies {0}"
|
||||
msgstr "Films {0}"
|
||||
#~ msgid "Movies {0}"
|
||||
#~ msgstr "Movies {0}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Movies {period}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/stats-display.tsx
|
||||
#~ msgid "Movies {periodSelect}"
|
||||
@@ -1342,7 +1415,7 @@ msgstr "Films {select}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
#~ msgid "Movies this month"
|
||||
#~ msgstr "Films ce mois-ci"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/register.tsx
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
@@ -1635,20 +1708,23 @@ msgstr "Actions rapides"
|
||||
msgid "Radarr List URL"
|
||||
msgstr "URL de liste Radarr"
|
||||
|
||||
#. placeholder {0}: input.stars
|
||||
#. placeholder {1}: input.stars
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
msgid "Rated {0} {1, plural, one {star} other {stars}}"
|
||||
msgstr "Noté {0} {1, plural, one {étoile} other {étoiles}}"
|
||||
#~ msgid "Rated {0} {1, plural, one {star} other {stars}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#~ msgid "Rated {0} star{1}"
|
||||
#~ msgstr "Rated {0} star{1}"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Rated {ratingStars} {ratingStars, plural, one {star} other {stars}}"
|
||||
msgstr "Noté {ratingStars} {ratingStars, plural, one {étoile} other {étoiles}}"
|
||||
msgid "Rated {ratingStars, plural, one {# star} other {# stars}}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#~ msgid "Rated {ratingStars} {ratingStars, plural, one {star} other {stars}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Rated {stars, plural, one {# star} other {# stars}}"
|
||||
msgstr "Noté {stars, plural, one {# étoile} other {# étoiles}}"
|
||||
@@ -1810,6 +1886,14 @@ msgstr "Nécessite un abonnement Plex Pass actif."
|
||||
msgid "Requires Emby Server 4.7.9+ and an active Emby Premiere license."
|
||||
msgstr "Nécessite Emby Server 4.7.9+ et une licence Emby Premiere active."
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Restart"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Restart Required"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-restore-section.tsx
|
||||
#: apps/web/src/components/settings/backup-restore-section.tsx
|
||||
msgid "Restore"
|
||||
@@ -1921,13 +2005,19 @@ msgstr "Rechercher des films, séries, personnes..."
|
||||
msgid "Search…"
|
||||
msgstr "Rechercher…"
|
||||
|
||||
#. placeholder {0}: season.seasonNumber
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Season {0}"
|
||||
msgstr "Saison {0}"
|
||||
#~ msgid "Season {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Season {seasonNumber}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
@@ -2018,12 +2108,18 @@ msgstr "Se connecter"
|
||||
msgid "Sign in to continue"
|
||||
msgstr "Connectez-vous pour continuer"
|
||||
|
||||
#. placeholder {0}: authConfig.data?.oidcProviderName ?? "SSO"
|
||||
#. placeholder {0}: authConfig?.oidcProviderName || "SSO"
|
||||
#: apps/native/src/app/(auth)/login.tsx
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
msgid "Sign in with {0}"
|
||||
msgstr "Se connecter avec {0}"
|
||||
#~ msgid "Sign in with {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
msgid "Sign in with {oidcProviderName}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/login.tsx
|
||||
msgid "Sign in with {providerName}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/native/src/components/header-avatar.tsx
|
||||
@@ -2048,10 +2144,17 @@ msgstr "Se déconnecter des autres sessions"
|
||||
msgid "Skipped"
|
||||
msgstr "Ignoré"
|
||||
|
||||
#. placeholder {0}: data.latestVersion
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Sofa needs to restart to apply the new layout direction."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "Sofa v{0} is available"
|
||||
msgstr "Sofa v{0} est disponible"
|
||||
#~ msgid "Sofa v{0} is available"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "Sofa v{latestVersion} is available"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
@@ -2118,10 +2221,13 @@ msgstr "Streaming"
|
||||
msgid "Sunday"
|
||||
msgstr "Dimanche"
|
||||
|
||||
#. placeholder {0}: info.name
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
msgid "Switch to {0}"
|
||||
msgstr "Passer à {0}"
|
||||
#~ msgid "Switch to {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
msgid "Switch to {name}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/+not-found.tsx
|
||||
msgid "The page you're looking for doesn't exist."
|
||||
@@ -2192,10 +2298,13 @@ msgstr "Cela invalidera l'URL {label} actuelle. Vous devrez la mettre à jour da
|
||||
msgid "This will mark every episode of this show as watched. You can undo this later by unmarking individual seasons."
|
||||
msgstr "Cela marquera tous les épisodes de cette série comme visionnés. Vous pourrez annuler cela en démarquant des saisons individuelles."
|
||||
|
||||
#. placeholder {0}: formatBackupDate(backup.createdAt)
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "This will permanently delete the backup from <0>{0}</0>. This cannot be undone."
|
||||
msgstr "Cela supprimera définitivement la sauvegarde du <0>{0}</0>. Cette action est irréversible."
|
||||
#~ msgid "This will permanently delete the backup from <0>{0}</0>. This cannot be undone."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "This will permanently delete the backup from <0>{backupDate}</0>. This cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/search/recently-viewed-list.ios.tsx
|
||||
#: apps/native/src/components/search/recently-viewed-list.tsx
|
||||
@@ -2327,10 +2436,13 @@ msgstr "Sans titre"
|
||||
msgid "Unwatch all"
|
||||
msgstr "Tout démarquer"
|
||||
|
||||
#. placeholder {0}: season.name ?? t`Season ${season.seasonNumber}`
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched all of {0}"
|
||||
msgstr "Tout démarqué de {0}"
|
||||
#~ msgid "Unwatched all of {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched all of {seasonLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched S{seasonNum} E{epNum}"
|
||||
@@ -2341,10 +2453,13 @@ msgstr "Démarqué S{seasonNum} E{epNum}"
|
||||
msgid "Up next"
|
||||
msgstr "Suivant"
|
||||
|
||||
#. placeholder {0}: updateCheck.data.updateCheck.latestVersion
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Update available: {0}"
|
||||
msgstr "Mise à jour disponible : {0}"
|
||||
#~ msgid "Update available: {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Update available: {latestVersion}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Update check"
|
||||
@@ -2381,11 +2496,13 @@ msgstr "Télécharger"
|
||||
msgid "Upload a .db file to replace the current database. A safety backup is created first."
|
||||
msgstr "Téléchargez un fichier .db pour remplacer la base de données actuelle. Une sauvegarde de sécurité est créée au préalable."
|
||||
|
||||
#. placeholder {0}: config.accept
|
||||
#. placeholder {1}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload a {0} export from your {1} account settings."
|
||||
msgstr "Téléchargez un export {0} depuis les paramètres de votre compte {1}."
|
||||
#~ msgid "Upload a {0} export from your {1} account settings."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload a {acceptFormat} export from your {sourceLabel} account settings."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload export file"
|
||||
@@ -2419,10 +2536,13 @@ msgstr "En attente d'autorisation..."
|
||||
msgid "Warnings"
|
||||
msgstr "Avertissements"
|
||||
|
||||
#. placeholder {0}: result.warnings.length
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Warnings ({0})"
|
||||
msgstr "Avertissements ({0})"
|
||||
#~ msgid "Warnings ({0})"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Warnings ({warningCount})"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-seasons.tsx
|
||||
msgid "Watch all"
|
||||
@@ -2465,7 +2585,7 @@ msgstr "Liste de suivi"
|
||||
|
||||
#: apps/native/src/components/titles/status-action-button.tsx
|
||||
#~ msgid "Watchlisted"
|
||||
#~ msgstr "Dans la liste de suivi"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
@@ -2505,10 +2625,13 @@ msgstr "Scénariste"
|
||||
msgid "You'll be signed out to change the server URL."
|
||||
msgstr "Vous serez déconnecté pour modifier l'URL du serveur."
|
||||
|
||||
#. placeholder {0}: data.currentVersion
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "You're running v{0}."
|
||||
msgstr "Vous utilisez la v{0}."
|
||||
#~ msgid "You're running v{0}."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "You're running v{currentVersion}."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Your code:"
|
||||
@@ -2522,3 +2645,4 @@ msgstr "Votre bibliothèque est vide"
|
||||
#: apps/native/src/app/(auth)/register.tsx
|
||||
msgid "Your name"
|
||||
msgstr "Votre nom"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+289
-165
@@ -8,20 +8,23 @@ msgstr ""
|
||||
"Language: it\n"
|
||||
"Project-Id-Version: sofa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-03-19 00:35\n"
|
||||
"PO-Revision-Date: 2026-03-20 23:13\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Italian\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Crowdin-Project: sofa\n"
|
||||
"X-Crowdin-Project-ID: 881052\n"
|
||||
"X-Crowdin-Language: it\n"
|
||||
"X-Crowdin-File: en.po\n"
|
||||
"X-Crowdin-File-ID: 14\n"
|
||||
"X-Crowdin-File: /packages/i18n/src/po/en.po\n"
|
||||
"X-Crowdin-File-ID: 26\n"
|
||||
|
||||
#. placeholder {0}: result.errors.length - 50
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "...and {0} more"
|
||||
msgstr "...e altri {0}"
|
||||
#~ msgid "...and {0} more"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
@@ -33,86 +36,99 @@ msgstr "{0, plural, one {# immagine} other {# immagini}}"
|
||||
msgid "{0, plural, one {# title} other {# titles}}"
|
||||
msgstr "{0, plural, one {# titolo} other {# titoli}}"
|
||||
|
||||
#. placeholder {0}: displayBackups.length
|
||||
#. placeholder {1}: displayBackups.length
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "{0} {1, plural, one {backup} other {backups}} stored"
|
||||
msgstr "{0} {1, plural, one {backup} other {backup}} archiviati"
|
||||
#~ msgid "{0} {1, plural, one {backup} other {backups}} stored"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
#~ msgid "{0} backup{1} stored"
|
||||
#~ msgstr "{0} backup{1} stored"
|
||||
|
||||
#. placeholder {0}: backups.backupCount
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} backups · last <0/>"
|
||||
msgstr "{0} backup · ultimo <0/>"
|
||||
#~ msgid "{0} backups · last <0/>"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: imageCache.imageCount.toLocaleString()
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} cached images"
|
||||
msgstr "{0} immagini in cache"
|
||||
#~ msgid "{0} cached images"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: member.episodeCount
|
||||
#. placeholder {1}: member.episodeCount !== 1 ? "s" : ""
|
||||
#: apps/web/src/components/titles/cast-carousel.tsx
|
||||
msgid "{0} ep{1}"
|
||||
msgstr "{0} ep{1}"
|
||||
#~ msgid "{0} ep{1}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#~ msgid "{0} images"
|
||||
#~ msgstr "{0} images"
|
||||
|
||||
#. placeholder {0}: stats.watchlist
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} items"
|
||||
msgstr "{0} elementi"
|
||||
#~ msgid "{0} items"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: preview.diagnostics.unresolved
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
msgstr "{0} elementi non hanno ID esterni e verranno risolti tramite ricerca per titolo, che potrebbe essere meno accurata."
|
||||
#~ msgid "{0} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: stats.movies
|
||||
#. placeholder {1}: stats.episodes
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} movies, {1} episodes"
|
||||
msgstr "{0} film, {1} episodi"
|
||||
#~ msgid "{0} movies, {1} episodes"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: stats.ratings
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} ratings"
|
||||
msgstr "{0} valutazioni"
|
||||
#~ msgid "{0} ratings"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#~ msgid "{0} titles"
|
||||
#~ msgstr "{0} titles"
|
||||
|
||||
#. placeholder {0}: JOB_LABELS[name] ?? name
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} triggered"
|
||||
msgstr "{0} attivato"
|
||||
#~ msgid "{0} triggered"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: item.watchedEpisodes
|
||||
#. placeholder {1}: item.totalEpisodes
|
||||
#. placeholder {2}: item.totalEpisodes
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
msgid "{0}/{1} {2, plural, one {episode} other {episodes}}"
|
||||
msgstr "{0}/{1} {2, plural, one {episodio} other {episodi}}"
|
||||
#~ msgid "{0}/{1} {2, plural, one {episode} other {episodes}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
#~ msgid "{0}/{1} episodes"
|
||||
#~ msgstr "{0}/{1} episodes"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "{count} earlier {count, plural, one {episode} other {episodes}} unwatched"
|
||||
msgstr "{count} {count, plural, one {episodio precedente non visto} other {episodi precedenti non visti}}"
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "{backupCount, plural, one {# backup} other {# backups}} stored"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: activeJobs.length
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{healthyCount} of {0} jobs healthy"
|
||||
msgstr "{healthyCount} di {0} job attivi"
|
||||
msgid "{backupCount} backups · last <0/>"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{cachedImageCount} cached images"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "{count, plural, one {# earlier episode} other {# earlier episodes}} unwatched"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#~ msgid "{count} earlier {count, plural, one {episode} other {episodes}} unwatched"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/cast-carousel.tsx
|
||||
msgid "{count} ep{suffix}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
#~ msgid "{healthyCount} of {0} jobs healthy"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{healthyCount} of {activeJobCount} jobs healthy"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{jobLabel} triggered"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-card.tsx
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
@@ -129,29 +145,54 @@ msgstr "Disconnesso: {label}"
|
||||
msgid "{label} URL regenerated"
|
||||
msgstr "URL {label} rigenerato"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{movieCount} movies, {episodeCount} episodes"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{ratingCount} ratings"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{unresolvedCount} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/title-card.tsx
|
||||
msgid "{watched}/{total} episodes"
|
||||
msgstr "{watched}/{total} episodi"
|
||||
|
||||
#. placeholder {0}: episodes.length
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount} of {0} episodes watched"
|
||||
msgstr "{watchedCount} di {0} episodi visti"
|
||||
#~ msgid "{watchedCount} of {0} episodes watched"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: episodes.length
|
||||
#. placeholder {1}: episodes.length
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount}/{0} {1, plural, one {episode} other {episodes}}"
|
||||
msgstr "{watchedCount}/{0} {1, plural, one {episodio} other {episodi}}"
|
||||
msgid "{watchedCount} of {episodeCount} episodes watched"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#~ msgid "{watchedCount}/{0} {1, plural, one {episode} other {episodes}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#~ msgid "{watchedCount}/{0} episodes"
|
||||
#~ msgstr "{watchedCount}/{0} episodes"
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount}/{episodeCount, plural, one {# episode} other {# episodes}}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
msgid "{watchedEpisodes}/{totalEpisodes, plural, one {# episode} other {# episodes}}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{watchlistCount} items"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
msgid "Account"
|
||||
msgstr "Account"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Actions"
|
||||
@@ -207,7 +248,7 @@ msgstr "Aggiunto alla watchlist"
|
||||
#: apps/web/src/components/nav-bar.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
msgid "Admin"
|
||||
msgstr "Admin"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/routes/_app/settings.tsx
|
||||
msgid "Admin only"
|
||||
@@ -268,10 +309,13 @@ msgstr "Autorizzazione riuscita ma impossibile recuperare la libreria. Riprova."
|
||||
msgid "Authorization was denied. Please try again."
|
||||
msgstr "Autorizzazione negata. Riprova."
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Authorize Sofa to read your {0} library. No password shared."
|
||||
msgstr "Autorizza Sofa a leggere la tua libreria {0}. Nessuna password condivisa."
|
||||
#~ msgid "Authorize Sofa to read your {0} library. No password shared."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Authorize Sofa to read your {sourceLabel} library. No password shared."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/update-check-section.tsx
|
||||
msgid "Automatic update checks"
|
||||
@@ -295,7 +339,7 @@ msgstr "Job in background"
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Backup"
|
||||
msgstr "Backup"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "Backup created"
|
||||
@@ -315,8 +359,8 @@ msgid "Backups"
|
||||
msgstr "Backup"
|
||||
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
#~ msgid "backups."
|
||||
#~ msgstr "backups."
|
||||
msgid "backups."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Buy"
|
||||
@@ -361,7 +405,7 @@ msgstr "Annulla modifica"
|
||||
#: apps/native/src/app/title/[id].tsx
|
||||
#: apps/web/src/components/titles/cast-carousel.tsx
|
||||
msgid "Cast"
|
||||
msgstr "Cast"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
@@ -374,11 +418,13 @@ msgstr "Recupera episodi"
|
||||
msgid "Caught Up"
|
||||
msgstr "In pari"
|
||||
|
||||
#. placeholder {0}: episodeIds.length
|
||||
#. placeholder {1}: episodeIds.length
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Caught up — marked {0} {1, plural, one {episode} other {episodes}} as watched"
|
||||
msgstr "Recuperati — {0} {1, plural, one {episodio} other {episodi}} segnati come visti"
|
||||
#~ msgid "Caught up — marked {0} {1, plural, one {episode} other {episodes}} as watched"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Caught up — marked {count, plural, one {# episode} other {# episodes}} as watched"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
@@ -414,10 +460,13 @@ msgstr "Controllato <0/>"
|
||||
msgid "Checking…"
|
||||
msgstr "Verifica in corso…"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Choose how to import your {0} data."
|
||||
msgstr "Scegli come importare i tuoi dati {0}."
|
||||
#~ msgid "Choose how to import your {0} data."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Choose how to import your {sourceLabel} data."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
#~ msgid "Choose your preferred display language"
|
||||
@@ -480,12 +529,12 @@ msgstr "Conferma nuova password"
|
||||
msgid "Connect"
|
||||
msgstr "Connetti"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Connect {0}"
|
||||
msgstr "Connetti {0}"
|
||||
#~ msgid "Connect {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-card.tsx
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Connect {label}"
|
||||
msgstr "Connetti {label}"
|
||||
|
||||
@@ -497,10 +546,13 @@ msgstr "Connetti a {source}"
|
||||
msgid "Connect to TMDB"
|
||||
msgstr "Connetti a TMDB"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Connect with {0}"
|
||||
msgstr "Connetti con {0}"
|
||||
#~ msgid "Connect with {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Connect with {sourceLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/server-url.tsx
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
@@ -596,12 +648,12 @@ msgstr "Zona pericolosa"
|
||||
#: apps/web/src/routes/_app/titles.$id.tsx
|
||||
#: apps/web/src/routes/_app/titles.$id.tsx
|
||||
msgid "Dashboard"
|
||||
msgstr "Dashboard"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Database"
|
||||
msgstr "Database"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "Database backups"
|
||||
@@ -703,7 +755,7 @@ msgstr "Montatore"
|
||||
#: apps/native/src/app/(auth)/register.tsx
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
msgid "Email"
|
||||
msgstr "Email"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
msgid "Enable the \"Playback Stop\" notification type"
|
||||
@@ -740,11 +792,11 @@ msgstr "Ambiente"
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#~ msgid "Episode {0}"
|
||||
#~ msgstr "Episodio {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#~ msgid "Episode {0}, {episodeLabel}"
|
||||
#~ msgstr "Episodio {0}, {episodeLabel}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
@@ -770,10 +822,13 @@ msgstr "Episodio visto"
|
||||
msgid "Episodes"
|
||||
msgstr "Episodi"
|
||||
|
||||
#. placeholder {0}: periodLabels[episodePeriod]
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Episodes {0}"
|
||||
msgstr "Episodi {0}"
|
||||
#~ msgid "Episodes {0}"
|
||||
#~ msgstr "Episodes {0}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Episodes {period}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/stats-display.tsx
|
||||
#~ msgid "Episodes {periodSelect}"
|
||||
@@ -785,17 +840,20 @@ msgstr "Episodi {select}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
#~ msgid "Episodes this week"
|
||||
#~ msgstr "Episodi di questa settimana"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/change-password.tsx
|
||||
#: apps/native/src/app/change-password.tsx
|
||||
msgid "Error"
|
||||
msgstr "Errore"
|
||||
|
||||
#. placeholder {0}: result.errors.length
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Errors ({0})"
|
||||
msgstr "Errori ({0})"
|
||||
#~ msgid "Errors ({0})"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Errors ({errorCount})"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(explore)/_layout.tsx
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
@@ -923,10 +981,13 @@ msgstr "Impossibile rimuovere l'immagine del profilo"
|
||||
msgid "Failed to sign in"
|
||||
msgstr "Impossibile accedere"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Failed to start {0} connection"
|
||||
msgstr "Impossibile avviare la connessione {0}"
|
||||
#~ msgid "Failed to start {0} connection"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Failed to start {sourceLabel} connection"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Failed to trigger job"
|
||||
@@ -1055,7 +1116,7 @@ msgstr "Ecco cosa sta succedendo nella tua libreria"
|
||||
#: apps/web/src/components/nav-bar.tsx
|
||||
#: apps/web/src/components/nav-bar.tsx
|
||||
msgid "Home"
|
||||
msgstr "Home"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
@@ -1086,15 +1147,18 @@ msgstr "Importazione completata"
|
||||
msgid "Import failed"
|
||||
msgstr "Importazione fallita"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {0}"
|
||||
msgstr "Importa da {0}"
|
||||
#~ msgid "Import from {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {source}"
|
||||
msgstr "Importa da {source}"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {sourceLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import is still running in the background. Check back later."
|
||||
@@ -1108,11 +1172,13 @@ msgstr "Opzioni di importazione"
|
||||
msgid "Imported"
|
||||
msgstr "Importati"
|
||||
|
||||
#. placeholder {0}: event.job.importedCount
|
||||
#. placeholder {1}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Imported {0} items from {1}"
|
||||
msgstr "Importati {0} elementi da {1}"
|
||||
#~ msgid "Imported {0} items from {1}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Imported {importedCount} items from {sourceLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Importing from {source}"
|
||||
@@ -1158,14 +1224,12 @@ msgid "Job"
|
||||
msgstr "Attività"
|
||||
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
#~ msgid "Keeping"
|
||||
#~ msgstr "Keeping"
|
||||
msgid "Keeping"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: (value: string | null) => value === "0" ? t`unlimited` : value ? t`last ${value}` : null
|
||||
#. placeholder {1}: [3, 5, 7, 14, 30, 0].map((n) => ( <SelectItem key={n} value={String(n)}> {n === 0 ? t`unlimited` : t`last ${n}`} </SelectItem> ))
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
msgid "Keeping <0><1><2>{0}</2></1><3>{1}</3></0> backups."
|
||||
msgstr "Mantenendo <0><1><2>{0}</2></1><3>{1}</3></0> backup."
|
||||
#~ msgid "Keeping <0><1><2>{0}</2></1><3>{1}</3></0> backups."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/command-palette.tsx
|
||||
#: apps/web/src/components/command-palette.tsx
|
||||
@@ -1186,19 +1250,25 @@ msgstr "ultimi {n}"
|
||||
msgid "last {value}"
|
||||
msgstr "ultimi {value}"
|
||||
|
||||
#. placeholder {0}: formatRelativeTime(lastEventAt)
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last event {0}"
|
||||
msgstr "Ultimo evento {0}"
|
||||
#~ msgid "Last event {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last event {relativeTime}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
msgid "Last event {timeAgo}"
|
||||
msgstr "Ultimo evento {timeAgo}"
|
||||
|
||||
#. placeholder {0}: formatRelativeTime(lastEventAt)
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last polled {0}"
|
||||
msgstr "Ultimo polling {0}"
|
||||
#~ msgid "Last polled {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last polled {relativeTime}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
msgid "Last polled {timeAgo}"
|
||||
@@ -1249,7 +1319,7 @@ msgstr "Segna tutti come visti"
|
||||
|
||||
#: apps/native/src/components/dashboard/continue-watching-card.tsx
|
||||
#~ msgid "Mark as Completed"
|
||||
#~ msgstr "Segna come completato"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/ui/poster-card.tsx
|
||||
msgid "Mark as Watched"
|
||||
@@ -1257,7 +1327,7 @@ msgstr "Segna come visto"
|
||||
|
||||
#: apps/native/src/components/ui/poster-card.tsx
|
||||
#~ msgid "Mark as Watching"
|
||||
#~ msgstr "Segna come in visione"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/title/[id].tsx
|
||||
#: apps/web/src/components/titles/title-actions.tsx
|
||||
@@ -1266,7 +1336,7 @@ msgstr "Segna come visto"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#~ msgid "Marked \"{titleName}\" as completed"
|
||||
#~ msgstr "Segnato \"{titleName}\" come completato"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
@@ -1285,7 +1355,7 @@ msgstr "Tutti gli episodi di \"{titleName}\" segnati come visti"
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#~ msgid "Marked as completed"
|
||||
#~ msgstr "Segnato come completato"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
@@ -1295,7 +1365,7 @@ msgstr "Segnato come visto"
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#~ msgid "Marked as watching"
|
||||
#~ msgstr "Segnato come in visione"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
msgid "Member since {memberSince}"
|
||||
@@ -1327,10 +1397,13 @@ msgstr "Film"
|
||||
msgid "Movies"
|
||||
msgstr "Film"
|
||||
|
||||
#. placeholder {0}: periodLabels[moviePeriod]
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Movies {0}"
|
||||
msgstr "Film {0}"
|
||||
#~ msgid "Movies {0}"
|
||||
#~ msgstr "Movies {0}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Movies {period}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/stats-display.tsx
|
||||
#~ msgid "Movies {periodSelect}"
|
||||
@@ -1342,7 +1415,7 @@ msgstr "Film {select}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
#~ msgid "Movies this month"
|
||||
#~ msgstr "Film di questo mese"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/register.tsx
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
@@ -1511,7 +1584,7 @@ msgstr "Analisi in corso..."
|
||||
#: apps/native/src/app/(auth)/register.tsx
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
msgid "Password"
|
||||
msgstr "Password"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/change-password.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
@@ -1635,20 +1708,23 @@ msgstr "Azioni rapide"
|
||||
msgid "Radarr List URL"
|
||||
msgstr "URL lista Radarr"
|
||||
|
||||
#. placeholder {0}: input.stars
|
||||
#. placeholder {1}: input.stars
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
msgid "Rated {0} {1, plural, one {star} other {stars}}"
|
||||
msgstr "Valutato {0} {1, plural, one {stella} other {stelle}}"
|
||||
#~ msgid "Rated {0} {1, plural, one {star} other {stars}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#~ msgid "Rated {0} star{1}"
|
||||
#~ msgstr "Rated {0} star{1}"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Rated {ratingStars} {ratingStars, plural, one {star} other {stars}}"
|
||||
msgstr "Valutato {ratingStars} {ratingStars, plural, one {stella} other {stelle}}"
|
||||
msgid "Rated {ratingStars, plural, one {# star} other {# stars}}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#~ msgid "Rated {ratingStars} {ratingStars, plural, one {star} other {stars}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Rated {stars, plural, one {# star} other {# stars}}"
|
||||
msgstr "{stars, plural, one {# stella} other {# stelle}}"
|
||||
@@ -1810,6 +1886,14 @@ msgstr "Richiede un abbonamento Plex Pass attivo."
|
||||
msgid "Requires Emby Server 4.7.9+ and an active Emby Premiere license."
|
||||
msgstr "Richiede Emby Server 4.7.9+ e una licenza Emby Premiere attiva."
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Restart"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Restart Required"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-restore-section.tsx
|
||||
#: apps/web/src/components/settings/backup-restore-section.tsx
|
||||
msgid "Restore"
|
||||
@@ -1921,13 +2005,19 @@ msgstr "Cerca film, serie, persone..."
|
||||
msgid "Search…"
|
||||
msgstr "Cerca…"
|
||||
|
||||
#. placeholder {0}: season.seasonNumber
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Season {0}"
|
||||
msgstr "Stagione {0}"
|
||||
#~ msgid "Season {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Season {seasonNumber}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
@@ -1949,7 +2039,7 @@ msgstr "Tracker film & TV self-hosted"
|
||||
|
||||
#: apps/web/src/routes/_app/settings.tsx
|
||||
msgid "Server"
|
||||
msgstr "Server"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Server Health"
|
||||
@@ -2018,12 +2108,18 @@ msgstr "Accedi invece"
|
||||
msgid "Sign in to continue"
|
||||
msgstr "Accedi per continuare"
|
||||
|
||||
#. placeholder {0}: authConfig.data?.oidcProviderName ?? "SSO"
|
||||
#. placeholder {0}: authConfig?.oidcProviderName || "SSO"
|
||||
#: apps/native/src/app/(auth)/login.tsx
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
msgid "Sign in with {0}"
|
||||
msgstr "Accedi con {0}"
|
||||
#~ msgid "Sign in with {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
msgid "Sign in with {oidcProviderName}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/login.tsx
|
||||
msgid "Sign in with {providerName}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/native/src/components/header-avatar.tsx
|
||||
@@ -2048,10 +2144,17 @@ msgstr "Esci dalle altre sessioni"
|
||||
msgid "Skipped"
|
||||
msgstr "Ignorati"
|
||||
|
||||
#. placeholder {0}: data.latestVersion
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Sofa needs to restart to apply the new layout direction."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "Sofa v{0} is available"
|
||||
msgstr "Sofa v{0} è disponibile"
|
||||
#~ msgid "Sofa v{0} is available"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "Sofa v{latestVersion} is available"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
@@ -2118,10 +2221,13 @@ msgstr "Streaming"
|
||||
msgid "Sunday"
|
||||
msgstr "Domenica"
|
||||
|
||||
#. placeholder {0}: info.name
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
msgid "Switch to {0}"
|
||||
msgstr "Passa a {0}"
|
||||
#~ msgid "Switch to {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
msgid "Switch to {name}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/+not-found.tsx
|
||||
msgid "The page you're looking for doesn't exist."
|
||||
@@ -2192,10 +2298,13 @@ msgstr "Questo invaliderà l'URL attuale di {label}. Dovrai aggiornarlo in {labe
|
||||
msgid "This will mark every episode of this show as watched. You can undo this later by unmarking individual seasons."
|
||||
msgstr "Questo segnerà tutti gli episodi di questa serie come visti. Puoi annullarlo in seguito de-segnando le singole stagioni."
|
||||
|
||||
#. placeholder {0}: formatBackupDate(backup.createdAt)
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "This will permanently delete the backup from <0>{0}</0>. This cannot be undone."
|
||||
msgstr "Questo eliminerà definitivamente il backup del <0>{0}</0>. L'operazione non può essere annullata."
|
||||
#~ msgid "This will permanently delete the backup from <0>{0}</0>. This cannot be undone."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "This will permanently delete the backup from <0>{backupDate}</0>. This cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/search/recently-viewed-list.ios.tsx
|
||||
#: apps/native/src/components/search/recently-viewed-list.tsx
|
||||
@@ -2266,7 +2375,7 @@ msgstr "Traccia cosa guardi. Sai cosa ti aspetta.<0/>La tua libreria, i tuoi dat
|
||||
#: apps/web/src/components/titles/trailer-dialog.tsx
|
||||
#: apps/web/src/components/titles/trailer-dialog.tsx
|
||||
msgid "Trailer"
|
||||
msgstr "Trailer"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/explore/hero-banner.tsx
|
||||
msgid "Trending today"
|
||||
@@ -2296,7 +2405,7 @@ msgstr "Martedì"
|
||||
#: apps/web/src/components/people/filmography-grid.tsx
|
||||
#: apps/web/src/components/titles/title-hero.tsx
|
||||
msgid "TV"
|
||||
msgstr "TV"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "TV episodes"
|
||||
@@ -2327,10 +2436,13 @@ msgstr "Senza titolo"
|
||||
msgid "Unwatch all"
|
||||
msgstr "Rimuovi visione dalla stagione"
|
||||
|
||||
#. placeholder {0}: season.name ?? t`Season ${season.seasonNumber}`
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched all of {0}"
|
||||
msgstr "Rimossa visione di {0}"
|
||||
#~ msgid "Unwatched all of {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched all of {seasonLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched S{seasonNum} E{epNum}"
|
||||
@@ -2341,10 +2453,13 @@ msgstr "Non visto S{seasonNum} E{epNum}"
|
||||
msgid "Up next"
|
||||
msgstr "Prossimo"
|
||||
|
||||
#. placeholder {0}: updateCheck.data.updateCheck.latestVersion
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Update available: {0}"
|
||||
msgstr "Aggiornamento disponibile: {0}"
|
||||
#~ msgid "Update available: {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Update available: {latestVersion}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Update check"
|
||||
@@ -2381,11 +2496,13 @@ msgstr "Carica"
|
||||
msgid "Upload a .db file to replace the current database. A safety backup is created first."
|
||||
msgstr "Carica un file .db per sostituire il database attuale. Prima viene creato un backup di sicurezza."
|
||||
|
||||
#. placeholder {0}: config.accept
|
||||
#. placeholder {1}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload a {0} export from your {1} account settings."
|
||||
msgstr "Carica un'esportazione {0} dalle impostazioni del tuo account {1}."
|
||||
#~ msgid "Upload a {0} export from your {1} account settings."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload a {acceptFormat} export from your {sourceLabel} account settings."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload export file"
|
||||
@@ -2419,10 +2536,13 @@ msgstr "In attesa di autorizzazione..."
|
||||
msgid "Warnings"
|
||||
msgstr "Avvisi"
|
||||
|
||||
#. placeholder {0}: result.warnings.length
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Warnings ({0})"
|
||||
msgstr "Avvisi ({0})"
|
||||
#~ msgid "Warnings ({0})"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Warnings ({warningCount})"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-seasons.tsx
|
||||
msgid "Watch all"
|
||||
@@ -2461,11 +2581,11 @@ msgstr "In visione"
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
#: apps/web/src/components/titles/status-button.tsx
|
||||
msgid "Watchlist"
|
||||
msgstr "Watchlist"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/status-action-button.tsx
|
||||
#~ msgid "Watchlisted"
|
||||
#~ msgstr "In watchlist"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
@@ -2505,10 +2625,13 @@ msgstr "Sceneggiatore"
|
||||
msgid "You'll be signed out to change the server URL."
|
||||
msgstr "Verrai disconnesso per cambiare l'URL del server."
|
||||
|
||||
#. placeholder {0}: data.currentVersion
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "You're running v{0}."
|
||||
msgstr "Stai usando la v{0}."
|
||||
#~ msgid "You're running v{0}."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "You're running v{currentVersion}."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Your code:"
|
||||
@@ -2522,3 +2645,4 @@ msgstr "La tua libreria è vuota"
|
||||
#: apps/native/src/app/(auth)/register.tsx
|
||||
msgid "Your name"
|
||||
msgstr "Il tuo nome"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+280
-156
@@ -8,20 +8,23 @@ msgstr ""
|
||||
"Language: pt\n"
|
||||
"Project-Id-Version: sofa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-03-19 00:35\n"
|
||||
"PO-Revision-Date: 2026-03-20 23:13\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Portuguese\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Crowdin-Project: sofa\n"
|
||||
"X-Crowdin-Project-ID: 881052\n"
|
||||
"X-Crowdin-Language: pt-PT\n"
|
||||
"X-Crowdin-File: en.po\n"
|
||||
"X-Crowdin-File-ID: 14\n"
|
||||
"X-Crowdin-File: /packages/i18n/src/po/en.po\n"
|
||||
"X-Crowdin-File-ID: 26\n"
|
||||
|
||||
#. placeholder {0}: result.errors.length - 50
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "...and {0} more"
|
||||
msgstr "...e mais {0}"
|
||||
#~ msgid "...and {0} more"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
@@ -33,86 +36,99 @@ msgstr "{0, plural, one {# imagem} other {# imagens}}"
|
||||
msgid "{0, plural, one {# title} other {# titles}}"
|
||||
msgstr "{0, plural, one {# título} other {# títulos}}"
|
||||
|
||||
#. placeholder {0}: displayBackups.length
|
||||
#. placeholder {1}: displayBackups.length
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "{0} {1, plural, one {backup} other {backups}} stored"
|
||||
msgstr "{0} {1, plural, one {backup armazenado} other {backups armazenados}}"
|
||||
#~ msgid "{0} {1, plural, one {backup} other {backups}} stored"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
#~ msgid "{0} backup{1} stored"
|
||||
#~ msgstr "{0} backup{1} stored"
|
||||
|
||||
#. placeholder {0}: backups.backupCount
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} backups · last <0/>"
|
||||
msgstr "{0} backups · último <0/>"
|
||||
#~ msgid "{0} backups · last <0/>"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: imageCache.imageCount.toLocaleString()
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} cached images"
|
||||
msgstr "{0} imagens em cache"
|
||||
#~ msgid "{0} cached images"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: member.episodeCount
|
||||
#. placeholder {1}: member.episodeCount !== 1 ? "s" : ""
|
||||
#: apps/web/src/components/titles/cast-carousel.tsx
|
||||
msgid "{0} ep{1}"
|
||||
msgstr "{0} ep{1}"
|
||||
#~ msgid "{0} ep{1}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#~ msgid "{0} images"
|
||||
#~ msgstr "{0} images"
|
||||
|
||||
#. placeholder {0}: stats.watchlist
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} items"
|
||||
msgstr "{0} itens"
|
||||
#~ msgid "{0} items"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: preview.diagnostics.unresolved
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
msgstr "{0} itens não têm IDs externos e serão resolvidos por pesquisa de título, o que pode ser menos preciso."
|
||||
#~ msgid "{0} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: stats.movies
|
||||
#. placeholder {1}: stats.episodes
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} movies, {1} episodes"
|
||||
msgstr "{0} filmes, {1} episódios"
|
||||
#~ msgid "{0} movies, {1} episodes"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: stats.ratings
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{0} ratings"
|
||||
msgstr "{0} avaliações"
|
||||
#~ msgid "{0} ratings"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#~ msgid "{0} titles"
|
||||
#~ msgstr "{0} titles"
|
||||
|
||||
#. placeholder {0}: JOB_LABELS[name] ?? name
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{0} triggered"
|
||||
msgstr "{0} acionado"
|
||||
#~ msgid "{0} triggered"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: item.watchedEpisodes
|
||||
#. placeholder {1}: item.totalEpisodes
|
||||
#. placeholder {2}: item.totalEpisodes
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
msgid "{0}/{1} {2, plural, one {episode} other {episodes}}"
|
||||
msgstr "{0}/{1} {2, plural, one {episódio} other {episódios}}"
|
||||
#~ msgid "{0}/{1} {2, plural, one {episode} other {episodes}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
#~ msgid "{0}/{1} episodes"
|
||||
#~ msgstr "{0}/{1} episodes"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "{count} earlier {count, plural, one {episode} other {episodes}} unwatched"
|
||||
msgstr "{count} {count, plural, one {episódio anterior não assistido} other {episódios anteriores não assistidos}}"
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "{backupCount, plural, one {# backup} other {# backups}} stored"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: activeJobs.length
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{healthyCount} of {0} jobs healthy"
|
||||
msgstr "{healthyCount} de {0} tarefas saudáveis"
|
||||
msgid "{backupCount} backups · last <0/>"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{cachedImageCount} cached images"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "{count, plural, one {# earlier episode} other {# earlier episodes}} unwatched"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#~ msgid "{count} earlier {count, plural, one {episode} other {episodes}} unwatched"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/cast-carousel.tsx
|
||||
msgid "{count} ep{suffix}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
#~ msgid "{healthyCount} of {0} jobs healthy"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{healthyCount} of {activeJobCount} jobs healthy"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "{jobLabel} triggered"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-card.tsx
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
@@ -129,25 +145,50 @@ msgstr "{label} desconectado"
|
||||
msgid "{label} URL regenerated"
|
||||
msgstr "URL de {label} regenerada"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{movieCount} movies, {episodeCount} episodes"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{ratingCount} ratings"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{unresolvedCount} items have no external IDs and will be resolved by title search, which may be less accurate."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/title-card.tsx
|
||||
msgid "{watched}/{total} episodes"
|
||||
msgstr "{watched}/{total} episódios"
|
||||
|
||||
#. placeholder {0}: episodes.length
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount} of {0} episodes watched"
|
||||
msgstr "{watchedCount} de {0} episódios assistidos"
|
||||
#~ msgid "{watchedCount} of {0} episodes watched"
|
||||
#~ msgstr ""
|
||||
|
||||
#. placeholder {0}: episodes.length
|
||||
#. placeholder {1}: episodes.length
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount}/{0} {1, plural, one {episode} other {episodes}}"
|
||||
msgstr "{watchedCount}/{0} {1, plural, one {episódio} other {episódios}}"
|
||||
msgid "{watchedCount} of {episodeCount} episodes watched"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#~ msgid "{watchedCount}/{0} {1, plural, one {episode} other {episodes}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#~ msgid "{watchedCount}/{0} episodes"
|
||||
#~ msgstr "{watchedCount}/{0} episodes"
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
msgid "{watchedCount}/{episodeCount, plural, one {# episode} other {# episodes}}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/continue-watching-card.tsx
|
||||
msgid "{watchedEpisodes}/{totalEpisodes, plural, one {# episode} other {# episodes}}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "{watchlistCount} items"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
msgid "Account"
|
||||
@@ -268,10 +309,13 @@ msgstr "Autorização concluída, mas falha ao buscar sua biblioteca. Tente nova
|
||||
msgid "Authorization was denied. Please try again."
|
||||
msgstr "Autorização negada. Tente novamente."
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Authorize Sofa to read your {0} library. No password shared."
|
||||
msgstr "Autorize o Sofa a ler sua biblioteca do {0}. Nenhuma senha é compartilhada."
|
||||
#~ msgid "Authorize Sofa to read your {0} library. No password shared."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Authorize Sofa to read your {sourceLabel} library. No password shared."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/update-check-section.tsx
|
||||
msgid "Automatic update checks"
|
||||
@@ -295,7 +339,7 @@ msgstr "Tarefas em segundo plano"
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Backup"
|
||||
msgstr "Backup"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "Backup created"
|
||||
@@ -312,11 +356,11 @@ msgstr "Agendamento de backup"
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
#: apps/web/src/routes/_app/settings.tsx
|
||||
msgid "Backups"
|
||||
msgstr "Backups"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
#~ msgid "backups."
|
||||
#~ msgstr "backups."
|
||||
msgid "backups."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Buy"
|
||||
@@ -374,11 +418,13 @@ msgstr "Colocar em dia"
|
||||
msgid "Caught Up"
|
||||
msgstr "Em dia"
|
||||
|
||||
#. placeholder {0}: episodeIds.length
|
||||
#. placeholder {1}: episodeIds.length
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Caught up — marked {0} {1, plural, one {episode} other {episodes}} as watched"
|
||||
msgstr "Em dia — {0} {1, plural, one {episódio marcado como assistido} other {episódios marcados como assistidos}}"
|
||||
#~ msgid "Caught up — marked {0} {1, plural, one {episode} other {episodes}} as watched"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Caught up — marked {count, plural, one {# episode} other {# episodes}} as watched"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
@@ -414,10 +460,13 @@ msgstr "Verificado <0/>"
|
||||
msgid "Checking…"
|
||||
msgstr "Verificando…"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Choose how to import your {0} data."
|
||||
msgstr "Escolha como importar seus dados do {0}."
|
||||
#~ msgid "Choose how to import your {0} data."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Choose how to import your {sourceLabel} data."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
#~ msgid "Choose your preferred display language"
|
||||
@@ -480,12 +529,12 @@ msgstr "Confirmar nova senha"
|
||||
msgid "Connect"
|
||||
msgstr "Conectar"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Connect {0}"
|
||||
msgstr "Conectar {0}"
|
||||
#~ msgid "Connect {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-card.tsx
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Connect {label}"
|
||||
msgstr "Conectar {label}"
|
||||
|
||||
@@ -497,10 +546,13 @@ msgstr "Conectar a {source}"
|
||||
msgid "Connect to TMDB"
|
||||
msgstr "Conectar ao TMDB"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Connect with {0}"
|
||||
msgstr "Conectar com {0}"
|
||||
#~ msgid "Connect with {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Connect with {sourceLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/server-url.tsx
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
@@ -697,7 +749,7 @@ msgstr "Baixar backup"
|
||||
#: apps/native/src/components/search/recently-viewed-row-content.tsx
|
||||
#: apps/web/src/components/people/person-hero.tsx
|
||||
msgid "Editor"
|
||||
msgstr "Editor"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/login.tsx
|
||||
#: apps/native/src/app/(auth)/register.tsx
|
||||
@@ -740,11 +792,11 @@ msgstr "Ambiente"
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#~ msgid "Episode {0}"
|
||||
#~ msgstr "Episódio {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#~ msgid "Episode {0}, {episodeLabel}"
|
||||
#~ msgstr "Episódio {0}, {episodeLabel}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
#: apps/native/src/components/titles/episode-row.tsx
|
||||
@@ -770,10 +822,13 @@ msgstr "Episódio assistido"
|
||||
msgid "Episodes"
|
||||
msgstr "Episódios"
|
||||
|
||||
#. placeholder {0}: periodLabels[episodePeriod]
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Episodes {0}"
|
||||
msgstr "Episódios {0}"
|
||||
#~ msgid "Episodes {0}"
|
||||
#~ msgstr "Episodes {0}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Episodes {period}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/stats-display.tsx
|
||||
#~ msgid "Episodes {periodSelect}"
|
||||
@@ -785,17 +840,20 @@ msgstr "Episódios {select}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
#~ msgid "Episodes this week"
|
||||
#~ msgstr "Episódios desta semana"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/change-password.tsx
|
||||
#: apps/native/src/app/change-password.tsx
|
||||
msgid "Error"
|
||||
msgstr "Erro"
|
||||
|
||||
#. placeholder {0}: result.errors.length
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Errors ({0})"
|
||||
msgstr "Erros ({0})"
|
||||
#~ msgid "Errors ({0})"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Errors ({errorCount})"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(explore)/_layout.tsx
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
@@ -923,10 +981,13 @@ msgstr "Falha ao remover foto de perfil"
|
||||
msgid "Failed to sign in"
|
||||
msgstr "Falha ao entrar"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Failed to start {0} connection"
|
||||
msgstr "Falha ao iniciar conexão com {0}"
|
||||
#~ msgid "Failed to start {0} connection"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Failed to start {sourceLabel} connection"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Failed to trigger job"
|
||||
@@ -1086,15 +1147,18 @@ msgstr "Importação concluída"
|
||||
msgid "Import failed"
|
||||
msgstr "Importação falhou"
|
||||
|
||||
#. placeholder {0}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {0}"
|
||||
msgstr "Importar de {0}"
|
||||
#~ msgid "Import from {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {source}"
|
||||
msgstr "Importar de {source}"
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import from {sourceLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Import is still running in the background. Check back later."
|
||||
@@ -1108,11 +1172,13 @@ msgstr "Opções de importação"
|
||||
msgid "Imported"
|
||||
msgstr "Importado"
|
||||
|
||||
#. placeholder {0}: event.job.importedCount
|
||||
#. placeholder {1}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Imported {0} items from {1}"
|
||||
msgstr "Importados {0} itens de {1}"
|
||||
#~ msgid "Imported {0} items from {1}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Imported {importedCount} items from {sourceLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Importing from {source}"
|
||||
@@ -1158,14 +1224,12 @@ msgid "Job"
|
||||
msgstr "Tarefa"
|
||||
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
#~ msgid "Keeping"
|
||||
#~ msgstr "Keeping"
|
||||
msgid "Keeping"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: (value: string | null) => value === "0" ? t`unlimited` : value ? t`last ${value}` : null
|
||||
#. placeholder {1}: [3, 5, 7, 14, 30, 0].map((n) => ( <SelectItem key={n} value={String(n)}> {n === 0 ? t`unlimited` : t`last ${n}`} </SelectItem> ))
|
||||
#: apps/web/src/components/settings/backup-schedule-section.tsx
|
||||
msgid "Keeping <0><1><2>{0}</2></1><3>{1}</3></0> backups."
|
||||
msgstr "Mantendo <0><1><2>{0}</2></1><3>{1}</3></0> backups."
|
||||
#~ msgid "Keeping <0><1><2>{0}</2></1><3>{1}</3></0> backups."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/command-palette.tsx
|
||||
#: apps/web/src/components/command-palette.tsx
|
||||
@@ -1186,19 +1250,25 @@ msgstr "últimos {n}"
|
||||
msgid "last {value}"
|
||||
msgstr "últimos {value}"
|
||||
|
||||
#. placeholder {0}: formatRelativeTime(lastEventAt)
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last event {0}"
|
||||
msgstr "Último evento {0}"
|
||||
#~ msgid "Last event {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last event {relativeTime}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
msgid "Last event {timeAgo}"
|
||||
msgstr "Último evento {timeAgo}"
|
||||
|
||||
#. placeholder {0}: formatRelativeTime(lastEventAt)
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last polled {0}"
|
||||
msgstr "Última verificação {0}"
|
||||
#~ msgid "Last polled {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/integration-card.tsx
|
||||
msgid "Last polled {relativeTime}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
msgid "Last polled {timeAgo}"
|
||||
@@ -1249,7 +1319,7 @@ msgstr "Marcar Todos como Assistidos"
|
||||
|
||||
#: apps/native/src/components/dashboard/continue-watching-card.tsx
|
||||
#~ msgid "Mark as Completed"
|
||||
#~ msgstr "Marcar como Concluído"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/ui/poster-card.tsx
|
||||
msgid "Mark as Watched"
|
||||
@@ -1257,7 +1327,7 @@ msgstr "Marcar como Assistido"
|
||||
|
||||
#: apps/native/src/components/ui/poster-card.tsx
|
||||
#~ msgid "Mark as Watching"
|
||||
#~ msgstr "Marcar como Assistindo"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/title/[id].tsx
|
||||
#: apps/web/src/components/titles/title-actions.tsx
|
||||
@@ -1266,7 +1336,7 @@ msgstr "Marcar como Assistido"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#~ msgid "Marked \"{titleName}\" as completed"
|
||||
#~ msgstr "Marcado \"{titleName}\" como concluído"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
@@ -1285,7 +1355,7 @@ msgstr "Todos os episódios de \"{titleName}\" marcados como vistos"
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#~ msgid "Marked as completed"
|
||||
#~ msgstr "Marcado como concluído"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
@@ -1295,7 +1365,7 @@ msgstr "Marcado como assistido"
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
#~ msgid "Marked as watching"
|
||||
#~ msgstr "Marcado como assistindo"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/account-section.tsx
|
||||
msgid "Member since {memberSince}"
|
||||
@@ -1327,10 +1397,13 @@ msgstr "Filme"
|
||||
msgid "Movies"
|
||||
msgstr "Filmes"
|
||||
|
||||
#. placeholder {0}: periodLabels[moviePeriod]
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Movies {0}"
|
||||
msgstr "Filmes {0}"
|
||||
#~ msgid "Movies {0}"
|
||||
#~ msgstr "Movies {0}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
msgid "Movies {period}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/dashboard/stats-display.tsx
|
||||
#~ msgid "Movies {periodSelect}"
|
||||
@@ -1342,7 +1415,7 @@ msgstr "Filmes {select}"
|
||||
|
||||
#: apps/native/src/app/(tabs)/(home)/index.tsx
|
||||
#~ msgid "Movies this month"
|
||||
#~ msgstr "Filmes este mês"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/register.tsx
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
@@ -1635,20 +1708,23 @@ msgstr "Ações Rápidas"
|
||||
msgid "Radarr List URL"
|
||||
msgstr "URL da Lista do Radarr"
|
||||
|
||||
#. placeholder {0}: input.stars
|
||||
#. placeholder {1}: input.stars
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
msgid "Rated {0} {1, plural, one {star} other {stars}}"
|
||||
msgstr "Avaliado com {0} {1, plural, one {estrela} other {estrelas}}"
|
||||
#~ msgid "Rated {0} {1, plural, one {star} other {stars}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#~ msgid "Rated {0} star{1}"
|
||||
#~ msgstr "Rated {0} star{1}"
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Rated {ratingStars} {ratingStars, plural, one {star} other {stars}}"
|
||||
msgstr "Avaliado com {ratingStars} {ratingStars, plural, one {estrela} other {estrelas}}"
|
||||
msgid "Rated {ratingStars, plural, one {# star} other {# stars}}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#~ msgid "Rated {ratingStars} {ratingStars, plural, one {star} other {stars}}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Rated {stars, plural, one {# star} other {# stars}}"
|
||||
msgstr "Avaliado com {stars, plural, one {# estrela} other {# estrelas}}"
|
||||
@@ -1810,6 +1886,14 @@ msgstr "Requer uma assinatura ativa do Plex Pass."
|
||||
msgid "Requires Emby Server 4.7.9+ and an active Emby Premiere license."
|
||||
msgstr "Requer Emby Server 4.7.9+ e uma licença ativa do Emby Premiere."
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Restart"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Restart Required"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-restore-section.tsx
|
||||
#: apps/web/src/components/settings/backup-restore-section.tsx
|
||||
msgid "Restore"
|
||||
@@ -1921,13 +2005,19 @@ msgstr "Pesquisar filmes, séries, pessoas..."
|
||||
msgid "Search…"
|
||||
msgstr "Pesquisar…"
|
||||
|
||||
#. placeholder {0}: season.seasonNumber
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Season {0}"
|
||||
msgstr "Temporada {0}"
|
||||
#~ msgid "Season {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/native/src/components/titles/season-accordion.tsx
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Season {seasonNumber}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
@@ -2018,12 +2108,18 @@ msgstr "Entrar em vez disso"
|
||||
msgid "Sign in to continue"
|
||||
msgstr "Entre para continuar"
|
||||
|
||||
#. placeholder {0}: authConfig.data?.oidcProviderName ?? "SSO"
|
||||
#. placeholder {0}: authConfig?.oidcProviderName || "SSO"
|
||||
#: apps/native/src/app/(auth)/login.tsx
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
msgid "Sign in with {0}"
|
||||
msgstr "Entrar com {0}"
|
||||
#~ msgid "Sign in with {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/auth-form.tsx
|
||||
msgid "Sign in with {oidcProviderName}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(auth)/login.tsx
|
||||
msgid "Sign in with {providerName}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
#: apps/native/src/components/header-avatar.tsx
|
||||
@@ -2048,10 +2144,17 @@ msgstr "Sair de outras sessões"
|
||||
msgid "Skipped"
|
||||
msgstr "Ignorado"
|
||||
|
||||
#. placeholder {0}: data.latestVersion
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Sofa needs to restart to apply the new layout direction."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "Sofa v{0} is available"
|
||||
msgstr "Sofa v{0} está disponível"
|
||||
#~ msgid "Sofa v{0} is available"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "Sofa v{latestVersion} is available"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
@@ -2118,10 +2221,13 @@ msgstr "Streaming"
|
||||
msgid "Sunday"
|
||||
msgstr "Domingo"
|
||||
|
||||
#. placeholder {0}: info.name
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
msgid "Switch to {0}"
|
||||
msgstr "Mudar para {0}"
|
||||
#~ msgid "Switch to {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/language-section.tsx
|
||||
msgid "Switch to {name}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/app/+not-found.tsx
|
||||
msgid "The page you're looking for doesn't exist."
|
||||
@@ -2192,10 +2298,13 @@ msgstr "Isso invalidará a URL atual do {label}. Você precisará atualizá-la n
|
||||
msgid "This will mark every episode of this show as watched. You can undo this later by unmarking individual seasons."
|
||||
msgstr "Isso marcará todos os episódios desta série como assistidos. Você pode desfazer isso mais tarde desmarcando temporadas individuais."
|
||||
|
||||
#. placeholder {0}: formatBackupDate(backup.createdAt)
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "This will permanently delete the backup from <0>{0}</0>. This cannot be undone."
|
||||
msgstr "Isso excluirá permanentemente o backup de <0>{0}</0>. Esta ação não pode ser desfeita."
|
||||
#~ msgid "This will permanently delete the backup from <0>{0}</0>. This cannot be undone."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/backup-section.tsx
|
||||
msgid "This will permanently delete the backup from <0>{backupDate}</0>. This cannot be undone."
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/components/search/recently-viewed-list.ios.tsx
|
||||
#: apps/native/src/components/search/recently-viewed-list.tsx
|
||||
@@ -2266,7 +2375,7 @@ msgstr "Acompanhe o que você assiste. Saiba o que vem a seguir.<0/>Sua bibliote
|
||||
#: apps/web/src/components/titles/trailer-dialog.tsx
|
||||
#: apps/web/src/components/titles/trailer-dialog.tsx
|
||||
msgid "Trailer"
|
||||
msgstr "Trailer"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/explore/hero-banner.tsx
|
||||
msgid "Trending today"
|
||||
@@ -2327,10 +2436,13 @@ msgstr "Sem título"
|
||||
msgid "Unwatch all"
|
||||
msgstr "Desmarcar todos"
|
||||
|
||||
#. placeholder {0}: season.name ?? t`Season ${season.seasonNumber}`
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched all of {0}"
|
||||
msgstr "Desmarcados todos os episódios de {0}"
|
||||
#~ msgid "Unwatched all of {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched all of {seasonLabel}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/use-title-actions.ts
|
||||
msgid "Unwatched S{seasonNum} E{epNum}"
|
||||
@@ -2341,10 +2453,13 @@ msgstr "Desmarcado T{seasonNum} E{epNum}"
|
||||
msgid "Up next"
|
||||
msgstr "A seguir"
|
||||
|
||||
#. placeholder {0}: updateCheck.data.updateCheck.latestVersion
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Update available: {0}"
|
||||
msgstr "Atualização disponível: {0}"
|
||||
#~ msgid "Update available: {0}"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "Update available: {latestVersion}"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/system-health-section.tsx
|
||||
msgid "Update check"
|
||||
@@ -2381,11 +2496,13 @@ msgstr "Enviar"
|
||||
msgid "Upload a .db file to replace the current database. A safety backup is created first."
|
||||
msgstr "Envie um arquivo .db para substituir o banco de dados atual. Um backup de segurança é criado primeiro."
|
||||
|
||||
#. placeholder {0}: config.accept
|
||||
#. placeholder {1}: config.label
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload a {0} export from your {1} account settings."
|
||||
msgstr "Envie um export {0} das configurações da sua conta {1}."
|
||||
#~ msgid "Upload a {0} export from your {1} account settings."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload a {acceptFormat} export from your {sourceLabel} account settings."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Upload export file"
|
||||
@@ -2419,10 +2536,13 @@ msgstr "Aguardando autorização..."
|
||||
msgid "Warnings"
|
||||
msgstr "Avisos"
|
||||
|
||||
#. placeholder {0}: result.warnings.length
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Warnings ({0})"
|
||||
msgstr "Avisos ({0})"
|
||||
#~ msgid "Warnings ({0})"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Warnings ({warningCount})"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-seasons.tsx
|
||||
msgid "Watch all"
|
||||
@@ -2465,7 +2585,7 @@ msgstr "Lista de Desejos"
|
||||
|
||||
#: apps/native/src/components/titles/status-action-button.tsx
|
||||
#~ msgid "Watchlisted"
|
||||
#~ msgstr "Na Lista de Desejos"
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
#: apps/native/src/components/settings/integration-configs.ts
|
||||
@@ -2505,10 +2625,13 @@ msgstr "Roteirista"
|
||||
msgid "You'll be signed out to change the server URL."
|
||||
msgstr "Você será desconectado para alterar a URL do servidor."
|
||||
|
||||
#. placeholder {0}: data.currentVersion
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "You're running v{0}."
|
||||
msgstr "Você está usando a v{0}."
|
||||
#~ msgid "You're running v{0}."
|
||||
#~ msgstr ""
|
||||
|
||||
#: apps/web/src/components/update-toast.tsx
|
||||
msgid "You're running v{currentVersion}."
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/settings/imports-section.tsx
|
||||
msgid "Your code:"
|
||||
@@ -2522,3 +2645,4 @@ msgstr "Sua biblioteca está vazia"
|
||||
#: apps/native/src/app/(auth)/register.tsx
|
||||
msgid "Your name"
|
||||
msgstr "Seu nome"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user