mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-07-18 02:04:35 +01:00
Compare commits
53 Commits
fix/plugin
...
feat/local
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c54f9321c9 | ||
|
|
470e69774d | ||
|
|
8a0d43fc98 | ||
|
|
2e9c30580e | ||
|
|
6dd98ccae8 | ||
|
|
b4eb853048 | ||
|
|
76d9b3177b | ||
|
|
2e79815d78 | ||
|
|
43ce50fe70 | ||
|
|
bd0eef0407 | ||
|
|
2755f340c4 | ||
|
|
63ed386369 | ||
|
|
a38737df2e | ||
|
|
ce1e1dfc77 | ||
|
|
719c875293 | ||
|
|
d6d2cf6aca | ||
|
|
4389b56bd0 | ||
|
|
294568eef3 | ||
|
|
0ee5488308 | ||
|
|
c0908ad44d | ||
|
|
b5b29d434c | ||
|
|
626c0a98a8 | ||
|
|
2592cbdc48 | ||
|
|
b34afb0715 | ||
|
|
fd667c127f | ||
|
|
0e5c3215f3 | ||
|
|
16187aab90 | ||
|
|
2acdf1eea6 | ||
|
|
976af60185 | ||
|
|
6b90d3e868 | ||
|
|
de81b36725 | ||
|
|
b83b5b0bbb | ||
|
|
ec92e98b16 | ||
|
|
9c0de94247 | ||
|
|
0a58514964 | ||
|
|
58f8015e3b | ||
|
|
a27ea154ba | ||
|
|
6c3fa704db | ||
|
|
fe315699b9 | ||
|
|
c3271859b8 | ||
|
|
294b3f19c3 | ||
|
|
e9bb6b3c40 | ||
|
|
9d437e8cd1 | ||
|
|
ebf6e31478 | ||
|
|
378288bf08 | ||
|
|
92460cf202 | ||
|
|
feb5a41cff | ||
|
|
97607b2263 | ||
|
|
d3bc2ac5d5 | ||
|
|
96f6ad000b | ||
|
|
be575b7c04 | ||
|
|
91de36c3bd | ||
|
|
62f50590d4 |
@@ -71,7 +71,7 @@ export default function AppearanceHideLibrariesPage() {
|
||||
))}
|
||||
</ListGroup>
|
||||
<Text className='px-4 text-xs text-neutral-500 mt-1'>
|
||||
{t("home.settings.other.select_liraries_you_want_to_hide")}
|
||||
{t("home.settings.other.select_libraries_you_want_to_hide")}
|
||||
</Text>
|
||||
</DisabledSetting>
|
||||
</ScrollView>
|
||||
|
||||
@@ -60,7 +60,7 @@ export default function HideLibrariesPage() {
|
||||
))}
|
||||
</ListGroup>
|
||||
<Text className='px-4 text-xs text-neutral-500 mt-1'>
|
||||
{t("home.settings.other.select_liraries_you_want_to_hide")}
|
||||
{t("home.settings.other.select_libraries_you_want_to_hide")}
|
||||
</Text>
|
||||
</DisabledSetting>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { ScrollView, View } from "react-native";
|
||||
import { ScrollView } from "react-native";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import DisabledSetting from "@/components/settings/DisabledSetting";
|
||||
import { JellyseerrSettings } from "@/components/settings/Jellyseerr";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
|
||||
export default function JellyseerrPluginPage() {
|
||||
const { pluginSettings } = useSettings();
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
return (
|
||||
@@ -13,9 +16,12 @@ export default function JellyseerrPluginPage() {
|
||||
paddingRight: insets.right,
|
||||
}}
|
||||
>
|
||||
<View className='p-4'>
|
||||
<DisabledSetting
|
||||
disabled={pluginSettings?.jellyseerrServerUrl?.locked === true}
|
||||
className='p-4'
|
||||
>
|
||||
<JellyseerrSettings />
|
||||
</View>
|
||||
</DisabledSetting>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { ScrollView, View } from "react-native";
|
||||
import { ScrollView } from "react-native";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import DisabledSetting from "@/components/settings/DisabledSetting";
|
||||
import { KefinTweaksSettings } from "@/components/settings/KefinTweaks";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
|
||||
export default function KefinTweaksPage() {
|
||||
const { pluginSettings } = useSettings();
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
return (
|
||||
@@ -13,9 +16,12 @@ export default function KefinTweaksPage() {
|
||||
paddingRight: insets.right,
|
||||
}}
|
||||
>
|
||||
<View className='px-4'>
|
||||
<DisabledSetting
|
||||
disabled={pluginSettings?.useKefinTweaks?.locked === true}
|
||||
className='p-4'
|
||||
>
|
||||
<KefinTweaksSettings />
|
||||
</View>
|
||||
</DisabledSetting>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useNavigation } from "expo-router";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
Linking,
|
||||
@@ -14,24 +14,22 @@ import { toast } from "sonner-native";
|
||||
import { Text } from "@/components/common/Text";
|
||||
import { ListGroup } from "@/components/list/ListGroup";
|
||||
import { ListItem } from "@/components/list/ListItem";
|
||||
import DisabledSetting from "@/components/settings/DisabledSetting";
|
||||
import { useNetworkAwareQueryClient } from "@/hooks/useNetworkAwareQueryClient";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
|
||||
export default function MarlinSearchPage() {
|
||||
const navigation = useNavigation();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
const { settings, updateSettings, pluginSettings } = useSettings();
|
||||
const queryClient = useNetworkAwareQueryClient();
|
||||
|
||||
const [value, setValue] = useState<string>(settings?.marlinServerUrl || "");
|
||||
|
||||
const searchEngineLocked = pluginSettings?.searchEngine?.locked === true;
|
||||
const marlinUrlLocked = pluginSettings?.marlinServerUrl?.locked === true;
|
||||
// Effective (user/admin merged) URL, same source the search screen uses —
|
||||
// the raw plugin value misses a user-configured Streamystats.
|
||||
const hasStreamystats = !!settings?.streamyStatsServerUrl;
|
||||
|
||||
const onSave = (val: string) => {
|
||||
updateSettings({
|
||||
marlinServerUrl: !val.endsWith("/") ? val : val.slice(0, -1),
|
||||
@@ -43,8 +41,15 @@ export default function MarlinSearchPage() {
|
||||
Linking.openURL("https://github.com/fredrikburmester/marlin-search");
|
||||
};
|
||||
|
||||
const disabled = useMemo(() => {
|
||||
return (
|
||||
pluginSettings?.searchEngine?.locked === true &&
|
||||
pluginSettings?.marlinServerUrl?.locked === true
|
||||
);
|
||||
}, [pluginSettings]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!marlinUrlLocked) {
|
||||
if (!pluginSettings?.marlinServerUrl?.locked) {
|
||||
navigation.setOptions({
|
||||
headerRight: () => (
|
||||
<TouchableOpacity onPress={() => onSave(value)} className='px-2'>
|
||||
@@ -55,7 +60,7 @@ export default function MarlinSearchPage() {
|
||||
),
|
||||
});
|
||||
}
|
||||
}, [navigation, value, marlinUrlLocked, t]);
|
||||
}, [navigation, value, pluginSettings?.marlinServerUrl?.locked, t]);
|
||||
|
||||
if (!settings) return null;
|
||||
|
||||
@@ -67,42 +72,52 @@ export default function MarlinSearchPage() {
|
||||
paddingRight: insets.right,
|
||||
}}
|
||||
>
|
||||
<View className='px-4'>
|
||||
<DisabledSetting disabled={disabled} className='px-4'>
|
||||
<ListGroup>
|
||||
{/* disabledByAdmin renders the "Disabled by admin" notice as the row's
|
||||
subtitle (same pattern as the Streamystats settings) — no clipping. */}
|
||||
<ListItem
|
||||
title={t(
|
||||
"home.settings.plugins.marlin_search.enable_marlin_search",
|
||||
)}
|
||||
disabledByAdmin={searchEngineLocked}
|
||||
// Streamystats owns the search engine while configured — block the
|
||||
// row tap too, not just the Switch, so it can't force "Jellyfin".
|
||||
disabled={hasStreamystats}
|
||||
onPress={() => {
|
||||
updateSettings({ searchEngine: "Jellyfin" });
|
||||
queryClient.invalidateQueries({ queryKey: ["search"] });
|
||||
}}
|
||||
<DisabledSetting
|
||||
disabled={
|
||||
pluginSettings?.searchEngine?.locked === true ||
|
||||
!!pluginSettings?.streamyStatsServerUrl?.value
|
||||
}
|
||||
showText={!pluginSettings?.marlinServerUrl?.locked}
|
||||
>
|
||||
<Switch
|
||||
value={settings.searchEngine === "Marlin"}
|
||||
disabled={searchEngineLocked || hasStreamystats}
|
||||
onValueChange={(val) => {
|
||||
updateSettings({ searchEngine: val ? "Marlin" : "Jellyfin" });
|
||||
<ListItem
|
||||
title={t(
|
||||
"home.settings.plugins.marlin_search.enable_marlin_search",
|
||||
)}
|
||||
onPress={() => {
|
||||
updateSettings({ searchEngine: "Jellyfin" });
|
||||
queryClient.invalidateQueries({ queryKey: ["search"] });
|
||||
}}
|
||||
/>
|
||||
</ListItem>
|
||||
>
|
||||
<Switch
|
||||
value={settings.searchEngine === "Marlin"}
|
||||
disabled={!!pluginSettings?.streamyStatsServerUrl?.value}
|
||||
onValueChange={(value) => {
|
||||
updateSettings({
|
||||
searchEngine: value ? "Marlin" : "Jellyfin",
|
||||
});
|
||||
queryClient.invalidateQueries({ queryKey: ["search"] });
|
||||
}}
|
||||
/>
|
||||
</ListItem>
|
||||
</DisabledSetting>
|
||||
</ListGroup>
|
||||
|
||||
<ListGroup className='mt-2'>
|
||||
<ListItem
|
||||
title={t("home.settings.plugins.marlin_search.url")}
|
||||
disabledByAdmin={marlinUrlLocked}
|
||||
<DisabledSetting
|
||||
disabled={pluginSettings?.marlinServerUrl?.locked === true}
|
||||
showText={!pluginSettings?.searchEngine?.locked}
|
||||
className='mt-2 flex flex-col rounded-xl overflow-hidden pl-4 bg-neutral-900 px-4'
|
||||
>
|
||||
<View
|
||||
className={"flex flex-row items-center bg-neutral-900 h-11 pr-4"}
|
||||
>
|
||||
<Text className='mr-4'>
|
||||
{t("home.settings.plugins.marlin_search.url")}
|
||||
</Text>
|
||||
<TextInput
|
||||
editable={!marlinUrlLocked && settings.searchEngine === "Marlin"}
|
||||
className='text-white text-right flex-1'
|
||||
editable={settings.searchEngine === "Marlin"}
|
||||
className='text-white'
|
||||
placeholder={t(
|
||||
"home.settings.plugins.marlin_search.server_url_placeholder",
|
||||
)}
|
||||
@@ -113,16 +128,15 @@ export default function MarlinSearchPage() {
|
||||
textContentType='URL'
|
||||
onChangeText={(text) => setValue(text)}
|
||||
/>
|
||||
</ListItem>
|
||||
</ListGroup>
|
||||
|
||||
</View>
|
||||
</DisabledSetting>
|
||||
<Text className='px-4 text-xs text-neutral-500 mt-1'>
|
||||
{t("home.settings.plugins.marlin_search.marlin_search_hint")}{" "}
|
||||
<Text className='text-blue-500' onPress={handleOpenLink}>
|
||||
{t("home.settings.plugins.marlin_search.read_more_about_marlin")}
|
||||
</Text>
|
||||
</Text>
|
||||
</View>
|
||||
</DisabledSetting>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,28 +1,9 @@
|
||||
import { useCallback } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Platform, ScrollView, TouchableOpacity, View } from "react-native";
|
||||
import { Platform, ScrollView, View } from "react-native";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import { toast } from "sonner-native";
|
||||
import { Text } from "@/components/common/Text";
|
||||
import { PluginSettings } from "@/components/settings/PluginSettings";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
|
||||
export default function PluginsPage() {
|
||||
const insets = useSafeAreaInsets();
|
||||
const { t } = useTranslation();
|
||||
const { refreshStreamyfinPluginSettings } = useSettings();
|
||||
|
||||
const handleRefreshFromServer = useCallback(async () => {
|
||||
// Returns undefined when the API call fails (handled internally).
|
||||
const refreshed = await refreshStreamyfinPluginSettings();
|
||||
if (refreshed) {
|
||||
toast.success(t("home.settings.plugins.streamystats.toasts.refreshed"));
|
||||
} else {
|
||||
toast.error(
|
||||
t("home.settings.plugins.streamystats.toasts.refresh_failed"),
|
||||
);
|
||||
}
|
||||
}, [refreshStreamyfinPluginSettings, t]);
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
@@ -37,17 +18,6 @@ export default function PluginsPage() {
|
||||
style={{ paddingTop: Platform.OS === "android" ? 10 : 0 }}
|
||||
>
|
||||
<PluginSettings />
|
||||
|
||||
{/* Pulls the centralised Streamyfin plugin settings for every plugin,
|
||||
so it lives on the plugins index rather than inside Streamystats. */}
|
||||
<TouchableOpacity
|
||||
onPress={handleRefreshFromServer}
|
||||
className='py-3 rounded-xl bg-neutral-800'
|
||||
>
|
||||
<Text className='text-center text-blue-500'>
|
||||
{t("home.settings.plugins.streamystats.refresh_from_server")}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</ScrollView>
|
||||
);
|
||||
|
||||
@@ -22,7 +22,12 @@ export default function StreamystatsPage() {
|
||||
const navigation = useNavigation();
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
const { settings, updateSettings, pluginSettings } = useSettings();
|
||||
const {
|
||||
settings,
|
||||
updateSettings,
|
||||
pluginSettings,
|
||||
refreshStreamyfinPluginSettings,
|
||||
} = useSettings();
|
||||
const queryClient = useNetworkAwareQueryClient();
|
||||
|
||||
// Local state for all editable fields
|
||||
@@ -44,21 +49,7 @@ export default function StreamystatsPage() {
|
||||
);
|
||||
|
||||
const isUrlLocked = pluginSettings?.streamyStatsServerUrl?.locked === true;
|
||||
const searchLocked = pluginSettings?.searchEngine?.locked === true;
|
||||
const movieRecsLocked =
|
||||
pluginSettings?.streamyStatsMovieRecommendations?.locked === true;
|
||||
const seriesRecsLocked =
|
||||
pluginSettings?.streamyStatsSeriesRecommendations?.locked === true;
|
||||
const promotedWatchlistsLocked =
|
||||
pluginSettings?.streamyStatsPromotedWatchlists?.locked === true;
|
||||
const hideWatchlistsTabLocked =
|
||||
pluginSettings?.hideWatchlistsTab?.locked === true;
|
||||
// The input renders the locked admin URL; enablement must follow the same
|
||||
// effective value or every toggle stays disabled until local state syncs.
|
||||
const effectiveUrl = isUrlLocked
|
||||
? (settings?.streamyStatsServerUrl ?? "")
|
||||
: url;
|
||||
const isStreamystatsEnabled = !!effectiveUrl;
|
||||
const isStreamystatsEnabled = !!url;
|
||||
|
||||
const onSave = useCallback(() => {
|
||||
const cleanUrl = url.endsWith("/") ? url.slice(0, -1) : url;
|
||||
@@ -122,6 +113,17 @@ export default function StreamystatsPage() {
|
||||
Linking.openURL("https://github.com/fredrikburmester/streamystats");
|
||||
};
|
||||
|
||||
const handleRefreshFromServer = useCallback(async () => {
|
||||
const newPluginSettings = await refreshStreamyfinPluginSettings();
|
||||
// Update local state with new values
|
||||
const newUrl = newPluginSettings?.streamyStatsServerUrl?.value || "";
|
||||
setUrl(newUrl);
|
||||
if (newUrl) {
|
||||
setUseForSearch(true);
|
||||
}
|
||||
toast.success(t("home.settings.plugins.streamystats.toasts.refreshed"));
|
||||
}, [refreshStreamyfinPluginSettings, t]);
|
||||
|
||||
if (!settings) return null;
|
||||
|
||||
return (
|
||||
@@ -144,7 +146,7 @@ export default function StreamystatsPage() {
|
||||
placeholder={t(
|
||||
"home.settings.plugins.streamystats.server_url_placeholder",
|
||||
)}
|
||||
value={effectiveUrl}
|
||||
value={url}
|
||||
keyboardType='url'
|
||||
returnKeyType='done'
|
||||
autoCapitalize='none'
|
||||
@@ -169,18 +171,11 @@ export default function StreamystatsPage() {
|
||||
>
|
||||
<ListItem
|
||||
title={t("home.settings.plugins.streamystats.enable_search")}
|
||||
disabledByAdmin={searchLocked}
|
||||
disabledByAdmin={pluginSettings?.searchEngine?.locked === true}
|
||||
>
|
||||
{/* Locked controls show the live admin value and can't be toggled —
|
||||
local form state would let the switch flip while the write guard
|
||||
drops the change. */}
|
||||
<Switch
|
||||
value={
|
||||
searchLocked
|
||||
? settings?.searchEngine === "Streamystats"
|
||||
: useForSearch
|
||||
}
|
||||
disabled={!isStreamystatsEnabled || searchLocked}
|
||||
value={useForSearch}
|
||||
disabled={!isStreamystatsEnabled}
|
||||
onValueChange={setUseForSearch}
|
||||
/>
|
||||
</ListItem>
|
||||
@@ -188,62 +183,52 @@ export default function StreamystatsPage() {
|
||||
title={t(
|
||||
"home.settings.plugins.streamystats.enable_movie_recommendations",
|
||||
)}
|
||||
disabledByAdmin={movieRecsLocked}
|
||||
disabledByAdmin={
|
||||
pluginSettings?.streamyStatsMovieRecommendations?.locked === true
|
||||
}
|
||||
>
|
||||
<Switch
|
||||
value={
|
||||
movieRecsLocked
|
||||
? (settings?.streamyStatsMovieRecommendations ?? false)
|
||||
: movieRecs
|
||||
}
|
||||
value={movieRecs}
|
||||
onValueChange={setMovieRecs}
|
||||
disabled={!isStreamystatsEnabled || movieRecsLocked}
|
||||
disabled={!isStreamystatsEnabled}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem
|
||||
title={t(
|
||||
"home.settings.plugins.streamystats.enable_series_recommendations",
|
||||
)}
|
||||
disabledByAdmin={seriesRecsLocked}
|
||||
disabledByAdmin={
|
||||
pluginSettings?.streamyStatsSeriesRecommendations?.locked === true
|
||||
}
|
||||
>
|
||||
<Switch
|
||||
value={
|
||||
seriesRecsLocked
|
||||
? (settings?.streamyStatsSeriesRecommendations ?? false)
|
||||
: seriesRecs
|
||||
}
|
||||
value={seriesRecs}
|
||||
onValueChange={setSeriesRecs}
|
||||
disabled={!isStreamystatsEnabled || seriesRecsLocked}
|
||||
disabled={!isStreamystatsEnabled}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem
|
||||
title={t(
|
||||
"home.settings.plugins.streamystats.enable_promoted_watchlists",
|
||||
)}
|
||||
disabledByAdmin={promotedWatchlistsLocked}
|
||||
disabledByAdmin={
|
||||
pluginSettings?.streamyStatsPromotedWatchlists?.locked === true
|
||||
}
|
||||
>
|
||||
<Switch
|
||||
value={
|
||||
promotedWatchlistsLocked
|
||||
? (settings?.streamyStatsPromotedWatchlists ?? false)
|
||||
: promotedWatchlists
|
||||
}
|
||||
value={promotedWatchlists}
|
||||
onValueChange={setPromotedWatchlists}
|
||||
disabled={!isStreamystatsEnabled || promotedWatchlistsLocked}
|
||||
disabled={!isStreamystatsEnabled}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem
|
||||
title={t("home.settings.plugins.streamystats.hide_watchlists_tab")}
|
||||
disabledByAdmin={hideWatchlistsTabLocked}
|
||||
disabledByAdmin={pluginSettings?.hideWatchlistsTab?.locked === true}
|
||||
>
|
||||
<Switch
|
||||
value={
|
||||
hideWatchlistsTabLocked
|
||||
? (settings?.hideWatchlistsTab ?? false)
|
||||
: hideWatchlistsTab
|
||||
}
|
||||
value={hideWatchlistsTab}
|
||||
onValueChange={setHideWatchlistsTab}
|
||||
disabled={!isStreamystatsEnabled || hideWatchlistsTabLocked}
|
||||
disabled={!isStreamystatsEnabled}
|
||||
/>
|
||||
</ListItem>
|
||||
</ListGroup>
|
||||
@@ -251,6 +236,15 @@ export default function StreamystatsPage() {
|
||||
{t("home.settings.plugins.streamystats.home_sections_hint")}
|
||||
</Text>
|
||||
|
||||
<TouchableOpacity
|
||||
onPress={handleRefreshFromServer}
|
||||
className='mt-6 py-3 rounded-xl bg-neutral-800'
|
||||
>
|
||||
<Text className='text-center text-blue-500'>
|
||||
{t("home.settings.plugins.streamystats.refresh_from_server")}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
{/* Disable button - only show if URL is not locked and Streamystats is enabled */}
|
||||
{!isUrlLocked && isStreamystatsEnabled && (
|
||||
<TouchableOpacity
|
||||
|
||||
233
app/(auth)/(tabs)/(home)/settings/segment-skip/page.tsx
Normal file
233
app/(auth)/(tabs)/(home)/settings/segment-skip/page.tsx
Normal file
@@ -0,0 +1,233 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { useNavigation } from "expo-router";
|
||||
import { TFunction } from "i18next";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { View } from "react-native";
|
||||
import { Text } from "@/components/common/Text";
|
||||
import { ListGroup } from "@/components/list/ListGroup";
|
||||
import { ListItem } from "@/components/list/ListItem";
|
||||
import { PlatformDropdown } from "@/components/PlatformDropdown";
|
||||
import DisabledSetting from "@/components/settings/DisabledSetting";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
|
||||
/**
|
||||
* Factory function to create skip options for a specific segment type
|
||||
* Reduces code duplication across all 5 segment types
|
||||
*/
|
||||
const useSkipOptions = (
|
||||
settingKey:
|
||||
| "skipIntro"
|
||||
| "skipOutro"
|
||||
| "skipRecap"
|
||||
| "skipCommercial"
|
||||
| "skipPreview",
|
||||
settings: ReturnType<typeof useSettings>["settings"] | null,
|
||||
updateSettings: ReturnType<typeof useSettings>["updateSettings"],
|
||||
t: TFunction<"translation", undefined>,
|
||||
) => {
|
||||
return useMemo(
|
||||
() => [
|
||||
{
|
||||
options: SEGMENT_SKIP_OPTIONS(t).map((option) => ({
|
||||
type: "radio" as const,
|
||||
label: option.label,
|
||||
value: option.value,
|
||||
selected: option.value === settings?.[settingKey],
|
||||
onPress: () => updateSettings({ [settingKey]: option.value }),
|
||||
})),
|
||||
},
|
||||
],
|
||||
[settings?.[settingKey], updateSettings, t, settingKey],
|
||||
);
|
||||
};
|
||||
|
||||
export default function SegmentSkipPage() {
|
||||
const { settings, updateSettings, pluginSettings } = useSettings();
|
||||
const { t } = useTranslation();
|
||||
const navigation = useNavigation();
|
||||
|
||||
useEffect(() => {
|
||||
navigation.setOptions({
|
||||
title: t("home.settings.other.segment_skip_settings"),
|
||||
});
|
||||
}, [navigation, t]);
|
||||
|
||||
const skipIntroOptions = useSkipOptions(
|
||||
"skipIntro",
|
||||
settings,
|
||||
updateSettings,
|
||||
t,
|
||||
);
|
||||
const skipOutroOptions = useSkipOptions(
|
||||
"skipOutro",
|
||||
settings,
|
||||
updateSettings,
|
||||
t,
|
||||
);
|
||||
const skipRecapOptions = useSkipOptions(
|
||||
"skipRecap",
|
||||
settings,
|
||||
updateSettings,
|
||||
t,
|
||||
);
|
||||
const skipCommercialOptions = useSkipOptions(
|
||||
"skipCommercial",
|
||||
settings,
|
||||
updateSettings,
|
||||
t,
|
||||
);
|
||||
const skipPreviewOptions = useSkipOptions(
|
||||
"skipPreview",
|
||||
settings,
|
||||
updateSettings,
|
||||
t,
|
||||
);
|
||||
|
||||
if (!settings) return null;
|
||||
|
||||
return (
|
||||
<DisabledSetting disabled={false} className='px-4'>
|
||||
<ListGroup>
|
||||
<ListItem
|
||||
title={t("home.settings.other.skip_intro")}
|
||||
subtitle={t("home.settings.other.skip_intro_description")}
|
||||
disabled={pluginSettings?.skipIntro?.locked}
|
||||
>
|
||||
<PlatformDropdown
|
||||
groups={skipIntroOptions}
|
||||
trigger={
|
||||
<View className='flex flex-row items-center justify-between py-1.5 pl-3'>
|
||||
<Text className='mr-1 text-[#8E8D91]'>
|
||||
{t(`home.settings.other.segment_skip_${settings.skipIntro}`)}
|
||||
</Text>
|
||||
<Ionicons
|
||||
name='chevron-expand-sharp'
|
||||
size={18}
|
||||
color='#5A5960'
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
title={t("home.settings.other.skip_intro")}
|
||||
/>
|
||||
</ListItem>
|
||||
|
||||
<ListItem
|
||||
title={t("home.settings.other.skip_outro")}
|
||||
subtitle={t("home.settings.other.skip_outro_description")}
|
||||
disabled={pluginSettings?.skipOutro?.locked}
|
||||
>
|
||||
<PlatformDropdown
|
||||
groups={skipOutroOptions}
|
||||
trigger={
|
||||
<View className='flex flex-row items-center justify-between py-1.5 pl-3'>
|
||||
<Text className='mr-1 text-[#8E8D91]'>
|
||||
{t(`home.settings.other.segment_skip_${settings.skipOutro}`)}
|
||||
</Text>
|
||||
<Ionicons
|
||||
name='chevron-expand-sharp'
|
||||
size={18}
|
||||
color='#5A5960'
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
title={t("home.settings.other.skip_outro")}
|
||||
/>
|
||||
</ListItem>
|
||||
|
||||
<ListItem
|
||||
title={t("home.settings.other.skip_recap")}
|
||||
subtitle={t("home.settings.other.skip_recap_description")}
|
||||
disabled={pluginSettings?.skipRecap?.locked}
|
||||
>
|
||||
<PlatformDropdown
|
||||
groups={skipRecapOptions}
|
||||
trigger={
|
||||
<View className='flex flex-row items-center justify-between py-1.5 pl-3'>
|
||||
<Text className='mr-1 text-[#8E8D91]'>
|
||||
{t(`home.settings.other.segment_skip_${settings.skipRecap}`)}
|
||||
</Text>
|
||||
<Ionicons
|
||||
name='chevron-expand-sharp'
|
||||
size={18}
|
||||
color='#5A5960'
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
title={t("home.settings.other.skip_recap")}
|
||||
/>
|
||||
</ListItem>
|
||||
|
||||
<ListItem
|
||||
title={t("home.settings.other.skip_commercial")}
|
||||
subtitle={t("home.settings.other.skip_commercial_description")}
|
||||
disabled={pluginSettings?.skipCommercial?.locked}
|
||||
>
|
||||
<PlatformDropdown
|
||||
groups={skipCommercialOptions}
|
||||
trigger={
|
||||
<View className='flex flex-row items-center justify-between py-1.5 pl-3'>
|
||||
<Text className='mr-1 text-[#8E8D91]'>
|
||||
{t(
|
||||
`home.settings.other.segment_skip_${settings.skipCommercial}`,
|
||||
)}
|
||||
</Text>
|
||||
<Ionicons
|
||||
name='chevron-expand-sharp'
|
||||
size={18}
|
||||
color='#5A5960'
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
title={t("home.settings.other.skip_commercial")}
|
||||
/>
|
||||
</ListItem>
|
||||
|
||||
<ListItem
|
||||
title={t("home.settings.other.skip_preview")}
|
||||
subtitle={t("home.settings.other.skip_preview_description")}
|
||||
disabled={pluginSettings?.skipPreview?.locked}
|
||||
>
|
||||
<PlatformDropdown
|
||||
groups={skipPreviewOptions}
|
||||
trigger={
|
||||
<View className='flex flex-row items-center justify-between py-1.5 pl-3'>
|
||||
<Text className='mr-1 text-[#8E8D91]'>
|
||||
{t(
|
||||
`home.settings.other.segment_skip_${settings.skipPreview}`,
|
||||
)}
|
||||
</Text>
|
||||
<Ionicons
|
||||
name='chevron-expand-sharp'
|
||||
size={18}
|
||||
color='#5A5960'
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
title={t("home.settings.other.skip_preview")}
|
||||
/>
|
||||
</ListItem>
|
||||
</ListGroup>
|
||||
</DisabledSetting>
|
||||
);
|
||||
}
|
||||
|
||||
const SEGMENT_SKIP_OPTIONS = (
|
||||
t: TFunction<"translation", undefined>,
|
||||
): Array<{
|
||||
label: string;
|
||||
value: "none" | "ask" | "auto";
|
||||
}> => [
|
||||
{
|
||||
label: t("home.settings.other.segment_skip_auto"),
|
||||
value: "auto",
|
||||
},
|
||||
{
|
||||
label: t("home.settings.other.segment_skip_ask"),
|
||||
value: "ask",
|
||||
},
|
||||
{
|
||||
label: t("home.settings.other.segment_skip_none"),
|
||||
value: "none",
|
||||
},
|
||||
];
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
RepeatMode,
|
||||
} from "@jellyfin/sdk/lib/generated-client";
|
||||
import {
|
||||
getMediaInfoApi,
|
||||
getPlaystateApi,
|
||||
getUserLibraryApi,
|
||||
} from "@jellyfin/sdk/lib/utils/api";
|
||||
@@ -31,6 +32,7 @@ import {
|
||||
} from "@/components/video-player/controls/utils/playback-speed-settings";
|
||||
import useRouter from "@/hooks/useAppRouter";
|
||||
import { useHaptic } from "@/hooks/useHaptic";
|
||||
import { useIntroPlayback } from "@/hooks/useIntroPlayback";
|
||||
import { useOrientation } from "@/hooks/useOrientation";
|
||||
import { usePlaybackManager } from "@/hooks/usePlaybackManager";
|
||||
import usePlaybackSpeed from "@/hooks/usePlaybackSpeed";
|
||||
@@ -60,8 +62,8 @@ import {
|
||||
getMpvSubtitleId,
|
||||
} from "@/utils/jellyfin/subtitleUtils";
|
||||
import { writeToLog } from "@/utils/log";
|
||||
import { msToTicks, ticksToSeconds } from "@/utils/time";
|
||||
import { generateDeviceProfile } from "../../../utils/profiles/native";
|
||||
import { generateDeviceProfile } from "@/utils/profiles/native";
|
||||
import { msToTicks, ticksToMs, ticksToSeconds } from "@/utils/time";
|
||||
|
||||
export default function DirectPlayerPage() {
|
||||
const videoRef = useRef<MpvPlayerViewRef>(null);
|
||||
@@ -99,6 +101,8 @@ export default function DirectPlayerPage() {
|
||||
const progress = useSharedValue(0);
|
||||
const isSeeking = useSharedValue(false);
|
||||
const cacheProgress = useSharedValue(0);
|
||||
// Track whether we've already triggered completion for the current intro
|
||||
const introCompletionTriggered = useSharedValue(false);
|
||||
const VolumeManager = Platform.isTV
|
||||
? null
|
||||
: require("react-native-volume-manager");
|
||||
@@ -170,6 +174,14 @@ export default function DirectPlayerPage() {
|
||||
isError: false,
|
||||
});
|
||||
|
||||
// Intro playback hook - manages intro video playback before main content
|
||||
const { intros, currentIntro, isPlayingIntro, skipAllIntros } =
|
||||
useIntroPlayback({
|
||||
api,
|
||||
itemId: item?.Id || null,
|
||||
userId: user?.Id,
|
||||
});
|
||||
|
||||
// Playback manager for progress reporting and adjacent items
|
||||
const playbackManager = usePlaybackManager({ item, isOffline: offline });
|
||||
const { nextItem, previousItem } = playbackManager;
|
||||
@@ -307,9 +319,43 @@ export default function DirectPlayerPage() {
|
||||
isError: false,
|
||||
});
|
||||
|
||||
// Intro stream state - separate from main content stream
|
||||
const [introStream, setIntroStream] = useState<Stream | null>(null);
|
||||
|
||||
// Ref to store the stream fetch function for refreshing subtitle tracks
|
||||
const refetchStreamRef = useRef<(() => Promise<Stream | null>) | null>(null);
|
||||
|
||||
// Live TV opens a server-side live stream via autoOpenLiveStream. If it is
|
||||
// never closed, Jellyfin's M3U tuner limit fills up and every channel then
|
||||
// fails with "simultaneous stream limit has been reached". reportPlaybackStopped
|
||||
// handles a clean stop, but a channel switch (the player re-fetches in place)
|
||||
// or an unmount after an error bypass it, so track the open live stream and
|
||||
// release it on those paths too.
|
||||
const apiRef = useRef(api);
|
||||
useEffect(() => {
|
||||
apiRef.current = api;
|
||||
}, [api]);
|
||||
|
||||
const releaseLiveStream = useCallback(
|
||||
(liveStreamId: string | null) => {
|
||||
if (!liveStreamId || !apiRef.current || offline) return;
|
||||
// Best effort: a failed close must not break teardown, and the slot is
|
||||
// also freed by the server's reap as a backstop.
|
||||
getMediaInfoApi(apiRef.current)
|
||||
.closeLiveStream({ liveStreamId })
|
||||
.catch(() => {});
|
||||
},
|
||||
[offline],
|
||||
);
|
||||
|
||||
// The effect cleanup releases the live stream both when it changes (channel
|
||||
// switch, which re-runs the effect) and when the player unmounts, so no
|
||||
// manual previous-id tracking is needed.
|
||||
useEffect(() => {
|
||||
const liveStreamId = stream?.mediaSource?.LiveStreamId ?? null;
|
||||
return () => releaseLiveStream(liveStreamId);
|
||||
}, [stream?.mediaSource?.LiveStreamId, releaseLiveStream]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchStreamData = async (): Promise<Stream | null> => {
|
||||
setStreamStatus({ isLoading: true, isError: false });
|
||||
@@ -402,6 +448,57 @@ export default function DirectPlayerPage() {
|
||||
offline,
|
||||
]);
|
||||
|
||||
// Fetch intro stream when current intro changes
|
||||
useEffect(() => {
|
||||
const fetchIntroStreamData = async () => {
|
||||
// Don't fetch intro stream if offline or no current intro
|
||||
if (offline || !currentIntro?.Id || !api || !user?.Id) {
|
||||
setIntroStream(null);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await getStreamUrl({
|
||||
api,
|
||||
item: currentIntro,
|
||||
startTimeTicks: 0, // Always start from beginning for intros
|
||||
userId: user.Id,
|
||||
audioStreamIndex: audioIndex,
|
||||
maxStreamingBitrate: bitrateValue,
|
||||
mediaSourceId: undefined,
|
||||
subtitleStreamIndex: subtitleIndex,
|
||||
deviceProfile: generateDeviceProfile(),
|
||||
});
|
||||
if (!res) return;
|
||||
const { mediaSource, sessionId, url } = res;
|
||||
|
||||
if (!sessionId || !mediaSource || !url) {
|
||||
console.error("Failed to get intro stream URL");
|
||||
return;
|
||||
}
|
||||
setIntroStream({ mediaSource, sessionId, url });
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch intro stream:", error);
|
||||
}
|
||||
};
|
||||
fetchIntroStreamData();
|
||||
}, [
|
||||
currentIntro,
|
||||
api,
|
||||
user?.Id,
|
||||
audioIndex,
|
||||
bitrateValue,
|
||||
subtitleIndex,
|
||||
offline,
|
||||
]);
|
||||
|
||||
// Reset intro completion flag when a new intro starts playing
|
||||
useEffect(() => {
|
||||
if (isPlayingIntro) {
|
||||
introCompletionTriggered.value = false;
|
||||
}
|
||||
}, [isPlayingIntro, currentIntro]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!stream || !api || offline) return;
|
||||
const reportPlaybackStart = async () => {
|
||||
@@ -445,6 +542,12 @@ export default function DirectPlayerPage() {
|
||||
MediaSourceId: mediaSourceId,
|
||||
PositionTicks: currentTimeInTicks,
|
||||
PlaySessionId: stream.sessionId,
|
||||
// Release the server-side live stream (and its tuner slot) on stop.
|
||||
// Jellyfin only closes a live stream opened via autoOpenLiveStream when
|
||||
// the stop report carries its LiveStreamId; without it the stream leaks
|
||||
// and Live TV eventually fails for everyone with "M3U simultaneous
|
||||
// stream limit has been reached". Undefined for non-live items (no-op).
|
||||
LiveStreamId: stream.mediaSource?.LiveStreamId ?? undefined,
|
||||
},
|
||||
});
|
||||
}, [api, item, mediaSourceId, stream, progress, offline]);
|
||||
@@ -568,6 +671,21 @@ export default function DirectPlayerPage() {
|
||||
lastUrlUpdateTime.value = now;
|
||||
}
|
||||
|
||||
// Handle intro completion - check if intro has reached its end
|
||||
if (isPlayingIntro && currentIntro) {
|
||||
const introDuration = ticksToMs(currentIntro.RunTimeTicks || 0);
|
||||
// Check if we're near the end of the intro (within 1000ms buffer)
|
||||
// Use a larger buffer to ensure reliable detection even with short intros
|
||||
// or if MPV doesn't fire progress callbacks frequently
|
||||
if (currentTime >= introDuration - 1000) {
|
||||
// Only trigger once per intro to avoid multiple calls
|
||||
if (!introCompletionTriggered.value) {
|
||||
introCompletionTriggered.value = true;
|
||||
skipAllIntros();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!item?.Id) return;
|
||||
|
||||
playbackManager.reportPlaybackProgress(
|
||||
@@ -584,6 +702,9 @@ export default function DirectPlayerPage() {
|
||||
isSeeking,
|
||||
isPlaybackStopped,
|
||||
isBuffering,
|
||||
isPlayingIntro,
|
||||
currentIntro,
|
||||
skipAllIntros,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -614,9 +735,11 @@ export default function DirectPlayerPage() {
|
||||
|
||||
/** Build video source config for MPV */
|
||||
const videoSource = useMemo<MpvVideoSource | undefined>(() => {
|
||||
if (!stream?.url) return undefined;
|
||||
// Use intro stream if playing intro, otherwise use main content stream
|
||||
const activeStream = isPlayingIntro ? introStream : stream;
|
||||
if (!activeStream?.url) return undefined;
|
||||
|
||||
const mediaSource = stream.mediaSource;
|
||||
const mediaSource = activeStream.mediaSource;
|
||||
const isTranscoding = Boolean(mediaSource?.TranscodingUrl);
|
||||
|
||||
// Get external subtitle URLs
|
||||
@@ -652,14 +775,17 @@ export default function DirectPlayerPage() {
|
||||
);
|
||||
|
||||
// Calculate start position directly here to avoid timing issues
|
||||
const startTicks = playbackPositionFromUrl
|
||||
? Number.parseInt(playbackPositionFromUrl, 10)
|
||||
: (item?.UserData?.PlaybackPositionTicks ?? 0);
|
||||
// For intros, always start from 0
|
||||
const startTicks = isPlayingIntro
|
||||
? 0
|
||||
: playbackPositionFromUrl
|
||||
? Number.parseInt(playbackPositionFromUrl, 10)
|
||||
: (item?.UserData?.PlaybackPositionTicks ?? 0);
|
||||
const startPos = ticksToSeconds(startTicks);
|
||||
|
||||
// Build source config - headers only needed for online streaming
|
||||
const source: MpvVideoSource = {
|
||||
url: stream.url,
|
||||
url: activeStream.url,
|
||||
startPosition: startPos,
|
||||
autoplay: true,
|
||||
initialSubtitleId,
|
||||
@@ -705,6 +831,8 @@ export default function DirectPlayerPage() {
|
||||
}, [
|
||||
stream?.url,
|
||||
stream?.mediaSource,
|
||||
introStream?.url,
|
||||
introStream?.mediaSource,
|
||||
stream?.requiredHttpHeaders,
|
||||
item?.UserData?.PlaybackPositionTicks,
|
||||
playbackPositionFromUrl,
|
||||
@@ -713,6 +841,7 @@ export default function DirectPlayerPage() {
|
||||
subtitleIndex,
|
||||
audioIndex,
|
||||
offline,
|
||||
isPlayingIntro,
|
||||
settings.mpvCacheEnabled,
|
||||
settings.mpvCacheSeconds,
|
||||
settings.mpvDemuxerMaxBytes,
|
||||
@@ -1318,7 +1447,7 @@ export default function DirectPlayerPage() {
|
||||
console.error("Video Error:", e.nativeEvent);
|
||||
Alert.alert(
|
||||
t("player.error"),
|
||||
t("player.an_error_occured_while_playing_the_video"),
|
||||
t("player.an_error_occurred_while_playing_the_video"),
|
||||
);
|
||||
writeToLog("ERROR", "Video Error", e.nativeEvent);
|
||||
}}
|
||||
@@ -1407,6 +1536,9 @@ export default function DirectPlayerPage() {
|
||||
getTechnicalInfo={getTechnicalInfo}
|
||||
playMethod={playMethod}
|
||||
transcodeReasons={transcodeReasons}
|
||||
isPlayingIntro={isPlayingIntro}
|
||||
skipAllIntros={skipAllIntros}
|
||||
intros={intros}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
|
||||
@@ -85,7 +85,8 @@ configureReanimatedLogger({
|
||||
if (!Platform.isTV) {
|
||||
Notifications.setNotificationHandler({
|
||||
handleNotification: async () => ({
|
||||
shouldShowAlert: true,
|
||||
shouldShowBanner: true,
|
||||
shouldShowList: true,
|
||||
shouldPlaySound: true,
|
||||
shouldSetBadge: false,
|
||||
}),
|
||||
@@ -350,9 +351,12 @@ function Layout() {
|
||||
notificationListener.current =
|
||||
Notifications?.addNotificationReceivedListener(
|
||||
(notification: Notification) => {
|
||||
// Log only the title — serializing the whole notification touches
|
||||
// the deprecated dataString getter (deprecation warning) and dumps
|
||||
// noisy payloads into the console.
|
||||
console.log(
|
||||
"Notification received while app running",
|
||||
notification,
|
||||
"Notification received while app running:",
|
||||
notification.request.content.title,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
248
bun.lock
248
bun.lock
@@ -347,63 +347,63 @@
|
||||
|
||||
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.1", "", { "os": "win32", "cpu": "x64" }, "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A=="],
|
||||
|
||||
"@expo-google-fonts/material-symbols": ["@expo-google-fonts/material-symbols@0.4.38", "", {}, "sha512-IJkBtN1o8u9BW5fvSii1MyHPQ7Q0HxbWcVBvOrOzgMLpVtZw7R2w94wBTVR7kZwv3w1JNTESMmLA5Sqn1+Z36A=="],
|
||||
"@expo-google-fonts/material-symbols": ["@expo-google-fonts/material-symbols@0.4.41", "", {}, "sha512-BKNSJ6oFGWi+aXu6PF+1EdI43J8Ag+Sm7Ste1SXYmC2eYOJasyjXHkKjgkIieBB1eDZQJSPWuPv421Vg6N5tCQ=="],
|
||||
|
||||
"@expo/cli": ["@expo/cli@56.1.16", "", { "dependencies": { "@expo/code-signing-certificates": "^0.0.6", "@expo/config": "~56.0.9", "@expo/config-plugins": "~56.0.9", "@expo/devcert": "^1.2.1", "@expo/env": "~2.3.0", "@expo/image-utils": "^0.10.1", "@expo/inline-modules": "^0.0.12", "@expo/json-file": "^10.2.0", "@expo/log-box": "^56.0.13", "@expo/metro": "~56.0.0", "@expo/metro-config": "~56.0.14", "@expo/metro-file-map": "^56.0.3", "@expo/osascript": "^2.6.0", "@expo/package-manager": "^1.12.1", "@expo/plist": "^0.7.0", "@expo/prebuild-config": "^56.0.16", "@expo/require-utils": "^56.1.3", "@expo/router-server": "^56.0.14", "@expo/schema-utils": "^56.0.0", "@expo/spawn-async": "^1.8.0", "@expo/ws-tunnel": "^2.0.0", "@expo/xcpretty": "^4.4.4", "@react-native/dev-middleware": "0.85.3", "accepts": "^1.3.8", "arg": "^5.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.4", "expo-server": "^56.0.5", "fetch-nodeshim": "^0.4.10", "getenv": "^2.0.0", "glob": "^13.0.0", "lan-network": "^0.2.1", "multitars": "^1.0.0", "node-forge": "^1.3.3", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", "picomatch": "^4.0.4", "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", "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": "main.js" } }, "sha512-VBQn0mqAwc67b9Cn0RVXyeodghomAx5xGRhA/bXaQzuxDjMQk0zIOb6pXMZX7yiIwJW66UZt/zQiJNSv6aWJYw=="],
|
||||
"@expo/cli": ["@expo/cli@56.1.20", "", { "dependencies": { "@expo/code-signing-certificates": "^0.0.6", "@expo/config": "~56.0.12", "@expo/config-plugins": "~56.0.13", "@expo/devcert": "^1.2.1", "@expo/env": "~2.3.1", "@expo/image-utils": "^0.10.3", "@expo/inline-modules": "^0.0.14", "@expo/json-file": "^10.2.0", "@expo/log-box": "^56.0.14", "@expo/metro": "~56.0.0", "@expo/metro-config": "~56.0.17", "@expo/metro-file-map": "^56.0.3", "@expo/osascript": "^2.6.0", "@expo/package-manager": "^1.12.1", "@expo/plist": "^0.7.0", "@expo/prebuild-config": "^56.0.20", "@expo/require-utils": "^56.1.5", "@expo/router-server": "^56.0.16", "@expo/schema-utils": "^56.0.2", "@expo/spawn-async": "^1.8.0", "@expo/ws-tunnel": "^2.0.0", "@expo/xcpretty": "^4.4.4", "@react-native/dev-middleware": "0.85.3", "accepts": "^1.3.8", "agent-cli-detector": "^0.1.2", "arg": "^5.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.6", "expo-server": "^56.0.5", "fetch-nodeshim": "^0.4.10", "getenv": "^2.0.0", "glob": "^13.0.0", "lan-network": "^0.2.1", "multitars": "^1.0.0", "node-forge": "^1.3.3", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", "picomatch": "^4.0.4", "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", "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": "main.js" } }, "sha512-xWkKvOBkOE3G/PpU29fjmAjKpCIqTIVSxG8oA+E6pYUElcPZ9gRofAdTE321lUoJVHwEjKmpn93EHqsajItDTQ=="],
|
||||
|
||||
"@expo/code-signing-certificates": ["@expo/code-signing-certificates@0.0.6", "", { "dependencies": { "node-forge": "^1.3.3" } }, "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w=="],
|
||||
|
||||
"@expo/config": ["@expo/config@56.0.9", "", { "dependencies": { "@expo/config-plugins": "~56.0.8", "@expo/config-types": "^56.0.5", "@expo/json-file": "^10.2.0", "@expo/require-utils": "^56.1.3", "deepmerge": "^4.3.1", "getenv": "^2.0.0", "glob": "^13.0.0", "resolve-workspace-root": "^2.0.0", "semver": "^7.6.0", "slugify": "^1.3.4" } }, "sha512-/lqFeWGSrhpKJVP8tTN8LjuoIe8u8q2w7FzBL0C+wHgl+WM8l1qUIEYWy/sMvsG/NbpUIUsDHJRhQvOkU58eIw=="],
|
||||
"@expo/config": ["@expo/config@56.0.12", "", { "dependencies": { "@expo/config-plugins": "~56.0.13", "@expo/config-types": "^56.0.7", "@expo/json-file": "^10.2.0", "@expo/require-utils": "^56.1.5", "deepmerge": "^4.3.1", "getenv": "^2.0.0", "glob": "^13.0.0", "resolve-workspace-root": "^2.0.0", "semver": "^7.6.0", "slugify": "^1.3.4" } }, "sha512-8X+FtflatWdFqBFlPxtyNRaj2dzMCPzi5wImO8IbhOLRKQVWyXdoLb26j0WjpWZaN1qo3Kf90t5yIcWdbbnfVA=="],
|
||||
|
||||
"@expo/config-plugins": ["@expo/config-plugins@56.0.9", "", { "dependencies": { "@expo/config-types": "^56.0.6", "@expo/json-file": "~10.2.0", "@expo/plist": "^0.7.0", "@expo/require-utils": "^56.1.3", "@expo/sdk-runtime-versions": "^1.0.0", "chalk": "^4.1.2", "debug": "^4.3.5", "getenv": "^2.0.0", "glob": "^13.0.0", "semver": "^7.5.4", "slugify": "^1.6.6", "xcode": "^3.0.1", "xml2js": "0.6.0" } }, "sha512-/6a/S9USwx8OC9tGjHxbviLFiBHyueN3aoNWMLvWDEJoZ1CIVW800ZBzwXq/FYNK2qzcN1LxFmQtzD1zeFQKNA=="],
|
||||
"@expo/config-plugins": ["@expo/config-plugins@56.0.13", "", { "dependencies": { "@expo/config-types": "^56.0.7", "@expo/json-file": "~10.2.0", "@expo/plist": "^0.7.0", "@expo/require-utils": "^56.1.5", "@expo/sdk-runtime-versions": "^1.0.0", "chalk": "^4.1.2", "debug": "^4.3.5", "getenv": "^2.0.0", "glob": "^13.0.0", "semver": "^7.5.4", "slugify": "^1.6.6", "xcode": "^3.0.1", "xml2js": "0.6.0" } }, "sha512-BWtRkvUKLb4xaMLTRXmrHPHl+RI5nKF2MKJEXODHmLtVgUlXOz66XSCU4bEvjfr8yYTx+8DQ0JO54Y7Y0kwokA=="],
|
||||
|
||||
"@expo/config-types": ["@expo/config-types@56.0.6", "", {}, "sha512-4Y6Aum5J4Re5NnxGVofRNe1aDwUBOmWhQYkynZsqzRtX/zEA1ADUeyHXuEckv9YD9djiyT7bKtLt5gKL3mA6VQ=="],
|
||||
"@expo/config-types": ["@expo/config-types@56.0.7", "", {}, "sha512-V7bxawNsNned/yMppAHdisIOxniZXgPKRWpIUiQOQBs45/A5MBd2gfDM4Ecq5gnbilnQUTaI6Zxn6JcW7L3TAA=="],
|
||||
|
||||
"@expo/devcert": ["@expo/devcert@1.2.1", "", { "dependencies": { "@expo/sudo-prompt": "^9.3.1", "debug": "^3.1.0" } }, "sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA=="],
|
||||
|
||||
"@expo/devtools": ["@expo/devtools@56.0.2", "", { "dependencies": { "chalk": "^4.1.2" }, "peerDependencies": { "react": "*", "react-native": "*" }, "optionalPeers": ["react", "react-native"] }, "sha512-ANl4kPdbe0/HQYWkDEN79S6bQhI+i/ZCnPxuC853pPsB4svhINC7Ku9lmGOKPsUUWWnrHg1spkDGQBZ4sD6JxQ=="],
|
||||
|
||||
"@expo/dom-webview": ["@expo/dom-webview@56.0.5", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-UIEJxkLg6cHqofKrpWpkn9E6ApxVRtCgZhZkARPr9VV7rBVloJgeroTHs31YgU/JpbI5lLQOnfOlGo54W6C2Ew=="],
|
||||
"@expo/dom-webview": ["@expo/dom-webview@56.0.6", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-DQY3Tj5nrPbpIfEQiD9xbyEFTu25yEORa02Eyzl5rXszDzxDT4VkZDHkyErNQOyE1qjublJHNFhE5bDm4tRfqA=="],
|
||||
|
||||
"@expo/env": ["@expo/env@2.3.0", "", { "dependencies": { "chalk": "^4.0.0", "debug": "^4.3.4", "getenv": "^2.0.0" } }, "sha512-9HnnIbzwTTdbwSjNLXTk0fPm9ZwMJ7c1/31tsni8HZ8Q62KzYCyspahH+V365vg5J6lr001DzNwBxVWSaYCQLg=="],
|
||||
"@expo/env": ["@expo/env@2.3.1", "", { "dependencies": { "chalk": "^4.0.0", "debug": "^4.3.4", "getenv": "^2.0.0" } }, "sha512-JvBdZa5OkTd+dGEtt3fLW9OF6RlIp9SNu9VyMSiWPV5szMDTSAYbX8Uj3cRvZcU1zzaRbqnTSsHk2AE8WXHfxQ=="],
|
||||
|
||||
"@expo/expo-modules-macros-plugin": ["@expo/expo-modules-macros-plugin@0.2.2", "", {}, "sha512-4IMzPDIo/VOXREQjsJtliSfqYVZvfzU2SLFS/9sKMWF848S8CHx+e/E+Vf0TcMvpWCCKX5umyqxb13KJJ+YUzg=="],
|
||||
|
||||
"@expo/fingerprint": ["@expo/fingerprint@0.19.4", "", { "dependencies": { "@expo/env": "^2.3.0", "@expo/spawn-async": "^1.8.0", "arg": "^5.0.2", "chalk": "^4.1.2", "debug": "^4.3.4", "getenv": "^2.0.0", "glob": "^13.0.0", "ignore": "^5.3.1", "minimatch": "^10.2.2", "resolve-from": "^5.0.0", "semver": "^7.6.0" }, "bin": { "fingerprint": "bin/cli.js" } }, "sha512-PsowRlO8+S7JlO8go7yhNEXp7sqlsWDE2AlCwoss7zH0dcajXFo74Fy0KdXEc4UXK7kKoHD37oDgsZ8aHSLr7A=="],
|
||||
"@expo/fingerprint": ["@expo/fingerprint@0.19.8", "", { "dependencies": { "@expo/env": "^2.3.1", "@expo/spawn-async": "^1.8.0", "arg": "^5.0.2", "chalk": "^4.1.2", "debug": "^4.3.4", "getenv": "^2.0.0", "glob": "^13.0.0", "ignore": "^5.3.1", "minimatch": "^10.2.2", "resolve-from": "^5.0.0", "semver": "^7.6.0" }, "bin": { "fingerprint": "bin/cli.js" } }, "sha512-zM0UMJLxYJnYq0+IzASGUYwQulENnC4qmXCAwJYmjD66AG+qTfyab4yTmL2gbiWyBAsWv0vPtP+ahEhtsT2CjQ=="],
|
||||
|
||||
"@expo/image-utils": ["@expo/image-utils@0.10.1", "", { "dependencies": { "@expo/require-utils": "^56.1.3", "@expo/spawn-async": "^1.8.0", "chalk": "^4.0.0", "getenv": "^2.0.0", "jimp-compact": "0.16.1", "parse-png": "^2.1.0", "semver": "^7.6.0" } }, "sha512-YDeefvmYdihS7Wp3ESDUVnOgOSWmj2Cczm9lVNDdm4MqQLdAKm/LPYg83HtFQPfefRlAxyHrQR/O9kIXN9C1Wg=="],
|
||||
"@expo/image-utils": ["@expo/image-utils@0.10.3", "", { "dependencies": { "@expo/require-utils": "^56.1.5", "@expo/spawn-async": "^1.8.0", "chalk": "^4.0.0", "getenv": "^2.0.0", "jimp-compact": "0.16.1", "parse-png": "^2.1.0", "semver": "^7.6.0" } }, "sha512-FgVp21Q05GRi08XwkzdZbBb/sBgCcP66snxlyN/HyisdtTcSbTr1qV5wkXYjq+6Q1xllXiKLmCwjDvydoN2vyg=="],
|
||||
|
||||
"@expo/inline-modules": ["@expo/inline-modules@0.0.12", "", { "dependencies": { "@expo/config-plugins": "~56.0.9" } }, "sha512-SNIZr/HWfIQPTZBwmukItxpc7ws1SgMUywYq1dnQvDknQDjJcuWAasIRFUjsK15yQ1xb4G5CP7VHtbN3V4lENg=="],
|
||||
"@expo/inline-modules": ["@expo/inline-modules@0.0.14", "", { "dependencies": { "@expo/config-plugins": "~56.0.13" } }, "sha512-jHrqsgpb5QnnwGfxD6NrUAMW9JcS1+j/e8GiLSy+12Md7aRnEWqi347xZ8Q57tkow1iXdeVLXPeyn1VmmCB8fA=="],
|
||||
|
||||
"@expo/json-file": ["@expo/json-file@10.2.0", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "json5": "^2.2.3" } }, "sha512-S6XzKe3R9GQeHiUPXc3xJjOv2VJhOEwFYf7xdC2z2cUqt3kZJ9mSO877sNQloVdnW/SUCtPY3bexlM7nwq+CAQ=="],
|
||||
|
||||
"@expo/local-build-cache-provider": ["@expo/local-build-cache-provider@56.0.8", "", { "dependencies": { "@expo/config": "~56.0.9", "chalk": "^4.1.2" } }, "sha512-UsuXwpNi57MNhzZ3be4XThc8xW6nzk3Wu37s1+2qcfZGeJcMLKDFfwO6n8YXeIiGlCsOi0Ee1rsTdgjrKt/YJQ=="],
|
||||
"@expo/local-build-cache-provider": ["@expo/local-build-cache-provider@56.0.10", "", { "dependencies": { "@expo/config": "~56.0.12", "chalk": "^4.1.2" } }, "sha512-ki4bnpcWaZRfOdcN1TYLuN02k+R8UaUJ9rQuSOKlj471ZnDcrAn/muugA8xHiIbZ/hS5HGNIy5z5A/unTPjVUw=="],
|
||||
|
||||
"@expo/log-box": ["@expo/log-box@56.0.13", "", { "dependencies": { "@expo/dom-webview": "^56.0.5", "anser": "^1.4.9", "stacktrace-parser": "^0.1.10" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-QWRZSpWPyjkDLVQio4R7oAzg/Av2MOt/DciFkfjr8qQ3qxGVn1Rt1oHP/80hvcWDcHFV7N6PqpyxRXw6nbxzKQ=="],
|
||||
"@expo/log-box": ["@expo/log-box@56.0.14", "", { "dependencies": { "@expo/dom-webview": "^56.0.6", "anser": "^1.4.9", "stacktrace-parser": "^0.1.10" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-3Eadcxz0J2NESG2iKe8DnAggsRCWqY0mBLhgQPNzClPVjS6o4NyD0F8kuOvWNngFwpJBC08HhY2o8P1mgSgeJg=="],
|
||||
|
||||
"@expo/metro": ["@expo/metro@56.0.0", "", { "dependencies": { "metro": "0.84.4", "metro-babel-transformer": "0.84.4", "metro-cache": "0.84.4", "metro-cache-key": "0.84.4", "metro-config": "0.84.4", "metro-core": "0.84.4", "metro-file-map": "0.84.4", "metro-minify-terser": "0.84.4", "metro-resolver": "0.84.4", "metro-runtime": "0.84.4", "metro-source-map": "0.84.4", "metro-symbolicate": "0.84.4", "metro-transform-plugins": "0.84.4", "metro-transform-worker": "0.84.4" } }, "sha512-5gIgQHtEpjjvsjKfVtIv23a98LLRV0/y07PDShEwYSytAMlE3FSF8RHXqtHc1sUJL6dn7hnuIBpIbrLXXuVi0A=="],
|
||||
|
||||
"@expo/metro-config": ["@expo/metro-config@56.0.14", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "@babel/core": "^7.20.0", "@babel/generator": "^7.20.5", "@expo/config": "~56.0.9", "@expo/env": "~2.3.0", "@expo/json-file": "~10.2.0", "@expo/metro": "~56.0.0", "@expo/require-utils": "^56.1.3", "@expo/spawn-async": "^1.8.0", "@jridgewell/gen-mapping": "^0.3.13", "@jridgewell/remapping": "^2.3.5", "@jridgewell/sourcemap-codec": "^1.5.5", "browserslist": "^4.25.0", "chalk": "^4.1.0", "debug": "^4.3.2", "getenv": "^2.0.0", "glob": "^13.0.0", "hermes-parser": "^0.33.3", "jsc-safe-url": "^0.2.4", "lightningcss": "^1.30.1", "picomatch": "^4.0.4", "postcss": "^8.5.14", "resolve-from": "^5.0.0" }, "peerDependencies": { "expo": "*" }, "optionalPeers": ["expo"] }, "sha512-O3CIHruaTJhswPAf/nf3i8QQ3f2jl+mEwSea1eb3khuplabdy/wTQz+JvHN8VGUFyg7JKwUGU1QfO6T3JiSQqA=="],
|
||||
"@expo/metro-config": ["@expo/metro-config@56.0.17", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "@babel/core": "^7.20.0", "@babel/generator": "^7.20.5", "@expo/config": "~56.0.12", "@expo/env": "~2.3.1", "@expo/json-file": "~10.2.0", "@expo/metro": "~56.0.0", "@expo/require-utils": "^56.1.5", "@expo/spawn-async": "^1.8.0", "@jridgewell/gen-mapping": "^0.3.13", "@jridgewell/remapping": "^2.3.5", "@jridgewell/sourcemap-codec": "^1.5.5", "browserslist": "^4.25.0", "chalk": "^4.1.0", "debug": "^4.3.2", "getenv": "^2.0.0", "glob": "^13.0.0", "hermes-parser": "^0.33.3", "jsc-safe-url": "^0.2.4", "lightningcss": "^1.30.1", "picomatch": "^4.0.4", "postcss": "^8.5.14", "resolve-from": "^5.0.0" }, "peerDependencies": { "expo": "*" }, "optionalPeers": ["expo"] }, "sha512-kxCDDCTPbd29gqVhic7fGAPzXbW+fNWerDeXNJdaoO7rutEwogEeud7UHpX4G0fZNMbio1eM5mAQa+edCm/IRw=="],
|
||||
|
||||
"@expo/metro-file-map": ["@expo/metro-file-map@56.0.3", "", { "dependencies": { "debug": "^4.3.4", "fb-watchman": "^2.0.2", "invariant": "^2.2.4", "jest-worker": "^29.7.0", "micromatch": "^4.0.4", "walker": "^1.0.8" } }, "sha512-5OGW3z8LgEYgMJOR7F3pC8llFLkb1fVqwAewbCl6S4Vkha8AFQMwOjT+9Wbka+V4rmpljpGqOnMhF4xZbD961w=="],
|
||||
|
||||
"@expo/metro-runtime": ["@expo/metro-runtime@56.0.15", "", { "dependencies": { "@expo/log-box": "^56.0.13", "anser": "^1.4.9", "pretty-format": "^29.7.0", "stacktrace-parser": "^0.1.10", "whatwg-fetch": "^3.0.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-dom": "*", "react-native": "*" }, "optionalPeers": ["react-dom"] }, "sha512-WIWeVsL6kCSB57oYZdUA4MTkH7c67UFMIjdNoQzKXwxZYwBFE/xL2cGPDC3z8RWt0femzJTVxAVZUOW/hiqRzA=="],
|
||||
"@expo/metro-runtime": ["@expo/metro-runtime@56.0.17", "", { "dependencies": { "@expo/log-box": "^56.0.14", "anser": "^1.4.9", "pretty-format": "^29.7.0", "stacktrace-parser": "^0.1.10", "whatwg-fetch": "^3.0.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-dom": "*", "react-native": "*" }, "optionalPeers": ["react-dom"] }, "sha512-mYZXMOX3SYqF4VC4G3eVq8+Hd0YfEjs/sSf2eKpqJl54fDtBxeJIu5DLHg9YIMsICPhUZ/r73syEm0835ZEM+g=="],
|
||||
|
||||
"@expo/osascript": ["@expo/osascript@2.6.0", "", { "dependencies": { "@expo/spawn-async": "^1.8.0" } }, "sha512-QvqDBlJXa8CS2vRORJ4wEflY1m0vVI07uSJdIRgBrLxRPBcsrXxrtU7+wXRXMqfq9zLwNP9XbvRsXF2omoDylg=="],
|
||||
"@expo/osascript": ["@expo/osascript@2.7.1", "", { "dependencies": { "@expo/spawn-async": "^1.8.0" } }, "sha512-Zn03EX6In7ts2lPUW2ESUSkEhEWQN1qqsiXjadtZMJOuZRkMiAg1ZQHuvz9DjByDWNJ2pBwAGyrts9lj9k389g=="],
|
||||
|
||||
"@expo/package-manager": ["@expo/package-manager@1.12.1", "", { "dependencies": { "@expo/json-file": "^10.2.0", "@expo/spawn-async": "^1.8.0", "chalk": "^4.0.0", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", "resolve-workspace-root": "^2.0.0" } }, "sha512-fQLiFAcFRWF53mtuLK32SUJQ1ahhrTcBZPZPedYTiUT5ha5FF+UO6bPtCc0Y/hgj0/m3HCGBAuSHjbg2kI9oPQ=="],
|
||||
"@expo/package-manager": ["@expo/package-manager@1.13.1", "", { "dependencies": { "@expo/json-file": "^11.0.1", "@expo/spawn-async": "^1.8.0", "chalk": "^4.0.0", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", "resolve-workspace-root": "^2.0.0" } }, "sha512-y/K+CaYYpZpNGZhSX4HyLT/vyIunFjNfyoxNysPBCefeLKI/VCx6f9LNPzrxayr3rCYO5bl9O8H+HRQK265Nkg=="],
|
||||
|
||||
"@expo/plist": ["@expo/plist@0.7.0", "", { "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" } }, "sha512-vrpryU1GoqSIRNqRB2D3IjXDmzNYfiQpEF6AH/xknlD7eiYmEDt3mb26V7cLcedcPG8PY/1xWHdBXVQJfEAh6Q=="],
|
||||
|
||||
"@expo/prebuild-config": ["@expo/prebuild-config@56.0.16", "", { "dependencies": { "@expo/config": "~56.0.9", "@expo/config-plugins": "~56.0.9", "@expo/config-types": "^56.0.6", "@expo/image-utils": "^0.10.1", "@expo/json-file": "^10.2.0", "@react-native/normalize-colors": "0.85.3", "debug": "^4.3.1", "expo-modules-autolinking": "~56.0.16", "resolve-from": "^5.0.0", "semver": "^7.6.0" } }, "sha512-ce9ENfPWO4WUWUVQz0OaqL3KYZ7YofP8O35ncnn7CHCaKwQ7BqxcCGJbh+qvP1UjlWeNB3CjHPrXXJ3bnZwlJw=="],
|
||||
"@expo/prebuild-config": ["@expo/prebuild-config@56.0.20", "", { "dependencies": { "@expo/config": "~56.0.12", "@expo/config-plugins": "~56.0.13", "@expo/config-types": "^56.0.7", "@expo/image-utils": "^0.10.3", "@expo/json-file": "^10.2.0", "@react-native/normalize-colors": "0.85.3", "debug": "^4.3.1", "expo-modules-autolinking": "~56.0.20", "resolve-from": "^5.0.0", "semver": "^7.6.0" } }, "sha512-S8K1lg1cqREpnUtWAhDSOitTVJssFVhJAAdtNSi1mZaG/HL5QHUB+dogHIHijfdWKBj4KPGGjBfo6GqdmzzgtA=="],
|
||||
|
||||
"@expo/react-native-action-sheet": ["@expo/react-native-action-sheet@4.1.1", "", { "dependencies": { "@types/hoist-non-react-statics": "^3.3.1", "hoist-non-react-statics": "^3.3.0" }, "peerDependencies": { "react": ">=18.0.0" } }, "sha512-4KRaba2vhqDRR7ObBj6nrD5uJw8ePoNHdIOMETTpgGTX7StUbrF4j/sfrP1YUyaPEa1P8FXdwG6pB+2WtrJd1A=="],
|
||||
|
||||
"@expo/require-utils": ["@expo/require-utils@56.1.3", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "@babel/core": "^7.25.2", "@babel/plugin-transform-modules-commonjs": "^7.24.8" }, "peerDependencies": { "typescript": "^5.0.0 || ^5.0.0-0 || ^6.0.0" }, "optionalPeers": ["typescript"] }, "sha512-KyLeOn/zzQSvuPpV5YhB/FPKnpQytno4luN918bGdPDssLBoS3N/0UbC3W0rJAn9kSFu+XpfR81eABRVsSdfgQ=="],
|
||||
"@expo/require-utils": ["@expo/require-utils@56.1.5", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "@babel/core": "^7.25.2", "@babel/plugin-transform-modules-commonjs": "^7.24.8" }, "peerDependencies": { "typescript": "^5.0.0 || ^5.0.0-0 || ^6.0.0" }, "optionalPeers": ["typescript"] }, "sha512-3wsdJLSpELhRPEMZCCREqAAFRGG23BUWJHGKIUxyqGkWvy5KPdzlBxGlVVb/6h9gNOflqgTtvTWaP2EuHoQ1HQ=="],
|
||||
|
||||
"@expo/router-server": ["@expo/router-server@56.0.14", "", { "dependencies": { "debug": "^4.3.4" }, "peerDependencies": { "@expo/metro-runtime": "^56.0.15", "expo": "*", "expo-constants": "^56.0.18", "expo-font": "^56.0.6", "expo-router": "*", "expo-server": "^56.0.5", "react": "*", "react-dom": "*", "react-server-dom-webpack": "~19.0.1 || ~19.1.2 || ~19.2.1" }, "optionalPeers": ["@expo/metro-runtime", "expo-router", "react-dom", "react-server-dom-webpack"] }, "sha512-2UCTtZfcq1ZPgp3wk8/+sq9DvFI9UxrPr1jcEKMAF2DGAJLosnpc8GWNNg2hkjt6SHUOdFHIPxujWPYyho2y3A=="],
|
||||
"@expo/router-server": ["@expo/router-server@56.0.16", "", { "dependencies": { "debug": "^4.3.4" }, "peerDependencies": { "@expo/metro-runtime": "^56.0.16", "expo": "*", "expo-constants": "^56.0.20", "expo-font": "^56.0.7", "expo-router": "*", "expo-server": "^56.0.5", "react": "*", "react-dom": "*", "react-server-dom-webpack": "~19.0.1 || ~19.1.2 || ~19.2.1" }, "optionalPeers": ["@expo/metro-runtime", "expo-router", "react-dom", "react-server-dom-webpack"] }, "sha512-df5BI5GFnSKqAhuALTPIbuHisd4CUhuYam7pwF9Dt1D6BinPctsteWWDm/sEGXdLVhsub4NPI7tvUHo/HWL7aA=="],
|
||||
|
||||
"@expo/schema-utils": ["@expo/schema-utils@56.0.1", "", {}, "sha512-CZ/+mYbQmWeOnkCGlWy9K+lFxbJSMFY7+TqBZcKzBSTU5Q7IGRvn/sOG3TdNjIdLPmbA8xe7R/c3UUQ28R9i9w=="],
|
||||
"@expo/schema-utils": ["@expo/schema-utils@56.0.2", "", {}, "sha512-WcOH1E6rwxRqNwBzPOVhd5GBbMlS04+5n+ZMdhdwKOg/Kt3suV+F8F6An+z8mUJ8eSuMM3HD9Sj09t7vc/Xjkw=="],
|
||||
|
||||
"@expo/sdk-runtime-versions": ["@expo/sdk-runtime-versions@1.0.0", "", {}, "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ=="],
|
||||
|
||||
@@ -411,7 +411,7 @@
|
||||
|
||||
"@expo/sudo-prompt": ["@expo/sudo-prompt@9.3.2", "", {}, "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw=="],
|
||||
|
||||
"@expo/ui": ["@expo/ui@56.0.18", "", { "dependencies": { "sf-symbols-typescript": "^2.1.0", "vaul": "^1.1.2" }, "peerDependencies": { "@babel/core": "*", "expo": "*", "react": "*", "react-dom": "*", "react-native": "*", "react-native-reanimated": "*", "react-native-worklets": "*" }, "optionalPeers": ["@babel/core", "react-dom", "react-native-reanimated", "react-native-worklets"] }, "sha512-2XgH5obigGtXm8zlb/V3g87NSiIcBcJ1xoQOEQYPoExL1DCNsHzaIecTh1XG/f/45ardo4OZNJwpbfYJ9X3qrQ=="],
|
||||
"@expo/ui": ["@expo/ui@56.0.22", "", { "dependencies": { "sf-symbols-typescript": "^2.1.0", "vaul": "^1.1.2" }, "peerDependencies": { "@babel/core": "*", "expo": "*", "react": "*", "react-dom": "*", "react-native": "*", "react-native-worklets": "*" }, "optionalPeers": ["@babel/core", "react-dom", "react-native-worklets"] }, "sha512-B6CXc+WJg2GE4KF6LrCPTf+ozMWKMG9TAVc//gQYUsLzFZzm0vCgUqXRiaNJ6BukpHoZPLKsQZ95VsSyTVda3A=="],
|
||||
|
||||
"@expo/vector-icons": ["@expo/vector-icons@15.1.1", "", { "peerDependencies": { "expo-font": ">=14.0.4", "react": "*", "react-native": "*" } }, "sha512-Iu2VkcoI5vygbtYngm7jb4ifxElNVXQYdDrYkT7UCEIiKLeWnQY0wf2ZhHZ+Wro6Sc5TaumpKUOqDRpLi5rkvw=="],
|
||||
|
||||
@@ -471,7 +471,7 @@
|
||||
|
||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
|
||||
|
||||
"@nodable/entities": ["@nodable/entities@2.2.0", "", {}, "sha512-9uGyhaQavEUMC8AIddIjau4NsnsXhou+j5sBAGojCM1oxmQpVKTWR/9JxABD6UAv12vpIms55fPZKFQEhG6uBg=="],
|
||||
"@nodable/entities": ["@nodable/entities@3.0.0", "", {}, "sha512-8L9xFeTYKhm49xfIypoe2W5wV1m/3Z58kT+7kR9A8OyFxcPduI4VmxaUMQyKYrRjUoLLSXv6EKKID5Tvj9cUVw=="],
|
||||
|
||||
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
||||
|
||||
@@ -479,37 +479,37 @@
|
||||
|
||||
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
|
||||
|
||||
"@radix-ui/primitive": ["@radix-ui/primitive@1.1.4", "", {}, "sha512-7AdCK9PQyiljKoBDbN8OuctCbd/esdwZPQ8RtOE3SsyQtUpiPb+ND75q0jEhC1m1ecBI0MFNeLJvwIh9iKHRcQ=="],
|
||||
"@radix-ui/primitive": ["@radix-ui/primitive@1.1.5", "", {}, "sha512-d86WIWFYNtGA0H/d8exstrTRTp7eWJYlYJbtNofxr/3ljupZYn6EFDG/Qgu/0Kc8v7yMUxySagqJsL1+PdYjWg=="],
|
||||
|
||||
"@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.10", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-IVVz4EvBcKjrzKgof714qDnz/SzQAkLA2Emh5edlHbgcE6fNd3Un6CJLlaYcnm8N4JmAtzQgse4dOKxcD2yc9g=="],
|
||||
"@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.12", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-nb67INpE0IahJKN7EYPp9m9YGwYeKlnzxT3MwXVkgCskaSJia97kG4T0ywpjNUSSnoJk/uvk12V8vbrEHEj+/Q=="],
|
||||
|
||||
"@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA=="],
|
||||
|
||||
"@radix-ui/react-context": ["@radix-ui/react-context@1.1.4", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-QwH4PO5urrbO+FaGd5Aglg+YJgWTyyuZ3g/6mKvsqraLkglDdckw9JafgL5McL5VEJ6EPNduPaT3ZE9BttDAqg=="],
|
||||
"@radix-ui/react-context": ["@radix-ui/react-context@1.2.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-fOE+JtN9rygNZkCnHRBEP0TAvLldlhyOxMsbwFvTP4nAs+nBmfnna+o/Zski2wkmY1YMrFC0aSzsHoLY47iLrg=="],
|
||||
|
||||
"@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.13", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.10", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-portal": "1.1.12", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TDTYmpdq8dI2+Xgvgj9AJ8Ghqq+Eph/TRVEdaFQPDItIY+6QSkU7MJMeevw1568Yw/2Ijz8BTphPSP2XejKphw=="],
|
||||
"@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.19", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-dismissable-layer": "1.1.15", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.12", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-+HhbN2+YtkRgVirjZ2afMeutQRuGOrdkWR5+EFC58SJojGmtyNQwYzgi6tHBpOxvFHefMtPeHdgtjz0BOGxFQg=="],
|
||||
|
||||
"@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA=="],
|
||||
|
||||
"@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-escape-keydown": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-2v+zNAWWe0ySxgC0D0yeXMPQ23xZVgXZTerTz+JKlmdRj6gfTqmCcR29jb6d290DezXPGgruHWDX/vYUebtErg=="],
|
||||
"@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-effect-event": "0.0.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-b0XaRlzn2QKuo10XyNgi2DAJDf5XC9d1nD3FJcuvCjbR7+4Ad28zmZsLsqx+hvDEzMnRuZaZxZm9gYObV6RmRA=="],
|
||||
|
||||
"@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.4", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-cot/aB/mOm0IYVYTTmQcEEK1M48lZWi8FlYe5nDPQQ8NYZUlXEFgncJ9p2Kzer3RKSrY7cTTpEMLZKNo9QoP5Q=="],
|
||||
|
||||
"@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.10", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Fas/lXQqhVvqwAb64s5RFeHiHYElZ6SUQbZaNd6EkfhP/Al7wTIQ9WIR4QVX475tlu5yFCEdDcJH6/UwsZjMWw=="],
|
||||
"@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.12", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-jjk/lqTeNL0azUx5ZYzVrl4NgaDIrdzTNE4mABV9yBFI7FQqN7pIgzV1bTleUezP2QiTGA1BFTqY8MegDgWX9A=="],
|
||||
|
||||
"@radix-ui/react-id": ["@radix-ui/react-id@1.1.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA=="],
|
||||
|
||||
"@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.12", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m309havGzsjLHHaIX50G5PlvRs3xkgPCsGk/5PTvYm8D5q33yG0J7w/712PTOhid7NTaFETtnSXjngHQavvhVw=="],
|
||||
"@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.13", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-z3oXfmaHLJTF1wktbjgD6cn9jiEbq3WSondB10LIuIt2m2Ym4iJlrW04/euMwENDdWDdE7z+OuY7Qyp1YpRSwA=="],
|
||||
|
||||
"@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.6", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zdTk4PlUO0E18HnZ3wYbW0KkJJxWCdiNYp6g6X1PtONFhxVkg01vliTJAmwIszU6mHiyBOoW9P0rAugl5/hULQ=="],
|
||||
"@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.7", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zBZ4QM5XG3JRanDmqXYf3MD6th4AFXFmgU6KNMFzUaV6F3uw9I5/zjMUvFriSEn5ewo1nxuibvyxJdmLlDcslA=="],
|
||||
|
||||
"@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.6", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wetd0QI77DbvrPpTAvH1SqOxsYF2wZe5TNxqwOd5Ty4XDpV3dpV0s8K/1MGMJBeY5o7lg8ub5VIt1Ub+yVen6g=="],
|
||||
"@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.7", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ=="],
|
||||
|
||||
"@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.10", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9gkwneI0guf8JDmrFxPjJF6Ozzgioyw+/lonYNCwefS9ZHA05er0BVHiXr+LbWGHxUfczvMY6G1oiZZi1VzjRw=="],
|
||||
"@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-collection": "1.1.12", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-40svmmugfM3mUN7VUDGVE1tQGOhyi8enlGD0CNJEcMM36C1f71PKM21DFgNHUfem0XnA+d8H8oN3Z9ZpJjSslg=="],
|
||||
|
||||
"@radix-ui/react-slot": ["@radix-ui/react-slot@1.3.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA=="],
|
||||
|
||||
"@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.6", "@radix-ui/react-roving-focus": "1.1.13", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-kxc9gI6/HfcU4nfMMVS3AmQK414kbU1IE6UCJmMmxjhO3cRPXOyYnmvyKD+ODt7q56nRq9l7Wovi6uaGwKgMlg=="],
|
||||
"@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.15", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-nRyXnrAVCwjeXcHbvEbLS6ndbTeKHG1RqCP4A8Gw5L4cemDzPXdD8rAmr6wet0v57R69wGvuIIsFjHSVkZiMzQ=="],
|
||||
|
||||
"@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw=="],
|
||||
|
||||
@@ -517,7 +517,7 @@
|
||||
|
||||
"@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.3", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA=="],
|
||||
|
||||
"@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.2", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-2uVLvLjgO7NZCWw01/FdqRwmA42J0BcjPMUCA+koFEOAb+zjqIP7SiFz/7zWPrKnVmSqr76Omq2ALyCuX4dhLw=="],
|
||||
"@radix-ui/react-use-is-hydrated": ["@radix-ui/react-use-is-hydrated@0.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-qwOiz4Tjo8CNnrOLAYUMXeZwDzXgXpvK4TKQPmWLECM9XoWvA6+0Z2/7Ag3A4ivjS4ovbLJPbskkxioFyBhr8A=="],
|
||||
|
||||
"@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jrBWOxZITuGcnjRCM2t2U5ZPkCLxD+Ym6DjfssS5haTj2iiak/DOb64JeN6OdLfLgptb6/e2kKR+ZuTrGoZTPA=="],
|
||||
|
||||
@@ -579,15 +579,15 @@
|
||||
|
||||
"@react-native/normalize-colors": ["@react-native/normalize-colors@0.85.3", "", {}, "sha512-hj0PScZEhIbcOvQV5yMKX3ha4XEIOy/SVE1Rrpp0beW0dpNLOgSC7KDxGewmDnIHK9YdQUXGY9eMEfShUMIaZw=="],
|
||||
|
||||
"@react-navigation/core": ["@react-navigation/core@7.21.1", "", { "dependencies": { "@react-navigation/routers": "^7.6.0", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", "query-string": "^7.1.3", "react-is": "^19.1.0", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "react": ">= 18.2.0" } }, "sha512-9eOK71VFEyJjm1bP8o4Gf7YYppWPZ+RdNIjTc+WbSM7AFEH0XXEIHkkhpIBuB416sDlRZ1CRxHk2frh1HPBZqw=="],
|
||||
"@react-navigation/core": ["@react-navigation/core@7.21.7", "", { "dependencies": { "@react-navigation/routers": "^7.6.2", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", "query-string": "^7.1.3", "react-is": "^19.1.0", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "react": ">= 18.2.0" } }, "sha512-Z/L+IX6035XLHhGcQUgKdQzizh2XUuBjF6yZmxgamD/wRr/DbH+KuaD0hNikrHge/cHNRovlZ3gSChElGVuHlQ=="],
|
||||
|
||||
"@react-navigation/elements": ["@react-navigation/elements@2.9.25", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@react-native-masked-view/masked-view": ">= 0.2.0", "@react-navigation/native": "^7.3.3", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0" }, "optionalPeers": ["@react-native-masked-view/masked-view"] }, "sha512-cV7Hny55aE/uge6f4UB0pbGQbFl3XjXLMW+lTBNuJs8P7a9tuf7dkkPHxxgnLIvxE+KJVI2K8CGabfDk4Ht0Sg=="],
|
||||
"@react-navigation/elements": ["@react-navigation/elements@2.9.32", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@react-native-masked-view/masked-view": ">= 0.2.0", "@react-navigation/native": "^7.3.10", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0" }, "optionalPeers": ["@react-native-masked-view/masked-view"] }, "sha512-sM04aRaAu3Fiqi+Q4dviv+rJ5VTLmJ6ZHQSA08cMSx1BXc7jdrZ40+laLxmNOPoWHgCv3k7KcAXp4HyB+nzQdw=="],
|
||||
|
||||
"@react-navigation/material-top-tabs": ["@react-navigation/material-top-tabs@7.4.28", "", { "dependencies": { "@react-navigation/elements": "^2.9.19", "color": "^4.2.3", "react-native-tab-view": "^4.3.0" }, "peerDependencies": { "@react-navigation/native": "^7.2.5", "react": ">= 18.2.0", "react-native": "*", "react-native-pager-view": ">= 6.0.0", "react-native-safe-area-context": ">= 4.0.0" } }, "sha512-WZHJSGV2PQOD2Vr9LF8apGvcsbDKukzF3Fhh8xVNIesqaSi9TPProv4dRw6YkenUkjvFVZYkOjvwAJOToePVpA=="],
|
||||
|
||||
"@react-navigation/native": ["@react-navigation/native@7.3.3", "", { "dependencies": { "@react-navigation/core": "^7.21.1", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", "standard-navigation": "^0.0.7", "use-latest-callback": "^0.2.4" }, "peerDependencies": { "react": ">= 18.2.0", "react-native": "*" } }, "sha512-VjZngfeiyJestZPT99CKHRi3qOR6XwnEEPWb6uHF/L7fBI6RBVP842iJf61MUHRTzsWPUT+epJqdf1wm8N5YkQ=="],
|
||||
"@react-navigation/native": ["@react-navigation/native@7.3.10", "", { "dependencies": { "@react-navigation/core": "^7.21.7", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", "standard-navigation": "^0.0.8", "use-latest-callback": "^0.2.4" }, "peerDependencies": { "react": ">= 18.2.0", "react-native": "*" } }, "sha512-8MLJc6T72nbiJYg0bVictXlPSJAVJVPLowncxMmixyU3pAsxKGnAoLH9FhN91l1DwGfc5mxJzVEQZ/EmNILrRw=="],
|
||||
|
||||
"@react-navigation/routers": ["@react-navigation/routers@7.6.0", "", { "dependencies": { "nanoid": "^3.3.11" } }, "sha512-lblhDXfS75jLc7G2K7BZGM+7cjqQXk13X/MA4fq/12r62zM+fBhhreLzYflSitrDDXFRJpSvJXy0ziiGU04Xow=="],
|
||||
"@react-navigation/routers": ["@react-navigation/routers@7.6.2", "", { "dependencies": { "nanoid": "^3.3.11" } }, "sha512-cYzWE/+kcX6RAaX1/peL07f4aIpxeE7uNDr89qJpfGuVz3WHs9dGE1QwbCyCK95fVYn1tvsOmbXbvR0o43uqKQ=="],
|
||||
|
||||
"@shopify/flash-list": ["@shopify/flash-list@2.0.3", "", { "dependencies": { "tslib": "2.8.1" }, "peerDependencies": { "@babel/runtime": "*", "react": "*", "react-native": "*" } }, "sha512-jUlHuZFoPdqRCDvOqsb2YkTttRPyV8Tb/EjCx3gE2wjr4UTM+fE0Ltv9bwBg0K7yo/SxRNXaW7xu5utusRb0xA=="],
|
||||
|
||||
@@ -597,23 +597,23 @@
|
||||
|
||||
"@sideway/pinpoint": ["@sideway/pinpoint@2.0.0", "", {}, "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="],
|
||||
|
||||
"@sinclair/typebox": ["@sinclair/typebox@0.27.10", "", {}, "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA=="],
|
||||
"@sinclair/typebox": ["@sinclair/typebox@0.27.12", "", {}, "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g=="],
|
||||
|
||||
"@tanstack/devtools-event-client": ["@tanstack/devtools-event-client@0.4.3", "", { "bin": { "intent": "bin/intent.js" } }, "sha512-OZI6QyULw0FI0wjgmeYzCIfbgPsOEzwJtCpa69XrfLMtNXLGnz3d/dIabk7frg0TmHo+Ah49w5I4KC7Tufwsvw=="],
|
||||
"@tanstack/devtools-event-client": ["@tanstack/devtools-event-client@0.4.4", "", { "bin": { "intent": "./bin/intent.js" } }, "sha512-6T5Yop/793YI+H+5J8Hsyj4kCih9sl4t3ElLgKioW5hk3ocn+ZdSJ94tT7vL7uabxSugWYBZlOTMPzEw2puvQw=="],
|
||||
|
||||
"@tanstack/pacer": ["@tanstack/pacer@0.18.0", "", { "dependencies": { "@tanstack/devtools-event-client": "^0.4.0", "@tanstack/store": "^0.8.0" } }, "sha512-qhCRSFei0hokQr3xYcQXqxsRD/LKlgHCxHXtKHrQoImp4x2Zu6tUOpUGVH4y2qexIrzSu3aibQBNNfC3Eay6Mg=="],
|
||||
|
||||
"@tanstack/query-core": ["@tanstack/query-core@5.101.0", "", {}, "sha512-cQetA74EB+seWySv1TTKr828TnP0u39m6LykwDXIo84SNortpDkp30TMEjkqtYCNP9c40uT/iwl6MLiufEt0Ow=="],
|
||||
"@tanstack/query-core": ["@tanstack/query-core@5.101.2", "", {}, "sha512-hH5MLoJhF7KaIGd7q3xTXGXvslI+GYlM1Z/35aSHHWaCJWB7XvTSHYuV3eM7tw+aE0mT/xMro4M4Q9rCGHT0lw=="],
|
||||
|
||||
"@tanstack/query-persist-client-core": ["@tanstack/query-persist-client-core@5.101.0", "", { "dependencies": { "@tanstack/query-core": "5.101.0" } }, "sha512-LH99WepGVLwlLfuOcQcPK7f3Xg/Gf+xlMMIj9xWu/8oQ3egnDzjr+a4HvEmi6PGob5SmGXvmDKZaH5+In9dzjw=="],
|
||||
"@tanstack/query-persist-client-core": ["@tanstack/query-persist-client-core@5.101.2", "", { "dependencies": { "@tanstack/query-core": "5.101.2" } }, "sha512-rgMsbvBVpSPDUsprC9FYxojdG0Q1LH6yq1i3DXz2aps4VEqv2l4Msj3YDqIifU3xkl/DrYe9YWntZAJLrM6xTg=="],
|
||||
|
||||
"@tanstack/query-sync-storage-persister": ["@tanstack/query-sync-storage-persister@5.101.0", "", { "dependencies": { "@tanstack/query-core": "5.101.0", "@tanstack/query-persist-client-core": "5.101.0" } }, "sha512-UAGbsIJe9vkV/rbFxUBOPH27Eu6K17KuVLfK1mSy8qoSUJ4qt6JKGMxA8NMUoowbPG0ZnTfRt1Y5SFsqfqlfcA=="],
|
||||
"@tanstack/query-sync-storage-persister": ["@tanstack/query-sync-storage-persister@5.101.2", "", { "dependencies": { "@tanstack/query-core": "5.101.2", "@tanstack/query-persist-client-core": "5.101.2" } }, "sha512-hRyLEJvkUWtfCUA3Lf5vD1CrXbHHK4pZNM/iNd7JM5GgC4CWzGIHkVkeg8zC2LV11KceKObKgjNuMSg3b6NOjA=="],
|
||||
|
||||
"@tanstack/react-pacer": ["@tanstack/react-pacer@0.19.4", "", { "dependencies": { "@tanstack/pacer": "0.18.0", "@tanstack/react-store": "^0.8.0" }, "peerDependencies": { "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-coj8ULAuR0qFpjAKD44gTgRuZyjxU6Xu+IX5MwwYvr4e61OtZcJshaExoOBKpCGde0Edb12jDnzzj2Im13Qm9Q=="],
|
||||
|
||||
"@tanstack/react-query": ["@tanstack/react-query@5.100.14", "", { "dependencies": { "@tanstack/query-core": "5.100.14" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-oOr6aRdSFEwWhzxEkD/9ZcItM3+LjBSkeVmadWKwUssAHTsqd/7bOjWrX4AbvEkoEhgAxzN0Xk6H/aYzXiYBAw=="],
|
||||
|
||||
"@tanstack/react-query-persist-client": ["@tanstack/react-query-persist-client@5.101.0", "", { "dependencies": { "@tanstack/query-persist-client-core": "5.101.0" }, "peerDependencies": { "@tanstack/react-query": "^5.101.0", "react": "^18 || ^19" } }, "sha512-AUcdBgz8V6sM9axzdqkVmWjYSOETkhr6yAZSBnEFyZT2jo6vkFq3UrpRuxGs6fmhKMWv8FA+ZJGcbaKPaoAElQ=="],
|
||||
"@tanstack/react-query-persist-client": ["@tanstack/react-query-persist-client@5.101.2", "", { "dependencies": { "@tanstack/query-persist-client-core": "5.101.2" }, "peerDependencies": { "@tanstack/react-query": "^5.101.2", "react": "^18 || ^19" } }, "sha512-19UpaRtf0lvB2QAJ2MoixxtGf3osMOd508g99EsttUj4+3eLs+ulnNgYjB7AkQMHrRlcbVXqpVNqWkB4a7g8Zw=="],
|
||||
|
||||
"@tanstack/react-store": ["@tanstack/react-store@0.8.1", "", { "dependencies": { "@tanstack/store": "0.8.1", "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-XItJt+rG8c5Wn/2L/bnxys85rBpm0BfMbhb4zmPVLXAKY9POrp1xd6IbU4PKoOI+jSEGc3vntPRfLGSgXfE2Ig=="],
|
||||
|
||||
@@ -657,7 +657,7 @@
|
||||
|
||||
"@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="],
|
||||
|
||||
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.1", "", {}, "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ=="],
|
||||
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.3", "", {}, "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg=="],
|
||||
|
||||
"@vibrant/color": ["@vibrant/color@4.0.4", "", {}, "sha512-Fq2tAszz4QOPWfHZ+KuEAchXUD8i594BM2fOJt8dI/fvYbiVoBycBF/BlNH6F4IWBubxXoPqD4JmmAHvFYbNew=="],
|
||||
|
||||
@@ -695,6 +695,8 @@
|
||||
|
||||
"agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
|
||||
|
||||
"agent-cli-detector": ["agent-cli-detector@0.1.2", "", { "bin": { "agent-cli-detector": "dist/cli.js" } }, "sha512-qdZ/9JFORtTKJNhT/IczMeEfEUbUU0K5umYeiIQHX+AjHs+Y9SXVzSgaYlpZeyNMrvuh2HpZiOTpvS57iPfBkQ=="],
|
||||
|
||||
"anser": ["anser@1.4.10", "", {}, "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww=="],
|
||||
|
||||
"ansi-escapes": ["ansi-escapes@7.3.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="],
|
||||
@@ -711,7 +713,7 @@
|
||||
|
||||
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
|
||||
|
||||
"anynum": ["anynum@1.0.0", "", {}, "sha512-xjR9/zBVnUOP6ztMIIgShjsxui80nQUQH+5xJnvrYLs+90bF25/KJqaAi8mk+B4RDtX1Nspi6fmp4YTEts8SfA=="],
|
||||
"anynum": ["anynum@1.0.1", "", {}, "sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A=="],
|
||||
|
||||
"appdirsjs": ["appdirsjs@1.2.7", "", {}, "sha512-Quji6+8kLBC3NnBeo14nPDq0+2jUs5s3/xEye+udFHumHhRk4M7aAMXp/PBJqkKYGuuyR9M/6Dq7d2AViiGmhw=="],
|
||||
|
||||
@@ -731,7 +733,7 @@
|
||||
|
||||
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
|
||||
|
||||
"axios": ["axios@1.18.0", "", { "dependencies": { "follow-redirects": "^1.16.0", "form-data": "^4.0.5", "https-proxy-agent": "^5.0.1", "proxy-from-env": "^2.1.0" } }, "sha512-E32NzpYKp++W7XRe52rHiXV2ehxmh3wbdgO7MHeFM+vqxLBYHzt0ElkiImtOBxtOmyp0yoC8C6uESVV84Y2/hw=="],
|
||||
"axios": ["axios@1.18.1", "", { "dependencies": { "follow-redirects": "^1.16.0", "form-data": "^4.0.5", "https-proxy-agent": "^5.0.1", "proxy-from-env": "^2.1.0" } }, "sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g=="],
|
||||
|
||||
"babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.17", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-define-polyfill-provider": "^0.6.8", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w=="],
|
||||
|
||||
@@ -747,17 +749,17 @@
|
||||
|
||||
"babel-plugin-transform-flow-enums": ["babel-plugin-transform-flow-enums@0.0.2", "", { "dependencies": { "@babel/plugin-syntax-flow": "^7.12.1" } }, "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ=="],
|
||||
|
||||
"babel-preset-expo": ["babel-preset-expo@56.0.15", "", { "dependencies": { "@babel/generator": "^7.20.5", "@babel/helper-module-imports": "^7.25.9", "@babel/plugin-proposal-decorators": "^7.12.9", "@babel/plugin-proposal-export-default-from": "^7.24.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-default-from": "^7.24.7", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-transform-async-generator-functions": "^7.25.4", "@babel/plugin-transform-async-to-generator": "^7.24.7", "@babel/plugin-transform-block-scoping": "^7.25.0", "@babel/plugin-transform-class-properties": "^7.25.4", "@babel/plugin-transform-class-static-block": "^7.27.1", "@babel/plugin-transform-classes": "^7.25.4", "@babel/plugin-transform-destructuring": "^7.24.8", "@babel/plugin-transform-export-namespace-from": "^7.25.9", "@babel/plugin-transform-flow-strip-types": "^7.25.2", "@babel/plugin-transform-for-of": "^7.24.7", "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", "@babel/plugin-transform-modules-commonjs": "^7.24.8", "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", "@babel/plugin-transform-object-rest-spread": "^7.24.7", "@babel/plugin-transform-optional-catch-binding": "^7.24.7", "@babel/plugin-transform-optional-chaining": "^7.24.8", "@babel/plugin-transform-parameters": "^7.24.7", "@babel/plugin-transform-private-methods": "^7.24.7", "@babel/plugin-transform-private-property-in-object": "^7.24.7", "@babel/plugin-transform-react-display-name": "^7.24.7", "@babel/plugin-transform-react-jsx": "^7.28.6", "@babel/plugin-transform-react-jsx-development": "^7.27.1", "@babel/plugin-transform-react-pure-annotations": "^7.27.1", "@babel/plugin-transform-runtime": "^7.24.7", "@babel/plugin-transform-typescript": "^7.25.2", "@babel/plugin-transform-unicode-regex": "^7.24.7", "@babel/preset-typescript": "^7.23.0", "@react-native/babel-plugin-codegen": "0.85.3", "babel-plugin-react-compiler": "^1.0.0", "babel-plugin-react-native-web": "~0.21.0", "babel-plugin-syntax-hermes-parser": "^0.33.3", "babel-plugin-transform-flow-enums": "^0.0.2", "debug": "^4.3.4" }, "peerDependencies": { "@babel/runtime": "^7.20.0", "expo": "*", "expo-widgets": "^56.0.18", "react-refresh": ">=0.14.0 <1.0.0" }, "optionalPeers": ["@babel/runtime", "expo", "expo-widgets"] }, "sha512-0MqbQoM6nBUbKvgu2xJ4VixZnUTGTq3HB2WwvOikdO4CiPxbQ+wGA25fOoHHSni5iEFW39wy6y1ookTWlq3wVw=="],
|
||||
"babel-preset-expo": ["babel-preset-expo@56.0.17", "", { "dependencies": { "@babel/generator": "^7.20.5", "@babel/helper-module-imports": "^7.25.9", "@babel/plugin-proposal-decorators": "^7.12.9", "@babel/plugin-proposal-export-default-from": "^7.24.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-default-from": "^7.24.7", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-transform-async-generator-functions": "^7.25.4", "@babel/plugin-transform-async-to-generator": "^7.24.7", "@babel/plugin-transform-block-scoping": "^7.25.0", "@babel/plugin-transform-class-properties": "^7.25.4", "@babel/plugin-transform-class-static-block": "^7.27.1", "@babel/plugin-transform-classes": "^7.25.4", "@babel/plugin-transform-destructuring": "^7.24.8", "@babel/plugin-transform-export-namespace-from": "^7.25.9", "@babel/plugin-transform-flow-strip-types": "^7.25.2", "@babel/plugin-transform-for-of": "^7.24.7", "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", "@babel/plugin-transform-modules-commonjs": "^7.24.8", "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", "@babel/plugin-transform-object-rest-spread": "^7.24.7", "@babel/plugin-transform-optional-catch-binding": "^7.24.7", "@babel/plugin-transform-optional-chaining": "^7.24.8", "@babel/plugin-transform-parameters": "^7.24.7", "@babel/plugin-transform-private-methods": "^7.24.7", "@babel/plugin-transform-private-property-in-object": "^7.24.7", "@babel/plugin-transform-react-display-name": "^7.24.7", "@babel/plugin-transform-react-jsx": "^7.28.6", "@babel/plugin-transform-react-jsx-development": "^7.27.1", "@babel/plugin-transform-react-pure-annotations": "^7.27.1", "@babel/plugin-transform-runtime": "^7.24.7", "@babel/plugin-transform-typescript": "^7.25.2", "@babel/plugin-transform-unicode-regex": "^7.24.7", "@babel/preset-typescript": "^7.23.0", "@react-native/babel-plugin-codegen": "0.85.3", "babel-plugin-react-compiler": "^1.0.0", "babel-plugin-react-native-web": "~0.21.0", "babel-plugin-syntax-hermes-parser": "^0.33.3", "babel-plugin-transform-flow-enums": "^0.0.2", "debug": "^4.3.4" }, "peerDependencies": { "@babel/runtime": "^7.20.0", "expo": "*", "expo-widgets": "^56.0.22", "react-refresh": ">=0.14.0 <1.0.0" }, "optionalPeers": ["@babel/runtime", "expo", "expo-widgets"] }, "sha512-yanAlbzaMMNqnju/uMnZsf3ltgssG71UubkfD+2iMaoXGNIj+TODEs9hF12jrTX2lzq/zH0HWSuRLZLNalf8fw=="],
|
||||
|
||||
"badgin": ["badgin@1.2.3", "", {}, "sha512-NQGA7LcfCpSzIbGRbkgjgdWkjy7HI+Th5VLxTJfW5EeaAf3fnS+xWQaQOCYiny+q6QSvxqoSO04vCx+4u++EJw=="],
|
||||
|
||||
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||
|
||||
"barcode-detector": ["barcode-detector@3.2.0", "", { "dependencies": { "zxing-wasm": "3.1.0" } }, "sha512-MrT5TT058ptG5YB157pHLfXKVpp0BKEfQBOb8QvzTbatzmLDu85JJ0Gd/sCYwbwdwStJvxsYflrSN6D6E4Ndyw=="],
|
||||
"barcode-detector": ["barcode-detector@3.2.1", "", { "dependencies": { "zxing-wasm": "3.1.1" } }, "sha512-zLL7AbT9uNJBUzYpKg9v5tUA4yQGReExSi60q0g660Mj0wjUhKmN0GrUF3qELo8ITW9THzyJXdZQkXLMnsieiw=="],
|
||||
|
||||
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
||||
|
||||
"baseline-browser-mapping": ["baseline-browser-mapping@2.10.37", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-girxaJ7WZssDOFhzCGZTDKoTa1gk6A1TbflaYTpykLJ4UU9Fz9kx1aREM8JCuoVHbL8X8T/mJg7w2oYSq72Oig=="],
|
||||
"baseline-browser-mapping": ["baseline-browser-mapping@2.10.43", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ=="],
|
||||
|
||||
"big-integer": ["big-integer@1.6.52", "", {}, "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg=="],
|
||||
|
||||
@@ -775,11 +777,11 @@
|
||||
|
||||
"bplist-parser": ["bplist-parser@0.3.2", "", { "dependencies": { "big-integer": "1.6.x" } }, "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ=="],
|
||||
|
||||
"brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="],
|
||||
"brace-expansion": ["brace-expansion@5.0.7", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA=="],
|
||||
|
||||
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
||||
|
||||
"browserslist": ["browserslist@4.28.2", "", { "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", "electron-to-chromium": "^1.5.328", "node-releases": "^2.0.36", "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg=="],
|
||||
"browserslist": ["browserslist@4.28.6", "", { "dependencies": { "baseline-browser-mapping": "^2.10.42", "caniuse-lite": "^1.0.30001803", "electron-to-chromium": "^1.5.389", "node-releases": "^2.0.51", "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw=="],
|
||||
|
||||
"bser": ["bser@2.1.1", "", { "dependencies": { "node-int64": "^0.4.0" } }, "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ=="],
|
||||
|
||||
@@ -803,7 +805,7 @@
|
||||
|
||||
"camelize": ["camelize@1.0.1", "", {}, "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ=="],
|
||||
|
||||
"caniuse-lite": ["caniuse-lite@1.0.30001799", "", {}, "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw=="],
|
||||
"caniuse-lite": ["caniuse-lite@1.0.30001806", "", {}, "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw=="],
|
||||
|
||||
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
@@ -885,7 +887,7 @@
|
||||
|
||||
"dayjs": ["dayjs@1.11.21", "", {}, "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA=="],
|
||||
|
||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
|
||||
"decamelize": ["decamelize@1.2.0", "", {}, "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="],
|
||||
|
||||
@@ -933,7 +935,7 @@
|
||||
|
||||
"ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
|
||||
|
||||
"electron-to-chromium": ["electron-to-chromium@1.5.374", "", {}, "sha512-HCF5i7izveksHSGqa7mhDh6tr3Uz9Dar2RAjwuh69bw3QGPVObjQIgLwQWeO/Rxp9/r0KdboKy9RbpQDl97fjg=="],
|
||||
"electron-to-chromium": ["electron-to-chromium@1.5.393", "", {}, "sha512-kiDJdIUawuEIcp9XoICKp1iTYDEbgguIPq526N1Q7jIQDeQ3CqoMx71025PI/7E48Ddtw2HuWsVjY7afEgNxmg=="],
|
||||
|
||||
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||
|
||||
@@ -983,33 +985,33 @@
|
||||
|
||||
"expect": ["expect@29.7.0", "", { "dependencies": { "@jest/expect-utils": "^29.7.0", "jest-get-type": "^29.6.3", "jest-matcher-utils": "^29.7.0", "jest-message-util": "^29.7.0", "jest-util": "^29.7.0" } }, "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw=="],
|
||||
|
||||
"expo": ["expo@56.0.12", "", { "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "^56.1.16", "@expo/config": "~56.0.9", "@expo/config-plugins": "~56.0.9", "@expo/devtools": "~56.0.2", "@expo/dom-webview": "~56.0.5", "@expo/fingerprint": "^0.19.4", "@expo/local-build-cache-provider": "^56.0.8", "@expo/log-box": "^56.0.13", "@expo/metro": "~56.0.0", "@expo/metro-config": "~56.0.14", "@ungap/structured-clone": "^1.3.0", "babel-preset-expo": "~56.0.15", "expo-asset": "~56.0.17", "expo-constants": "~56.0.18", "expo-file-system": "~56.0.8", "expo-font": "~56.0.7", "expo-keep-awake": "~56.0.3", "expo-modules-autolinking": "~56.0.16", "expo-modules-core": "~56.0.17", "pretty-format": "^29.7.0", "react-refresh": "^0.14.2", "whatwg-url-minimum": "^0.1.2" }, "peerDependencies": { "@expo/metro-runtime": "*", "react": "*", "react-dom": "*", "react-native": "*", "react-native-web": "*", "react-native-webview": "*" }, "optionalPeers": ["@expo/metro-runtime", "react-dom", "react-native-web", "react-native-webview"], "bin": { "expo": "bin/cli", "fingerprint": "bin/fingerprint", "expo-modules-autolinking": "bin/autolinking" } }, "sha512-FxgdI/Yqva6iJOThZIHfvxlKPxs4EC4uScUnEswwSArR/Fj9k430O13R590LcOQTsdNsjIs+GBHwjfoAY6vmAQ=="],
|
||||
"expo": ["expo@56.0.16", "", { "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "^56.1.20", "@expo/config": "~56.0.12", "@expo/config-plugins": "~56.0.13", "@expo/devtools": "~56.0.2", "@expo/dom-webview": "~56.0.6", "@expo/fingerprint": "^0.19.8", "@expo/local-build-cache-provider": "^56.0.10", "@expo/log-box": "^56.0.14", "@expo/metro": "~56.0.0", "@expo/metro-config": "~56.0.17", "@ungap/structured-clone": "^1.3.0", "babel-preset-expo": "~56.0.17", "expo-asset": "~56.0.20", "expo-constants": "~56.0.21", "expo-file-system": "~56.0.8", "expo-font": "~56.0.7", "expo-keep-awake": "~56.0.3", "expo-modules-autolinking": "~56.0.20", "expo-modules-core": "~56.0.21", "pretty-format": "^29.7.0", "react-refresh": "^0.14.2", "whatwg-url-minimum": "^0.1.2" }, "peerDependencies": { "@expo/metro-runtime": "*", "react": "*", "react-dom": "*", "react-native": "*", "react-native-web": "*", "react-native-webview": "*" }, "optionalPeers": ["@expo/metro-runtime", "react-dom", "react-native-web", "react-native-webview"], "bin": { "expo": "bin/cli", "fingerprint": "bin/fingerprint", "expo-modules-autolinking": "bin/autolinking" } }, "sha512-6G1yfBKG3J16HBgF2ehdd1iZBlRmbDF/lB7SG30v4jojgvN03HZkENHujKfuGuBqDBlzkkXjZvpxRVvIUQTAMQ=="],
|
||||
|
||||
"expo-application": ["expo-application@56.0.3", "", { "peerDependencies": { "expo": "*" } }, "sha512-DdGGPlMuM6cSTeKhbvh6OeLr2O/+EI5BHKYrD+Do8sJPYgLwzGrgESELfyjJCpEhFzT+TgKIdmLmWXhNUQnHiw=="],
|
||||
|
||||
"expo-asset": ["expo-asset@56.0.17", "", { "dependencies": { "@expo/image-utils": "^0.10.1", "expo-constants": "~56.0.18" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-GFN5j+8SPkyv0nfsiFHewmdB/D0tL237TsBE/gSfFOFy/J3a52py7IulcSqkA3sQE/u/UlD5BmvP5ssS4//nUg=="],
|
||||
"expo-asset": ["expo-asset@56.0.20", "", { "dependencies": { "@expo/image-utils": "^0.10.3", "expo-constants": "~56.0.21" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-pjVw3JDiaq6Ee15UbDeZpiGNAHJqfOZwY61VPlFiznuuj7f/b2tvegujeIEu2+p6C2/tioZGGD6zWQuJ9Ob3uQ=="],
|
||||
|
||||
"expo-audio": ["expo-audio@56.0.12", "", { "peerDependencies": { "expo": "*", "expo-asset": "*", "react": "*", "react-native": "*" } }, "sha512-ne2UIO/HsQoBL9e+tGs5N9Sf3NyW5sJMm4sDkexbSJRc2IchLDG+9Msu/+l5N4RlZ8SiF42wRyWsh/Usg+SwOw=="],
|
||||
|
||||
"expo-background-task": ["expo-background-task@56.0.19", "", { "dependencies": { "expo-task-manager": "~56.0.19" }, "peerDependencies": { "expo": "*" } }, "sha512-TuFqorlz4HXtWAwQGcg+/URXpBwjwNsAxdis/6m5mhtgBIVbX2gYYv/s6eIf8lh2cAI1zFkb+/bHHuC2aOAGGA=="],
|
||||
"expo-background-task": ["expo-background-task@56.0.22", "", { "dependencies": { "expo-task-manager": "~56.0.22" }, "peerDependencies": { "expo": "*" } }, "sha512-kXl9sn5ZJS4zeRKvpGbxBBTVCezUQFZZdUTbXcnIb+4jUl3jRwuygelyExqQi0f84M5dTLoHnaTxgz9d5y+NXg=="],
|
||||
|
||||
"expo-blur": ["expo-blur@56.0.3", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-KDDtrpWc2tYlm1WCPaOgBtv+YEGqe5ELheFPIgSNgHt28NQUDcfBcFsA9Us2StDh6osmSD6NbKxOt5bU6PcDbQ=="],
|
||||
"expo-blur": ["expo-blur@56.0.4", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-/rNpe2NDTmMbSktVJb5z7HoX6apYtq8KVKJNjWOQV7NG01+LvctWzFeMNxWSZVWfIKTndqdqABwqcpYmiCRxxg=="],
|
||||
|
||||
"expo-brightness": ["expo-brightness@56.0.5", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-AkCGW+Lj8I4o2+Yjs1bzjIJz44cgNXfAN+pf01uDwmA1/1JTIy8x1eISvmz6d2r/1OhdyBZxeDkACNLVMDx5zA=="],
|
||||
|
||||
"expo-build-properties": ["expo-build-properties@56.0.19", "", { "dependencies": { "@expo/schema-utils": "^56.0.0", "resolve-from": "^5.0.0", "semver": "^7.6.0" }, "peerDependencies": { "expo": "*" } }, "sha512-InoviXcxWosNp4cC7L3SWoiY99Xr2HdgN+LYHb6mUm/BBVxy1mIMrZR+3PJ2gwDZzW6EJNDz8ioASWGHBTmzpA=="],
|
||||
"expo-build-properties": ["expo-build-properties@56.0.23", "", { "dependencies": { "@expo/schema-utils": "^56.0.2", "resolve-from": "^5.0.0", "semver": "^7.6.0" }, "peerDependencies": { "expo": "*" } }, "sha512-xb9QX+x/AsDw8wVdox3jNpf8eVUc8PYq3lycF2OOlmHkmn+ecmxmtdCpB3ZDLjtdem8XrgycgLIba7WTdc7o7w=="],
|
||||
|
||||
"expo-camera": ["expo-camera@56.0.8", "", { "dependencies": { "barcode-detector": "^3.0.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*", "react-native-web": "*" }, "optionalPeers": ["react-native-web"] }, "sha512-UDOpUUMisFRmCv1XQV1MJCKGAH2CsIC1Rs6P9Bbc6JLVmbxEKAd5dK68y6cScOdWURxVfJ0PRcjYnSuc8ayyIQ=="],
|
||||
|
||||
"expo-constants": ["expo-constants@56.0.18", "", { "dependencies": { "@expo/env": "~2.3.0" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-8AMtbDGl/WVPnWlmbpGmvcdnNCy9E4PFnwdVwj600vljkMDPSxcAcjw8GVXEPk3PpZ+ngTqsrkltWyj0UKYAxw=="],
|
||||
"expo-constants": ["expo-constants@56.0.21", "", { "dependencies": { "@expo/env": "~2.3.1" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-q9LkK9tNTW2z/5hXgpwWoCXO1fBrqn4FgwTiLerM9WOu1wtg99NevAtG3BEG8t5Awtub+NsLidiFZzBat45RKw=="],
|
||||
|
||||
"expo-crypto": ["expo-crypto@56.0.4", "", { "peerDependencies": { "expo": "*" } }, "sha512-fRNEhoXRXgAWBpe3/hq5X+KXTit3OZqdiAGts1YvNEUHQb+H5591mpPac0Yw+sZg9pXcrjRnzo5AxvZaENpc7g=="],
|
||||
|
||||
"expo-dev-client": ["expo-dev-client@56.0.20", "", { "dependencies": { "expo-dev-launcher": "~56.0.20", "expo-dev-menu": "~56.0.17", "expo-dev-menu-interface": "~56.0.0", "expo-manifests": "~56.0.4", "expo-updates-interface": "~56.0.1" }, "peerDependencies": { "expo": "*" } }, "sha512-KebW4r8HhIiRrPzs6ZqVhp/so8buyglAO1h4No0Ibr5C2XRnlIoGWCN4zC6rW7IsI3iKUXcofLAQV9OjoxjiwQ=="],
|
||||
"expo-dev-client": ["expo-dev-client@56.0.23", "", { "dependencies": { "expo-dev-launcher": "~56.0.24", "expo-dev-menu": "~56.0.20", "expo-dev-menu-interface": "~56.0.0", "expo-manifests": "~56.0.4", "expo-updates-interface": "~56.0.1" }, "peerDependencies": { "expo": "*" } }, "sha512-3yQc4McvFTxqFpQe0wZ/Ek9bLXIy/ilnHBPy1UqUjzFfarJNd5FUoWp+1ovE8Gt59OPiIsKl+VzPq330hwQxkg=="],
|
||||
|
||||
"expo-dev-launcher": ["expo-dev-launcher@56.0.20", "", { "dependencies": { "@expo/schema-utils": "^56.0.0", "expo-dev-menu": "~56.0.17", "expo-manifests": "~56.0.4" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-cTuC3GkPl9CTwO3CKnVmEm9qoQ0WairhwvTh6qMlg+zr/QU/tdiU++uDBX67hf9+FuxQOkWGp5khFNosT+0cIg=="],
|
||||
"expo-dev-launcher": ["expo-dev-launcher@56.0.24", "", { "dependencies": { "@expo/schema-utils": "^56.0.2", "expo-dev-menu": "~56.0.20", "expo-manifests": "~56.0.4" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-uzYYpWY2rdLUS+ct9Loku4LGdMp7XwBHPAhuHu/R0SMHl4IxFx8VLFAbOaO34NrDWqB6fqdze1qHoA6DxeuZIA=="],
|
||||
|
||||
"expo-dev-menu": ["expo-dev-menu@56.0.17", "", { "dependencies": { "expo-dev-menu-interface": "~56.0.0" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-OofRkOOZnaDriSav3JDN4NP2lsLt2eOa/Ryptr5nMD62SwnFyK4R6n6PkPVaDU3LSsZqndAJHmN6inS+oziayQ=="],
|
||||
"expo-dev-menu": ["expo-dev-menu@56.0.20", "", { "dependencies": { "expo-dev-menu-interface": "~56.0.0" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-PJH+RtOWDV7E5oic7cLKN7+AO/oE3QPnHzooxwzGrcjiySCQOvkFC67SNfBCxXXaMFMRf2MwihqY4PllAVAUyw=="],
|
||||
|
||||
"expo-dev-menu-interface": ["expo-dev-menu-interface@56.0.1", "", { "peerDependencies": { "expo": "*" } }, "sha512-odATx0ZL/Kis10sKSBiKiGQxAB6coSi/KQtKcMhnQVNno6FkRh5/4e5BqcEvpq2rNMTiQp4ytNAQHtdwbPXvGA=="],
|
||||
|
||||
@@ -1033,23 +1035,23 @@
|
||||
|
||||
"expo-linear-gradient": ["expo-linear-gradient@56.0.4", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-KUp1dNSRtuMyiExhf6FJf5YUtmw2cRaPytl10HQi7isj5Yac38udmD55T2tglNYTZlvgT5+oflpyFoH15hmOcw=="],
|
||||
|
||||
"expo-linking": ["expo-linking@56.0.14", "", { "dependencies": { "expo-constants": "~56.0.18", "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-IvVQHWC+Cj4fK5qD3iEVYqpU2a4rLW0IpAAlGJ4MH+H1fyZiHh3eN6qg2WmoclOEPfYATSuEa+dQT6wfgVpXlQ=="],
|
||||
"expo-linking": ["expo-linking@56.0.15", "", { "dependencies": { "expo-constants": "~56.0.20", "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-V3tkCxHIWO624ayw2L5Nfi0/bPgYy/0MgmoQR7g3FAKF4nyAayK8IhgAInz4MZ5Ao5Bb+5uZWDdUaS4yyEb+Gw=="],
|
||||
|
||||
"expo-localization": ["expo-localization@56.0.6", "", { "dependencies": { "rtl-detect": "^1.0.2" }, "peerDependencies": { "expo": "*", "react": "*" } }, "sha512-zzBVoUFHCVNBywcxGsspoZeIXebihOo/AnmQYE4jMv8gHCSKlLNFT+ft+0+mWcZCMs9necvUs8S8TDonAu/xBA=="],
|
||||
|
||||
"expo-location": ["expo-location@56.0.18", "", { "dependencies": { "@expo/image-utils": "^0.10.1" }, "peerDependencies": { "expo": "*" } }, "sha512-6xP0UwGy8a7EEHAMeigYAp3HNo3yWHAg05tVPUfwrOWepWPpFXmjsfUBUxQdkpfpjddJ9r+f4PplxZqKI0LtjA=="],
|
||||
"expo-location": ["expo-location@56.0.21", "", { "dependencies": { "@expo/image-utils": "^0.10.3" }, "peerDependencies": { "expo": "*" } }, "sha512-HTwhlF9eWwRI/LSI0JW08Y96aYfcGpScbEn7xIH4PgxUC80kHOHI5CP0v/GlkIzT2Qhfr6cP9Jw9wnPdBfV//g=="],
|
||||
|
||||
"expo-manifests": ["expo-manifests@56.0.4", "", { "dependencies": { "expo-json-utils": "~56.0.0" }, "peerDependencies": { "expo": "*" } }, "sha512-Fokawl2UkiExIF0bqGoblRFA8lYpROVD+EpvDwSW4LgqQyPwNua1gLSgHZjdl5GsVugfRMMWE3LHaibDyX93hw=="],
|
||||
|
||||
"expo-modules-autolinking": ["expo-modules-autolinking@56.0.16", "", { "dependencies": { "@expo/require-utils": "^56.1.3", "@expo/spawn-async": "^1.8.0", "chalk": "^4.1.0", "commander": "^7.2.0" }, "bin": { "expo-modules-autolinking": "bin/expo-modules-autolinking.js" } }, "sha512-9JnL4N46P8ubDpDIfWolDn7nxU2j1rY67xY/dNVuyH0m+HG+r/JI16VYtjIf4COpZtEuFo4D3h3MBeFzGucMnw=="],
|
||||
"expo-modules-autolinking": ["expo-modules-autolinking@56.0.20", "", { "dependencies": { "@expo/require-utils": "^56.1.5", "@expo/spawn-async": "^1.8.0", "chalk": "^4.1.0", "commander": "^7.2.0" }, "bin": { "expo-modules-autolinking": "bin/expo-modules-autolinking.js" } }, "sha512-bIUaHtWlqQpculjhN1wERVBoVeRCefkW3zXY/SqiXSm/6uofZy3NRF1t5Co44lmBQczAs/lFR7BwA8lmUiGMnw=="],
|
||||
|
||||
"expo-modules-core": ["expo-modules-core@56.0.17", "", { "dependencies": { "@expo/expo-modules-macros-plugin": "0.2.2", "expo-modules-jsi": "~56.0.10", "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*", "react-native-worklets": "^0.7.4 || ^0.8.0" }, "optionalPeers": ["react-native-worklets"] }, "sha512-5J8whnT7Ccp+BrFClLmpF76omBqn95VZExroTm01Dgjm4vpty1Rb7U3we+ZUceNHtRd07Lw30u7FNfDgIhEbRQ=="],
|
||||
"expo-modules-core": ["expo-modules-core@56.0.21", "", { "dependencies": { "@expo/expo-modules-macros-plugin": "0.2.2", "expo-modules-jsi": "~56.0.12", "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*", "react-native-worklets": "^0.7.4 || ^0.8.0" }, "optionalPeers": ["react-native-worklets"] }, "sha512-lT413DZFuX/cSsOqGtZnqtyCGlY3F3FFDiVhwzB8wX4Ei9HZYPXhV59Mm8SNJquo8+JfLRi3arv3z5U4MqJRcA=="],
|
||||
|
||||
"expo-modules-jsi": ["expo-modules-jsi@56.0.10", "", { "peerDependencies": { "react-native": "*" } }, "sha512-fHZcFpYO/o62GYa6fJyAQJZcAShzhoN0iMMDzbr7vD3ewET6e1vAlTonbEakN9F0VHEgBFJ4NREy87uwVcpCuA=="],
|
||||
"expo-modules-jsi": ["expo-modules-jsi@56.0.12", "", { "peerDependencies": { "react-native": "*" } }, "sha512-OnXiNbXzYybZPh5QnJyIIwQjQfN7PP4Di/2Hz0xQHKLgQmCfn/zAQziOjbUXVeL3cAyZ8+uDnTDYmDAc3B2qhQ=="],
|
||||
|
||||
"expo-notifications": ["expo-notifications@56.0.18", "", { "dependencies": { "@expo/image-utils": "^0.10.1", "abort-controller": "^3.0.0", "badgin": "^1.1.5", "expo-application": "~56.0.3", "expo-constants": "~56.0.18" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-HHnrwyCLC5srFojcHYS2KskbNroy9o2fwPKdyhjrdjjrBu4sNRKm4LepcuZjDy98cZKEm89WIPW8O45vut8Rgw=="],
|
||||
"expo-notifications": ["expo-notifications@56.0.21", "", { "dependencies": { "@expo/image-utils": "^0.10.3", "abort-controller": "^3.0.0", "badgin": "^1.1.5", "expo-application": "~56.0.3", "expo-constants": "~56.0.21" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-j1rczqoAj0oBZYzcckMyILlJSLQdqOJuh7YzAckzTHkMuIPa7H0SF6IwcFIig1Tdqjku3aONqct6bbscY+qznw=="],
|
||||
|
||||
"expo-router": ["expo-router@56.2.11", "", { "dependencies": { "@expo/log-box": "^56.0.13", "@expo/metro-runtime": "^56.0.15", "@expo/schema-utils": "^56.0.0", "@expo/ui": "^56.0.18", "@radix-ui/react-slot": "^1.2.0", "@radix-ui/react-tabs": "^1.1.12", "@react-native-masked-view/masked-view": "^0.3.2", "@testing-library/jest-dom": "^6.9.1", "@testing-library/user-event": "^14.6.1", "client-only": "^0.0.1", "color": "^4.2.3", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "expo-glass-effect": "^56.0.4", "expo-server": "^56.0.5", "expo-symbols": "^56.0.6", "fast-deep-equal": "^3.1.3", "invariant": "^2.2.4", "nanoid": "^3.3.8", "query-string": "^7.1.3", "react-fast-compare": "^3.2.2", "react-is": "^19.1.0", "react-native-drawer-layout": "^4.2.2", "react-native-screens": "^4.25.2", "server-only": "^0.0.1", "sf-symbols-typescript": "^2.1.0", "shallowequal": "^1.1.0", "standard-navigation": "^0.0.5", "vaul": "^1.1.2" }, "peerDependencies": { "@testing-library/react-native": ">= 13.2.0", "expo": "*", "expo-constants": "^56.0.18", "expo-linking": "^56.0.14", "react": "*", "react-dom": "*", "react-native": "*", "react-native-gesture-handler": "*", "react-native-reanimated": "*", "react-native-safe-area-context": ">= 5.4.0", "react-native-web": "*", "react-server-dom-webpack": "~19.0.4 || ~19.1.5 || ~19.2.4" }, "optionalPeers": ["@testing-library/react-native", "react-dom", "react-native-gesture-handler", "react-native-reanimated", "react-native-web", "react-server-dom-webpack"] }, "sha512-08DBTrKv3QanOc9u1JNxSEChW9c/qNFbQ0dO28OLvufWWfdSRkSdHmh365D2FgoZg1qaOzZPCDuL3tM6nGSfkQ=="],
|
||||
"expo-router": ["expo-router@56.2.15", "", { "dependencies": { "@expo/log-box": "^56.0.14", "@expo/metro-runtime": "^56.0.17", "@expo/schema-utils": "^56.0.2", "@expo/ui": "^56.0.22", "@radix-ui/react-slot": "^1.2.0", "@radix-ui/react-tabs": "^1.1.12", "@react-native-masked-view/masked-view": "^0.3.2", "@testing-library/jest-dom": "^6.9.1", "@testing-library/user-event": "^14.6.1", "client-only": "^0.0.1", "color": "^4.2.3", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "expo-glass-effect": "^56.0.4", "expo-server": "^56.0.5", "expo-symbols": "^56.0.6", "fast-deep-equal": "^3.1.3", "invariant": "^2.2.4", "nanoid": "^3.3.8", "query-string": "^7.1.3", "react-fast-compare": "^3.2.2", "react-is": "^19.1.0", "react-native-drawer-layout": "^4.2.2", "react-native-screens": "^4.25.2", "server-only": "^0.0.1", "sf-symbols-typescript": "^2.1.0", "shallowequal": "^1.1.0", "standard-navigation": "^0.0.5", "vaul": "^1.1.2" }, "peerDependencies": { "@testing-library/react-native": ">= 13.2.0", "expo": "*", "expo-constants": "^56.0.21", "expo-linking": "^56.0.15", "react": "*", "react-dom": "*", "react-native": "*", "react-native-gesture-handler": "*", "react-native-reanimated": "*", "react-native-safe-area-context": ">= 5.4.0", "react-native-web": "*", "react-server-dom-webpack": "~19.0.4 || ~19.1.5 || ~19.2.4" }, "optionalPeers": ["@testing-library/react-native", "react-dom", "react-native-gesture-handler", "react-native-reanimated", "react-native-web", "react-server-dom-webpack"] }, "sha512-VdPIBuJ0D2cv4gCulU5slhDlF9ocDNXsne03qu5AcTYROLIctlYDAzzLax7lSKZLP6GI6+Xw+I2dN7QMjC9UCA=="],
|
||||
|
||||
"expo-screen-orientation": ["expo-screen-orientation@56.0.5", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-Puf4L/cgM8z45Z2fwZzJtlVGSk0ZM/l3gBqXm50bKTACmUk8P8fr7HVbDfs8reyoZuEKKFZJ0VlnKo5i6cSotQ=="],
|
||||
|
||||
@@ -1057,9 +1059,9 @@
|
||||
|
||||
"expo-server": ["expo-server@56.0.5", "", {}, "sha512-SmM2p2g3Jrktpiazcst+OxhjSzOHXKAY4BPURHYHXvApzzoybMmrNF4IEZ8DKZ145BhSe4ydAmlEFCRTsdtgUQ=="],
|
||||
|
||||
"expo-sharing": ["expo-sharing@56.0.18", "", { "dependencies": { "@expo/config-plugins": "^56.0.9", "@expo/config-types": "^56.0.6", "@expo/plist": "^0.7.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-45w4BWNFmdTczp+fJX6YfwJrn9sX+VeRWz2VWLhauygcCrym44HtVDXX5yVYPB9TW9ZesLcEI+CCrCBNWL7smQ=="],
|
||||
"expo-sharing": ["expo-sharing@56.0.22", "", { "dependencies": { "@expo/config-plugins": "^56.0.13", "@expo/config-types": "^56.0.7", "@expo/plist": "^0.7.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-r2lt8sJUbEi6O1DIK192GEk6JayBEQNjfTvJ3iHzW//5dUy20NCaLSKFeE2z+DE+lVzu5izOocWRwIbbubywvw=="],
|
||||
|
||||
"expo-splash-screen": ["expo-splash-screen@56.0.10", "", { "dependencies": { "@expo/config-plugins": "~56.0.8", "@expo/image-utils": "^0.10.1", "xml2js": "0.6.0" }, "peerDependencies": { "expo": "*" } }, "sha512-vDIlo8hzt9HlCZQ0kSY66v83D1WEXOJbVMeyPDfXDu9tbDdPMNUyDpi4WGJXikAjxnAKfbt5Mv5NnEbxINy+VA=="],
|
||||
"expo-splash-screen": ["expo-splash-screen@56.0.13", "", { "dependencies": { "@expo/config-plugins": "~56.0.13", "@expo/image-utils": "^0.10.3", "xml2js": "0.6.0" }, "peerDependencies": { "expo": "*" } }, "sha512-8+ytfHX4/B5sj97N4PIzm4IP/7uDbbYTsY/vOMWa7ASTVkGZB+pXB23dBwBu7TcKx5w9Wt0NkaPAwy6dhNEdag=="],
|
||||
|
||||
"expo-status-bar": ["expo-status-bar@56.0.4", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-IGs/fDfkHXofy2ZQrGiXayhFK04HB85FZXorhcEhDZEcqASKgSqpak+HwUtAaR0MeTJwWyHNF7I6VmVbbp8EcA=="],
|
||||
|
||||
@@ -1067,7 +1069,7 @@
|
||||
|
||||
"expo-system-ui": ["expo-system-ui@56.0.5", "", { "dependencies": { "@react-native/normalize-colors": "0.85.3", "debug": "^4.3.2" }, "peerDependencies": { "expo": "*", "react-native": "*", "react-native-web": "*" }, "optionalPeers": ["react-native-web"] }, "sha512-n1MmnUArV4cc3gVed9fGtluPme00PE9axKVx+NHbKxHFMam5l4GcOI7PxbYKFNx8o7WA1LRD7eLW33agmZrxGg=="],
|
||||
|
||||
"expo-task-manager": ["expo-task-manager@56.0.19", "", { "dependencies": { "unimodules-app-loader": "~56.0.0" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-eDeBR8vXlOAXBck29AzPl+tv4QlJus+cgkQ0TGOBqAlgRPWPWd7ebhqrhb0KRieUZIvzlycfcxjHR/+AiEiMHA=="],
|
||||
"expo-task-manager": ["expo-task-manager@56.0.22", "", { "dependencies": { "unimodules-app-loader": "~56.0.0" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-EtYC7o5phj1nGQbdXwSF1fIm9Ws5oP/+wCMWS/Tl15OS3vrsG1INEyptKCNVoEEuXZ15wdhSlmp7J4Y2P5uO/A=="],
|
||||
|
||||
"expo-updates-interface": ["expo-updates-interface@56.0.2", "", { "peerDependencies": { "expo": "*" } }, "sha512-eWTwSZ9y8vrULG2oBn2TQSSIwBGSq/TxGJ3jY6tuVS2FWH/ASRIiKs3zkUZTRoC3ZuV2alz0mUClYV7nNrFx8g=="],
|
||||
|
||||
@@ -1081,9 +1083,9 @@
|
||||
|
||||
"fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
|
||||
|
||||
"fast-xml-builder": ["fast-xml-builder@1.2.0", "", { "dependencies": { "path-expression-matcher": "^1.5.0", "xml-naming": "^0.1.0" } }, "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q=="],
|
||||
"fast-xml-builder": ["fast-xml-builder@1.3.0", "", { "dependencies": { "path-expression-matcher": "^1.6.2", "xml-naming": "^0.3.0" } }, "sha512-F74cZEdCvuw9P41GAC3rod4X04jjWGM1JPEv/GWSqFTWLsdyMSBMBMlm9Hk3GLBgLBbdBNY8yee0pQh2RBVESQ=="],
|
||||
|
||||
"fast-xml-parser": ["fast-xml-parser@5.9.0", "", { "dependencies": { "@nodable/entities": "^2.2.0", "fast-xml-builder": "^1.2.0", "is-unsafe": "^1.0.1", "path-expression-matcher": "^1.5.0", "strnum": "^2.4.0", "xml-naming": "^0.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-duBuXbyIhEeNO4GjFuVqr0nF047oNwr18aum+zJyqo0MUG/n7Afgs3Qv3D6VN3ONedUKxiuFlPiMGIa0Z11chA=="],
|
||||
"fast-xml-parser": ["fast-xml-parser@5.10.1", "", { "dependencies": { "@nodable/entities": "^3.0.0", "fast-xml-builder": "^1.2.0", "is-unsafe": "^2.0.0", "path-expression-matcher": "^1.6.2", "strnum": "^2.4.1", "xml-naming": "^0.3.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-IEMIf7298kXuZSRFoGfMYrl7is8LpavODgbNz1cwIudv7KwVFnuU+UsMporfq6PD6aXSlawZlARiA3UywCTfMw=="],
|
||||
|
||||
"fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="],
|
||||
|
||||
@@ -1113,7 +1115,7 @@
|
||||
|
||||
"flow-enums-runtime": ["flow-enums-runtime@0.0.6", "", {}, "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw=="],
|
||||
|
||||
"follow-redirects": ["follow-redirects@1.16.0", "", { "peerDependencies": { "debug": "*" }, "optionalPeers": ["debug"] }, "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw=="],
|
||||
"follow-redirects": ["follow-redirects@1.16.0", "", {}, "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw=="],
|
||||
|
||||
"fontfaceobserver": ["fontfaceobserver@2.3.0", "", {}, "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg=="],
|
||||
|
||||
@@ -1187,9 +1189,9 @@
|
||||
|
||||
"hyphenate-style-name": ["hyphenate-style-name@1.1.0", "", {}, "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw=="],
|
||||
|
||||
"i18next": ["i18next@26.3.1", "", { "peerDependencies": { "typescript": "^5 || ^6" }, "optionalPeers": ["typescript"] }, "sha512-txQqd5EULsqEh9OJqRH15aCaOuy/nLJyhw5EHCSKLKJE1aBbb3Zve2+uQIxgWhPm1QqUQoWyQBm2kfmmIrzkcQ=="],
|
||||
"i18next": ["i18next@26.3.6", "", { "peerDependencies": { "typescript": "^5 || ^6 || ^7" }, "optionalPeers": ["typescript"] }, "sha512-Bu5Z2nAXgfVyM8xvW3jk9EKRIuX37PudsrBViThNFx7CR7aaYTpP01cxNB/E4c4UUzTDiAZRstEhsRfPOL/8xA=="],
|
||||
|
||||
"iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="],
|
||||
"iconv-lite": ["iconv-lite@0.7.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ=="],
|
||||
|
||||
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
||||
|
||||
@@ -1231,7 +1233,7 @@
|
||||
|
||||
"is-unicode-supported": ["is-unicode-supported@0.1.0", "", {}, "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="],
|
||||
|
||||
"is-unsafe": ["is-unsafe@1.0.1", "", {}, "sha512-CLK2+VdgERgD96EYm5lUQssZYlRg2tkZnbsxZoacmSiRxiFJ4Nk4SzjCl+Ur+v3kXIY9dTIdb3IH22y1mZ56LA=="],
|
||||
"is-unsafe": ["is-unsafe@2.0.0", "", {}, "sha512-2LdV822R+wmI86unXA93WCFpL6g+av8ynWk0nrHyJqGop5VoocYsSLFgN8jrfalT6iGeLNM4KXuVSsULP53kEA=="],
|
||||
|
||||
"is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="],
|
||||
|
||||
@@ -1269,7 +1271,7 @@
|
||||
|
||||
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
|
||||
|
||||
"js-yaml": ["js-yaml@4.2.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw=="],
|
||||
"js-yaml": ["js-yaml@4.3.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q=="],
|
||||
|
||||
"jsc-safe-url": ["jsc-safe-url@0.2.4", "", {}, "sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q=="],
|
||||
|
||||
@@ -1327,7 +1329,7 @@
|
||||
|
||||
"lint-staged": ["lint-staged@17.0.8", "", { "dependencies": { "listr2": "^10.2.1", "picomatch": "^4.0.4", "string-argv": "^0.3.2", "tinyexec": "^1.2.4" }, "optionalDependencies": { "yaml": "^2.9.0" }, "bin": { "lint-staged": "bin/lint-staged.js" } }, "sha512-B2P/d+jVW0UXOQ0MVMLrB/9ydA1P+zz6jYfdrbbEd9ur3S2rcbduFWKiUCC02Sm5hbC8nrm7y24WuYMG54HfxA=="],
|
||||
|
||||
"listr2": ["listr2@10.2.1", "", { "dependencies": { "cli-truncate": "^5.2.0", "eventemitter3": "^5.0.4", "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^10.0.0" } }, "sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q=="],
|
||||
"listr2": ["listr2@10.2.2", "", { "dependencies": { "cli-truncate": "^5.2.0", "eventemitter3": "^5.0.4", "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^10.0.0" } }, "sha512-JtNtbZj8q5BnDMR7trpwvwk3RIrANtIVzEUm8w7amp6xelLgyuq+4WZoTH913XaQAoH/cNdYhaNzBPA2U3xbDw=="],
|
||||
|
||||
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
||||
|
||||
@@ -1421,7 +1423,7 @@
|
||||
|
||||
"mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="],
|
||||
|
||||
"nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="],
|
||||
"nanoid": ["nanoid@3.3.16", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q=="],
|
||||
|
||||
"nativewind": ["nativewind@2.0.11", "", { "dependencies": { "@babel/generator": "^7.18.7", "@babel/helper-module-imports": "7.18.6", "@babel/types": "7.19.0", "css-mediaquery": "^0.1.2", "css-to-react-native": "^3.0.0", "micromatch": "^4.0.5", "postcss": "^8.4.12", "postcss-calc": "^8.2.4", "postcss-color-functional-notation": "^4.2.2", "postcss-css-variables": "^0.18.0", "postcss-nested": "^5.0.6", "react-is": "^18.1.0", "use-sync-external-store": "^1.1.0" }, "peerDependencies": { "tailwindcss": "~3" } }, "sha512-qCEXUwKW21RYJ33KRAJl3zXq2bCq82WoI564fI21D/TiqhfmstZOqPN53RF8qK1NDK6PGl56b2xaTxgObEePEg=="],
|
||||
|
||||
@@ -1435,7 +1437,7 @@
|
||||
|
||||
"node-int64": ["node-int64@0.4.0", "", {}, "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw=="],
|
||||
|
||||
"node-releases": ["node-releases@2.0.47", "", {}, "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og=="],
|
||||
"node-releases": ["node-releases@2.0.51", "", {}, "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ=="],
|
||||
|
||||
"node-stream-zip": ["node-stream-zip@1.15.0", "", {}, "sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw=="],
|
||||
|
||||
@@ -1495,7 +1497,7 @@
|
||||
|
||||
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
|
||||
|
||||
"path-expression-matcher": ["path-expression-matcher@1.5.0", "", {}, "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ=="],
|
||||
"path-expression-matcher": ["path-expression-matcher@1.6.2", "", {}, "sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ=="],
|
||||
|
||||
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
||||
|
||||
@@ -1507,7 +1509,7 @@
|
||||
|
||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||
|
||||
"picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
|
||||
"picomatch": ["picomatch@4.0.5", "", {}, "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A=="],
|
||||
|
||||
"pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="],
|
||||
|
||||
@@ -1519,7 +1521,7 @@
|
||||
|
||||
"pngjs": ["pngjs@5.0.0", "", {}, "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw=="],
|
||||
|
||||
"postcss": ["postcss@8.5.15", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A=="],
|
||||
"postcss": ["postcss@8.5.19", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ=="],
|
||||
|
||||
"postcss-calc": ["postcss-calc@8.2.4", "", { "dependencies": { "postcss-selector-parser": "^6.0.9", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.2.2" } }, "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q=="],
|
||||
|
||||
@@ -1559,7 +1561,7 @@
|
||||
|
||||
"qrcode": ["qrcode@1.5.4", "", { "dependencies": { "dijkstrajs": "^1.0.1", "pngjs": "^5.0.0", "yargs": "^15.3.1" }, "bin": { "qrcode": "bin/qrcode" } }, "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg=="],
|
||||
|
||||
"qs": ["qs@6.15.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw=="],
|
||||
"qs": ["qs@6.15.3", "", { "dependencies": { "es-define-property": "^1.0.1", "side-channel": "^1.1.1" } }, "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A=="],
|
||||
|
||||
"query-string": ["query-string@7.1.3", "", { "dependencies": { "decode-uri-component": "^0.2.2", "filter-obj": "^1.1.0", "split-on-first": "^1.0.0", "strict-uri-encode": "^2.0.0" } }, "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg=="],
|
||||
|
||||
@@ -1581,7 +1583,7 @@
|
||||
|
||||
"react-freeze": ["react-freeze@1.0.4", "", { "peerDependencies": { "react": ">=17.0.0" } }, "sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA=="],
|
||||
|
||||
"react-i18next": ["react-i18next@17.0.8", "", { "dependencies": { "@babel/runtime": "^7.29.2", "html-parse-stringify": "^3.0.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "i18next": ">= 26.2.0", "react": ">= 16.8.0", "react-dom": "*", "react-native": "*", "typescript": "^5 || ^6" }, "optionalPeers": ["react-dom", "react-native", "typescript"] }, "sha512-0ooKbGLU8JXhe1zwpQUWIeXSgLPOfwJmgheWRIUpcoA0CpyabpGhayjdG+/eA5esC1AQ8h2jWpXjJfzQzeDOCw=="],
|
||||
"react-i18next": ["react-i18next@17.0.8", "", { "dependencies": { "@babel/runtime": "^7.29.2", "html-parse-stringify": "^3.0.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "i18next": ">= 26.2.0", "react": ">= 16.8.0", "typescript": "^5 || ^6" }, "optionalPeers": ["typescript"] }, "sha512-0ooKbGLU8JXhe1zwpQUWIeXSgLPOfwJmgheWRIUpcoA0CpyabpGhayjdG+/eA5esC1AQ8h2jWpXjJfzQzeDOCw=="],
|
||||
|
||||
"react-is": ["react-is@19.2.7", "", {}, "sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A=="],
|
||||
|
||||
@@ -1601,7 +1603,7 @@
|
||||
|
||||
"react-native-draggable-flatlist": ["react-native-draggable-flatlist@4.0.3", "", { "dependencies": { "@babel/preset-typescript": "^7.17.12" }, "peerDependencies": { "react-native": ">=0.64.0", "react-native-gesture-handler": ">=2.0.0", "react-native-reanimated": ">=2.8.0" } }, "sha512-2F4x5BFieWdGq9SetD2nSAR7s7oQCSgNllYgERRXXtNfSOuAGAVbDb/3H3lP0y5f7rEyNwabKorZAD/SyyNbDw=="],
|
||||
|
||||
"react-native-drawer-layout": ["react-native-drawer-layout@4.2.5", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.2.4" }, "peerDependencies": { "react": ">= 18.2.0", "react-native": "*", "react-native-gesture-handler": ">= 2.0.0", "react-native-reanimated": ">= 2.0.0" } }, "sha512-Yl82uLkXjXuq7222hWGIDsq5A6R/bsCeCEgdIxQUxAEHf00oRdDnRByLx3Fsij3qwtmYNPGrHV1NH8G8hbCbLQ=="],
|
||||
"react-native-drawer-layout": ["react-native-drawer-layout@4.2.8", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.2.4" }, "peerDependencies": { "react": ">= 18.2.0", "react-native": "*", "react-native-gesture-handler": ">= 2.0.0", "react-native-reanimated": ">= 2.0.0" } }, "sha512-IswXoXEaQAnzUGo7tJyMPHP0qyUc/7zufpG+kpiStYegHpKQBBnlQoRdXkL1HbCa2o1ROWDhCSJ8XS0V4LNcjQ=="],
|
||||
|
||||
"react-native-edge-to-edge": ["react-native-edge-to-edge@1.8.1", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-bhvsKqeX9PGkY9wBUk9vni/tJNJdKtLPbs/j3e/3CdV4JmUWfTXYYoL+4Hc8Wmej+5eJxkc8KOFa454ruFWBCA=="],
|
||||
|
||||
@@ -1741,7 +1743,7 @@
|
||||
|
||||
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
||||
|
||||
"shell-quote": ["shell-quote@1.8.4", "", {}, "sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ=="],
|
||||
"shell-quote": ["shell-quote@1.10.0", "", {}, "sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA=="],
|
||||
|
||||
"side-channel": ["side-channel@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4", "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ=="],
|
||||
|
||||
@@ -1781,7 +1783,7 @@
|
||||
|
||||
"stacktrace-parser": ["stacktrace-parser@0.1.11", "", { "dependencies": { "type-fest": "^0.7.1" } }, "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg=="],
|
||||
|
||||
"standard-navigation": ["standard-navigation@0.0.7", "", {}, "sha512-NCGLCNyuXrFOkGHxdNZFnpsehGtiq1oXbPhKl7ZuxFO5J//H2evqqOchmD4YwEUJnkjO4kH9Xp4hQX6hdAYCKQ=="],
|
||||
"standard-navigation": ["standard-navigation@0.0.8", "", { "peerDependencies": { "react": "*" } }, "sha512-TyVbo7INUDWtsUWDFn8RR7kwR87U0S4xHfLfbbnyeC581TmmyqQ+eM+nPw8rQTSD8QitRVcYfPaSHr/QJiUy1g=="],
|
||||
|
||||
"statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
|
||||
|
||||
@@ -1803,7 +1805,7 @@
|
||||
|
||||
"strip-indent": ["strip-indent@3.0.0", "", { "dependencies": { "min-indent": "^1.0.0" } }, "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ=="],
|
||||
|
||||
"strnum": ["strnum@2.4.0", "", { "dependencies": { "anynum": "^1.0.0" } }, "sha512-sHrVyWWdq28RbhjuJdZsA1SnGRJV6NiXbk6AXBxDOsgAcA+lmpUZCYjOdLBxkXMwis6RRe7dlZt4VlIWFVzkmg=="],
|
||||
"strnum": ["strnum@2.4.1", "", { "dependencies": { "anynum": "^1.0.1" } }, "sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg=="],
|
||||
|
||||
"strtok3": ["strtok3@6.3.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^4.1.0" } }, "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw=="],
|
||||
|
||||
@@ -1825,7 +1827,7 @@
|
||||
|
||||
"terminal-link": ["terminal-link@2.1.1", "", { "dependencies": { "ansi-escapes": "^4.2.1", "supports-hyperlinks": "^2.0.0" } }, "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ=="],
|
||||
|
||||
"terser": ["terser@5.48.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q=="],
|
||||
"terser": ["terser@5.49.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA=="],
|
||||
|
||||
"text-encoding": ["text-encoding@0.7.0", "", {}, "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA=="],
|
||||
|
||||
@@ -1863,7 +1865,7 @@
|
||||
|
||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"tsx": ["tsx@4.22.4", "", { "dependencies": { "esbuild": "~0.28.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg=="],
|
||||
"tsx": ["tsx@4.23.1", "", { "dependencies": { "esbuild": "~0.28.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-GQHnkIfxyx1wYCOS/wonik5MVRZU9hi1TEZmzGZSCJB1y9YgoZ8H6itNE/u4suE+yLmOzuE4E5S4TZ/ZX2wcWQ=="],
|
||||
|
||||
"type-fest": ["type-fest@0.7.1", "", {}, "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg=="],
|
||||
|
||||
@@ -1941,11 +1943,11 @@
|
||||
|
||||
"wrap-ansi": ["wrap-ansi@10.0.0", "", { "dependencies": { "ansi-styles": "^6.2.3", "string-width": "^8.2.0", "strip-ansi": "^7.1.2" } }, "sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ=="],
|
||||
|
||||
"ws": ["ws@7.5.11", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA=="],
|
||||
"ws": ["ws@7.5.12", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-1xGnbYN3zbog9CwuNDQULNRrTCLIn46/WmpR1f0w6PsCYQHkylZr5vkd6kfMZYV6pRnQkcPNRyiA8LsrNKyhpg=="],
|
||||
|
||||
"xcode": ["xcode@3.0.1", "", { "dependencies": { "simple-plist": "^1.1.0", "uuid": "^7.0.3" } }, "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA=="],
|
||||
|
||||
"xml-naming": ["xml-naming@0.1.0", "", {}, "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw=="],
|
||||
"xml-naming": ["xml-naming@0.3.0", "", {}, "sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ=="],
|
||||
|
||||
"xml2js": ["xml2js@0.6.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w=="],
|
||||
|
||||
@@ -1957,7 +1959,7 @@
|
||||
|
||||
"yaml": ["yaml@2.9.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA=="],
|
||||
|
||||
"yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
|
||||
"yargs": ["yargs@17.7.3", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g=="],
|
||||
|
||||
"yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
|
||||
|
||||
@@ -1965,7 +1967,7 @@
|
||||
|
||||
"zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="],
|
||||
|
||||
"zxing-wasm": ["zxing-wasm@3.1.0", "", { "dependencies": { "@types/emscripten": "^1.41.5", "type-fest": "^5.7.0" } }, "sha512-5+3V1wPRx4gvbeLH2jB7n2cKrYJ1q4i3QgjnBUtrDPeqxJSi6BdzKJg4y6aF6bgW8zfntnYJyrkqFMevDhL2NA=="],
|
||||
"zxing-wasm": ["zxing-wasm@3.1.1", "", { "dependencies": { "@types/emscripten": "^1.41.5", "type-fest": "^5.8.0" } }, "sha512-g0sPJBIubO6zLcJh1jftLPIN6xziaqLsvLgtpGKwDrEhyXXqla3E3yjFrznlr78UHIOMzbJPi0HDWKs/KgaB7A=="],
|
||||
|
||||
"@babel/helper-module-transforms/@babel/helper-module-imports": ["@babel/helper-module-imports@7.29.7", "", { "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g=="],
|
||||
|
||||
@@ -1981,11 +1983,11 @@
|
||||
|
||||
"@expo/cli/ora": ["ora@3.4.0", "", { "dependencies": { "chalk": "^2.4.2", "cli-cursor": "^2.1.0", "cli-spinners": "^2.0.0", "log-symbols": "^2.2.0", "strip-ansi": "^5.2.0", "wcwidth": "^1.0.1" } }, "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg=="],
|
||||
|
||||
"@expo/cli/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"@expo/cli/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"@expo/cli/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=="],
|
||||
|
||||
"@expo/cli/ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="],
|
||||
"@expo/cli/ws": ["ws@8.21.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw=="],
|
||||
|
||||
"@expo/cli/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||
|
||||
@@ -1993,13 +1995,13 @@
|
||||
|
||||
"@expo/config/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
|
||||
|
||||
"@expo/config/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"@expo/config/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"@expo/config-plugins/getenv": ["getenv@2.0.0", "", {}, "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ=="],
|
||||
|
||||
"@expo/config-plugins/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
|
||||
|
||||
"@expo/config-plugins/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"@expo/config-plugins/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"@expo/devcert/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
|
||||
|
||||
@@ -2009,39 +2011,41 @@
|
||||
|
||||
"@expo/fingerprint/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
|
||||
|
||||
"@expo/fingerprint/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"@expo/fingerprint/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"@expo/image-utils/getenv": ["getenv@2.0.0", "", {}, "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ=="],
|
||||
|
||||
"@expo/image-utils/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"@expo/image-utils/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"@expo/metro-config/getenv": ["getenv@2.0.0", "", {}, "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ=="],
|
||||
|
||||
"@expo/metro-config/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
|
||||
|
||||
"@expo/package-manager/@expo/json-file": ["@expo/json-file@11.0.1", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "json5": "^2.2.3" } }, "sha512-zxHWj4MKKMAL29ZQSY/Fssx4Thluk40JmuGNaeS078wy/NhlFhnVi+rHHunulE3xJAJ0CM73m8VK2+GkF9eRwQ=="],
|
||||
|
||||
"@expo/package-manager/ora": ["ora@3.4.0", "", { "dependencies": { "chalk": "^2.4.2", "cli-cursor": "^2.1.0", "cli-spinners": "^2.0.0", "log-symbols": "^2.2.0", "strip-ansi": "^5.2.0", "wcwidth": "^1.0.1" } }, "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg=="],
|
||||
|
||||
"@expo/prebuild-config/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"@expo/prebuild-config/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"@expo/ws-tunnel/ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="],
|
||||
"@expo/ws-tunnel/ws": ["ws@8.21.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw=="],
|
||||
|
||||
"@jimp/png/pngjs": ["pngjs@6.0.0", "", {}, "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="],
|
||||
|
||||
"@react-native-community/cli/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"@react-native-community/cli/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"@react-native-community/cli-doctor/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"@react-native-community/cli-doctor/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"@react-native-community/cli-server-api/open": ["open@6.4.0", "", { "dependencies": { "is-wsl": "^1.1.0" } }, "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg=="],
|
||||
|
||||
"@react-native-community/cli-server-api/ws": ["ws@6.2.4", "", { "dependencies": { "async-limiter": "~1.0.0" } }, "sha512-PNIUUyLI5YpkJZj60YBzX1o0ByQ4ovvfmq9N/Kig/PAYbVlGyz4R6G0SEWrD0O9acc0sT2+IdMBVLFv8FSi0Nw=="],
|
||||
"@react-native-community/cli-server-api/ws": ["ws@6.2.5", "", { "dependencies": { "async-limiter": "~1.0.0" } }, "sha512-T7pPl+DnmNrKRuttAIQwueReX5GqsedYEWp3/H//CG35+DyUOe1+/voAeE8idxgfLsQf2tO+rdtBd1FnPopgTQ=="],
|
||||
|
||||
"@react-native-community/cli-tools/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"@react-native-community/cli-tools/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"@react-native/babel-preset/@react-native/babel-plugin-codegen": ["@react-native/babel-plugin-codegen@0.86.0", "", { "dependencies": { "@babel/traverse": "^7.29.0", "@react-native/codegen": "0.86.0" } }, "sha512-qdsABWNW7uTll90l4Vh03gjeyu3WVDi2CyiiyvYGMRDcoYbjbQi6df3BMAm9lQI2yslZ1T14LlDDAsgTwNxplA=="],
|
||||
|
||||
"@react-native/babel-preset/babel-plugin-syntax-hermes-parser": ["babel-plugin-syntax-hermes-parser@0.36.0", "", { "dependencies": { "hermes-parser": "0.36.0" } }, "sha512-LhD0xdoedDw7ansQgXbB2DADLZIK/LRXuWNBPuVzMc5S2WK5GyT89tCM+cQzxFGO0mGyLK6D5TrVOJJzAoDy8Q=="],
|
||||
|
||||
"@react-native/community-cli-plugin/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"@react-native/community-cli-plugin/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"@react-native/metro-babel-transformer/hermes-parser": ["hermes-parser@0.36.0", "", { "dependencies": { "hermes-estree": "0.36.0" } }, "sha512-GdpwMmH5x6IpC1cijvcvYnlPB60Mh6kTSF/NFdYV/j56gYdi+0RIakYs+eqOV+bbO0SW7mgVVGSsTJxyPQfo3w=="],
|
||||
|
||||
@@ -2075,7 +2079,7 @@
|
||||
|
||||
"chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||
|
||||
"cli-truncate/string-width": ["string-width@8.2.1", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="],
|
||||
"cli-truncate/string-width": ["string-width@8.2.2", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg=="],
|
||||
|
||||
"cliui/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=="],
|
||||
|
||||
@@ -2089,7 +2093,7 @@
|
||||
|
||||
"error-ex/is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="],
|
||||
|
||||
"expo-build-properties/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"expo-build-properties/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"expo-modules-autolinking/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
|
||||
|
||||
@@ -2157,15 +2161,15 @@
|
||||
|
||||
"nativewind/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
|
||||
|
||||
"npm-package-arg/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"npm-package-arg/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"parse-png/pngjs": ["pngjs@3.4.0", "", {}, "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="],
|
||||
|
||||
"patch-package/fs-extra": ["fs-extra@10.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ=="],
|
||||
|
||||
"patch-package/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"patch-package/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"path-scurry/lru-cache": ["lru-cache@11.5.1", "", {}, "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A=="],
|
||||
"path-scurry/lru-cache": ["lru-cache@11.5.2", "", {}, "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g=="],
|
||||
|
||||
"pixelmatch/pngjs": ["pngjs@3.4.0", "", {}, "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="],
|
||||
|
||||
@@ -2183,17 +2187,17 @@
|
||||
|
||||
"react-native/commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="],
|
||||
|
||||
"react-native/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"react-native/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"react-native-drawer-layout/color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="],
|
||||
|
||||
"react-native-reanimated/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"react-native-reanimated/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"react-native-web/@react-native/normalize-colors": ["@react-native/normalize-colors@0.74.89", "", {}, "sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg=="],
|
||||
|
||||
"react-native-web/memoize-one": ["memoize-one@6.0.0", "", {}, "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="],
|
||||
|
||||
"react-native-worklets/semver": ["semver@7.8.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA=="],
|
||||
"react-native-worklets/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"readable-web-to-node-stream/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="],
|
||||
|
||||
@@ -2227,13 +2231,13 @@
|
||||
|
||||
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
||||
|
||||
"wrap-ansi/string-width": ["string-width@8.2.1", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="],
|
||||
"wrap-ansi/string-width": ["string-width@8.2.2", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg=="],
|
||||
|
||||
"wrap-ansi/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="],
|
||||
|
||||
"xml2js/xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="],
|
||||
|
||||
"zxing-wasm/type-fest": ["type-fest@5.7.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg=="],
|
||||
"zxing-wasm/type-fest": ["type-fest@5.8.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-YGYEVz3Fm5iy/AybuA0oyNFq7H4CgQNfRp/qfe8nurE1kuCeNm3/vfm9X4Mtl+qLyaKJUh5xrFZwogr41SMjYA=="],
|
||||
|
||||
"@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=="],
|
||||
|
||||
|
||||
@@ -35,8 +35,10 @@ const ContinueWatchingPoster: React.FC<ContinueWatchingPosterProps> = ({
|
||||
return `${api?.basePath}/Items/${item.Id}/Images/Primary?fillHeight=389&quality=80`;
|
||||
}
|
||||
if (item.Type === "Episode") {
|
||||
if (item.ParentBackdropItemId && item.ParentThumbImageTag) {
|
||||
return `${api?.basePath}/Items/${item.ParentBackdropItemId}/Images/Thumb?fillHeight=389&quality=80&tag=${item.ParentThumbImageTag}`;
|
||||
// Matched pair: the parent that owns the Thumb (ParentThumbItemId), not the
|
||||
// backdrop owner — otherwise the Thumb tag is requested on the wrong item → black.
|
||||
if (item.ParentThumbItemId && item.ParentThumbImageTag) {
|
||||
return `${api?.basePath}/Items/${item.ParentThumbItemId}/Images/Thumb?fillHeight=389&quality=80&tag=${item.ParentThumbImageTag}`;
|
||||
}
|
||||
|
||||
return `${api?.basePath}/Items/${item.Id}/Images/Primary?fillHeight=389&quality=80`;
|
||||
@@ -61,7 +63,8 @@ const ContinueWatchingPoster: React.FC<ContinueWatchingPosterProps> = ({
|
||||
}
|
||||
|
||||
return `${api?.basePath}/Items/${item.Id}/Images/Primary?fillHeight=389&quality=80`;
|
||||
}, [item]);
|
||||
// useEpisodePoster in deps so flipping the prop re-computes the URL live.
|
||||
}, [api, item, useEpisodePoster]);
|
||||
|
||||
if (!url)
|
||||
return <View className='aspect-video border border-neutral-800 w-44' />;
|
||||
|
||||
@@ -16,9 +16,12 @@ export const SeriesCard: React.FC<{ items: BaseItemDto[] }> = ({ items }) => {
|
||||
const { showActionSheetWithOptions } = useActionSheet();
|
||||
const router = useRouter();
|
||||
|
||||
// Keyed on SeriesId so recycled FlashList cells re-read the correct poster
|
||||
// instead of freezing the first-rendered series' image (empty deps bug).
|
||||
const base64Image = useMemo(() => {
|
||||
return storage.getString(items[0].SeriesId!);
|
||||
}, []);
|
||||
const seriesId = items[0]?.SeriesId;
|
||||
return seriesId ? storage.getString(seriesId) : undefined;
|
||||
}, [items[0]?.SeriesId]);
|
||||
|
||||
const deleteSeries = useCallback(
|
||||
async () =>
|
||||
|
||||
@@ -65,10 +65,11 @@ const HeroCard: React.FC<HeroCardProps> = React.memo(
|
||||
const posterUrl = useMemo(() => {
|
||||
if (!api) return null;
|
||||
|
||||
// For episodes, always use series thumb
|
||||
// For episodes, always use series thumb.
|
||||
// Matched pair: ParentThumbItemId owns the Thumb tag, not ParentBackdropItemId.
|
||||
if (item.Type === "Episode") {
|
||||
if (item.ParentThumbImageTag) {
|
||||
return `${api.basePath}/Items/${item.ParentBackdropItemId}/Images/Thumb?fillHeight=400&quality=80&tag=${item.ParentThumbImageTag}`;
|
||||
if (item.ParentThumbItemId && item.ParentThumbImageTag) {
|
||||
return `${api.basePath}/Items/${item.ParentThumbItemId}/Images/Thumb?fillHeight=400&quality=80&tag=${item.ParentThumbImageTag}`;
|
||||
}
|
||||
if (item.SeriesId) {
|
||||
return `${api.basePath}/Items/${item.SeriesId}/Images/Thumb?fillHeight=400&quality=80`;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import type { PropsWithChildren, ReactNode } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { TouchableOpacity, View, type ViewProps } from "react-native";
|
||||
import { Text } from "../common/Text";
|
||||
|
||||
@@ -33,10 +32,7 @@ export const ListItem: React.FC<PropsWithChildren<Props>> = ({
|
||||
disabledByAdmin = false,
|
||||
...viewProps
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const effectiveSubtitle = disabledByAdmin
|
||||
? t("home.settings.disabled_by_admin")
|
||||
: subtitle;
|
||||
const effectiveSubtitle = disabledByAdmin ? "Disabled by admin" : subtitle;
|
||||
const isDisabled = disabled || disabledByAdmin;
|
||||
if (onPress)
|
||||
return (
|
||||
|
||||
@@ -146,7 +146,7 @@ export const Login: React.FC = () => {
|
||||
} else {
|
||||
Alert.alert(
|
||||
t("login.connection_failed"),
|
||||
t("login.an_unexpected_error_occured"),
|
||||
t("login.an_unexpected_error_occurred"),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
|
||||
@@ -437,7 +437,7 @@ export const TVLogin: React.FC = () => {
|
||||
} else {
|
||||
Alert.alert(
|
||||
t("login.connection_failed"),
|
||||
t("login.an_unexpected_error_occured"),
|
||||
t("login.an_unexpected_error_occurred"),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
@@ -499,7 +499,7 @@ export const TVLogin: React.FC = () => {
|
||||
const message =
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: t("login.an_unexpected_error_occured");
|
||||
: t("login.an_unexpected_error_occurred");
|
||||
Alert.alert(t("login.connection_failed"), message);
|
||||
goToQRScreen();
|
||||
} finally {
|
||||
@@ -523,7 +523,7 @@ export const TVLogin: React.FC = () => {
|
||||
} else {
|
||||
Alert.alert(
|
||||
t("login.connection_failed"),
|
||||
t("login.an_unexpected_error_occured"),
|
||||
t("login.an_unexpected_error_occurred"),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
@@ -768,7 +768,7 @@ export const TVLogin: React.FC = () => {
|
||||
const message =
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: t("login.an_unexpected_error_occured");
|
||||
: t("login.an_unexpected_error_occurred");
|
||||
Alert.alert(t("login.connection_failed"), message);
|
||||
goToQRScreen();
|
||||
});
|
||||
|
||||
@@ -20,10 +20,7 @@ export const JellyseerrSettings = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [user] = useAtom(userAtom);
|
||||
const { settings, updateSettings, pluginSettings } = useSettings();
|
||||
// Only the server URL is admin-lockable — the password stays editable so
|
||||
// the user can still sign in to the admin-pinned Jellyseerr server.
|
||||
const urlLocked = pluginSettings?.jellyseerrServerUrl?.locked === true;
|
||||
const { settings, updateSettings } = useSettings();
|
||||
|
||||
const [jellyseerrPassword, setJellyseerrPassword] = useState<
|
||||
string | undefined
|
||||
@@ -33,25 +30,22 @@ export const JellyseerrSettings = () => {
|
||||
string | undefined
|
||||
>(settings?.jellyseerrServerUrl || undefined);
|
||||
|
||||
// When the URL is admin-pinned, ignore any locally-typed value so the login
|
||||
// targets the same server the (read-only) input displays.
|
||||
const effectiveServerUrl = urlLocked
|
||||
? settings?.jellyseerrServerUrl
|
||||
: jellyseerrServerUrl || settings?.jellyseerrServerUrl;
|
||||
|
||||
const loginToJellyseerrMutation = useMutation({
|
||||
mutationFn: async () => {
|
||||
if (!effectiveServerUrl) throw new Error("Missing server url");
|
||||
if (!jellyseerrServerUrl && !settings?.jellyseerrServerUrl)
|
||||
throw new Error("Missing server url");
|
||||
if (!user?.Name)
|
||||
throw new Error("Missing required information for login");
|
||||
const jellyseerrTempApi = new JellyseerrApi(effectiveServerUrl);
|
||||
const jellyseerrTempApi = new JellyseerrApi(
|
||||
jellyseerrServerUrl || settings.jellyseerrServerUrl || "",
|
||||
);
|
||||
const testResult = await jellyseerrTempApi.test();
|
||||
if (!testResult.isValid) throw new Error("Invalid server url");
|
||||
return jellyseerrTempApi.login(user.Name, jellyseerrPassword || "");
|
||||
},
|
||||
onSuccess: (user) => {
|
||||
setJellyseerrUser(user);
|
||||
updateSettings({ jellyseerrServerUrl: effectiveServerUrl });
|
||||
updateSettings({ jellyseerrServerUrl });
|
||||
},
|
||||
onError: () => {
|
||||
toast.error(t("jellyseerr.failed_to_login"));
|
||||
@@ -121,41 +115,30 @@ export const JellyseerrSettings = () => {
|
||||
</>
|
||||
) : (
|
||||
<View className='flex flex-col rounded-xl overflow-hidden p-4 bg-neutral-900'>
|
||||
<View style={{ opacity: urlLocked ? 0.5 : 1 }}>
|
||||
<Text className='font-bold mb-1'>
|
||||
{t("home.settings.plugins.jellyseerr.server_url")}
|
||||
<Text className='font-bold mb-1'>
|
||||
{t("home.settings.plugins.jellyseerr.server_url")}
|
||||
</Text>
|
||||
<View className='flex flex-col shrink mb-2'>
|
||||
<Text className='text-xs text-gray-600'>
|
||||
{t("home.settings.plugins.jellyseerr.server_url_hint")}
|
||||
</Text>
|
||||
<View className='flex flex-col shrink mb-2'>
|
||||
<Text className='text-xs text-gray-600'>
|
||||
{t("home.settings.plugins.jellyseerr.server_url_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<Input
|
||||
className='border border-neutral-800 mb-2'
|
||||
placeholder={t(
|
||||
"home.settings.plugins.jellyseerr.server_url_placeholder",
|
||||
)}
|
||||
value={
|
||||
urlLocked
|
||||
? settings?.jellyseerrServerUrl
|
||||
: (jellyseerrServerUrl ?? settings?.jellyseerrServerUrl)
|
||||
}
|
||||
defaultValue={
|
||||
settings?.jellyseerrServerUrl ?? jellyseerrServerUrl
|
||||
}
|
||||
keyboardType='url'
|
||||
returnKeyType='done'
|
||||
autoCapitalize='none'
|
||||
textContentType='URL'
|
||||
onChangeText={setjellyseerrServerUrl}
|
||||
editable={!urlLocked && !loginToJellyseerrMutation.isPending}
|
||||
/>
|
||||
{urlLocked && (
|
||||
<Text className='text-xs text-red-600 mb-2'>
|
||||
{t("home.settings.disabled_by_admin")}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
<Input
|
||||
className='border border-neutral-800 mb-2'
|
||||
placeholder={t(
|
||||
"home.settings.plugins.jellyseerr.server_url_placeholder",
|
||||
)}
|
||||
value={jellyseerrServerUrl ?? settings?.jellyseerrServerUrl}
|
||||
defaultValue={
|
||||
settings?.jellyseerrServerUrl ?? jellyseerrServerUrl
|
||||
}
|
||||
keyboardType='url'
|
||||
returnKeyType='done'
|
||||
autoCapitalize='none'
|
||||
textContentType='URL'
|
||||
onChangeText={setjellyseerrServerUrl}
|
||||
editable={!loginToJellyseerrMutation.isPending}
|
||||
/>
|
||||
<View>
|
||||
<Text className='font-bold mb-2'>
|
||||
{t("home.settings.plugins.jellyseerr.password")}
|
||||
|
||||
@@ -1,28 +1,33 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Switch } from "react-native";
|
||||
import { Switch, Text, View } from "react-native";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
import { ListGroup } from "../list/ListGroup";
|
||||
import { ListItem } from "../list/ListItem";
|
||||
|
||||
export const KefinTweaksSettings = () => {
|
||||
const { settings, updateSettings, pluginSettings } = useSettings();
|
||||
const { settings, updateSettings } = useSettings();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const isEnabled = settings?.useKefinTweaks ?? false;
|
||||
const locked = pluginSettings?.useKefinTweaks?.locked === true;
|
||||
|
||||
return (
|
||||
<ListGroup>
|
||||
<ListItem
|
||||
title={t("home.settings.plugins.kefinTweaks.watchlist_enabler")}
|
||||
disabledByAdmin={locked}
|
||||
>
|
||||
<Switch
|
||||
value={isEnabled}
|
||||
disabled={locked}
|
||||
onValueChange={(value) => updateSettings({ useKefinTweaks: value })}
|
||||
/>
|
||||
</ListItem>
|
||||
</ListGroup>
|
||||
<View className=''>
|
||||
<View className='flex flex-col rounded-xl overflow-hidden p-4 bg-neutral-900'>
|
||||
<Text className='text-xs text-red-600 mb-2'>
|
||||
{t("home.settings.plugins.kefinTweaks.watchlist_enabler")}
|
||||
</Text>
|
||||
|
||||
<View className='flex flex-row items-center justify-between mt-2'>
|
||||
<Text className='text-white'>
|
||||
{isEnabled ? t("Watchlist On") : t("Watchlist Off")}
|
||||
</Text>
|
||||
|
||||
<Switch
|
||||
value={isEnabled}
|
||||
onValueChange={(value) => updateSettings({ useKefinTweaks: value })}
|
||||
trackColor={{ false: "#555", true: "purple" }}
|
||||
thumbColor={isEnabled ? "#fff" : "#ccc"}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ import { BITRATES } from "@/components/BitrateSelector";
|
||||
import { PlatformDropdown } from "@/components/PlatformDropdown";
|
||||
import { PLAYBACK_SPEEDS } from "@/components/PlaybackSpeedSelector";
|
||||
import DisabledSetting from "@/components/settings/DisabledSetting";
|
||||
import useRouter from "@/hooks/useAppRouter";
|
||||
import * as ScreenOrientation from "@/packages/expo-screen-orientation";
|
||||
import { ScreenOrientationEnum, useSettings } from "@/utils/atoms/settings";
|
||||
import { Text } from "../common/Text";
|
||||
@@ -15,6 +16,7 @@ import { ListGroup } from "../list/ListGroup";
|
||||
import { ListItem } from "../list/ListItem";
|
||||
|
||||
export const PlaybackControlsSettings: React.FC = () => {
|
||||
const router = useRouter();
|
||||
const { settings, updateSettings, pluginSettings } = useSettings();
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -251,6 +253,15 @@ export const PlaybackControlsSettings: React.FC = () => {
|
||||
title={t("home.settings.other.max_auto_play_episode_count")}
|
||||
/>
|
||||
</ListItem>
|
||||
|
||||
{/* Media Segment Skip Settings */}
|
||||
<ListItem
|
||||
title={t("home.settings.other.segment_skip_settings")}
|
||||
subtitle={t("home.settings.other.segment_skip_settings_description")}
|
||||
onPress={() => router.push("/settings/segment-skip/page")}
|
||||
>
|
||||
<Ionicons name='chevron-forward' size={20} color='#8E8D91' />
|
||||
</ListItem>
|
||||
</ListGroup>
|
||||
</DisabledSetting>
|
||||
);
|
||||
|
||||
@@ -20,12 +20,7 @@ export const PluginSettings = () => {
|
||||
>
|
||||
<ListItem
|
||||
onPress={() => router.push("/settings/plugins/jellyseerr/page")}
|
||||
title='Jellyseerr'
|
||||
showArrow
|
||||
/>
|
||||
<ListItem
|
||||
onPress={() => router.push("/settings/plugins/streamystats/page")}
|
||||
title='Streamystats'
|
||||
title={"Jellyseerr"}
|
||||
showArrow
|
||||
/>
|
||||
<ListItem
|
||||
@@ -33,6 +28,11 @@ export const PluginSettings = () => {
|
||||
title='Marlin Search'
|
||||
showArrow
|
||||
/>
|
||||
<ListItem
|
||||
onPress={() => router.push("/settings/plugins/streamystats/page")}
|
||||
title='Streamystats'
|
||||
showArrow
|
||||
/>
|
||||
<ListItem
|
||||
onPress={() => router.push("/settings/plugins/kefinTweaks/page")}
|
||||
title='KefinTweaks'
|
||||
|
||||
@@ -58,7 +58,7 @@ export const QuickConnect: React.FC<Props> = ({ ...props }) => {
|
||||
successHapticFeedback();
|
||||
Alert.alert(
|
||||
t("home.settings.quick_connect.success"),
|
||||
t("home.settings.quick_connect.quick_connect_autorized"),
|
||||
t("home.settings.quick_connect.quick_connect_authorized"),
|
||||
);
|
||||
setQuickConnectCode(undefined);
|
||||
bottomSheetModalRef?.current?.close();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Platform, View } from "react-native";
|
||||
import { Alert, Platform, View } from "react-native";
|
||||
import { toast } from "sonner-native";
|
||||
import { Text } from "@/components/common/Text";
|
||||
import { Colors } from "@/constants/Colors";
|
||||
@@ -12,6 +12,7 @@ import { ListItem } from "../list/ListItem";
|
||||
export const StorageSettings = () => {
|
||||
const { deleteAllFiles, appSizeUsage } = useDownload();
|
||||
const { t } = useTranslation();
|
||||
const queryClient = useQueryClient();
|
||||
const successHapticFeedback = useHaptic("success");
|
||||
const errorHapticFeedback = useHaptic("error");
|
||||
|
||||
@@ -27,16 +28,38 @@ export const StorageSettings = () => {
|
||||
used: (app.total - app.remaining) / app.total,
|
||||
};
|
||||
},
|
||||
// Keep the bar moving while a download is writing to disk.
|
||||
refetchInterval: 10 * 1000,
|
||||
});
|
||||
|
||||
const onDeleteClicked = async () => {
|
||||
try {
|
||||
await deleteAllFiles();
|
||||
successHapticFeedback();
|
||||
} catch (_e) {
|
||||
errorHapticFeedback();
|
||||
toast.error(t("home.settings.toasts.error_deleting_files"));
|
||||
}
|
||||
const onDeleteClicked = () => {
|
||||
Alert.alert(
|
||||
t("home.settings.storage.delete_all_downloaded_files_confirm"),
|
||||
t("home.settings.storage.delete_all_downloaded_files_confirm_desc"),
|
||||
[
|
||||
{
|
||||
text: t("common.cancel"),
|
||||
style: "cancel",
|
||||
},
|
||||
{
|
||||
text: t("common.ok"),
|
||||
style: "destructive",
|
||||
onPress: async () => {
|
||||
try {
|
||||
await deleteAllFiles();
|
||||
successHapticFeedback();
|
||||
} catch (_e) {
|
||||
errorHapticFeedback();
|
||||
toast.error(t("home.settings.toasts.error_deleting_files"));
|
||||
} finally {
|
||||
// Reflect the freed space immediately instead of waiting for
|
||||
// the next poll.
|
||||
queryClient.invalidateQueries({ queryKey: ["appSize"] });
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
);
|
||||
};
|
||||
|
||||
const calculatePercentage = (value: number, total: number) => {
|
||||
|
||||
@@ -139,9 +139,10 @@ export const TVPosterCard: React.FC<TVPosterCardProps> = ({
|
||||
if (orientation === "horizontal") {
|
||||
// Episode: prefer series thumb image for consistent look (like hero section)
|
||||
if (item.Type === "Episode") {
|
||||
// First try parent/series thumb (horizontal series artwork)
|
||||
if (item.ParentBackdropItemId && item.ParentThumbImageTag) {
|
||||
return `${api.basePath}/Items/${item.ParentBackdropItemId}/Images/Thumb?fillHeight=700&quality=80&tag=${item.ParentThumbImageTag}`;
|
||||
// First try parent/series thumb (horizontal series artwork).
|
||||
// Matched pair: ParentThumbItemId owns the Thumb tag, not ParentBackdropItemId.
|
||||
if (item.ParentThumbItemId && item.ParentThumbImageTag) {
|
||||
return `${api.basePath}/Items/${item.ParentThumbItemId}/Images/Thumb?fillHeight=700&quality=80&tag=${item.ParentThumbImageTag}`;
|
||||
}
|
||||
// Fall back to episode's own primary image
|
||||
if (item.ImageTags?.Primary) {
|
||||
|
||||
@@ -35,7 +35,9 @@ interface BottomControlsProps {
|
||||
currentTime: number;
|
||||
remainingTime: number;
|
||||
showSkipButton: boolean;
|
||||
skipButtonText: string;
|
||||
showSkipCreditButton: boolean;
|
||||
skipCreditButtonText: string;
|
||||
hasContentAfterCredits: boolean;
|
||||
skipIntro: () => void;
|
||||
skipCredit: () => void;
|
||||
@@ -75,6 +77,11 @@ interface BottomControlsProps {
|
||||
minutes: number;
|
||||
seconds: number;
|
||||
};
|
||||
|
||||
// Intro playback props
|
||||
isPlayingIntro?: boolean;
|
||||
skipAllIntros?: () => void;
|
||||
intros?: BaseItemDto[];
|
||||
}
|
||||
|
||||
export const BottomControls: FC<BottomControlsProps> = ({
|
||||
@@ -87,7 +94,9 @@ export const BottomControls: FC<BottomControlsProps> = ({
|
||||
currentTime,
|
||||
remainingTime,
|
||||
showSkipButton,
|
||||
skipButtonText,
|
||||
showSkipCreditButton,
|
||||
skipCreditButtonText,
|
||||
hasContentAfterCredits,
|
||||
skipIntro,
|
||||
skipCredit,
|
||||
@@ -108,6 +117,9 @@ export const BottomControls: FC<BottomControlsProps> = ({
|
||||
trickPlayUrl,
|
||||
trickplayInfo,
|
||||
time,
|
||||
isPlayingIntro = false,
|
||||
skipAllIntros,
|
||||
intros = [],
|
||||
}) => {
|
||||
const { settings } = useSettings();
|
||||
const { t } = useTranslation();
|
||||
@@ -180,10 +192,18 @@ export const BottomControls: FC<BottomControlsProps> = ({
|
||||
) : null}
|
||||
</View>
|
||||
<View className='flex flex-row items-center space-x-2 shrink-0'>
|
||||
{/* Skip Intro button - shows when playing intro videos */}
|
||||
{isPlayingIntro && intros.length > 0 && skipAllIntros && (
|
||||
<SkipButton
|
||||
showButton={true}
|
||||
onPress={skipAllIntros}
|
||||
buttonText='Skip Intro'
|
||||
/>
|
||||
)}
|
||||
<SkipButton
|
||||
showButton={showSkipButton}
|
||||
onPress={skipIntro}
|
||||
buttonText='Skip Intro'
|
||||
buttonText={skipButtonText}
|
||||
/>
|
||||
{/* Smart Skip Credits behavior:
|
||||
- Show "Skip Credits" if there's content after credits OR no next episode
|
||||
@@ -193,7 +213,7 @@ export const BottomControls: FC<BottomControlsProps> = ({
|
||||
showSkipCreditButton && (hasContentAfterCredits || !nextItem)
|
||||
}
|
||||
onPress={skipCredit}
|
||||
buttonText='Skip Credits'
|
||||
buttonText={skipCreditButtonText}
|
||||
/>
|
||||
{settings.autoPlayNextEpisode !== false &&
|
||||
(settings.maxAutoPlayEpisodeCount.value === -1 ||
|
||||
|
||||
@@ -4,7 +4,15 @@ import type {
|
||||
MediaSourceInfo,
|
||||
} from "@jellyfin/sdk/lib/generated-client";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
import { type FC, useCallback, useEffect, useState } from "react";
|
||||
import {
|
||||
type FC,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { StyleSheet, useWindowDimensions, View } from "react-native";
|
||||
import Animated, {
|
||||
Easing,
|
||||
@@ -16,17 +24,17 @@ import Animated, {
|
||||
} from "react-native-reanimated";
|
||||
import ContinueWatchingOverlay from "@/components/video-player/controls/ContinueWatchingOverlay";
|
||||
import useRouter from "@/hooks/useAppRouter";
|
||||
import { useCreditSkipper } from "@/hooks/useCreditSkipper";
|
||||
import { useHaptic } from "@/hooks/useHaptic";
|
||||
import { useIntroSkipper } from "@/hooks/useIntroSkipper";
|
||||
import { usePlaybackManager } from "@/hooks/usePlaybackManager";
|
||||
import { useSegmentSkipper } from "@/hooks/useSegmentSkipper";
|
||||
import { useTrickplay } from "@/hooks/useTrickplay";
|
||||
import type { TechnicalInfo } from "@/modules/mpv-player";
|
||||
import { DownloadedItem } from "@/providers/Downloads/types";
|
||||
import { useOfflineMode } from "@/providers/OfflineModeProvider";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
import { getDefaultPlaySettings } from "@/utils/jellyfin/getDefaultPlaySettings";
|
||||
import { ticksToMs } from "@/utils/time";
|
||||
import { useSegments } from "@/utils/segments";
|
||||
import { msToSeconds, ticksToMs } from "@/utils/time";
|
||||
import { BottomControls } from "./BottomControls";
|
||||
import { CenterControls } from "./CenterControls";
|
||||
import { CONTROLS_CONSTANTS } from "./constants";
|
||||
@@ -43,6 +51,9 @@ import { useControlsTimeout } from "./useControlsTimeout";
|
||||
import { PlaybackSpeedScope } from "./utils/playback-speed-settings";
|
||||
import { type AspectRatio } from "./VideoScalingModeSelector";
|
||||
|
||||
// No-op function to avoid creating new references on every render
|
||||
const noop = () => {};
|
||||
|
||||
interface Props {
|
||||
item: BaseItemDto;
|
||||
isPlaying: boolean;
|
||||
@@ -73,6 +84,10 @@ interface Props {
|
||||
getTechnicalInfo?: () => Promise<TechnicalInfo>;
|
||||
playMethod?: "DirectPlay" | "DirectStream" | "Transcode";
|
||||
transcodeReasons?: string[];
|
||||
// Intro playback props
|
||||
isPlayingIntro?: boolean;
|
||||
skipAllIntros?: () => void;
|
||||
intros?: BaseItemDto[];
|
||||
}
|
||||
|
||||
export const Controls: FC<Props> = ({
|
||||
@@ -102,6 +117,9 @@ export const Controls: FC<Props> = ({
|
||||
getTechnicalInfo,
|
||||
playMethod,
|
||||
transcodeReasons,
|
||||
isPlayingIntro = false,
|
||||
skipAllIntros,
|
||||
intros = [],
|
||||
}) => {
|
||||
const offline = useOfflineMode();
|
||||
const { settings, updateSettings } = useSettings();
|
||||
@@ -111,6 +129,18 @@ export const Controls: FC<Props> = ({
|
||||
const [episodeView, setEpisodeView] = useState(false);
|
||||
const [showAudioSlider, setShowAudioSlider] = useState(false);
|
||||
|
||||
// Ref to track pending play timeout for cleanup and cancellation
|
||||
const playTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
|
||||
// Clean up timeout on unmount
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (playTimeoutRef.current) {
|
||||
clearTimeout(playTimeoutRef.current);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
const { height: screenHeight, width: screenWidth } = useWindowDimensions();
|
||||
const { previousItem, nextItem } = usePlaybackManager({
|
||||
item,
|
||||
@@ -316,27 +346,122 @@ export const Controls: FC<Props> = ({
|
||||
subtitleIndex: string;
|
||||
}>();
|
||||
|
||||
const { showSkipButton, skipIntro } = useIntroSkipper(
|
||||
item.Id!,
|
||||
currentTime,
|
||||
seek,
|
||||
play,
|
||||
// Fetch all segments for the current item
|
||||
const { data: segments } = useSegments(
|
||||
item.Id ?? "",
|
||||
offline,
|
||||
api,
|
||||
downloadedFiles,
|
||||
api,
|
||||
);
|
||||
|
||||
const { showSkipCreditButton, skipCredit, hasContentAfterCredits } =
|
||||
useCreditSkipper(
|
||||
item.Id!,
|
||||
currentTime,
|
||||
seek,
|
||||
play,
|
||||
offline,
|
||||
api,
|
||||
downloadedFiles,
|
||||
maxMs,
|
||||
);
|
||||
// Convert milliseconds to seconds for segment comparison
|
||||
const currentTimeSeconds = msToSeconds(currentTime);
|
||||
const maxSeconds = maxMs ? msToSeconds(maxMs) : undefined;
|
||||
|
||||
// Wrapper to convert segment skip from seconds to milliseconds
|
||||
// Includes 200ms delay to allow seek operation to complete before resuming playback
|
||||
const seekMs = useCallback(
|
||||
(timeInSeconds: number) => {
|
||||
// Cancel any pending play call to avoid race conditions
|
||||
if (playTimeoutRef.current) {
|
||||
clearTimeout(playTimeoutRef.current);
|
||||
}
|
||||
seek(timeInSeconds * 1000);
|
||||
// Brief delay ensures the seek operation completes before resuming playback
|
||||
// Without this, playback may resume from the old position
|
||||
playTimeoutRef.current = setTimeout(() => {
|
||||
play();
|
||||
playTimeoutRef.current = null;
|
||||
}, 200);
|
||||
},
|
||||
[seek, play],
|
||||
);
|
||||
|
||||
// Use unified segment skipper for all segment types
|
||||
const introSkipper = useSegmentSkipper({
|
||||
segments: segments?.introSegments || [],
|
||||
segmentType: "Intro",
|
||||
currentTime: currentTimeSeconds,
|
||||
seek: seekMs,
|
||||
isPaused: !isPlaying,
|
||||
});
|
||||
|
||||
const outroSkipper = useSegmentSkipper({
|
||||
segments: segments?.creditSegments || [],
|
||||
segmentType: "Outro",
|
||||
currentTime: currentTimeSeconds,
|
||||
totalDuration: maxSeconds,
|
||||
seek: seekMs,
|
||||
isPaused: !isPlaying,
|
||||
});
|
||||
|
||||
const recapSkipper = useSegmentSkipper({
|
||||
segments: segments?.recapSegments || [],
|
||||
segmentType: "Recap",
|
||||
currentTime: currentTimeSeconds,
|
||||
seek: seekMs,
|
||||
isPaused: !isPlaying,
|
||||
});
|
||||
|
||||
const commercialSkipper = useSegmentSkipper({
|
||||
segments: segments?.commercialSegments || [],
|
||||
segmentType: "Commercial",
|
||||
currentTime: currentTimeSeconds,
|
||||
seek: seekMs,
|
||||
isPaused: !isPlaying,
|
||||
});
|
||||
|
||||
const previewSkipper = useSegmentSkipper({
|
||||
segments: segments?.previewSegments || [],
|
||||
segmentType: "Preview",
|
||||
currentTime: currentTimeSeconds,
|
||||
seek: seekMs,
|
||||
isPaused: !isPlaying,
|
||||
});
|
||||
|
||||
// Determine which segment button to show (priority order)
|
||||
// Commercial > Recap > Intro > Preview > Outro
|
||||
const activeSegment = useMemo(() => {
|
||||
if (commercialSkipper.currentSegment)
|
||||
return { type: "Commercial", ...commercialSkipper };
|
||||
if (recapSkipper.currentSegment) return { type: "Recap", ...recapSkipper };
|
||||
if (introSkipper.currentSegment) return { type: "Intro", ...introSkipper };
|
||||
if (previewSkipper.currentSegment)
|
||||
return { type: "Preview", ...previewSkipper };
|
||||
if (outroSkipper.currentSegment) return { type: "Outro", ...outroSkipper };
|
||||
return null;
|
||||
}, [
|
||||
commercialSkipper.currentSegment,
|
||||
recapSkipper.currentSegment,
|
||||
introSkipper.currentSegment,
|
||||
previewSkipper.currentSegment,
|
||||
outroSkipper.currentSegment,
|
||||
commercialSkipper,
|
||||
recapSkipper,
|
||||
introSkipper,
|
||||
previewSkipper,
|
||||
outroSkipper,
|
||||
]);
|
||||
|
||||
// Legacy compatibility: map to old variable names
|
||||
const showSkipButton = !!(
|
||||
activeSegment &&
|
||||
["Intro", "Recap", "Commercial", "Preview"].includes(activeSegment.type)
|
||||
);
|
||||
const skipIntro = activeSegment?.skipSegment || noop;
|
||||
const showSkipCreditButton = activeSegment?.type === "Outro";
|
||||
const skipCredit = outroSkipper.skipSegment;
|
||||
const hasContentAfterCredits =
|
||||
outroSkipper.currentSegment && maxSeconds
|
||||
? outroSkipper.currentSegment.endTime < maxSeconds
|
||||
: false;
|
||||
|
||||
// Get button text based on segment type using i18n
|
||||
const { t } = useTranslation();
|
||||
const skipButtonText = activeSegment
|
||||
? t(`player.skip_${activeSegment.type.toLowerCase()}`)
|
||||
: t("player.skip_intro");
|
||||
const skipCreditButtonText = t("player.skip_outro");
|
||||
|
||||
const goToItemCommon = useCallback(
|
||||
(item: BaseItemDto) => {
|
||||
@@ -571,7 +696,9 @@ export const Controls: FC<Props> = ({
|
||||
currentTime={currentTime}
|
||||
remainingTime={remainingTime}
|
||||
showSkipButton={showSkipButton}
|
||||
skipButtonText={skipButtonText}
|
||||
showSkipCreditButton={showSkipCreditButton}
|
||||
skipCreditButtonText={skipCreditButtonText}
|
||||
hasContentAfterCredits={hasContentAfterCredits}
|
||||
skipIntro={skipIntro}
|
||||
skipCredit={skipCredit}
|
||||
@@ -592,6 +719,9 @@ export const Controls: FC<Props> = ({
|
||||
trickPlayUrl={trickPlayUrl}
|
||||
trickplayInfo={trickplayInfo}
|
||||
time={isSliding || showRemoteBubble ? time : remoteTime}
|
||||
isPlayingIntro={isPlayingIntro}
|
||||
skipAllIntros={skipAllIntros}
|
||||
intros={intros}
|
||||
/>
|
||||
</Animated.View>
|
||||
</>
|
||||
|
||||
46
hooks/useIntroPlayback.ts
Normal file
46
hooks/useIntroPlayback.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import type { Api } from "@jellyfin/sdk";
|
||||
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { useEffect, useState } from "react";
|
||||
import { getIntros } from "@/utils/intros";
|
||||
|
||||
interface UseIntroPlaybackProps {
|
||||
api: Api | null;
|
||||
itemId: string | null;
|
||||
userId?: string;
|
||||
}
|
||||
|
||||
export function useIntroPlayback({
|
||||
api,
|
||||
itemId,
|
||||
userId,
|
||||
}: UseIntroPlaybackProps) {
|
||||
const [intros, setIntros] = useState<BaseItemDto[]>([]);
|
||||
const [isPlayingIntro, setIsPlayingIntro] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchIntros() {
|
||||
if (!api || !itemId) return;
|
||||
|
||||
const introItems = await getIntros(api, itemId, userId);
|
||||
setIntros(introItems);
|
||||
// Set isPlayingIntro to true when intros are available
|
||||
setIsPlayingIntro(introItems.length > 0);
|
||||
}
|
||||
|
||||
fetchIntros();
|
||||
}, [api, itemId, userId]);
|
||||
|
||||
// Only play the first intro if intros are available.. might be nice to configure this at some point with tags or something 🤷♂️
|
||||
const currentIntro = intros.length > 0 ? intros[0] : null;
|
||||
|
||||
const skipAllIntros = () => {
|
||||
setIsPlayingIntro(false);
|
||||
};
|
||||
|
||||
return {
|
||||
intros,
|
||||
currentIntro,
|
||||
isPlayingIntro,
|
||||
skipAllIntros,
|
||||
};
|
||||
}
|
||||
105
hooks/useSegmentSkipper.ts
Normal file
105
hooks/useSegmentSkipper.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
import { MediaTimeSegment } from "@/providers/Downloads/types";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
import { useHaptic } from "./useHaptic";
|
||||
|
||||
type SegmentType = "Intro" | "Outro" | "Recap" | "Commercial" | "Preview";
|
||||
|
||||
interface UseSegmentSkipperProps {
|
||||
segments: MediaTimeSegment[];
|
||||
segmentType: SegmentType;
|
||||
currentTime: number;
|
||||
totalDuration?: number;
|
||||
seek: (time: number) => void;
|
||||
isPaused: boolean;
|
||||
}
|
||||
|
||||
interface UseSegmentSkipperReturn {
|
||||
currentSegment: MediaTimeSegment | null;
|
||||
skipSegment: (notifyOrUseHaptics?: boolean) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic hook to handle all media segment types (intro, outro, recap, commercial, preview)
|
||||
* Supports three modes: 'none' (disabled), 'ask' (show button), 'auto' (auto-skip)
|
||||
*/
|
||||
export const useSegmentSkipper = ({
|
||||
segments,
|
||||
segmentType,
|
||||
currentTime,
|
||||
totalDuration,
|
||||
seek,
|
||||
isPaused,
|
||||
}: UseSegmentSkipperProps): UseSegmentSkipperReturn => {
|
||||
const { settings } = useSettings();
|
||||
const haptic = useHaptic();
|
||||
const autoSkipTriggeredRef = useRef(false);
|
||||
|
||||
// Get skip mode based on segment type
|
||||
const skipMode = (() => {
|
||||
switch (segmentType) {
|
||||
case "Intro":
|
||||
return settings.skipIntro;
|
||||
case "Outro":
|
||||
return settings.skipOutro;
|
||||
case "Recap":
|
||||
return settings.skipRecap;
|
||||
case "Commercial":
|
||||
return settings.skipCommercial;
|
||||
case "Preview":
|
||||
return settings.skipPreview;
|
||||
default:
|
||||
return "none";
|
||||
}
|
||||
})();
|
||||
|
||||
// Find current segment
|
||||
const currentSegment =
|
||||
segments.find(
|
||||
(segment) =>
|
||||
currentTime >= segment.startTime && currentTime < segment.endTime,
|
||||
) || null;
|
||||
|
||||
// Skip function with optional haptic feedback
|
||||
const skipSegment = useCallback(
|
||||
(notifyOrUseHaptics = true) => {
|
||||
if (!currentSegment) return;
|
||||
|
||||
// For Outro segments, prevent seeking past the end
|
||||
if (segmentType === "Outro" && totalDuration) {
|
||||
const seekTime = Math.min(currentSegment.endTime, totalDuration);
|
||||
seek(seekTime);
|
||||
} else {
|
||||
seek(currentSegment.endTime);
|
||||
}
|
||||
|
||||
// Only trigger haptic feedback if explicitly requested (manual skip)
|
||||
if (notifyOrUseHaptics) {
|
||||
haptic();
|
||||
}
|
||||
},
|
||||
[currentSegment, segmentType, totalDuration, seek, haptic],
|
||||
);
|
||||
// Auto-skip logic when mode is 'auto'
|
||||
useEffect(() => {
|
||||
if (skipMode !== "auto" || isPaused) {
|
||||
autoSkipTriggeredRef.current = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentSegment && !autoSkipTriggeredRef.current) {
|
||||
autoSkipTriggeredRef.current = true;
|
||||
skipSegment(false); // Don't trigger haptics for auto-skip
|
||||
}
|
||||
|
||||
if (!currentSegment) {
|
||||
autoSkipTriggeredRef.current = false;
|
||||
}
|
||||
}, [currentSegment, skipMode, isPaused, skipSegment]);
|
||||
|
||||
// Return null segment if skip mode is 'none'
|
||||
return {
|
||||
currentSegment: skipMode === "none" ? null : currentSegment,
|
||||
skipSegment,
|
||||
};
|
||||
};
|
||||
@@ -96,5 +96,24 @@ export function getDownloadedItemSize(id: string): number {
|
||||
*/
|
||||
export function calculateTotalDownloadedSize(): number {
|
||||
const items = getAllDownloadedItems();
|
||||
return items.reduce((sum, item) => sum + (item.videoFileSize || 0), 0);
|
||||
return items.reduce((sum, item) => {
|
||||
// Trickplay bytes count too — getDownloadedItemSize models per-item size
|
||||
// as video + trickplay, the total must match.
|
||||
const trickplaySize = item.trickPlayData?.size ?? 0;
|
||||
// Read the live file size on disk so the total reflects actual usage and
|
||||
// self-heals items whose stored videoFileSize is 0 (old schema, or
|
||||
// `fileInfo.size` was undefined at download time). Fall back to the stored
|
||||
// value if the file can't be stat'd.
|
||||
if (item.videoFilePath) {
|
||||
try {
|
||||
const file = new File(filePathToUri(item.videoFilePath));
|
||||
if (file.exists) {
|
||||
return sum + (file.size ?? item.videoFileSize ?? 0) + trickplaySize;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("Failed to stat downloaded file for size:", error);
|
||||
}
|
||||
}
|
||||
return sum + (item.videoFileSize ?? 0) + trickplaySize;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
@@ -289,7 +289,24 @@ export function useDownloadOperations({
|
||||
);
|
||||
|
||||
const appSizeUsage = useCallback(async () => {
|
||||
const totalSize = calculateTotalDownloadedSize();
|
||||
let totalSize = calculateTotalDownloadedSize();
|
||||
|
||||
// Also count in-progress downloads (they write straight to their final
|
||||
// path) so the growing file shows up as app usage instead of drifting
|
||||
// into the generic device share until completion.
|
||||
for (const process of processes) {
|
||||
try {
|
||||
const file = new File(
|
||||
Paths.document,
|
||||
`${generateFilename(process.item)}.mp4`,
|
||||
);
|
||||
if (file.exists) {
|
||||
totalSize += file.size ?? 0;
|
||||
}
|
||||
} catch {
|
||||
// File not created yet — ignore.
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const [freeDiskStorage, totalDiskCapacity] = await Promise.all([
|
||||
@@ -310,7 +327,7 @@ export function useDownloadOperations({
|
||||
appSize: totalSize,
|
||||
};
|
||||
}
|
||||
}, []);
|
||||
}, [processes]);
|
||||
|
||||
return {
|
||||
startBackgroundDownload,
|
||||
|
||||
@@ -32,12 +32,6 @@ export interface MediaTimeSegment {
|
||||
text: string;
|
||||
}
|
||||
|
||||
export interface Segment {
|
||||
startTime: number;
|
||||
endTime: number;
|
||||
text: string;
|
||||
}
|
||||
|
||||
/** Represents a single downloaded media item with all necessary metadata for offline playback. */
|
||||
export interface DownloadedItem {
|
||||
/** The Jellyfin item DTO. */
|
||||
@@ -56,6 +50,12 @@ export interface DownloadedItem {
|
||||
introSegments?: MediaTimeSegment[];
|
||||
/** The credit segments for the item. */
|
||||
creditSegments?: MediaTimeSegment[];
|
||||
/** The recap segments for the item. */
|
||||
recapSegments?: MediaTimeSegment[];
|
||||
/** The commercial segments for the item. */
|
||||
commercialSegments?: MediaTimeSegment[];
|
||||
/** The preview segments for the item. */
|
||||
previewSegments?: MediaTimeSegment[];
|
||||
/** The user data for the item. */
|
||||
userData: UserData;
|
||||
}
|
||||
@@ -144,6 +144,12 @@ export type JobStatus = {
|
||||
introSegments?: MediaTimeSegment[];
|
||||
/** Pre-downloaded credit segments (optional) - downloaded before video starts */
|
||||
creditSegments?: MediaTimeSegment[];
|
||||
/** Pre-downloaded recap segments (optional) - downloaded before video starts */
|
||||
recapSegments?: MediaTimeSegment[];
|
||||
/** Pre-downloaded commercial segments (optional) - downloaded before video starts */
|
||||
commercialSegments?: MediaTimeSegment[];
|
||||
/** Pre-downloaded preview segments (optional) - downloaded before video starts */
|
||||
previewSegments?: MediaTimeSegment[];
|
||||
/** The audio stream index selected for this download */
|
||||
audioStreamIndex?: number;
|
||||
/** The subtitle stream index selected for this download */
|
||||
|
||||
@@ -386,7 +386,7 @@ export const JellyfinProvider: React.FC<{ children: ReactNode }> = ({
|
||||
default:
|
||||
throw new Error(
|
||||
t(
|
||||
"login.an_unexpected_error_occured_did_you_enter_the_correct_url",
|
||||
"login.an_unexpected_error_occurred_did_you_enter_the_correct_url",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "حسنًا",
|
||||
"connection_failed": "فشل الاتصال",
|
||||
"could_not_connect_to_server": "تعذر الاتصال بالخادم. يرجى التحقق من الرابط واتصال الشبكة.",
|
||||
"an_unexpected_error_occured": "حدث خطأ غير متوقع",
|
||||
"an_unexpected_error_occurred": "حدث خطأ غير متوقع",
|
||||
"change_server": "تغيير الخادم",
|
||||
"invalid_username_or_password": "اسم المستخدم أو كلمة المرور غير صالحة",
|
||||
"user_does_not_have_permission_to_log_in": "ليس لدى المستخدم صَلاحِيَة تسجيل الدخول",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "يستغرق الخادم وقتًا طويلاً للرد، يرجى المحاولة مرة أخرى لاحقًا",
|
||||
"server_received_too_many_requests_try_again_later": "تلقى الخادم عددًا كبيرًا جدًا من الطلبات، يرجى المحاولة مرة أخرى لاحقًا.",
|
||||
"there_is_a_server_error": "هناك خطأ في الخادم",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "حدث خطأ غير متوقع. هل أدخلت رابط الخادم بشكل صحيح؟",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "حدث خطأ غير متوقع. هل أدخلت رابط الخادم بشكل صحيح؟",
|
||||
"too_old_server_text": "تم اكتشاف خادم Jellyfin غير مدعوم",
|
||||
"too_old_server_description": "يرجى تحديث Jellyfin إلى أحدث إصدار"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "تفويض الدخول السريع",
|
||||
"enter_the_quick_connect_code": "أدخل رمز الدخول السريع...",
|
||||
"success": "نجاح",
|
||||
"quick_connect_autorized": "تم تفويض الدخول السريع",
|
||||
"quick_connect_authorized": "تم تفويض الدخول السريع",
|
||||
"error": "خطأ",
|
||||
"invalid_code": "رمز غير صالح",
|
||||
"authorize": "تفويض"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "إظهار روابط القائمة المخصصة",
|
||||
"show_large_home_carousel": "إظهار شريط العرض الكبير (تجريبي)",
|
||||
"hide_libraries": "إخفاء المكتبات",
|
||||
"select_liraries_you_want_to_hide": "اختر المكتبات التي تريد إخفاءها من تبويب المكتبة وأقسام الصفحة الرئيسية.",
|
||||
"select_libraries_you_want_to_hide": "اختر المكتبات التي تريد إخفاءها من تبويب المكتبة وأقسام الصفحة الرئيسية.",
|
||||
"disable_haptic_feedback": "تعطيل ردود الفعل اللمسية",
|
||||
"default_quality": "الجودة الافتراضية",
|
||||
"default_playback_speed": "سرعة التشغيل الافتراضية",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "الجهاز {{availableSpace}}%",
|
||||
"size_used": "تم استخدام {{used}} من {{total}}",
|
||||
"delete_all_downloaded_files": "حذف جميع الملفات التي تم تنزيلها",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "التخزين المؤقت للموسيقى",
|
||||
"music_cache_description": "تخزين الأغاني تلقائياً أثناء الاستماع لضمان تشغيل أكثر سلاسة ودعم الاستماع بدون اتصال",
|
||||
"clear_music_cache": "مسح التخزين المؤقت للموسيقى",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "خطأ",
|
||||
"failed_to_get_stream_url": "فشل في الحصول على رابط البث",
|
||||
"an_error_occured_while_playing_the_video": "حدث خطأ أثناء تشغيل الفيديو. تحقق من السجلات في الإعدادات.",
|
||||
"an_error_occurred_while_playing_the_video": "حدث خطأ أثناء تشغيل الفيديو. تحقق من السجلات في الإعدادات.",
|
||||
"client_error": "خطأ في المشغّل",
|
||||
"could_not_create_stream_for_chromecast": "تعذر إنشاء بث لـChromecast",
|
||||
"message_from_server": "رسالة من الخادم: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Entesos",
|
||||
"connection_failed": "Ha fallat la connexió",
|
||||
"could_not_connect_to_server": "No s'ha pogut connectar amb el servidor. Comproveu l'URL i la connexió de xarxa.",
|
||||
"an_unexpected_error_occured": "S'ha produït un error inesperat",
|
||||
"an_unexpected_error_occurred": "S'ha produït un error inesperat",
|
||||
"change_server": "Canvia el servidor",
|
||||
"invalid_username_or_password": "Nom d'usuari o contrasenya incorrectes",
|
||||
"user_does_not_have_permission_to_log_in": "L'usuari no té permís per iniciar sessió",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "El servidor triga massa a respondre, torneu-ho a provar més tard",
|
||||
"server_received_too_many_requests_try_again_later": "El servidor ha rebut massa sol·licituds, torneu-ho a provar més tard.",
|
||||
"there_is_a_server_error": "Error del servidor",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "S'ha produït un error inesperat. Heu introduït correctament l'URL del servidor?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "S'ha produït un error inesperat. Heu introduït correctament l'URL del servidor?",
|
||||
"too_old_server_text": "Unsupported Jellyfin Server Discovered",
|
||||
"too_old_server_description": "Please update Jellyfin to the latest version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autoritza connexió ràpida",
|
||||
"enter_the_quick_connect_code": "Introdueix el codi de connexió ràpida...",
|
||||
"success": "Èxit",
|
||||
"quick_connect_autorized": "Connexió ràpida autoritzada",
|
||||
"quick_connect_authorized": "Connexió ràpida autoritzada",
|
||||
"error": "Error",
|
||||
"invalid_code": "Codi invàlid",
|
||||
"authorize": "Autoritza"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Mostrar enllaços del menú personalitzats",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Oculta biblioteques",
|
||||
"select_liraries_you_want_to_hide": "Seleccioneu les biblioteques que voleu ocultar de la pestanya Biblioteca i de les seccions de la pàgina d'inici.",
|
||||
"select_libraries_you_want_to_hide": "Seleccioneu les biblioteques que voleu ocultar de la pestanya Biblioteca i de les seccions de la pàgina d'inici.",
|
||||
"disable_haptic_feedback": "Desactiva la resposta hàptica",
|
||||
"default_quality": "Qualitat per defecte",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Dispositiu {{availableSpace}}%",
|
||||
"size_used": "{{used}} de {{total}} utilitzat",
|
||||
"delete_all_downloaded_files": "Suprimeix tots els fitxers descarregats",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Error",
|
||||
"failed_to_get_stream_url": "No s'ha pogut obtenir l'URL del flux",
|
||||
"an_error_occured_while_playing_the_video": "S'ha produït un error en reproduir el vídeo. Consulteu els registres a la configuració.",
|
||||
"an_error_occurred_while_playing_the_video": "S'ha produït un error en reproduir el vídeo. Consulteu els registres a la configuració.",
|
||||
"client_error": "Error del client",
|
||||
"could_not_create_stream_for_chromecast": "No s'ha pogut crear un flux per a Chromecast",
|
||||
"message_from_server": "Missatge del servidor: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Rozumím",
|
||||
"connection_failed": "Připojení se nezdařilo",
|
||||
"could_not_connect_to_server": "Nelze se připojit k serveru. Zkontrolujte adresu URL a síťové připojení.",
|
||||
"an_unexpected_error_occured": "Došlo k neočekávané chybě",
|
||||
"an_unexpected_error_occurred": "Došlo k neočekávané chybě",
|
||||
"change_server": "Změnit server",
|
||||
"invalid_username_or_password": "Neplatné uživatelské jméno nebo heslo",
|
||||
"user_does_not_have_permission_to_log_in": "Uživatel nemá oprávnění k přihlášení",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Reakce na server trvá příliš dlouho, zkuste to znovu později",
|
||||
"server_received_too_many_requests_try_again_later": "Server obdržel příliš mnoho požadavků, opakujte akci později.",
|
||||
"there_is_a_server_error": "Došlo k chybě serveru",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Došlo k neočekávané chybě. Vložili jste adresu URL serveru?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Došlo k neočekávané chybě. Vložili jste adresu URL serveru?",
|
||||
"too_old_server_text": "Objeven nepodporovaný Jellyfin server",
|
||||
"too_old_server_description": "Prosím aktualizujte Jellyfin na nejnovější verzi"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autorizovat rychlé připojení",
|
||||
"enter_the_quick_connect_code": "Zadejte kód rychlého připojení...",
|
||||
"success": "Úspěšně",
|
||||
"quick_connect_autorized": "Oprávněné Rychlé připojení",
|
||||
"quick_connect_authorized": "Oprávněné Rychlé připojení",
|
||||
"error": "Chyba",
|
||||
"invalid_code": "Neplatný kód",
|
||||
"authorize": "Autorizovat"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Zobrazit vlastní Menu odkazy",
|
||||
"show_large_home_carousel": "Zobrazit velký přehled (beta)",
|
||||
"hide_libraries": "Skrýt knihovny",
|
||||
"select_liraries_you_want_to_hide": "Vyberte knihovny, které chcete skrýt v záložce Knihovna a v sekcích domovské stránky.",
|
||||
"select_libraries_you_want_to_hide": "Vyberte knihovny, které chcete skrýt v záložce Knihovna a v sekcích domovské stránky.",
|
||||
"disable_haptic_feedback": "Zakázat Haptickou zpětnou vazbu",
|
||||
"default_quality": "Výchozí kvalita",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Zařízení {{availableSpace}}%",
|
||||
"size_used": "{{used}} z {{total}} využito",
|
||||
"delete_all_downloaded_files": "Odstranit všechny stažené soubory",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Chyba",
|
||||
"failed_to_get_stream_url": "Nepodařilo se získat URL streamu",
|
||||
"an_error_occured_while_playing_the_video": "Při přehrávání videa došlo k chybě. Zkontrolujte logy v nastavení.",
|
||||
"an_error_occurred_while_playing_the_video": "Při přehrávání videa došlo k chybě. Zkontrolujte logy v nastavení.",
|
||||
"client_error": "Chyba klienta",
|
||||
"could_not_create_stream_for_chromecast": "Nelze vytvořit stream pro Chromecast",
|
||||
"message_from_server": "Zpráva od serveru: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Forstået",
|
||||
"connection_failed": "Forbindelsen mislykkedes",
|
||||
"could_not_connect_to_server": "Kunne ikke oprette forbindelse til serveren. Tjek venligst URL'en og din netværksforbindelse.",
|
||||
"an_unexpected_error_occured": "Der opstod en uventet fejl",
|
||||
"an_unexpected_error_occurred": "Der opstod en uventet fejl",
|
||||
"change_server": "Skift server",
|
||||
"invalid_username_or_password": "Ugyldigt brugernavn eller adgangskode",
|
||||
"user_does_not_have_permission_to_log_in": "Brugeren har ikke tilladelse til at logge ind",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Serveren svarer for langsomt, prøv igen senere",
|
||||
"server_received_too_many_requests_try_again_later": "Serveren modtog for mange forespørgsler, prøv igen senere.",
|
||||
"there_is_a_server_error": "Der er en serverfejl",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Der opstod en uventet fejl. Har du indtastet serverens URL korrekt?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Der opstod en uventet fejl. Har du indtastet serverens URL korrekt?",
|
||||
"too_old_server_text": "Ikke Understøttet Jellyfin Server Opdaget",
|
||||
"too_old_server_description": "Opdater venligst Jellyfin til den seneste version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autoriser Hurtigforbindelse",
|
||||
"enter_the_quick_connect_code": "Indtast koden til hurtigforbindelse...",
|
||||
"success": "Succes",
|
||||
"quick_connect_autorized": "Hurtigforbindelse autoriseret",
|
||||
"quick_connect_authorized": "Hurtigforbindelse autoriseret",
|
||||
"error": "Fejl",
|
||||
"invalid_code": "Ugyldig kode",
|
||||
"authorize": "Autoriser"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Vis tilpassede menulinks",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Skjul biblioteker",
|
||||
"select_liraries_you_want_to_hide": "Vælg de biblioteker, du ønsker at skjule fra fanen Bibliotek og startside sektionerne.",
|
||||
"select_libraries_you_want_to_hide": "Vælg de biblioteker, du ønsker at skjule fra fanen Bibliotek og startside sektionerne.",
|
||||
"disable_haptic_feedback": "Deaktiver haptisk feedback",
|
||||
"default_quality": "Standard kvalitet",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Enhedsforbrug: {{availableSpace}}%",
|
||||
"size_used": "{{used}} af {{total}} brugt",
|
||||
"delete_all_downloaded_files": "Slet alle downloadede filer",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Fejl",
|
||||
"failed_to_get_stream_url": "Kunne ikke hente stream URL'en",
|
||||
"an_error_occured_while_playing_the_video": "Der opstod en fejl under afspilning af videoen. Tjek logfilerne i indstillinger.",
|
||||
"an_error_occurred_while_playing_the_video": "Der opstod en fejl under afspilning af videoen. Tjek logfilerne i indstillinger.",
|
||||
"client_error": "Klientfejl",
|
||||
"could_not_create_stream_for_chromecast": "Kunne ikke oprette en stream til Chromecast",
|
||||
"message_from_server": "Besked fra server: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Verstanden",
|
||||
"connection_failed": "Verbindung fehlgeschlagen",
|
||||
"could_not_connect_to_server": "Verbindung zum Server fehlgeschlagen. Bitte überprüf die URL und deine Netzwerkverbindung.",
|
||||
"an_unexpected_error_occured": "Ein unerwarteter Fehler ist aufgetreten",
|
||||
"an_unexpected_error_occurred": "Ein unerwarteter Fehler ist aufgetreten",
|
||||
"change_server": "Server wechseln",
|
||||
"invalid_username_or_password": "Ungültiger Benutzername oder Passwort",
|
||||
"user_does_not_have_permission_to_log_in": "Benutzer hat keine Berechtigung, um sich anzumelden",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Der Server benötigt zu lange, um zu antworten. Bitte versuch es später erneut",
|
||||
"server_received_too_many_requests_try_again_later": "Der Server hat zu viele Anfragen erhalten. Bitte versuch es später erneut.",
|
||||
"there_is_a_server_error": "Es gibt einen Serverfehler",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Ein unerwarteter Fehler ist aufgetreten. Hast du die Server-URL korrekt eingegeben?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Ein unerwarteter Fehler ist aufgetreten. Hast du die Server-URL korrekt eingegeben?",
|
||||
"too_old_server_text": "Nicht unterstützter Jellyfin Server entdeckt",
|
||||
"too_old_server_description": "Bitte aktualisiere Jellyfin auf die neueste Version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Quick Connect autorisieren",
|
||||
"enter_the_quick_connect_code": "Quick Connect-Code eingeben...",
|
||||
"success": "Erfolgreich verbunden",
|
||||
"quick_connect_autorized": "Quick Connect autorisiert",
|
||||
"quick_connect_authorized": "Quick Connect autorisiert",
|
||||
"error": "Fehler",
|
||||
"invalid_code": "Ungültiger Code",
|
||||
"authorize": "Autorisieren"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Benutzerdefinierte Menülinks anzeigen",
|
||||
"show_large_home_carousel": "Zeige große Startseiten-Übersicht (Beta)",
|
||||
"hide_libraries": "Bibliotheken ausblenden",
|
||||
"select_liraries_you_want_to_hide": "Bibliotheken auswählen die aus dem Bibliothekstab und der Startseite ausgeblendet werden sollen.",
|
||||
"select_libraries_you_want_to_hide": "Bibliotheken auswählen die aus dem Bibliothekstab und der Startseite ausgeblendet werden sollen.",
|
||||
"disable_haptic_feedback": "Haptisches Feedback deaktivieren",
|
||||
"default_quality": "Standardqualität",
|
||||
"default_playback_speed": "Standard-Wiedergabegeschwindigkeit",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Gerät {{availableSpace}}%",
|
||||
"size_used": "{{used}} von {{total}} genutzt",
|
||||
"delete_all_downloaded_files": "Alle heruntergeladenen Dateien löschen",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Musik-Cache",
|
||||
"music_cache_description": "Beim Anhören Titel automatisch in den Cache laden um bessere Wiedergabe und Offline-Wiedergabe zu ermöglichen",
|
||||
"clear_music_cache": "Musik-Cache leeren",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Fehler",
|
||||
"failed_to_get_stream_url": "Fehler beim Abrufen der Stream-URL",
|
||||
"an_error_occured_while_playing_the_video": "Ein Fehler ist beim Abspielen des Videos aufgetreten. Logs in den Einstellungen überprüfen.",
|
||||
"an_error_occurred_while_playing_the_video": "Ein Fehler ist beim Abspielen des Videos aufgetreten. Logs in den Einstellungen überprüfen.",
|
||||
"client_error": "Client-Fehler",
|
||||
"could_not_create_stream_for_chromecast": "Konnte keinen Stream für Chromecast erstellen",
|
||||
"message_from_server": "Nachricht vom Server: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Το Κατάλαβα",
|
||||
"connection_failed": "Η Σύνδεση Απέτυχε",
|
||||
"could_not_connect_to_server": "Δεν ήταν δυνατή η σύνδεση με τον διακομιστή. Παρακαλώ ελέγξτε τη διεύθυνση URL και τη σύνδεση δικτύου σας.",
|
||||
"an_unexpected_error_occured": "Παρουσιάστηκε Απροσδόκητο Σφάλμα",
|
||||
"an_unexpected_error_occurred": "Παρουσιάστηκε Απροσδόκητο Σφάλμα",
|
||||
"change_server": "Αλλαγή Διακομιστή",
|
||||
"invalid_username_or_password": "Μη έγκυρο όνομα χρήστη ή κωδικός πρόσβασης",
|
||||
"user_does_not_have_permission_to_log_in": "Ο χρήστης δεν έχει άδεια να συνδεθεί",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Ο διακομιστής καθυστερεί πάρα πολύ για να απαντήσει, δοκιμάστε ξανά αργότερα",
|
||||
"server_received_too_many_requests_try_again_later": "Ο διακομιστής έλαβε πάρα πολλά αιτήματα, δοκιμάστε ξανά αργότερα.",
|
||||
"there_is_a_server_error": "Υπάρχει ένα σφάλμα διακομιστή",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Παρουσιάστηκε μη αναμενόμενο σφάλμα. Εισαγάγετε σωστά το URL του διακομιστή?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Παρουσιάστηκε μη αναμενόμενο σφάλμα. Εισαγάγετε σωστά το URL του διακομιστή?",
|
||||
"too_old_server_text": "Ανακαλύφθηκε Μη Υποστηριζόμενος Εξυπηρετητής Jellyfin",
|
||||
"too_old_server_description": "Παρακαλούμε ενημερώστε το Jellyfin στην τελευταία έκδοση"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Εξουσιοδότηση Γρήγορης Σύνδεσης",
|
||||
"enter_the_quick_connect_code": "Εισάγετε τον κωδικό γρήγορης σύνδεσης...",
|
||||
"success": "Επιτυχία",
|
||||
"quick_connect_autorized": "Γρήγορη Σύνδεση Εξουσιοδοτήθηκε",
|
||||
"quick_connect_authorized": "Γρήγορη Σύνδεση Εξουσιοδοτήθηκε",
|
||||
"error": "Σφάλμα",
|
||||
"invalid_code": "Μη Έγκυρος Κωδικός",
|
||||
"authorize": "Εξουσιοδότηση"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Εμφάνιση Προσαρμοσμένων Συνδέσμων Μενού",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Απόκρυψη Βιβλιοθηκών",
|
||||
"select_liraries_you_want_to_hide": "Επιλέξτε τις βιβλιοθήκες που θέλετε να αποκρύψετε από την καρτέλα της Βιβλιοθήκης και τις ενότητες της αρχικής σελίδας.",
|
||||
"select_libraries_you_want_to_hide": "Επιλέξτε τις βιβλιοθήκες που θέλετε να αποκρύψετε από την καρτέλα της Βιβλιοθήκης και τις ενότητες της αρχικής σελίδας.",
|
||||
"disable_haptic_feedback": "Απενεργοποίηση Απτικής Ανατροφοδότησης",
|
||||
"default_quality": "Προεπιλεγμένη Ποιότητα",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Device {{availableSpace}}%",
|
||||
"size_used": "{{used}} {{total}} Χρησιμοποιείται",
|
||||
"delete_all_downloaded_files": "Διαγραφή Όλων Των Ληφθέντων Αρχείων",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Σφάλμα",
|
||||
"failed_to_get_stream_url": "Αποτυχία λήψης του URL ροής",
|
||||
"an_error_occured_while_playing_the_video": "Παρουσιάστηκε σφάλμα κατά την αναπαραγωγή του βίντεο. Ελέγξτε τα αρχεία καταγραφής στις ρυθμίσεις.",
|
||||
"an_error_occurred_while_playing_the_video": "Παρουσιάστηκε σφάλμα κατά την αναπαραγωγή του βίντεο. Ελέγξτε τα αρχεία καταγραφής στις ρυθμίσεις.",
|
||||
"client_error": "Σφάλμα Πελάτη",
|
||||
"could_not_create_stream_for_chromecast": "Αδυναμία δημιουργίας ροής για το Chromecast",
|
||||
"message_from_server": "Μήνυμα από το διακομιστή: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Got it",
|
||||
"connection_failed": "Connection failed",
|
||||
"could_not_connect_to_server": "Could not connect to the server. Please check the URL and your network connection.",
|
||||
"an_unexpected_error_occured": "An unexpected error occurred",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Change server",
|
||||
"invalid_username_or_password": "Invalid username or password",
|
||||
"user_does_not_have_permission_to_log_in": "User does not have permission to log in",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Server is taking too long to respond, try again later",
|
||||
"server_received_too_many_requests_try_again_later": "Server received too many requests, try again later.",
|
||||
"there_is_a_server_error": "There is a server error",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Unsupported Jellyfin server discovered",
|
||||
"too_old_server_description": "Please update Jellyfin to the latest version"
|
||||
},
|
||||
@@ -118,7 +118,6 @@
|
||||
},
|
||||
"settings": {
|
||||
"settings_title": "Settings",
|
||||
"disabled_by_admin": "Disabled by admin",
|
||||
"log_out_button": "Log out",
|
||||
"switch_user": {
|
||||
"title": "Switch user",
|
||||
@@ -189,7 +188,7 @@
|
||||
"authorize_button": "Authorize Quick Connect",
|
||||
"enter_the_quick_connect_code": "Enter the Quick Connect code...",
|
||||
"success": "Success",
|
||||
"quick_connect_autorized": "Quick Connect authorized",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Error",
|
||||
"invalid_code": "Invalid code",
|
||||
"authorize": "Authorize"
|
||||
@@ -296,15 +295,31 @@
|
||||
"UNKNOWN": "Unknown"
|
||||
},
|
||||
"safe_area_in_controls": "Safe area in controls",
|
||||
"video_player": "Video Player",
|
||||
"show_custom_menu_links": "Show custom menu links",
|
||||
"show_large_home_carousel": "Show large home carousel (beta)",
|
||||
"hide_libraries": "Hide libraries",
|
||||
"select_liraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Disable haptic feedback",
|
||||
"default_quality": "Default quality",
|
||||
"default_playback_speed": "Default playback speed",
|
||||
"auto_play_next_episode": "Auto-play next episode",
|
||||
"max_auto_play_episode_count": "Max auto-play episode count",
|
||||
"segment_skip_settings": "Segment Skip Settings",
|
||||
"segment_skip_settings_description": "Configure skip behavior for intros, credits, and other segments",
|
||||
"skip_intro": "Skip Intro",
|
||||
"skip_intro_description": "Action when intro segment is detected",
|
||||
"skip_outro": "Skip Outro/Credits",
|
||||
"skip_outro_description": "Action when outro/credits segment is detected",
|
||||
"skip_recap": "Skip Recap",
|
||||
"skip_recap_description": "Action when recap segment is detected",
|
||||
"skip_commercial": "Skip Commercial",
|
||||
"skip_commercial_description": "Action when commercial segment is detected",
|
||||
"skip_preview": "Skip Preview",
|
||||
"skip_preview_description": "Action when preview segment is detected",
|
||||
"segment_skip_none": "None",
|
||||
"segment_skip_ask": "Show Skip Button",
|
||||
"segment_skip_auto": "Auto Skip",
|
||||
"disabled": "Disabled"
|
||||
},
|
||||
"music": {
|
||||
@@ -371,7 +386,6 @@
|
||||
"toasts": {
|
||||
"saved": "Saved",
|
||||
"refreshed": "Settings refreshed from server",
|
||||
"refresh_failed": "Couldn't refresh settings from server",
|
||||
"disabled": "Streamystats disabled"
|
||||
},
|
||||
"refresh_from_server": "Refresh settings from server"
|
||||
@@ -386,6 +400,8 @@
|
||||
"device_usage": "Device {{availableSpace}}%",
|
||||
"size_used": "{{used}} of {{total}} used",
|
||||
"delete_all_downloaded_files": "Delete all downloaded files",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear music cache",
|
||||
@@ -600,7 +616,7 @@
|
||||
"mpv_player_title": "MPV player",
|
||||
"error": "Error",
|
||||
"failed_to_get_stream_url": "Failed to get the stream URL",
|
||||
"an_error_occured_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Client error",
|
||||
"could_not_create_stream_for_chromecast": "Could not create a stream for Chromecast",
|
||||
"message_from_server": "Message from server: {{message}}",
|
||||
@@ -628,6 +644,10 @@
|
||||
"add_opensubtitles_key_hint": "Add OpenSubtitles API key in settings for client-side fallback",
|
||||
"settings": "Settings",
|
||||
"skip_intro": "Skip intro",
|
||||
"skip_outro": "Skip outro",
|
||||
"skip_recap": "Skip recap",
|
||||
"skip_commercial": "Skip commercial",
|
||||
"skip_preview": "Skip preview",
|
||||
"skip_credits": "Skip credits",
|
||||
"stopPlayback": "Stop playback",
|
||||
"stopPlayingTitle": "Stop playing \"{{title}}\"?",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Entendido",
|
||||
"connection_failed": "Conexión fallida",
|
||||
"could_not_connect_to_server": "No se pudo conectar al servidor. Por favor comprueba la URL y tu conexión de red.",
|
||||
"an_unexpected_error_occured": "Ha ocurrido un error inesperado",
|
||||
"an_unexpected_error_occurred": "Ha ocurrido un error inesperado",
|
||||
"change_server": "Cambiar servidor",
|
||||
"invalid_username_or_password": "Usuario o contraseña inválidos",
|
||||
"user_does_not_have_permission_to_log_in": "El usuario no tiene permiso para iniciar sesión",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "El servidor está tardando mucho en responder, inténtalo de nuevo más tarde.",
|
||||
"server_received_too_many_requests_try_again_later": "El servidor está recibiendo muchas peticiones, inténtalo de nuevo más tarde.",
|
||||
"there_is_a_server_error": "Hay un error en el servidor",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Ha ocurrido un error inesperado. ¿Has introducido la URL correcta?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Ha ocurrido un error inesperado. ¿Has introducido la URL correcta?",
|
||||
"too_old_server_text": "Servidor Jellyfin no soportado descubierto",
|
||||
"too_old_server_description": "Por favor, actualiza Jellyfin a la última versión"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autorizar conexión rápida",
|
||||
"enter_the_quick_connect_code": "Introduce el código de conexión rápida...",
|
||||
"success": "Hecho",
|
||||
"quick_connect_autorized": "Conexión rápida autorizada",
|
||||
"quick_connect_authorized": "Conexión rápida autorizada",
|
||||
"error": "Error",
|
||||
"invalid_code": "Código inválido",
|
||||
"authorize": "Autorizar"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Mostrar enlaces de menú personalizados",
|
||||
"show_large_home_carousel": "Mostrar carrusel del menú principal grande (beta)",
|
||||
"hide_libraries": "Ocultar bibliotecas",
|
||||
"select_liraries_you_want_to_hide": "Selecciona las bibliotecas que quieres ocultar de la pestaña Bibliotecas y de Inicio.",
|
||||
"select_libraries_you_want_to_hide": "Selecciona las bibliotecas que quieres ocultar de la pestaña Bibliotecas y de Inicio.",
|
||||
"disable_haptic_feedback": "Desactivar feedback háptico",
|
||||
"default_quality": "Calidad por defecto",
|
||||
"default_playback_speed": "Velocidad de reproducción predeterminada",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Dispositivo {{availableSpace}}%",
|
||||
"size_used": "{{used}} de {{total}} usado",
|
||||
"delete_all_downloaded_files": "Eliminar todos los archivos descargados",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Caché de música",
|
||||
"music_cache_description": "Cachear automáticamente las canciones mientras escuchas una reproducción más suave y soporte sin conexión",
|
||||
"clear_music_cache": "Borrar Caché de Música",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Error",
|
||||
"failed_to_get_stream_url": "Error al obtener la URL del Steam",
|
||||
"an_error_occured_while_playing_the_video": "Ha ocurrido un error al reproducir el vídeo. Comprueba los registros en la configuración.",
|
||||
"an_error_occurred_while_playing_the_video": "Ha ocurrido un error al reproducir el vídeo. Comprueba los registros en la configuración.",
|
||||
"client_error": "Error del cliente",
|
||||
"could_not_create_stream_for_chromecast": "No se pudo crear el Steam para Chromecast",
|
||||
"message_from_server": "Mensaje del servidor: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Okei",
|
||||
"connection_failed": "Yhteys epäonnistui",
|
||||
"could_not_connect_to_server": "Yhteyttä palvelimeen ei voitu muodostaa. Tarkista URL-osoite ja verkkoyhteytesi.",
|
||||
"an_unexpected_error_occured": "Odottamaton virhe tapahtui",
|
||||
"an_unexpected_error_occurred": "Odottamaton virhe tapahtui",
|
||||
"change_server": "Vaihda palvelinta",
|
||||
"invalid_username_or_password": "Virheellinen käyttäjätunnus tai salasana",
|
||||
"user_does_not_have_permission_to_log_in": "Käyttäjällä ei ole oikeuksia kirjautua sisään",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Palvelin reagoi liian hitaasti, yritä myöhemmin uudelleen",
|
||||
"server_received_too_many_requests_try_again_later": "Palvelin sai liian monta pyyntöä, yritä myöhemmin uudelleen.",
|
||||
"there_is_a_server_error": "Palvelimessa on virhe",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Odottamaton virhe tapahtui. Syötitkö palvelimen URL-osoitteen oikein?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Odottamaton virhe tapahtui. Syötitkö palvelimen URL-osoitteen oikein?",
|
||||
"too_old_server_text": "Ei-tuettu Jellyfin-palvelin löydetty",
|
||||
"too_old_server_description": "Ole hyvä ja päivitä Jellyfin uusimpaan versioon"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Valtuuta pikayhdistys",
|
||||
"enter_the_quick_connect_code": "Syötä nopean yhteyden koodi...",
|
||||
"success": "Onnistui",
|
||||
"quick_connect_autorized": "Pikayhdistys valtuutettu",
|
||||
"quick_connect_authorized": "Pikayhdistys valtuutettu",
|
||||
"error": "Virhe",
|
||||
"invalid_code": "Virheellinen koodi",
|
||||
"authorize": "Valtuuta"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Näytä mukautetut valikkolinkit",
|
||||
"show_large_home_carousel": "Näytä suuri kotikaruselli (beta)",
|
||||
"hide_libraries": "Piilota kirjastot",
|
||||
"select_liraries_you_want_to_hide": "Valitse kirjastot, jotka haluat piilottaa Kirjasto-välilehdeltä ja etusivun osioista.",
|
||||
"select_libraries_you_want_to_hide": "Valitse kirjastot, jotka haluat piilottaa Kirjasto-välilehdeltä ja etusivun osioista.",
|
||||
"disable_haptic_feedback": "Poista haptinen palautteet käytöstä",
|
||||
"default_quality": "Oletuslaatu",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Laitteen käyttö {{availableSpace}}%",
|
||||
"size_used": "{{used}} / {{total}} käytössä",
|
||||
"delete_all_downloaded_files": "Poista kaikki ladatut tiedostot",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Virhe",
|
||||
"failed_to_get_stream_url": "Lähetyksen URL-osoitteen haku epäonnistui",
|
||||
"an_error_occured_while_playing_the_video": "Videon toiston yhteydessä tapahtui virhe. Tarkista lokit asetuksista.",
|
||||
"an_error_occurred_while_playing_the_video": "Videon toiston yhteydessä tapahtui virhe. Tarkista lokit asetuksista.",
|
||||
"client_error": "Asiakkaan Virhe",
|
||||
"could_not_create_stream_for_chromecast": "Suoratoistoa ei voitu luoda Chromecastia varten",
|
||||
"message_from_server": "Viesti palvelimelta: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "D'accord",
|
||||
"connection_failed": "La connexion a échoué",
|
||||
"could_not_connect_to_server": "Impossible de se connecter au serveur. Veuillez vérifier l’URL et votre connexion réseau.",
|
||||
"an_unexpected_error_occured": "Une erreur inattendue s'est produite",
|
||||
"an_unexpected_error_occurred": "Une erreur inattendue s'est produite",
|
||||
"change_server": "Changer de serveur",
|
||||
"invalid_username_or_password": "Nom d'utilisateur ou mot de passe invalide",
|
||||
"user_does_not_have_permission_to_log_in": "L'utilisateur n'a pas la permission de se connecter",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Le serveur prend trop de temps à répondre, réessayez plus tard",
|
||||
"server_received_too_many_requests_try_again_later": "Le serveur a reçu trop de demandes, réessayez plus tard.",
|
||||
"there_is_a_server_error": "Il y a une erreur de serveur",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Une erreur inattendue s’est produite. Avez-vous correctement saisi l’URL du serveur ?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Une erreur inattendue s’est produite. Avez-vous correctement saisi l’URL du serveur ?",
|
||||
"too_old_server_text": "Serveur Jellyfin non pris en charge découvert",
|
||||
"too_old_server_description": "Veuillez mettre à jour Jellyfin vers la dernière version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autoriser une connexion rapide",
|
||||
"enter_the_quick_connect_code": "Entrez le code de connexion rapide...",
|
||||
"success": "Succès",
|
||||
"quick_connect_autorized": "Connexion rapide autorisée",
|
||||
"quick_connect_authorized": "Connexion rapide autorisée",
|
||||
"error": "Erreur",
|
||||
"invalid_code": "Code invalide",
|
||||
"authorize": "Autoriser"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Afficher les liens personnalisés",
|
||||
"show_large_home_carousel": "Afficher le grand carrousel d’accueil (bêta)",
|
||||
"hide_libraries": "Masquer les bibliothèques",
|
||||
"select_liraries_you_want_to_hide": "Sélectionnez les bibliothèques que vous souhaitez masquer dans l'onglet Bibliothèque et les sections de la page d'accueil.",
|
||||
"select_libraries_you_want_to_hide": "Sélectionnez les bibliothèques que vous souhaitez masquer dans l'onglet Bibliothèque et les sections de la page d'accueil.",
|
||||
"disable_haptic_feedback": "Désactiver le retour haptique",
|
||||
"default_quality": "Qualité par défaut",
|
||||
"default_playback_speed": "Vitesse de lecture par défaut",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Appareil {{availableSpace}}%",
|
||||
"size_used": "{{used}} de {{total}} utilisés",
|
||||
"delete_all_downloaded_files": "Supprimer tous les fichiers téléchargés",
|
||||
"delete_all_downloaded_files_confirm": "Supprimer tous les fichiers téléchargés ?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Êtes-vous sûr de vouloir supprimer tous les fichiers téléchargés ? Cette action est irréversible.",
|
||||
"music_cache_title": "Mise en cache de la musique",
|
||||
"music_cache_description": "Mettez automatiquement en cache les chansons au fur et à mesure que vous écoutez pour une lecture plus fluide et une prise en charge hors ligne",
|
||||
"clear_music_cache": "Vider le cache de la musique",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "Lecteur MPV",
|
||||
"error": "Erreur",
|
||||
"failed_to_get_stream_url": "Échec de l'obtention de l'URL du flux",
|
||||
"an_error_occured_while_playing_the_video": "Une erreur s’est produite lors de la lecture de la vidéo. Vérifiez les journaux dans les paramètres.",
|
||||
"an_error_occurred_while_playing_the_video": "Une erreur s’est produite lors de la lecture de la vidéo. Vérifiez les journaux dans les paramètres.",
|
||||
"client_error": "Erreur du client",
|
||||
"could_not_create_stream_for_chromecast": "Impossible de créer un flux sur la Chromecast",
|
||||
"message_from_server": "Message du serveur : {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "קיבלתי",
|
||||
"connection_failed": "ההתחברות נכשלה",
|
||||
"could_not_connect_to_server": "לא היה ניתן להתחבר לשרת. אנא בדוק את הקישור ואת חיבור הרשת שלך.",
|
||||
"an_unexpected_error_occured": "קרתה שגיאה לא צפויה",
|
||||
"an_unexpected_error_occurred": "קרתה שגיאה לא צפויה",
|
||||
"change_server": "החלף שרת",
|
||||
"invalid_username_or_password": "שם משתמש או סיסמה שגויים",
|
||||
"user_does_not_have_permission_to_log_in": "לחשבון זה אין גישה להתחבר",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "השרת לוקח יותר מדי זמן כדי להגיב, נסה שוב מאוחר יותר",
|
||||
"server_received_too_many_requests_try_again_later": "השרת קיבל יותר מדי קריאות, נסה שוב מאוחר יותר",
|
||||
"there_is_a_server_error": "קרתה שגיאה בצד השרת",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "קרתה שגיאה לא צפויה. האם כתובת השרת שהוקלדה נכונה?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "קרתה שגיאה לא צפויה. האם כתובת השרת שהוקלדה נכונה?",
|
||||
"too_old_server_text": "נמצא שרת Jellyfin שלא נתמך",
|
||||
"too_old_server_description": "אנא עדכן את גרסת ה-Jellyfin למעודכנת ביותר"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "אשר התחברות מהירה",
|
||||
"enter_the_quick_connect_code": "הקלד את קוד ההתחברות המהירה...",
|
||||
"success": "הצלחה",
|
||||
"quick_connect_autorized": "חיבור מהיר אושר",
|
||||
"quick_connect_authorized": "חיבור מהיר אושר",
|
||||
"error": "שגיאה",
|
||||
"invalid_code": "קוד שגוי",
|
||||
"authorize": "אשר"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "הצג קישורים לתפריטים מותאמים אישית",
|
||||
"show_large_home_carousel": "הצג קרוסלה גדולה במסך הבית (בטא)",
|
||||
"hide_libraries": "הסתר ספריות",
|
||||
"select_liraries_you_want_to_hide": "בחר את הספריות שתרצה להסתיר ממסך הספריות וגם ממסך הבית.",
|
||||
"select_libraries_you_want_to_hide": "בחר את הספריות שתרצה להסתיר ממסך הספריות וגם ממסך הבית.",
|
||||
"disable_haptic_feedback": "בטל משוב רטט",
|
||||
"default_quality": "איכות ברירת מחדל",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "מכשיר {{availableSpace}}%",
|
||||
"size_used": "השתמשת ב-{{used}} מתוך {{total}}",
|
||||
"delete_all_downloaded_files": "מחק את כל הקבצים שהורדו",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "שגיאה",
|
||||
"failed_to_get_stream_url": "נכשל בהשגת קישור הזרם",
|
||||
"an_error_occured_while_playing_the_video": "קרתה תקלה במהלך הניגון של הקובץ. בדוק את הלוגים בהגדרות.",
|
||||
"an_error_occurred_while_playing_the_video": "קרתה תקלה במהלך הניגון של הקובץ. בדוק את הלוגים בהגדרות.",
|
||||
"client_error": "שגיאת לקוח",
|
||||
"could_not_create_stream_for_chromecast": "נכשל ביצירת זרם עבור Chromecast",
|
||||
"message_from_server": "הודעה מהשרת: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Értettem",
|
||||
"connection_failed": "Kapcsolódás Sikertelen",
|
||||
"could_not_connect_to_server": "Nem sikerült csatlakozni a szerverhez. Kérjük, ellenőrizd az URL-t és a hálózati kapcsolatot.",
|
||||
"an_unexpected_error_occured": "Váratlan Hiba Történt",
|
||||
"an_unexpected_error_occurred": "Váratlan Hiba Történt",
|
||||
"change_server": "Szerverváltás",
|
||||
"invalid_username_or_password": "Érvénytelen Felhasználónév vagy Jelszó",
|
||||
"user_does_not_have_permission_to_log_in": "A felhasználónak nincs jogosultsága a bejelentkezéshez",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "A szerver túl sokáig válaszol, próbáld újra később",
|
||||
"server_received_too_many_requests_try_again_later": "A szerver túl sok kérést kapott, próbáld újra később.",
|
||||
"there_is_a_server_error": "Szerverhiba történt",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Váratlan hiba történt. Helyesen adtad meg a szerver URL-jét?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Váratlan hiba történt. Helyesen adtad meg a szerver URL-jét?",
|
||||
"too_old_server_text": "Nem Támogatott Jellyfin-szerver",
|
||||
"too_old_server_description": "Frissítsd a Jellyfint a legújabb verzióra"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Gyorscsatlakozás Engedélyezése",
|
||||
"enter_the_quick_connect_code": "Add meg a gyors csatlakozási kódot...",
|
||||
"success": "Siker",
|
||||
"quick_connect_autorized": "Gyorscsatlakozás Engedélyezve",
|
||||
"quick_connect_authorized": "Gyorscsatlakozás Engedélyezve",
|
||||
"error": "Hiba",
|
||||
"invalid_code": "Érvénytelen Kód",
|
||||
"authorize": "Engedélyezés"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Egyéni Menülinkek Megjelenítése",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Könyvtárak Elrejtése",
|
||||
"select_liraries_you_want_to_hide": "Válaszd ki azokat a könyvtárakat, amelyeket el szeretnél rejteni a Könyvtár fülön és a kezdőlapon.",
|
||||
"select_libraries_you_want_to_hide": "Válaszd ki azokat a könyvtárakat, amelyeket el szeretnél rejteni a Könyvtár fülön és a kezdőlapon.",
|
||||
"disable_haptic_feedback": "Haptikus Visszajelzés Letiltása",
|
||||
"default_quality": "Alapértelmezett Minőség",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Eszköz {{availableSpace}}%",
|
||||
"size_used": "{{used}} / {{total}} Használatban",
|
||||
"delete_all_downloaded_files": "Minden Letöltött Fájl Törlése",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Hiba",
|
||||
"failed_to_get_stream_url": "Nem sikerült lekérni a stream URL-t",
|
||||
"an_error_occured_while_playing_the_video": "Hiba történt a videó lejátszása közben. Ellenőrizd a naplókat a beállításokban.",
|
||||
"an_error_occurred_while_playing_the_video": "Hiba történt a videó lejátszása közben. Ellenőrizd a naplókat a beállításokban.",
|
||||
"client_error": "Kliens Hiba",
|
||||
"could_not_create_stream_for_chromecast": "A Chromecast stream létrehozása sikertelen volt",
|
||||
"message_from_server": "Üzenet a szervertől: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Capito",
|
||||
"connection_failed": "Connessione fallita",
|
||||
"could_not_connect_to_server": "Impossibile connettersi al server. Controllare l'URL e la connessione di rete.",
|
||||
"an_unexpected_error_occured": "Si è verificato un errore inaspettato",
|
||||
"an_unexpected_error_occurred": "Si è verificato un errore inaspettato",
|
||||
"change_server": "Cambiare il server",
|
||||
"invalid_username_or_password": "Nome utente o password non validi",
|
||||
"user_does_not_have_permission_to_log_in": "L'utente non ha il permesso di accedere",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Il server sta impiegando troppo tempo per rispondere, riprovare più tardi",
|
||||
"server_received_too_many_requests_try_again_later": "Il server ha ricevuto troppe richieste, riprovare più tardi.",
|
||||
"there_is_a_server_error": "Si è verificato un errore del server",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Si è verificato un errore imprevisto. L'URL del server è stato inserito correttamente?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Si è verificato un errore imprevisto. L'URL del server è stato inserito correttamente?",
|
||||
"too_old_server_text": "Scoperto Server Jellyfin non supportato",
|
||||
"too_old_server_description": "Aggiorna Jellyfin all'ultima versione"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autorizza Connessione Rapida",
|
||||
"enter_the_quick_connect_code": "Inserisci il codice per la Connessione Rapida...",
|
||||
"success": "Successo",
|
||||
"quick_connect_autorized": "Connessione Rapida autorizzata",
|
||||
"quick_connect_authorized": "Connessione Rapida autorizzata",
|
||||
"error": "Errore",
|
||||
"invalid_code": "Codice invalido",
|
||||
"authorize": "Autorizza"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Mostra i link del menu personalizzato",
|
||||
"show_large_home_carousel": "Mostra Carosello Grande nella Home (beta)",
|
||||
"hide_libraries": "Nascondi Librerie",
|
||||
"select_liraries_you_want_to_hide": "Selezionate le librerie che volete nascondere dalla scheda Libreria e dalle sezioni della pagina iniziale.",
|
||||
"select_libraries_you_want_to_hide": "Selezionate le librerie che volete nascondere dalla scheda Libreria e dalle sezioni della pagina iniziale.",
|
||||
"disable_haptic_feedback": "Disabilita il feedback aptico",
|
||||
"default_quality": "Qualità predefinita",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Dispositivo {{availableSpace}}%",
|
||||
"size_used": "{{used}} di {{total}} usato",
|
||||
"delete_all_downloaded_files": "Cancella Tutti i File Scaricati",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Precarica automaticamente i brani mentre ascolti per una riproduzione più fluida e il supporto offline",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Errore",
|
||||
"failed_to_get_stream_url": "Impossibile ottenere l'URL dello stream",
|
||||
"an_error_occured_while_playing_the_video": "Si è verificato un errore durante la riproduzione del video. Controllare i log nelle impostazioni.",
|
||||
"an_error_occurred_while_playing_the_video": "Si è verificato un errore durante la riproduzione del video. Controllare i log nelle impostazioni.",
|
||||
"client_error": "Errore del client",
|
||||
"could_not_create_stream_for_chromecast": "Impossibile creare uno stream per Chromecast",
|
||||
"message_from_server": "Messaggio dal server",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "了解",
|
||||
"connection_failed": "接続に失敗しました",
|
||||
"could_not_connect_to_server": "サーバーに接続できませんでした。URLとネットワーク接続を確認してください。",
|
||||
"an_unexpected_error_occured": "予期しないエラーが発生しました",
|
||||
"an_unexpected_error_occurred": "予期しないエラーが発生しました",
|
||||
"change_server": "サーバーの変更",
|
||||
"invalid_username_or_password": "ユーザー名またはパスワードが無効です",
|
||||
"user_does_not_have_permission_to_log_in": "ユーザーにログイン権限がありません",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "サーバーの応答に時間がかかりすぎています。しばらくしてからもう一度お試しください。",
|
||||
"server_received_too_many_requests_try_again_later": "サーバーにリクエストが多すぎます。後でもう一度お試しください。",
|
||||
"there_is_a_server_error": "サーバーエラーが発生しました",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "予期しないエラーが発生しました。サーバーのURLを正しく入力しましたか?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "予期しないエラーが発生しました。サーバーのURLを正しく入力しましたか?",
|
||||
"too_old_server_text": "サポートされていないJellyfinサーバー発見",
|
||||
"too_old_server_description": "Jellyfinを最新バージョンにアップデートしてください"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "クイックコネクトを承認する",
|
||||
"enter_the_quick_connect_code": "クイックコネクトコードを入力...",
|
||||
"success": "成功しました",
|
||||
"quick_connect_autorized": "クイックコネクトが承認されました",
|
||||
"quick_connect_authorized": "クイックコネクトが承認されました",
|
||||
"error": "エラー",
|
||||
"invalid_code": "無効なコードです",
|
||||
"authorize": "承認"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "カスタムメニューのリンクを表示",
|
||||
"show_large_home_carousel": "大きなヒーロー(Beta)",
|
||||
"hide_libraries": "ライブラリを非表示",
|
||||
"select_liraries_you_want_to_hide": "ライブラリタブとホームページセクションから非表示にするライブラリを選択します。",
|
||||
"select_libraries_you_want_to_hide": "ライブラリタブとホームページセクションから非表示にするライブラリを選択します。",
|
||||
"disable_haptic_feedback": "触覚フィードバックを無効にする",
|
||||
"default_quality": "デフォルトの品質",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "デバイス {{availableSpace}}%",
|
||||
"size_used": "{{used}} / {{total}} 使用済み",
|
||||
"delete_all_downloaded_files": "すべてのダウンロードファイルを削除",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "エラー",
|
||||
"failed_to_get_stream_url": "ストリームURLを取得できませんでした",
|
||||
"an_error_occured_while_playing_the_video": "動画の再生中にエラーが発生しました。設定でログを確認してください。",
|
||||
"an_error_occurred_while_playing_the_video": "動画の再生中にエラーが発生しました。設定でログを確認してください。",
|
||||
"client_error": "クライアントエラー",
|
||||
"could_not_create_stream_for_chromecast": "Chromecastのストリームを作成できませんでした",
|
||||
"message_from_server": "サーバーからのメッセージ",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "성공",
|
||||
"connection_failed": "연결 실패",
|
||||
"could_not_connect_to_server": "서버에 연결되지 않았습니다. URL과 네트워크 상태를 확인하세요.",
|
||||
"an_unexpected_error_occured": "예기치 않은 오류가 발생했습니다",
|
||||
"an_unexpected_error_occurred": "예기치 않은 오류가 발생했습니다",
|
||||
"change_server": "서버 변경",
|
||||
"invalid_username_or_password": "잘못된 아이디 혹은 비밀번호입니다",
|
||||
"user_does_not_have_permission_to_log_in": "로그인 하기 위한 권한이 없습니다",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "서버 응답이 너무 느립니다. 나중에 다시 시도하세요",
|
||||
"server_received_too_many_requests_try_again_later": "서버가 너무 많은 요청을 받았습니다. 나중에 다시 시도하세요.",
|
||||
"there_is_a_server_error": "서버 에러",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "예기치 않은 오류가 발생했습니다. 서버 URL을 올바르게 입력하셨습니까?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "예기치 않은 오류가 발생했습니다. 서버 URL을 올바르게 입력하셨습니까?",
|
||||
"too_old_server_text": "Unsupported Jellyfin Server Discovered",
|
||||
"too_old_server_description": "Please update Jellyfin to the latest version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "퀵 커넥트 승인",
|
||||
"enter_the_quick_connect_code": "퀵 커넥트 코드 입력...",
|
||||
"success": "성공",
|
||||
"quick_connect_autorized": "퀵 커넥트 승인됨",
|
||||
"quick_connect_authorized": "퀵 커넥트 승인됨",
|
||||
"error": "오류",
|
||||
"invalid_code": "유효하지 않은 코드",
|
||||
"authorize": "승인"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "사용자 지정 메뉴 링크 표시",
|
||||
"show_large_home_carousel": "대형 홈 슬라이드 배너 표시 (베타)",
|
||||
"hide_libraries": "라이브러리 숨기기",
|
||||
"select_liraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Disable Haptic Feedback",
|
||||
"default_quality": "Default Quality",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "디바이스 {{availableSpace}}%",
|
||||
"size_used": "{{used}} of {{total}} Used",
|
||||
"delete_all_downloaded_files": "Delete All Downloaded Files",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Error",
|
||||
"failed_to_get_stream_url": "Failed to get the stream URL",
|
||||
"an_error_occured_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Client Error",
|
||||
"could_not_create_stream_for_chromecast": "Could not create a stream for Chromecast",
|
||||
"message_from_server": "Message from Server: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Begrepen",
|
||||
"connection_failed": "Verbinding mislukt",
|
||||
"could_not_connect_to_server": "Kon niet verbinden met de server. Controleer de URL en je netwerkverbinding.",
|
||||
"an_unexpected_error_occured": "Er is een onverwachte fout opgetreden",
|
||||
"an_unexpected_error_occurred": "Er is een onverwachte fout opgetreden",
|
||||
"change_server": "Server wijzigen",
|
||||
"invalid_username_or_password": "Onjuiste gebruikersnaam of wachtwoord",
|
||||
"user_does_not_have_permission_to_log_in": "Gebruiker heeft geen rechten om aan te melden",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "De server doet er te lang over om te antwoorden, probeer later opnieuw",
|
||||
"server_received_too_many_requests_try_again_later": "De server heeft te veel aanvragen ontvangen, probeer later opnieuw",
|
||||
"there_is_a_server_error": "Er is een serverfout",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Er is een onverwachte fout opgetreden. Heb je de server URL correct ingegeven?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Er is een onverwachte fout opgetreden. Heb je de server URL correct ingegeven?",
|
||||
"too_old_server_text": "Niet-ondersteunde Jellyfin Server Ontdekt",
|
||||
"too_old_server_description": "Werk Jellyfin bij naar de laatste versie"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Snel Verbinden toestaan",
|
||||
"enter_the_quick_connect_code": "Vul de Snel Verbinden code in...",
|
||||
"success": "Succes",
|
||||
"quick_connect_autorized": "Snel Verbinden toegestaan",
|
||||
"quick_connect_authorized": "Snel Verbinden toegestaan",
|
||||
"error": "Fout",
|
||||
"invalid_code": "Ongeldige code",
|
||||
"authorize": "Toestaan"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Aangepaste menulinks tonen",
|
||||
"show_large_home_carousel": "Toon grote carrousel op startpagina (bèta)",
|
||||
"hide_libraries": "Verberg Bibliotheken",
|
||||
"select_liraries_you_want_to_hide": "Selecteer de bibliotheken die je wil verbergen van de Bibliotheektab en hoofdpagina onderdelen.",
|
||||
"select_libraries_you_want_to_hide": "Selecteer de bibliotheken die je wil verbergen van de Bibliotheektab en hoofdpagina onderdelen.",
|
||||
"disable_haptic_feedback": "Haptische feedback uitschakelen",
|
||||
"default_quality": "Standaard kwaliteit",
|
||||
"default_playback_speed": "Standaard Afspeelsnelheid",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Toestel {{availableSpace}}%",
|
||||
"size_used": "{{used}} van {{total}} gebruikt",
|
||||
"delete_all_downloaded_files": "Verwijder alle gedownloade bestanden",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Fout",
|
||||
"failed_to_get_stream_url": "De stream-URL kon niet worden verkregen",
|
||||
"an_error_occured_while_playing_the_video": "Er is een fout opgetreden tijdens het afspelen van de video. Controleer de logs in de instellingen.",
|
||||
"an_error_occurred_while_playing_the_video": "Er is een fout opgetreden tijdens het afspelen van de video. Controleer de logs in de instellingen.",
|
||||
"client_error": "Fout van de client",
|
||||
"could_not_create_stream_for_chromecast": "Kon geen stream maken voor Chromecast",
|
||||
"message_from_server": "Bericht van de server",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Har det",
|
||||
"connection_failed": "Tilkobling mislyktes",
|
||||
"could_not_connect_to_server": "Kunne ikke koble til serveren. Kontroller nettadressen og nettverkstilkoblingen.",
|
||||
"an_unexpected_error_occured": "En uventet feil oppstod",
|
||||
"an_unexpected_error_occurred": "En uventet feil oppstod",
|
||||
"change_server": "Endre server",
|
||||
"invalid_username_or_password": "Ugyldig brukernavn eller passord",
|
||||
"user_does_not_have_permission_to_log_in": "Brukeren har ikke tillatelse til å logge inn",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Serveren tar for lang tid å svare, prøv igjen senere",
|
||||
"server_received_too_many_requests_try_again_later": "Serveren mottok for mange forespørsler, prøv igjen senere.",
|
||||
"there_is_a_server_error": "Det er en serverfeil",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Det oppstod en uventet feil. Sendte du inn URLen til serveren riktig?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Det oppstod en uventet feil. Sendte du inn URLen til serveren riktig?",
|
||||
"too_old_server_text": "Ustøttet Jellyfin Server oppdaget",
|
||||
"too_old_server_description": "Vennligst oppdater Jellyfin til nyeste versjon"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autoriser rask tilkobling",
|
||||
"enter_the_quick_connect_code": "Skriv inn hurtig-tilkobling kode...",
|
||||
"success": "Vellykket",
|
||||
"quick_connect_autorized": "Hurtig tilkobling autorisert",
|
||||
"quick_connect_authorized": "Hurtig tilkobling autorisert",
|
||||
"error": "Feil",
|
||||
"invalid_code": "Ugyldig kode",
|
||||
"authorize": "Autoriser"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Vis tilpassede menylenker",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Skjul biblioteker",
|
||||
"select_liraries_you_want_to_hide": "Velg bibliotekene du vil skjule deg for Biblioteket og avsnittene for hjemmesider.",
|
||||
"select_libraries_you_want_to_hide": "Velg bibliotekene du vil skjule deg for Biblioteket og avsnittene for hjemmesider.",
|
||||
"disable_haptic_feedback": "Deaktiver Haptisk tilbakemelding",
|
||||
"default_quality": "Standard kvalitet",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Enhet {{availableSpace}}%",
|
||||
"size_used": "{{used}} av {{total}} er i bruk",
|
||||
"delete_all_downloaded_files": "Slett alle nedlastede filer",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Feil",
|
||||
"failed_to_get_stream_url": "Kan ikke hente nettadressen for stream",
|
||||
"an_error_occured_while_playing_the_video": "En feil oppstod under video. Sjekk loggene i innstillingene.",
|
||||
"an_error_occurred_while_playing_the_video": "En feil oppstod under video. Sjekk loggene i innstillingene.",
|
||||
"client_error": "Feil med annonsør",
|
||||
"could_not_create_stream_for_chromecast": "Kan ikke opprette en strøm for Chromecast",
|
||||
"message_from_server": "Melding fra tjener: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Rozumiem",
|
||||
"connection_failed": "Połączenie nieudane",
|
||||
"could_not_connect_to_server": "Nie można połączyć się z serwerem. Sprawdź adres URL oraz połączenie sieciowe.",
|
||||
"an_unexpected_error_occured": "Wystąpił nieoczekiwany błąd",
|
||||
"an_unexpected_error_occurred": "Wystąpił nieoczekiwany błąd",
|
||||
"change_server": "Zmień serwer",
|
||||
"invalid_username_or_password": "Nieprawidłowa nazwa użytkownika lub hasło",
|
||||
"user_does_not_have_permission_to_log_in": "Użytkownik nie ma uprawnień do logowania",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Serwer zbyt długo nie odpowiada – spróbuj ponownie później",
|
||||
"server_received_too_many_requests_try_again_later": "Serwer otrzymał zbyt wiele żądań – spróbuj ponownie później.",
|
||||
"there_is_a_server_error": "Wystąpił błąd serwera",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Wystąpił nieoczekiwany błąd. Czy wpisałeś poprawny adres URL?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Wystąpił nieoczekiwany błąd. Czy wpisałeś poprawny adres URL?",
|
||||
"too_old_server_text": "Wykryto nieobsługiwany serwer Jellyfin",
|
||||
"too_old_server_description": "Proszę zaktualizować Jellyfin do najnowszej wersji"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autoryzuj szybkie połączenie",
|
||||
"enter_the_quick_connect_code": "Wpisz kod szybkiego połączenia...",
|
||||
"success": "Sukces",
|
||||
"quick_connect_autorized": "Szybkie połączenie autoryzowane",
|
||||
"quick_connect_authorized": "Szybkie połączenie autoryzowane",
|
||||
"error": "Błąd",
|
||||
"invalid_code": "Nieprawidłowy kod",
|
||||
"authorize": "Autoryzuj"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Pokaż niestandardowe odnośniki w menu",
|
||||
"show_large_home_carousel": "Wyświetl Dużą Karuzelę na ekranie głównym (beta)",
|
||||
"hide_libraries": "Ukryj biblioteki",
|
||||
"select_liraries_you_want_to_hide": "Wybierz biblioteki, które chcesz ukryć na karcie Biblioteka i w sekcjach strony głównej.",
|
||||
"select_libraries_you_want_to_hide": "Wybierz biblioteki, które chcesz ukryć na karcie Biblioteka i w sekcjach strony głównej.",
|
||||
"disable_haptic_feedback": "Wyłącz wibracje",
|
||||
"default_quality": "Domyślna jakość",
|
||||
"default_playback_speed": "Domyślna prędkość odtwarzania",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Urządzenie {{availableSpace}}%",
|
||||
"size_used": "{{used}} z {{total}} wykorzystane",
|
||||
"delete_all_downloaded_files": "Usuń wszystkie pobrane pliki",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Bufor muzyki",
|
||||
"music_cache_description": "Automatycznie buforuj piosenki w trakcie słuchania dla płynniejszego odtwarzania i wsparcia offline",
|
||||
"clear_music_cache": "Wyczyść bufor muzyki",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Błąd",
|
||||
"failed_to_get_stream_url": "Nie udało się pobrać adresu strumienia",
|
||||
"an_error_occured_while_playing_the_video": "Wystąpił błąd podczas odtwarzania wideo. Sprawdź logi w ustawieniach.",
|
||||
"an_error_occurred_while_playing_the_video": "Wystąpił błąd podczas odtwarzania wideo. Sprawdź logi w ustawieniach.",
|
||||
"client_error": "Błąd klienta",
|
||||
"could_not_create_stream_for_chromecast": "Nie udało się utworzyć strumienia dla Chromecasta",
|
||||
"message_from_server": "Wiadomość z serwera: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Tenho isso",
|
||||
"connection_failed": "Falha na conexão",
|
||||
"could_not_connect_to_server": "Não foi possível conectar ao servidor. Verifique a URL e sua conexão de rede.",
|
||||
"an_unexpected_error_occured": "Ocorreu um erro inesperado",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Alterar Servidor",
|
||||
"invalid_username_or_password": "Usuário ou senha inválidos",
|
||||
"user_does_not_have_permission_to_log_in": "Usuário não tem permissão para fazer login",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "O servidor está demorando muito para responder, tente novamente mais tarde",
|
||||
"server_received_too_many_requests_try_again_later": "O servidor recebeu muitos pedidos, tente novamente mais tarde.",
|
||||
"there_is_a_server_error": "Existe um erro no servidor",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Ocorreu um erro inesperado. Você inseriu a URL do servidor corretamente?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Servidor Jellyfin Descoberto Não Suportado",
|
||||
"too_old_server_description": "Por favor, atualize o Jellyfin para a versão mais recente"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autorizar conexão rápida",
|
||||
"enter_the_quick_connect_code": "Insira o código de conexão rápida...",
|
||||
"success": "Sucesso",
|
||||
"quick_connect_autorized": "Acesso Rápido Autorizado",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Erro",
|
||||
"invalid_code": "Código inválido",
|
||||
"authorize": "Autorizar"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Mostrar Links de Menu Personalizado",
|
||||
"show_large_home_carousel": "Mostrar Carrossel Grande (beta)",
|
||||
"hide_libraries": "Ocultar bibliotecas",
|
||||
"select_liraries_you_want_to_hide": "Selecione as bibliotecas que você deseja ocultar da aba Biblioteca e seções da página inicial.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Desativar o retorno tátil",
|
||||
"default_quality": "Qualidade Padrão",
|
||||
"default_playback_speed": "Velocidade padrão de reprodução",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Dispositivo {{availableSpace}}%",
|
||||
"size_used": "{{used}} de {{total}} Utilizados",
|
||||
"delete_all_downloaded_files": "Excluir todos os arquivos baixados",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Cache de Música",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Limpar Cache de Música",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "ERRO",
|
||||
"failed_to_get_stream_url": "Falha ao obter a URL de transmissão",
|
||||
"an_error_occured_while_playing_the_video": "Ocorreu um erro ao reproduzir o vídeo. Verifique os logs nas configurações.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Erro de Cliente",
|
||||
"could_not_create_stream_for_chromecast": "Não foi possível criar um fluxo para o Chromecast",
|
||||
"message_from_server": "Mensagem do Servidor: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Am înţeles",
|
||||
"connection_failed": "Conectare eșuată",
|
||||
"could_not_connect_to_server": "Nu s-a putut conecta la server. Verificați adresa URL și conexiunea la internet.",
|
||||
"an_unexpected_error_occured": "A apărut o eroare neașteptată",
|
||||
"an_unexpected_error_occurred": "A apărut o eroare neașteptată",
|
||||
"change_server": "Schimba",
|
||||
"invalid_username_or_password": "Nume de utilizator sau parolă greșită",
|
||||
"user_does_not_have_permission_to_log_in": "Utilizatorul nu are permisiunea de a se conecta",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Serverul răspunde prea greu, încearcă din nou mai târziu.",
|
||||
"server_received_too_many_requests_try_again_later": "Serverul a primit prea multe solicitări, încercați din nou mai târziu.",
|
||||
"there_is_a_server_error": "Eroare de server",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "A apărut o eroare neașteptată. Ați introdus corect adresa URL a serverului?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "A apărut o eroare neașteptată. Ați introdus corect adresa URL a serverului?",
|
||||
"too_old_server_text": "Serverul Jellyfin Neacceptat Descoperit",
|
||||
"too_old_server_description": "Vă rugăm să actualizați Jellyfin la cea mai recentă versiune"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autorizare conectare rapidă",
|
||||
"enter_the_quick_connect_code": "Introduceți codul pt. conectare rapidă...",
|
||||
"success": "Succes",
|
||||
"quick_connect_autorized": "Conectare rapidă autorizată",
|
||||
"quick_connect_authorized": "Conectare rapidă autorizată",
|
||||
"error": "Eroare",
|
||||
"invalid_code": "Cod invalid.",
|
||||
"authorize": "Autorizează"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Afișează link-uri personalizate în meniu",
|
||||
"show_large_home_carousel": "Arată Caruselul Media Mare (beta)",
|
||||
"hide_libraries": "Ascunde bibliotecile",
|
||||
"select_liraries_you_want_to_hide": "Selectează bibliotecile pe care dorești să le ascunzi din fila Bibliotecă și din secțiunile paginii principale.",
|
||||
"select_libraries_you_want_to_hide": "Selectează bibliotecile pe care dorești să le ascunzi din fila Bibliotecă și din secțiunile paginii principale.",
|
||||
"disable_haptic_feedback": "Dezactivează vibrațiile tactile",
|
||||
"default_quality": "Calitate implicită",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Dispozitiv {{availableSpace}}%",
|
||||
"size_used": "{{used}} din {{total}} folosit",
|
||||
"delete_all_downloaded_files": "Ștergeți toate fișierele descărcate",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Eroare",
|
||||
"failed_to_get_stream_url": "Nu s-a putut obține adresa URL a fluxului",
|
||||
"an_error_occured_while_playing_the_video": "A apărut o eroare la redarea videoclipului. Verificați jurnalele în setări.",
|
||||
"an_error_occurred_while_playing_the_video": "A apărut o eroare la redarea videoclipului. Verificați jurnalele în setări.",
|
||||
"client_error": "Eroare client",
|
||||
"could_not_create_stream_for_chromecast": "Nu s-a putut crea un flux pentru Chromecast",
|
||||
"message_from_server": "Mesaj de la server: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Принято",
|
||||
"connection_failed": "Соединение не удалось",
|
||||
"could_not_connect_to_server": "Не удалось подключиться к серверу. Пожалуйста, проверьте URL и ваше интернет-соединение.",
|
||||
"an_unexpected_error_occured": "Возникла непредвиденная ошибка",
|
||||
"an_unexpected_error_occurred": "Возникла непредвиденная ошибка",
|
||||
"change_server": "Поменять сервер",
|
||||
"invalid_username_or_password": "Неправильное имя пользователя или пароль",
|
||||
"user_does_not_have_permission_to_log_in": "Пользователь не имеет прав на вход",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Сервер долго не отвечает, попробуйте позже",
|
||||
"server_received_too_many_requests_try_again_later": "Сервер получил слишком много запросов, попробуйте позже.",
|
||||
"there_is_a_server_error": "Возникла ошибка сервера",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Возникла непредвиденная ошибка. Вы правильно ввели URL?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Возникла непредвиденная ошибка. Вы правильно ввели URL?",
|
||||
"too_old_server_text": "Обнаружен неподдерживаемый сервер Jellyfin",
|
||||
"too_old_server_description": "Пожалуйста, обновите Jellyfin до последней версии"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Авторизовать через быстрое подключение",
|
||||
"enter_the_quick_connect_code": "Введите код для быстрого подключения...",
|
||||
"success": "Успех",
|
||||
"quick_connect_autorized": "Быстрое подключение авторизовано",
|
||||
"quick_connect_authorized": "Быстрое подключение авторизовано",
|
||||
"error": "Ошибка",
|
||||
"invalid_code": "Неверный код",
|
||||
"authorize": "Авторизовать"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Показать ссылки пользовательского меню",
|
||||
"show_large_home_carousel": "Показывать большую карусель (beta)",
|
||||
"hide_libraries": "Скрыть библиотеки",
|
||||
"select_liraries_you_want_to_hide": "Выберите Библиотеки, которое хотите спрятать из вкладки Библиотеки и домашней страницы.",
|
||||
"select_libraries_you_want_to_hide": "Выберите Библиотеки, которое хотите спрятать из вкладки Библиотеки и домашней страницы.",
|
||||
"disable_haptic_feedback": "Отключить тактильную обратную связь",
|
||||
"default_quality": "Качество по умолчанию",
|
||||
"default_playback_speed": "Скорость воспроизведения по умолчанию",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Устройство {{availableSpace}}%",
|
||||
"size_used": "{{used}} из {{total}} использовано",
|
||||
"delete_all_downloaded_files": "Удалить все загруженные файлы",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Кеш музыки",
|
||||
"music_cache_description": "Автоматически кешировать песни по мере прослушивания для плавного воспроизведения и поддержки отсутствия интернета",
|
||||
"clear_music_cache": "Очистить кеш музыки",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Ошибка",
|
||||
"failed_to_get_stream_url": "Не удалось получить URL потока",
|
||||
"an_error_occured_while_playing_the_video": "Возникла Неожиданная ошибка во время воспроизведения. Проверьте логи в настройках.",
|
||||
"an_error_occurred_while_playing_the_video": "Возникла Неожиданная ошибка во время воспроизведения. Проверьте логи в настройках.",
|
||||
"client_error": "Ошибка клиента",
|
||||
"could_not_create_stream_for_chromecast": "Не удалось создать поток для Chromecast",
|
||||
"message_from_server": "Сообщение от сервера: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Koden har mottagits",
|
||||
"connection_failed": "Anslutningen Misslyckades",
|
||||
"could_not_connect_to_server": "Det gick inte att ansluta till servern. Kontrollera webbadressen och din nätverksanslutning.",
|
||||
"an_unexpected_error_occured": "Ett Oväntat Fel Uppstod",
|
||||
"an_unexpected_error_occurred": "Ett Oväntat Fel Uppstod",
|
||||
"change_server": "Byt Server",
|
||||
"invalid_username_or_password": "Ogiltigt användarnamn eller lösenord",
|
||||
"user_does_not_have_permission_to_log_in": "Användaren har inte behörighet att logga in",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Servern svarar för långsamt, försök igen senare",
|
||||
"server_received_too_many_requests_try_again_later": "Servern har fått för många förfrågningar, försök igen senare.",
|
||||
"there_is_a_server_error": "Ett serverfel uppstod",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Ett oväntat fel uppstod. Har du angett serverns URL korrekt?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Ett oväntat fel uppstod. Har du angett serverns URL korrekt?",
|
||||
"too_old_server_text": "Jellyfin Servern Stöds Inte",
|
||||
"too_old_server_description": "Var God Uppdatera Jellyfin Till Den Senaste Versionen"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Godkänn snabbanslutning",
|
||||
"enter_the_quick_connect_code": "Ange snabbanslutningskod...",
|
||||
"success": "Snabbanslutning lyckades",
|
||||
"quick_connect_autorized": "Snabbanslutning Godkänd",
|
||||
"quick_connect_authorized": "Snabbanslutning Godkänd",
|
||||
"error": "Fel",
|
||||
"invalid_code": "Ogiltig kod",
|
||||
"authorize": "Autentisera"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Visa anpassade menylänkar",
|
||||
"show_large_home_carousel": "Visa toppbanner (beta)",
|
||||
"hide_libraries": "Dölj bibliotek",
|
||||
"select_liraries_you_want_to_hide": "Välj de bibliotek du vill dölja på fliken Bibliotek och på startsidan.",
|
||||
"select_libraries_you_want_to_hide": "Välj de bibliotek du vill dölja på fliken Bibliotek och på startsidan.",
|
||||
"disable_haptic_feedback": "Stäng av vibrationer",
|
||||
"default_quality": "Förvald Kvalitet",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Telefon {{availableSpace}}%",
|
||||
"size_used": "{{used}} av {{total}} används",
|
||||
"delete_all_downloaded_files": "Ta bort alla nerladdade filer",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Musikcache",
|
||||
"music_cache_description": "Cacha automatiskt låtar när du lyssnar för smidigare uppspelning och offline-stöd",
|
||||
"clear_music_cache": "Rensa musikcache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Fel",
|
||||
"failed_to_get_stream_url": "Kunde inte hämta stream-URL",
|
||||
"an_error_occured_while_playing_the_video": "Ett fel uppstod vid uppspelning av videon. Kontrollera loggarna i inställningarna.",
|
||||
"an_error_occurred_while_playing_the_video": "Ett fel uppstod vid uppspelning av videon. Kontrollera loggarna i inställningarna.",
|
||||
"client_error": "Klientfel",
|
||||
"could_not_create_stream_for_chromecast": "Kunde inte skapa stream för Chromecast",
|
||||
"message_from_server": "Meddelande från servern: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Got It",
|
||||
"connection_failed": "Connection Failed",
|
||||
"could_not_connect_to_server": "Could not connect to the server. Please check the URL and your network connection.",
|
||||
"an_unexpected_error_occured": "An Unexpected Error Occurred",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Change Server",
|
||||
"invalid_username_or_password": "Invalid Username or Password",
|
||||
"user_does_not_have_permission_to_log_in": "ผู้ใช้ไม่มีสิทธิ์ในการเข้าสู่ระบบ",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Server is taking too long to respond, try again later",
|
||||
"server_received_too_many_requests_try_again_later": "Server received too many requests, try again later.",
|
||||
"there_is_a_server_error": "There is a server error",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Unsupported Jellyfin Server Discovered",
|
||||
"too_old_server_description": "Please update Jellyfin to the latest version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Authorize Quick Connect",
|
||||
"enter_the_quick_connect_code": "Enter the quick connect code...",
|
||||
"success": "Success",
|
||||
"quick_connect_autorized": "Quick Connect Authorized",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Error",
|
||||
"invalid_code": "Invalid Code",
|
||||
"authorize": "Authorize"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Show Custom Menu Links",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Hide Libraries",
|
||||
"select_liraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Disable Haptic Feedback",
|
||||
"default_quality": "Default Quality",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Device {{availableSpace}}%",
|
||||
"size_used": "{{used}} of {{total}} Used",
|
||||
"delete_all_downloaded_files": "Delete All Downloaded Files",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Error",
|
||||
"failed_to_get_stream_url": "Failed to get the stream URL",
|
||||
"an_error_occured_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Client Error",
|
||||
"could_not_create_stream_for_chromecast": "Could not create a stream for Chromecast",
|
||||
"message_from_server": "Message from Server: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "jIyaj",
|
||||
"connection_failed": "ngoQlaHbe'",
|
||||
"could_not_connect_to_server": "SeHlaw veS Ho'Do'laHbe'. URL 'ej ret ghun mej.",
|
||||
"an_unexpected_error_occured": "num ghIq Doch",
|
||||
"an_unexpected_error_occurred": "num ghIq Doch",
|
||||
"change_server": "Ho'Do' veS yIghoS",
|
||||
"invalid_username_or_password": "tlhIngan pagh ngoq De' law'be'",
|
||||
"user_does_not_have_permission_to_log_in": "tlhIngan lut 'el je'laHbe'",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Ho'Do' veS jachrup. pItlh yIHaD",
|
||||
"server_received_too_many_requests_try_again_later": "Ho'Do' veS lutlh ngeb petlh law'. pItlh yIHaD.",
|
||||
"there_is_a_server_error": "Ho'Do' veS ghIq maS",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "num ghIq Doch. URL mej Danej'a'?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "num ghIq Doch. URL mej Danej'a'?",
|
||||
"too_old_server_text": "Unsupported Jellyfin Server Discovered",
|
||||
"too_old_server_description": "**Jellyfin chu'qu' Dotlh yIchoHmoH**"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "parmaq ngoQ yIje'",
|
||||
"enter_the_quick_connect_code": "parmaq ngoQ De' yI'el...",
|
||||
"success": "Qapla'",
|
||||
"quick_connect_autorized": "parmaq ngoQ je'laH",
|
||||
"quick_connect_authorized": "parmaq ngoQ je'laH",
|
||||
"error": "ghIq",
|
||||
"invalid_code": "De' law'be'",
|
||||
"authorize": "yIje'"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "menuDaq ret teqlu' yInej",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "De'wI' bom yIQIj",
|
||||
"select_liraries_you_want_to_hide": "De'wI' bom Danej QIj yIwIv.",
|
||||
"select_libraries_you_want_to_hide": "De'wI' bom Danej QIj yIwIv.",
|
||||
"disable_haptic_feedback": "Qub quvHa' yIQIj",
|
||||
"default_quality": "wa' luj",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "naDev {{availableSpace}}%",
|
||||
"size_used": "{{used}} / {{total}} ram",
|
||||
"delete_all_downloaded_files": "Hoch Qaw' Doch yIQaw'",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "ghIq",
|
||||
"failed_to_get_stream_url": "tlhol ret URL tu'laHbe'",
|
||||
"an_error_occured_while_playing_the_video": "mu'tlhegh tlholDI' ghIq. menDaq De' qon mej.",
|
||||
"an_error_occurred_while_playing_the_video": "mu'tlhegh tlholDI' ghIq. menDaq De' qon mej.",
|
||||
"client_error": "lut 'el ghIq",
|
||||
"could_not_create_stream_for_chromecast": "Chromecast tlhol ret qonlaHbe'",
|
||||
"message_from_server": "Ho'Do' veS jach: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Anlaşıldı",
|
||||
"connection_failed": "Bağlantı başarısız",
|
||||
"could_not_connect_to_server": "Sunucuya bağlanılamadı. Lütfen URL'yi ve ağ bağlantınızı kontrol edin.",
|
||||
"an_unexpected_error_occured": "Beklenmedik bir hata oluştu",
|
||||
"an_unexpected_error_occurred": "Beklenmedik bir hata oluştu",
|
||||
"change_server": "Sunucu değiştir",
|
||||
"invalid_username_or_password": "Geçersiz kullanıcı adı veya şifre",
|
||||
"user_does_not_have_permission_to_log_in": "Kullanıcının giriş yapma izni yok",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Sunucunun yanıt vermesi çok uzun sürüyor, lütfen daha sonra tekrar deneyin",
|
||||
"server_received_too_many_requests_try_again_later": "Sunucu çok fazla istek aldı, lütfen daha sonra tekrar deneyin.",
|
||||
"there_is_a_server_error": "Sunucu hatası var",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Beklenmedik bir hata oluştu. Sunucu URL'sini doğru girdiğinizden emin misiniz?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Beklenmedik bir hata oluştu. Sunucu URL'sini doğru girdiğinizden emin misiniz?",
|
||||
"too_old_server_text": "Desteklenmeyen Jellyfin Sunucu sürümü bulundu.",
|
||||
"too_old_server_description": "Lütfen Jellyfin'i en son sürüme güncelleyin."
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Hızlı Bağlantıyı Yetkilendir",
|
||||
"enter_the_quick_connect_code": "Hızlı bağlantı kodunu girin...",
|
||||
"success": "Başarılı",
|
||||
"quick_connect_autorized": "Hızlı Bağlantı Yetkilendirildi",
|
||||
"quick_connect_authorized": "Hızlı Bağlantı Yetkilendirildi",
|
||||
"error": "Hata",
|
||||
"invalid_code": "Geçersiz kod",
|
||||
"authorize": "Yetkilendir"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Özel Menü Bağlantılarını Göster",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Kütüphaneleri Gizle",
|
||||
"select_liraries_you_want_to_hide": "Kütüphane sekmesinden ve ana sayfa bölümlerinden gizlemek istediğiniz kütüphaneleri seçin.",
|
||||
"select_libraries_you_want_to_hide": "Kütüphane sekmesinden ve ana sayfa bölümlerinden gizlemek istediğiniz kütüphaneleri seçin.",
|
||||
"disable_haptic_feedback": "Dokunsal Geri Bildirimi Devre Dışı Bırak",
|
||||
"default_quality": "Varsayılan kalite",
|
||||
"default_playback_speed": "Varsayılan Oynatma Hızı",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Cihaz {{availableSpace}}%",
|
||||
"size_used": "{{used}} / {{total}} kullanıldı",
|
||||
"delete_all_downloaded_files": "Tüm indirilen dosyaları sil",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Müzik Ön Belleği",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Müzik Ön Belleğini Temizle",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Hata",
|
||||
"failed_to_get_stream_url": "Yayın URL'si alınamadı",
|
||||
"an_error_occured_while_playing_the_video": "Video oynatılırken bir hata oluştu. Ayarlardaki günlüklere bakın.",
|
||||
"an_error_occurred_while_playing_the_video": "Video oynatılırken bir hata oluştu. Ayarlardaki günlüklere bakın.",
|
||||
"client_error": "İstemci hatası",
|
||||
"could_not_create_stream_for_chromecast": "Chromecast için yayın oluşturulamadı",
|
||||
"message_from_server": "Sunucudan mesaj: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Готово",
|
||||
"connection_failed": "Помилка зʼєднання",
|
||||
"could_not_connect_to_server": "Неможливо підʼєднатися до серверу. Будь ласка перевірте URL і ваше зʼєднання з мережею",
|
||||
"an_unexpected_error_occured": "Сталася несподівана помилка",
|
||||
"an_unexpected_error_occurred": "Сталася несподівана помилка",
|
||||
"change_server": "Змінити сервер",
|
||||
"invalid_username_or_password": "Неправильні імʼя користувача або пароль",
|
||||
"user_does_not_have_permission_to_log_in": "Користувач не маю дозволу на вхід",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Сервер відповідає занадто довго, будь-ласка спробуйте пізніше",
|
||||
"server_received_too_many_requests_try_again_later": "Сервер отримав забагато запитів, будь ласка спробуйте пізніше.",
|
||||
"there_is_a_server_error": "Відбулася помилка на стороні сервера",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Відбулася несподівана помилка. Чи введений URL сервера правильний?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Відбулася несподівана помилка. Чи введений URL сервера правильний?",
|
||||
"too_old_server_text": "Unsupported Jellyfin Server Discovered",
|
||||
"too_old_server_description": "Please update Jellyfin to the latest version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Авторизуйте Швидке Зʼєднання",
|
||||
"enter_the_quick_connect_code": "Введіть код для швидкого зʼєднання...",
|
||||
"success": "Успіх",
|
||||
"quick_connect_autorized": "Швидке Зʼєднання авторизовано",
|
||||
"quick_connect_authorized": "Швидке Зʼєднання авторизовано",
|
||||
"error": "Помилка",
|
||||
"invalid_code": "Не правильний код",
|
||||
"authorize": "Авторизувати"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Показати користувацькі посилання меню",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Сховати медіатеки",
|
||||
"select_liraries_you_want_to_hide": "Виберіть медіатеки, що бажаєте приховати з вкладки Медіатека і з секції на головній сторінці.",
|
||||
"select_libraries_you_want_to_hide": "Виберіть медіатеки, що бажаєте приховати з вкладки Медіатека і з секції на головній сторінці.",
|
||||
"disable_haptic_feedback": "Вимкнути тактильний зворотний зв'язок",
|
||||
"default_quality": "Якість за замовченням",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Гаджет {{availableSpace}}%",
|
||||
"size_used": "{{used}} з {{total}} використано",
|
||||
"delete_all_downloaded_files": "Видалити усі завантаженні файли",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Помилка",
|
||||
"failed_to_get_stream_url": "Не вдалося отримати URL-адресу потоку",
|
||||
"an_error_occured_while_playing_the_video": "Під час відтворення відео сталася помилка. Перевірте журнал в налаштуваннях.",
|
||||
"an_error_occurred_while_playing_the_video": "Під час відтворення відео сталася помилка. Перевірте журнал в налаштуваннях.",
|
||||
"client_error": "Помилка клієнту",
|
||||
"could_not_create_stream_for_chromecast": "Не вдалося створити потік для Chromecast",
|
||||
"message_from_server": "Повідомлення від серверу: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Đã hiểu",
|
||||
"connection_failed": "Kết nối thất bại",
|
||||
"could_not_connect_to_server": "Không thể kết nối tới máy chủ. Vui lòng kiểm tra URL và kết nối mạng.",
|
||||
"an_unexpected_error_occured": "Đã xảy ra lỗi không mong muốn",
|
||||
"an_unexpected_error_occurred": "Đã xảy ra lỗi không mong muốn",
|
||||
"change_server": "Đổi máy chủ",
|
||||
"invalid_username_or_password": "Tên đăng nhập hoặc mật khẩu không đúng",
|
||||
"user_does_not_have_permission_to_log_in": "Người dùng không có quyền đăng nhập",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Máy chủ phản hồi quá lâu, vui lòng thử lại sau",
|
||||
"server_received_too_many_requests_try_again_later": "Máy chủ nhận quá nhiều yêu cầu, vui lòng thử lại sau.",
|
||||
"there_is_a_server_error": "Đã xảy ra lỗi ở máy chủ",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Đã xảy ra lỗi không mong muốn. Bạn có chắc đã nhập đúng URL máy chủ?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "Đã xảy ra lỗi không mong muốn. Bạn có chắc đã nhập đúng URL máy chủ?",
|
||||
"too_old_server_text": "Unsupported Jellyfin Server Discovered",
|
||||
"too_old_server_description": "Please update Jellyfin to the latest version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Cho phép Kết nối nhanh",
|
||||
"enter_the_quick_connect_code": "Nhập mã kết nối nhanh...",
|
||||
"success": "Thành công",
|
||||
"quick_connect_autorized": "Kết nối nhanh đã được cho phép",
|
||||
"quick_connect_authorized": "Kết nối nhanh đã được cho phép",
|
||||
"error": "Lỗi",
|
||||
"invalid_code": "Mã không hợp lệ",
|
||||
"authorize": "Cho phép"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Hiện liên kết tùy chỉnh",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Ẩn thư viện",
|
||||
"select_liraries_you_want_to_hide": "Chọn các thư viện muốn ẩn khỏi mục Thư viện và Trang chủ.",
|
||||
"select_libraries_you_want_to_hide": "Chọn các thư viện muốn ẩn khỏi mục Thư viện và Trang chủ.",
|
||||
"disable_haptic_feedback": "Tắt phản hồi rung",
|
||||
"default_quality": "Chất lượng mặc định",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Thiết bị sử dụng {{availableSpace}}%",
|
||||
"size_used": "{{used}} / {{total}} đã dùng",
|
||||
"delete_all_downloaded_files": "Xóa toàn bộ tập tin đã tải",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Lỗi",
|
||||
"failed_to_get_stream_url": "Không thể lấy URL phát trực tiếp",
|
||||
"an_error_occured_while_playing_the_video": "Có lỗi khi phát video. Xem nhật ký trong cài đặt.",
|
||||
"an_error_occurred_while_playing_the_video": "Có lỗi khi phát video. Xem nhật ký trong cài đặt.",
|
||||
"client_error": "Lỗi phía máy khách",
|
||||
"could_not_create_stream_for_chromecast": "Không thể tạo luồng cho Chromecast",
|
||||
"message_from_server": "Thông báo từ máy chủ: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Got It",
|
||||
"connection_failed": "Connection Failed",
|
||||
"could_not_connect_to_server": "Could not connect to the server. Please check the URL and your network connection.",
|
||||
"an_unexpected_error_occured": "An Unexpected Error Occurred",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Change Server",
|
||||
"invalid_username_or_password": "Invalid Username or Password",
|
||||
"user_does_not_have_permission_to_log_in": "User does not have permission to log in",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Server is taking too long to respond, try again later",
|
||||
"server_received_too_many_requests_try_again_later": "Server received too many requests, try again later.",
|
||||
"there_is_a_server_error": "There is a server error",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Unsupported Jellyfin Server Discovered",
|
||||
"too_old_server_description": "Please update Jellyfin to the latest version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Authorize Quick Connect",
|
||||
"enter_the_quick_connect_code": "Enter the quick connect code...",
|
||||
"success": "Success",
|
||||
"quick_connect_autorized": "Quick Connect Authorized",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Error",
|
||||
"invalid_code": "Invalid Code",
|
||||
"authorize": "Authorize"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Show Custom Menu Links",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Hide Libraries",
|
||||
"select_liraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Disable Haptic Feedback",
|
||||
"default_quality": "Default Quality",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -384,6 +384,8 @@
|
||||
"device_usage": "Device {{availableSpace}}%",
|
||||
"size_used": "{{used}} of {{total}} Used",
|
||||
"delete_all_downloaded_files": "Delete All Downloaded Files",
|
||||
"delete_all_downloaded_files_confirm": "Delete All Downloaded Files?",
|
||||
"delete_all_downloaded_files_confirm_desc": "Are you sure you want to delete all downloaded files? This action cannot be undone.",
|
||||
"music_cache_title": "Music Cache",
|
||||
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
|
||||
"clear_music_cache": "Clear Music Cache",
|
||||
@@ -598,7 +600,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Error",
|
||||
"failed_to_get_stream_url": "Failed to get the stream URL",
|
||||
"an_error_occured_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Client Error",
|
||||
"could_not_create_stream_for_chromecast": "Could not create a stream for Chromecast",
|
||||
"message_from_server": "Message from Server: {{message}}",
|
||||
|
||||
@@ -176,6 +176,9 @@ export enum VideoPlayer {
|
||||
MPV = 0,
|
||||
}
|
||||
|
||||
// Segment skip behavior options
|
||||
export type SegmentSkipMode = "none" | "ask" | "auto";
|
||||
|
||||
// TV Typography scale presets
|
||||
export enum TVTypographyScale {
|
||||
Small = "small",
|
||||
@@ -247,6 +250,12 @@ export type Settings = {
|
||||
maxAutoPlayEpisodeCount: MaxAutoPlayEpisodeCount;
|
||||
autoPlayEpisodeCount: number;
|
||||
autoPlayNextEpisode: boolean;
|
||||
// Media segment skip preferences
|
||||
skipIntro: SegmentSkipMode;
|
||||
skipOutro: SegmentSkipMode;
|
||||
skipRecap: SegmentSkipMode;
|
||||
skipCommercial: SegmentSkipMode;
|
||||
skipPreview: SegmentSkipMode;
|
||||
// Playback speed settings
|
||||
defaultPlaybackSpeed: number;
|
||||
playbackSpeedPerMedia: Record<string, number>;
|
||||
@@ -350,6 +359,12 @@ export const defaultValues: Settings = {
|
||||
maxAutoPlayEpisodeCount: { key: "3", value: 3 },
|
||||
autoPlayEpisodeCount: 0,
|
||||
autoPlayNextEpisode: true,
|
||||
// Media segment skip defaults
|
||||
skipIntro: "ask",
|
||||
skipOutro: "ask",
|
||||
skipRecap: "ask",
|
||||
skipCommercial: "ask",
|
||||
skipPreview: "ask",
|
||||
// Playback speed defaults
|
||||
defaultPlaybackSpeed: 1.0,
|
||||
playbackSpeedPerMedia: {},
|
||||
@@ -449,6 +464,11 @@ export const pluginSettingsAtom = atom<PluginLockableSettings | undefined>(
|
||||
const hasMeaningfulSettingValue = (value: unknown) =>
|
||||
value !== undefined && value !== null && value !== "";
|
||||
|
||||
const getEffectiveSettingValue = <K extends keyof Settings>(
|
||||
settings: Partial<Settings> | null | undefined,
|
||||
settingsKey: K,
|
||||
) => settings?.[settingsKey] ?? defaultValues[settingsKey];
|
||||
|
||||
export const useSettings = () => {
|
||||
const api = useAtomValue(apiAtom);
|
||||
const [_settings, setSettings] = useAtom(settingsAtom);
|
||||
@@ -505,17 +525,7 @@ export const useSettings = () => {
|
||||
if (!_settings) {
|
||||
return;
|
||||
}
|
||||
// Admin-locked settings are enforced at write time too: a control that
|
||||
// isn't disabled in the UI must not persist a value the admin pinned.
|
||||
// The read memo already overrides locked keys, but without this guard the
|
||||
// write would silently land in user storage and resurface once unlocked.
|
||||
const sanitizedUpdate = Object.fromEntries(
|
||||
Object.entries(update).filter(
|
||||
([key]) => pluginSettings?.[key as keyof Settings]?.locked !== true,
|
||||
),
|
||||
) as Partial<Settings>;
|
||||
|
||||
const hasChanges = Object.entries(sanitizedUpdate).some(
|
||||
const hasChanges = Object.entries(update).some(
|
||||
([key, value]) => _settings[key as keyof Settings] !== value,
|
||||
);
|
||||
|
||||
@@ -524,7 +534,7 @@ export const useSettings = () => {
|
||||
const newSettings = {
|
||||
...defaultValues,
|
||||
..._settings,
|
||||
...sanitizedUpdate,
|
||||
...update,
|
||||
} as Settings;
|
||||
setSettings(newSettings);
|
||||
saveSettings(newSettings);
|
||||
@@ -547,24 +557,13 @@ export const useSettings = () => {
|
||||
// Normalize object-typed settings from plugin (plain primitive → { key, value })
|
||||
value = normalizePluginValue(settingsKey, value);
|
||||
|
||||
// When unlocked, keep the user's value only if they explicitly diverged
|
||||
// from the app default. Otherwise the plugin value is the admin's
|
||||
// default and must win over the hardcoded app default — e.g. a toggle
|
||||
// that was always locked then unlocked should reflect the plugin
|
||||
// default, not the app's `false`. Object-typed settings compare by
|
||||
// reference, so their behaviour is unchanged.
|
||||
const userValue = _settings?.[settingsKey];
|
||||
const userDiverged =
|
||||
hasMeaningfulSettingValue(userValue) &&
|
||||
userValue !== defaultValues[settingsKey];
|
||||
const effectiveValue = getEffectiveSettingValue(_settings, settingsKey);
|
||||
|
||||
(acc as any)[settingsKey] = locked
|
||||
? value
|
||||
: userDiverged
|
||||
? userValue
|
||||
: hasMeaningfulSettingValue(value)
|
||||
? value
|
||||
: defaultValues[settingsKey];
|
||||
: hasMeaningfulSettingValue(effectiveValue)
|
||||
? effectiveValue
|
||||
: value;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
28
utils/intros.ts
Normal file
28
utils/intros.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { Api } from "@jellyfin/sdk";
|
||||
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { getUserLibraryApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
|
||||
/**
|
||||
* Fetches intro items for a given media item using the Jellyfin SDK
|
||||
* @param api - The Jellyfin API instance
|
||||
* @param itemId - The ID of the media item
|
||||
* @param userId - Optional user ID
|
||||
* @returns Promise<BaseItemDto[]> - Array of intro items
|
||||
*/
|
||||
export async function getIntros(
|
||||
api: Api,
|
||||
itemId: string,
|
||||
userId?: string,
|
||||
): Promise<BaseItemDto[]> {
|
||||
try {
|
||||
const response = await getUserLibraryApi(api).getIntros({
|
||||
itemId,
|
||||
userId,
|
||||
});
|
||||
|
||||
return response.data.Items || [];
|
||||
} catch (error) {
|
||||
console.error("Error fetching intros:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -74,10 +74,16 @@ export const getSegmentsForItem = (
|
||||
): {
|
||||
introSegments: MediaTimeSegment[];
|
||||
creditSegments: MediaTimeSegment[];
|
||||
recapSegments: MediaTimeSegment[];
|
||||
commercialSegments: MediaTimeSegment[];
|
||||
previewSegments: MediaTimeSegment[];
|
||||
} => {
|
||||
return {
|
||||
introSegments: item.introSegments || [],
|
||||
creditSegments: item.creditSegments || [],
|
||||
recapSegments: item.recapSegments || [],
|
||||
commercialSegments: item.commercialSegments || [],
|
||||
previewSegments: item.previewSegments || [],
|
||||
};
|
||||
};
|
||||
|
||||
@@ -95,6 +101,9 @@ const fetchMediaSegments = async (
|
||||
): Promise<{
|
||||
introSegments: MediaTimeSegment[];
|
||||
creditSegments: MediaTimeSegment[];
|
||||
recapSegments: MediaTimeSegment[];
|
||||
commercialSegments: MediaTimeSegment[];
|
||||
previewSegments: MediaTimeSegment[];
|
||||
} | null> => {
|
||||
try {
|
||||
const response = await api.axiosInstance.get<MediaSegmentsResponse>(
|
||||
@@ -102,13 +111,22 @@ const fetchMediaSegments = async (
|
||||
{
|
||||
headers: getAuthHeaders(api),
|
||||
params: {
|
||||
includeSegmentTypes: ["Intro", "Outro"],
|
||||
includeSegmentTypes: [
|
||||
"Intro",
|
||||
"Outro",
|
||||
"Recap",
|
||||
"Commercial",
|
||||
"Preview",
|
||||
],
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const introSegments: MediaTimeSegment[] = [];
|
||||
const creditSegments: MediaTimeSegment[] = [];
|
||||
const recapSegments: MediaTimeSegment[] = [];
|
||||
const commercialSegments: MediaTimeSegment[] = [];
|
||||
const previewSegments: MediaTimeSegment[] = [];
|
||||
|
||||
response.data.Items.forEach((segment) => {
|
||||
const timeSegment: MediaTimeSegment = {
|
||||
@@ -124,13 +142,27 @@ const fetchMediaSegments = async (
|
||||
case "Outro":
|
||||
creditSegments.push(timeSegment);
|
||||
break;
|
||||
// Optionally handle other types like Recap, Commercial, Preview
|
||||
case "Recap":
|
||||
recapSegments.push(timeSegment);
|
||||
break;
|
||||
case "Commercial":
|
||||
commercialSegments.push(timeSegment);
|
||||
break;
|
||||
case "Preview":
|
||||
previewSegments.push(timeSegment);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
return { introSegments, creditSegments };
|
||||
return {
|
||||
introSegments,
|
||||
creditSegments,
|
||||
recapSegments,
|
||||
commercialSegments,
|
||||
previewSegments,
|
||||
};
|
||||
} catch (_error) {
|
||||
// Return null to indicate we should try legacy endpoints
|
||||
return null;
|
||||
@@ -146,6 +178,9 @@ const fetchLegacySegments = async (
|
||||
): Promise<{
|
||||
introSegments: MediaTimeSegment[];
|
||||
creditSegments: MediaTimeSegment[];
|
||||
recapSegments: MediaTimeSegment[];
|
||||
commercialSegments: MediaTimeSegment[];
|
||||
previewSegments: MediaTimeSegment[];
|
||||
}> => {
|
||||
const introSegments: MediaTimeSegment[] = [];
|
||||
const creditSegments: MediaTimeSegment[] = [];
|
||||
@@ -184,7 +219,13 @@ const fetchLegacySegments = async (
|
||||
console.error("Failed to fetch legacy segments", error);
|
||||
}
|
||||
|
||||
return { introSegments, creditSegments };
|
||||
return {
|
||||
introSegments,
|
||||
creditSegments,
|
||||
recapSegments: [],
|
||||
commercialSegments: [],
|
||||
previewSegments: [],
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchAndParseSegments = async (
|
||||
@@ -193,6 +234,9 @@ export const fetchAndParseSegments = async (
|
||||
): Promise<{
|
||||
introSegments: MediaTimeSegment[];
|
||||
creditSegments: MediaTimeSegment[];
|
||||
recapSegments: MediaTimeSegment[];
|
||||
commercialSegments: MediaTimeSegment[];
|
||||
previewSegments: MediaTimeSegment[];
|
||||
}> => {
|
||||
// Try new API first (Jellyfin 10.11+)
|
||||
const newSegments = await fetchMediaSegments(itemId, api);
|
||||
|
||||
Reference in New Issue
Block a user