diff --git a/apis/personHistoryApi.ts b/apis/personHistoryApi.ts new file mode 100644 index 0000000..eac8e63 --- /dev/null +++ b/apis/personHistoryApi.ts @@ -0,0 +1,169 @@ +export type PersonMini = { + personId: number; + name: string; + birthDate: string | null; + imageUrl?: string | null; +}; + +export type PersonHistoryRecord = { + seasonId: number; + showId: number; + startDate: string | null; + endDate: string | null; + seasonNumber: number; + partner: PersonMini | null; + seasonParticipants: (PersonMini & { partner?: PersonMini | null })[]; +}; + +type RawSeasonNew = { + seasonId: number; + showId?: number; + show?: number; + seasonNumber: number; + startDate: string | null; + endDate: string | null; + partner?: { + personId: number; + name: string; + birthDate?: string | null; + imageUrl?: string | null; + } | null; + seasonParticipants?: { + personId: number; + name: string; + birthDate?: string | null; + imageUrl?: string | null; + }[]; +}; + +type RawPersonOld = { + personId: number; + name: string; + birthDate?: string | null; + imageUrl?: string | null; +}; + +type RawSeasonOld = { + seasonId: number; + show?: number; + showId?: number; + seasonNumber: number; + startDate: string | null; + endDate: string | null; + seasonParticipants?: + | { + id?: { seasonId?: number; personId?: number }; + person?: RawPersonOld | null; + partner?: RawPersonOld | null; + }[] + | null; +}; + +const PERSONS_BASE_URL = "http://45.157.177.99:8080/persons"; + +function toMini(p: any | undefined | null): PersonMini | null { + if (!p || !p.personId || !p.name) return null; + return { + personId: Number(p.personId), + name: String(p.name), + birthDate: p.birthDate ?? null, + imageUrl: p.imageUrl ?? null, + }; +} + +function isFlatSeason(s: any): s is RawSeasonNew { + const sp = s?.seasonParticipants; + return Array.isArray(sp) && (sp.length === 0 || "personId" in (sp[0] ?? {})); +} + +function mapSeason( + s: RawSeasonNew | RawSeasonOld, + requestedPersonId: number +): PersonHistoryRecord { + const showId = Number((s as any).showId ?? (s as any).show ?? 0) || 0; + const base = { + seasonId: s.seasonId, + showId, + startDate: s.startDate ?? null, + endDate: s.endDate ?? null, + seasonNumber: s.seasonNumber, + }; + + if (isFlatSeason(s)) { + const seasonParticipants = Array.isArray(s.seasonParticipants) + ? s.seasonParticipants + .map((p) => toMini(p)) + .filter((x): x is PersonMini => !!x) + : []; + + const partner = toMini(s.partner ?? null); + + return { + ...base, + partner, + + seasonParticipants, + }; + } + + const spOld = (s as RawSeasonOld).seasonParticipants; + const seasonParticipantsOld = Array.isArray(spOld) + ? spOld + .map((p) => { + const pid = p.person?.personId ?? p.id?.personId; + const name = p.person?.name ?? null; + if (!pid || !name) return null; + + const me: PersonMini = { + personId: Number(pid), + name: String(name), + birthDate: p.person?.birthDate ?? null, + imageUrl: p.person?.imageUrl ?? null, + }; + + const partnerMini = toMini(p.partner ?? null); + + return { + ...me, + partner: partnerMini, + }; + }) + .filter((x): x is NonNullable => !!x) + : []; + + const me = + seasonParticipantsOld.find((pp) => pp.personId === requestedPersonId) || + null; + const partner = (me?.partner ?? null) as PersonMini | null; + + return { + ...base, + partner, + seasonParticipants: seasonParticipantsOld, + }; +} + +export async function getPersonHistory( + personId: number, + signal?: AbortSignal +): Promise { + const apiKey = process.env.EXPO_PUBLIC_API_KEY; + const url = `${PERSONS_BASE_URL}/${personId}/history`; + + const res = await fetch(url, { + signal, + headers: { + "Content-Type": "application/json", + "X-API-Key": apiKey ?? "", + }, + }); + + if (!res.ok) throw new Error("GetPersonHistory failed " + res.status); + + const data: unknown = await res.json(); + if (!Array.isArray(data)) return []; + + return (data as (RawSeasonNew | RawSeasonOld)[]).map((s) => + mapSeason(s, personId) + ); +} diff --git a/apis/showApi.ts b/apis/showApi.ts index c8c94bc..a6c8605 100644 --- a/apis/showApi.ts +++ b/apis/showApi.ts @@ -24,7 +24,7 @@ export type Show = { concept: string; startDate?: string; endDate?: string | null; - logoUri: string; + logoUrl: string; running: boolean; }; @@ -58,7 +58,7 @@ export async function getShows(): Promise { streamingService: s.streamingServices, concept: s.concept, running: s.running, - logoUri: s.logoUrl ?? "", + logoUrl: s.logoUrl ?? "", })); } catch (error) { console.error("Fetch error:", error); @@ -67,34 +67,27 @@ export async function getShows(): Promise { } export async function getShowById(showId: number): Promise { - try { - const apiKey = process.env.EXPO_PUBLIC_API_KEY; - const response = await fetch(`${SHOW_API_URL}/${showId}`, { - headers: { - "Content-Type": "application/json", - "X-API-Key": apiKey ?? "", - }, - }); - if (!response.ok) { - console.error("Fetch error:", response); - return null; - } - const s: RawShow = await response.json(); - return { - id: s.showId, - title: s.title, - description: s.description, - genres: s.genre ? s.genre.split(",").map((g) => g.trim()) : [], - thumbnailUri: s.thumbnailUrl, - bannerUri: s.bannerUrl ?? "", - logoUri: s.logoUrl ?? "", - streamingService: s.streamingServices, - concept: s.concept, - running: s.running, - - }; - } catch (error) { - console.error("Fetch error:", error); - return null; - } + const apiKey = process.env.EXPO_PUBLIC_API_KEY; + const url = `${SHOW_API_URL}/${showId}`; + const res = await fetch(url, { + headers: { + "Content-Type": "application/json", + "X-API-Key": apiKey ?? "", + }, + }); + if (res.status === 404) return null; + if (!res.ok) throw new Error("getShowById failed " + res.status); + const s = (await res.json()) as RawShow; + return { + id: s.showId, + title: s.title, + description: s.description, + genres: s.genre ? s.genre.split(",").map((g) => g.trim()) : [], + thumbnailUri: s.thumbnailUrl, + bannerUri: s.bannerUrl ?? "", + streamingService: s.streamingServices, + concept: s.concept, + running: s.running, + logoUrl: s.logoUrl ?? "", + }; } diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 43e8784..930c750 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -48,11 +48,6 @@ export default function HomeScreen() { return Array.from(uniqueServices); }, [shows]); - console.log( - "Start Dates:", - shows.map((show) => show.startDate) - ); - if (loading) { return ( diff --git a/app/participant.tsx b/app/participant.tsx index 634a8a1..ec2e6fc 100644 --- a/app/participant.tsx +++ b/app/participant.tsx @@ -2,56 +2,188 @@ import styles from "@/app/stackStyles/participantStyles"; import { useShowContext } from "@/contexts/ShowContext"; import Ionicons from "@expo/vector-icons/Ionicons"; import { router, useLocalSearchParams } from "expo-router"; -import React, { useMemo, useState } from "react"; -import { Text, TouchableOpacity, View } from "react-native"; +import React from "react"; +import { Text, TouchableOpacity, View, Image, Dimensions } from "react-native"; +import { + getPersonHistory, + type PersonMini, + type PersonHistoryRecord, +} from "@/apis/personHistoryApi"; +import { getShowById } from "@/apis/showApi"; import { GestureHandlerRootView, ScrollView, } from "react-native-gesture-handler"; -export default function ParticipantScreen() { - const [appearances] = useState< - { - showId: number; - seasons: number[]; - }[] - >([]); - const { shows } = useShowContext(); - const { name } = useLocalSearchParams(); +type SeasonEntry = { + seasonNumber: number; + partner: PersonMini | null; + participants: PersonMini[]; + startDate: string | null; +}; - const resolved = useMemo( - () => - (appearances as any[]) - .map((a) => { - const show = shows.find((s) => s.id === a.showId); - if (!show) return null; +type AppearanceGroup = { + show: { + id: number; + title: string; + bannerUri: string; + thumbnailUri: string; + }; + seasons: SeasonEntry[]; +}; + +export default function ParticipantScreen() { + const { shows } = useShowContext(); + const { name, participantId } = useLocalSearchParams(); + + const pid = Array.isArray(participantId) + ? Number(participantId[0]) + : Number(participantId); + + const [loading, setLoading] = React.useState(false); + const [error, setError] = React.useState(null); + + const [appearances, setAppearances] = React.useState([]); + + const formatYear = (iso?: string | null) => { + if (!iso) return null; + const [y] = iso.split("-"); + return y || null; + }; + + React.useEffect(() => { + if (!pid || Number.isNaN(pid)) return; + const controller = new AbortController(); + setLoading(true); + setError(null); + + (async () => { + try { + const hist = await getPersonHistory(pid, controller.signal); + + const grouped = new Map>(); + for (const h of hist) { + if (!Number.isFinite(h.showId) || h.showId <= 0) continue; + const seasonsForShow = + grouped.get(h.showId) ?? new Map(); + + const existing = seasonsForShow.get(h.seasonNumber); + if (existing) { + seasonsForShow.set(h.seasonNumber, { + seasonNumber: h.seasonNumber, + partner: existing.partner ?? h.partner ?? null, + participants: existing.participants.length + ? existing.participants + : (h.seasonParticipants ?? []), + startDate: existing.startDate ?? h.startDate ?? null, + }); + } else { + seasonsForShow.set(h.seasonNumber, { + seasonNumber: h.seasonNumber, + partner: h.partner ?? null, + participants: h.seasonParticipants ?? [], + startDate: h.startDate ?? null, + }); + } + + grouped.set(h.showId, seasonsForShow); + } + + const showIds = Array.from(grouped.keys()); + + const fromContext = showIds + .map((id) => shows.find((s) => s.id === id)) + .filter((s): s is (typeof shows)[number] => !!s); + + const missingIds = showIds.filter( + (id) => !fromContext.some((s) => s.id === id) + ); + + const fetched = await Promise.all( + missingIds.map(async (id) => { + try { + const s = await getShowById(id); + return s; + } catch { + return null; + } + }) + ); + + const allShows = [ + ...fromContext, + ...fetched.filter(Boolean), + ] as typeof shows; + + const result: AppearanceGroup[] = allShows.map((s) => { + const seasonsMap = grouped.get(s.id)!; + const seasonsSorted = Array.from(seasonsMap.values()).sort( + (a, b) => a.seasonNumber - b.seasonNumber + ); return { - show, - seasons: a.seasons as number[], - partners: a.partners as { - seasonNumber: number; - partner?: { id: number; name: string; imageUrl?: string | null }; - }[], + show: { + id: s.id, + title: s.title, + bannerUri: s.bannerUri, + thumbnailUri: s.thumbnailUri, + }, + seasons: seasonsSorted, }; - }) - .filter( - ( - v - ): v is { - show: (typeof shows)[number]; - seasons: number[]; - partners: { - seasonNumber: number; - partner?: { id: number; name: string; imageUrl?: string | null }; - }[]; - } => !!v - ), - [appearances, shows] + }); + + result.sort((a, b) => + a.show.title.localeCompare(b.show.title, "de", { + sensitivity: "base", + }) + ); + + setAppearances(result); + } catch (e: any) { + if (!controller.signal.aborted) + setError(e?.message || "Fehler beim Laden"); + } finally { + if (!controller.signal.aborted) setLoading(false); + } + })(); + + return () => controller.abort(); + }, [pid, shows]); + + const [expandedShows, setExpandedShows] = React.useState>( + new Set() + ); + const toggleExpand = React.useCallback((showId: number) => { + setExpandedShows((prev) => { + const next = new Set(prev); + if (next.has(showId)) next.delete(showId); + else next.add(showId); + return next; + }); + }, []); + + const goToShow = React.useCallback((id: number) => { + router.push({ pathname: "/showDetails", params: { id: String(id) } }); + }, []); + + const goToPerson = React.useCallback( + (p: PersonMini) => { + if (!p?.personId) return; + + if (p.personId === pid) return; + router.push({ + pathname: "/participant", + params: { participantId: String(p.personId), name: p.name }, + }); + }, + [pid] ); return ( - + {name} Auftritte: - - - {/* - {resolved.map(({ show, seasons, partners }) => { - const seasonPartnerLines = partners.map((p) => { - const label = `Staffel ${p.seasonNumber}`; - if (!p.partner) return label; - return `${label} • Partner: ${p.partner.name}`; - }); + {appearances.map(({ show, seasons }) => { + const partners = Array.from( + new Map( + seasons + .map((s) => s.partner) + .filter((p): p is NonNullable => !!p) + .map((p) => [p.personId, p]) + ).values() + ); + + const allParticipants = Array.from( + new Map( + seasons + .flatMap((s) => s.participants) + .filter((p) => p.personId !== pid) + .map((p) => [p.personId, p]) + ).values() + ); + + const isExpanded = expandedShows.has(show.id); + const visible = isExpanded + ? allParticipants + : allParticipants.slice(0, 12); + const restCount = Math.max( + allParticipants.length - visible.length, + 0 + ); + return ( - - - + + goToShow(show.id)} + > + + + {show.title} - - - {seasonPartnerLines.join("\n")} + + ({formatYear(seasons[0]?.startDate)}) - + + Staffel {seasons.map((s) => s.seasonNumber).join(" und ")} + + + + + + Weitere Teilnehmer + + + + + {visible.map((p) => ( + goToPerson(p)} + > + + {p.name} + + + ))} + + {!isExpanded && restCount > 0 && ( + toggleExpand(show.id)} + style={styles.moreChip} + > + + +{restCount} mehr + + + )} + + {isExpanded && allParticipants.length > 12 && ( + toggleExpand(show.id)} + style={styles.moreChip} + > + Weniger + + )} + + + + {partners.length > 0 && ( + <> + + + Partner + + + + + {partners.map((p) => ( + + {p.name} + + ))} + + )} + ); })} - */} + diff --git a/app/showDetails.tsx b/app/showDetails.tsx index 8e9e027..ded2a5c 100644 --- a/app/showDetails.tsx +++ b/app/showDetails.tsx @@ -4,7 +4,6 @@ import StackHeader from "@/components/ui/StackHeader"; import { useSeasonContext } from "@/contexts/SeasonContext"; import { router, useLocalSearchParams } from "expo-router"; import React from "react"; - import { Dimensions, Image, @@ -99,6 +98,21 @@ export default function ShowDetails() { }); }, [startDate]); + const handleOpenParticipant = React.useCallback( + (p: { id: number; name: string }) => { + router.push({ + pathname: "/participant", + params: { + participantId: p.id, + name: p.name, + originShowId: String(showId), + originSeason: String(selectedSeason), + }, + }); + }, + [showId, selectedSeason] + ); + return ( @@ -210,23 +224,11 @@ export default function ShowDetails() { styles.participantContainer, { backgroundColor: "hsl(336, 79%, 63%)" }, ]} - onPress={() => - router.push({ - pathname: "/participant", - params: { - participantId: p.id, - name: p.name, - }, - }) - } + onPress={() => handleOpenParticipant(p)} > diff --git a/app/stackStyles/participantStyles.tsx b/app/stackStyles/participantStyles.tsx index d52f13d..4d4727c 100644 --- a/app/stackStyles/participantStyles.tsx +++ b/app/stackStyles/participantStyles.tsx @@ -7,15 +7,15 @@ const styles = StyleSheet.create({ }, closeIcon: { position: "absolute", - top: Dimensions.get("window").height * 0.07, + top: Dimensions.get("window").height * 0.065, right: 15, }, participantName: { color: "white", - fontSize: 24, + fontSize: 20, fontWeight: "600", textAlign: "center", - marginTop: Dimensions.get("window").height * 0.075, + marginTop: Dimensions.get("window").height * 0.06, }, participantImage: { width: "100%", @@ -49,7 +49,7 @@ const styles = StyleSheet.create({ }, performedShowsSection: { width: "100%", - height: Dimensions.get("window").height, + height: "100%", backgroundColor: "hsl(221, 39%, 0%)", marginTop: 20, }, @@ -60,14 +60,7 @@ const styles = StyleSheet.create({ marginTop: 15, marginLeft: 15, }, - showContainer: { - width: "85%", - height: 180, - backgroundColor: "hsl(336, 79%, 63%)", - borderRadius: 10, - alignSelf: "center", - marginTop: 15, - }, + showImage: { width: "100%", height: "100%", @@ -94,14 +87,89 @@ const styles = StyleSheet.create({ fontSize: 12, fontWeight: "600", textAlign: "center", - marginTop: 10, + marginTop: 15, }, showSeason: { color: "hsl(0, 0%, 80%)", fontSize: 12, fontWeight: "400", textAlign: "center", - marginTop: 3, + marginTop: 5, + }, + showContainer: { + width: Dimensions.get("window").width - 75, + height: 200, + borderRadius: 15, + marginTop: 20, + alignItems: "center", + backgroundColor: "hsl(336, 79%, 63%)", + }, + + card: { + width: Dimensions.get("window").width - 75, + alignItems: "center", + }, + + horizontalLine: { + height: 50, + width: 2, + backgroundColor: "hsl(0, 0%, 70%)", + marginTop: 10, + alignSelf: "center", + }, + partnerLabel: { + color: "hsl(0, 0%, 80%)", + fontSize: 12, + fontWeight: "400", + textAlign: "center", + marginTop: 10, + }, + participantContainer: { + width: "auto", + height: "auto", + borderRadius: 15, + marginTop: 15, + alignItems: "center", + justifyContent: "center", + backgroundColor: "hsl(221, 39%, 12%)", + padding: 10, + }, + + participantLabel: { + color: "white", + fontSize: 12, + }, + participantRow: { + flexDirection: "row", + flexWrap: "wrap", + gap: 6, + + alignItems: "center", + justifyContent: "flex-start", + }, + + participantChip: { + paddingVertical: 4, + paddingHorizontal: 8, + borderRadius: 12, + backgroundColor: "hsl(221, 39%, 18%)", + maxWidth: 160, + }, + participantChipText: { + color: "hsl(0, 0%, 85%)", + fontSize: 11, + }, + + moreChip: { + paddingVertical: 4, + paddingHorizontal: 10, + borderRadius: 12, + backgroundColor: "hsl(221, 39%, 28%)", + }, + moreChipText: { + color: "white", + fontSize: 11, + fontWeight: "600", }, }); diff --git a/package-lock.json b/package-lock.json index 42dae93..1d5b505 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,9 +14,9 @@ "@react-navigation/bottom-tabs": "^7.3.10", "@react-navigation/elements": "^2.3.8", "@react-navigation/native": "^7.1.6", - "expo": "~54.0.16", + "expo": "54.0.17", "expo-blur": "~15.0.7", - "expo-constants": "~18.0.9", + "expo-constants": "~18.0.10", "expo-font": "~14.0.8", "expo-haptics": "~15.0.7", "expo-image": "~3.0.10", @@ -25,11 +25,11 @@ "expo-splash-screen": "~31.0.10", "expo-status-bar": "~3.0.8", "expo-symbols": "~1.0.7", - "expo-system-ui": "~6.0.7", + "expo-system-ui": "~6.0.8", "expo-web-browser": "~15.0.8", "react": "19.1.0", "react-dom": "19.1.0", - "react-native": "0.81.4", + "react-native": "0.81.5", "react-native-gesture-handler": "~2.28.0", "react-native-reanimated": "~4.1.1", "react-native-safe-area-context": "~5.6.0", @@ -3513,9 +3513,9 @@ } }, "node_modules/@react-native/assets-registry": { - "version": "0.81.4", - "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.81.4.tgz", - "integrity": "sha512-AMcDadefBIjD10BRqkWw+W/VdvXEomR6aEZ0fhQRAv7igrBzb4PTn4vHKYg+sUK0e3wa74kcMy2DLc/HtnGcMA==", + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.81.5.tgz", + "integrity": "sha512-705B6x/5Kxm1RKRvSv0ADYWm5JOnoiQ1ufW7h8uu2E6G9Of/eE6hP/Ivw3U5jI16ERqZxiKQwk34VJbB0niX9w==", "license": "MIT", "engines": { "node": ">= 20.19.4" @@ -3636,12 +3636,12 @@ } }, "node_modules/@react-native/community-cli-plugin": { - "version": "0.81.4", - "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.81.4.tgz", - "integrity": "sha512-8mpnvfcLcnVh+t1ok6V9eozWo8Ut+TZhz8ylJ6gF9d6q9EGDQX6s8jenan5Yv/pzN4vQEKI4ib2pTf/FELw+SA==", + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.81.5.tgz", + "integrity": "sha512-yWRlmEOtcyvSZ4+OvqPabt+NS36vg0K/WADTQLhrYrm9qdZSuXmq8PmdJWz/68wAqKQ+4KTILiq2kjRQwnyhQw==", "license": "MIT", "dependencies": { - "@react-native/dev-middleware": "0.81.4", + "@react-native/dev-middleware": "0.81.5", "debug": "^4.4.0", "invariant": "^2.2.4", "metro": "^0.83.1", @@ -3665,10 +3665,41 @@ } } }, + "node_modules/@react-native/community-cli-plugin/node_modules/@react-native/debugger-frontend": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.81.5.tgz", + "integrity": "sha512-bnd9FSdWKx2ncklOetCgrlwqSGhMHP2zOxObJbOWXoj7GHEmih4MKarBo5/a8gX8EfA1EwRATdfNBQ81DY+h+w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 20.19.4" + } + }, + "node_modules/@react-native/community-cli-plugin/node_modules/@react-native/dev-middleware": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.81.5.tgz", + "integrity": "sha512-WfPfZzboYgo/TUtysuD5xyANzzfka8Ebni6RIb2wDxhb56ERi7qDrE4xGhtPsjCL4pQBXSVxyIlCy0d8I6EgGA==", + "license": "MIT", + "dependencies": { + "@isaacs/ttlcache": "^1.4.1", + "@react-native/debugger-frontend": "0.81.5", + "chrome-launcher": "^0.15.2", + "chromium-edge-launcher": "^0.2.0", + "connect": "^3.6.5", + "debug": "^4.4.0", + "invariant": "^2.2.4", + "nullthrows": "^1.1.1", + "open": "^7.0.3", + "serve-static": "^1.16.2", + "ws": "^6.2.3" + }, + "engines": { + "node": ">= 20.19.4" + } + }, "node_modules/@react-native/community-cli-plugin/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -3677,6 +3708,15 @@ "node": ">=10" } }, + "node_modules/@react-native/community-cli-plugin/node_modules/ws": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", + "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==", + "license": "MIT", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, "node_modules/@react-native/debugger-frontend": { "version": "0.81.4", "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.81.4.tgz", @@ -3718,18 +3758,18 @@ } }, "node_modules/@react-native/gradle-plugin": { - "version": "0.81.4", - "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.81.4.tgz", - "integrity": "sha512-T7fPcQvDDCSusZFVSg6H1oVDKb/NnVYLnsqkcHsAF2C2KGXyo3J7slH/tJAwNfj/7EOA2OgcWxfC1frgn9TQvw==", + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.81.5.tgz", + "integrity": "sha512-hORRlNBj+ReNMLo9jme3yQ6JQf4GZpVEBLxmTXGGlIL78MAezDZr5/uq9dwElSbcGmLEgeiax6e174Fie6qPLg==", "license": "MIT", "engines": { "node": ">= 20.19.4" } }, "node_modules/@react-native/js-polyfills": { - "version": "0.81.4", - "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.81.4.tgz", - "integrity": "sha512-sr42FaypKXJHMVHhgSbu2f/ZJfrLzgaoQ+HdpRvKEiEh2mhFf6XzZwecyLBvWqf2pMPZa+CpPfNPiejXjKEy8w==", + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.81.5.tgz", + "integrity": "sha512-fB7M1CMOCIUudTRuj7kzxIBTVw2KXnsgbQ6+4cbqSxo8NmRRhA0Ul4ZUzZj3rFd3VznTL4Brmocv1oiN0bWZ8w==", "license": "MIT", "engines": { "node": ">= 20.19.4" @@ -3741,29 +3781,6 @@ "integrity": "sha512-9nRRHO1H+tcFqjb9gAM105Urtgcanbta2tuqCVY0NATHeFPDEAB7gPyiLxCHKMi1NbhP6TH0kxgSWXKZl1cyRg==", "license": "MIT" }, - "node_modules/@react-native/virtualized-lists": { - "version": "0.81.4", - "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.81.4.tgz", - "integrity": "sha512-hBM+rMyL6Wm1Q4f/WpqGsaCojKSNUBqAXLABNGoWm1vabZ7cSnARMxBvA/2vo3hLcoR4v7zDK8tkKm9+O0LjVA==", - "license": "MIT", - "dependencies": { - "invariant": "^2.2.4", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 20.19.4" - }, - "peerDependencies": { - "@types/react": "^19.1.0", - "react": "*", - "react-native": "*" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@react-navigation/bottom-tabs": { "version": "7.4.7", "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-7.4.7.tgz", @@ -5453,39 +5470,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", - "license": "MIT", - "dependencies": { - "callsites": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-callsite/node_modules/callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", - "license": "MIT", - "dependencies": { - "caller-callsite": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -5852,65 +5836,6 @@ "url": "https://opencollective.com/core-js" } }, - "node_modules/cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "license": "MIT", - "dependencies": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cosmiconfig/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/cosmiconfig/node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", - "license": "MIT", - "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cosmiconfig/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/cosmiconfig/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/cross-fetch": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", @@ -6252,15 +6177,6 @@ "node": ">=8" } }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "node_modules/error-stack-parser": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", @@ -6911,9 +6827,9 @@ "license": "MIT" }, "node_modules/expo": { - "version": "54.0.16", - "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.16.tgz", - "integrity": "sha512-PRZuxVVbky0nuP1xR4zzPqb5jolBnmwTe+a56xWVFWz0j8s9DCs5HNR7ot/t9Q//8oFCS5FMGcFgxjHXl/W6hA==", + "version": "54.0.17", + "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.17.tgz", + "integrity": "sha512-MLIobliRuHxFSXGxn8J77dbV9lkYpQQYJF4I6VF5QcvSNMHmLu74s34G4zX7YFoLOdnPXlyomBSRsghqY5OQJA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.0", @@ -6932,7 +6848,7 @@ "expo-file-system": "~19.0.17", "expo-font": "~14.0.9", "expo-keep-awake": "~15.0.7", - "expo-modules-autolinking": "3.0.17", + "expo-modules-autolinking": "3.0.18", "expo-modules-core": "3.0.22", "pretty-format": "^29.7.0", "react-refresh": "^0.14.2", @@ -6989,12 +6905,12 @@ } }, "node_modules/expo-constants": { - "version": "18.0.9", - "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.9.tgz", - "integrity": "sha512-sqoXHAOGDcr+M9NlXzj1tGoZyd3zxYDy215W6E0Z0n8fgBaqce9FAYQE2bu5X4G629AYig5go7U6sQz7Pjcm8A==", + "version": "18.0.10", + "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.10.tgz", + "integrity": "sha512-Rhtv+X974k0Cahmvx6p7ER5+pNhBC0XbP1lRviL2J1Xl4sT2FBaIuIxF/0I0CbhOsySf0ksqc5caFweAy9Ewiw==", "license": "MIT", "dependencies": { - "@expo/config": "~12.0.9", + "@expo/config": "~12.0.10", "@expo/env": "~2.0.7" }, "peerDependencies": { @@ -7077,9 +6993,9 @@ } }, "node_modules/expo-modules-autolinking": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.17.tgz", - "integrity": "sha512-ZNX41ylfaceY++UMMrYKoVW/7mIVOIKY1nzBdCyY7GII0sVDvuueTxKWyOVi5jC8uBpnf7kqr4P1gdchfbmP5Q==", + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.18.tgz", + "integrity": "sha512-zanQWn4QrqJtyYGHUdL6OqjU8LKXIOgqF1PAkpNV33SPNb2ZFMBxM4vB1Y8EvqGeoouV7zRqxgXtXvDkAIFndA==", "license": "MIT", "dependencies": { "@expo/spawn-async": "^1.7.2", @@ -7237,12 +7153,12 @@ } }, "node_modules/expo-system-ui": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/expo-system-ui/-/expo-system-ui-6.0.7.tgz", - "integrity": "sha512-NT+/r/BOg08lFI9SZO2WFi9X1ZmawkVStknioWzQq6Mt4KinoMS6yl3eLbyOLM3LoptN13Ywfo4W5KHA6TV9Ow==", + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/expo-system-ui/-/expo-system-ui-6.0.8.tgz", + "integrity": "sha512-DzJYqG2fibBSLzPDL4BybGCiilYOtnI1OWhcYFwoM4k0pnEzMBt1Vj8Z67bXglDDuz2HCQPGNtB3tQft5saKqQ==", "license": "MIT", "dependencies": { - "@react-native/normalize-colors": "0.81.4", + "@react-native/normalize-colors": "0.81.5", "debug": "^4.3.2" }, "peerDependencies": { @@ -7256,6 +7172,12 @@ } } }, + "node_modules/expo-system-ui/node_modules/@react-native/normalize-colors": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.81.5.tgz", + "integrity": "sha512-0HuJ8YtqlTVRXGZuGeBejLE04wSQsibpTI+RGOyVqxZvgtlLLC/Ssw0UmbHhT4lYMp2fhdtvKZSs5emWB1zR/g==", + "license": "MIT" + }, "node_modules/expo-web-browser": { "version": "15.0.8", "resolved": "https://registry.npmjs.org/expo-web-browser/-/expo-web-browser-15.0.8.tgz", @@ -8405,12 +8327,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "license": "MIT" - }, "node_modules/is-async-function": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", @@ -8550,15 +8466,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", @@ -9144,12 +9051,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "license": "MIT" - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -9709,9 +9610,9 @@ } }, "node_modules/metro": { - "version": "0.83.1", - "resolved": "https://registry.npmjs.org/metro/-/metro-0.83.1.tgz", - "integrity": "sha512-UGKepmTxoGD4HkQV8YWvpvwef7fUujNtTgG4Ygf7m/M0qjvb9VuDmAsEU+UdriRX7F61pnVK/opz89hjKlYTXA==", + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro/-/metro-0.83.3.tgz", + "integrity": "sha512-+rP+/GieOzkt97hSJ0MrPOuAH/jpaS21ZDvL9DJ35QYRDlQcwzcvUlGUf79AnQxq/2NPiS/AULhhM4TKutIt8Q==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.24.7", @@ -9729,24 +9630,24 @@ "error-stack-parser": "^2.0.6", "flow-enums-runtime": "^0.0.6", "graceful-fs": "^4.2.4", - "hermes-parser": "0.29.1", + "hermes-parser": "0.32.0", "image-size": "^1.0.2", "invariant": "^2.2.4", "jest-worker": "^29.7.0", "jsc-safe-url": "^0.2.2", "lodash.throttle": "^4.1.1", - "metro-babel-transformer": "0.83.1", - "metro-cache": "0.83.1", - "metro-cache-key": "0.83.1", - "metro-config": "0.83.1", - "metro-core": "0.83.1", - "metro-file-map": "0.83.1", - "metro-resolver": "0.83.1", - "metro-runtime": "0.83.1", - "metro-source-map": "0.83.1", - "metro-symbolicate": "0.83.1", - "metro-transform-plugins": "0.83.1", - "metro-transform-worker": "0.83.1", + "metro-babel-transformer": "0.83.3", + "metro-cache": "0.83.3", + "metro-cache-key": "0.83.3", + "metro-config": "0.83.3", + "metro-core": "0.83.3", + "metro-file-map": "0.83.3", + "metro-resolver": "0.83.3", + "metro-runtime": "0.83.3", + "metro-source-map": "0.83.3", + "metro-symbolicate": "0.83.3", + "metro-transform-plugins": "0.83.3", + "metro-transform-worker": "0.83.3", "mime-types": "^2.1.27", "nullthrows": "^1.1.1", "serialize-error": "^2.1.0", @@ -9763,39 +9664,54 @@ } }, "node_modules/metro-babel-transformer": { - "version": "0.83.1", - "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.83.1.tgz", - "integrity": "sha512-r3xAD3964E8dwDBaZNSO2aIIvWXjIK80uO2xo0/pi3WI8XWT9h5SCjtGWtMtE5PRWw+t20TN0q1WMRsjvhC1rQ==", + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.83.3.tgz", + "integrity": "sha512-1vxlvj2yY24ES1O5RsSIvg4a4WeL7PFXgKOHvXTXiW0deLvQr28ExXj6LjwCCDZ4YZLhq6HddLpZnX4dEdSq5g==", "license": "MIT", "dependencies": { "@babel/core": "^7.25.2", "flow-enums-runtime": "^0.0.6", - "hermes-parser": "0.29.1", + "hermes-parser": "0.32.0", "nullthrows": "^1.1.1" }, "engines": { "node": ">=20.19.4" } }, + "node_modules/metro-babel-transformer/node_modules/hermes-estree": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.32.0.tgz", + "integrity": "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ==", + "license": "MIT" + }, + "node_modules/metro-babel-transformer/node_modules/hermes-parser": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.32.0.tgz", + "integrity": "sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw==", + "license": "MIT", + "dependencies": { + "hermes-estree": "0.32.0" + } + }, "node_modules/metro-cache": { - "version": "0.83.1", - "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.83.1.tgz", - "integrity": "sha512-7N/Ad1PHa1YMWDNiyynTPq34Op2qIE68NWryGEQ4TSE3Zy6a8GpsYnEEZE4Qi6aHgsE+yZHKkRczeBgxhnFIxQ==", + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.83.3.tgz", + "integrity": "sha512-3jo65X515mQJvKqK3vWRblxDEcgY55Sk3w4xa6LlfEXgQ9g1WgMh9m4qVZVwgcHoLy0a2HENTPCCX4Pk6s8c8Q==", "license": "MIT", "dependencies": { "exponential-backoff": "^3.1.1", "flow-enums-runtime": "^0.0.6", "https-proxy-agent": "^7.0.5", - "metro-core": "0.83.1" + "metro-core": "0.83.3" }, "engines": { "node": ">=20.19.4" } }, "node_modules/metro-cache-key": { - "version": "0.83.1", - "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.83.1.tgz", - "integrity": "sha512-ZUs+GD5CNeDLxx5UUWmfg26IL+Dnbryd+TLqTlZnDEgehkIa11kUSvgF92OFfJhONeXzV4rZDRGNXoo6JT+8Gg==", + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.83.3.tgz", + "integrity": "sha512-59ZO049jKzSmvBmG/B5bZ6/dztP0ilp0o988nc6dpaDsU05Cl1c/lRf+yx8m9WW/JVgbmfO5MziBU559XjI5Zw==", "license": "MIT", "dependencies": { "flow-enums-runtime": "^0.0.6" @@ -9805,42 +9721,42 @@ } }, "node_modules/metro-config": { - "version": "0.83.1", - "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.83.1.tgz", - "integrity": "sha512-HJhpZx3wyOkux/jeF1o7akFJzZFdbn6Zf7UQqWrvp7gqFqNulQ8Mju09raBgPmmSxKDl4LbbNeigkX0/nKY1QA==", + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.83.3.tgz", + "integrity": "sha512-mTel7ipT0yNjKILIan04bkJkuCzUUkm2SeEaTads8VfEecCh+ltXchdq6DovXJqzQAXuR2P9cxZB47Lg4klriA==", "license": "MIT", "dependencies": { "connect": "^3.6.5", - "cosmiconfig": "^5.0.5", "flow-enums-runtime": "^0.0.6", "jest-validate": "^29.7.0", - "metro": "0.83.1", - "metro-cache": "0.83.1", - "metro-core": "0.83.1", - "metro-runtime": "0.83.1" + "metro": "0.83.3", + "metro-cache": "0.83.3", + "metro-core": "0.83.3", + "metro-runtime": "0.83.3", + "yaml": "^2.6.1" }, "engines": { "node": ">=20.19.4" } }, "node_modules/metro-core": { - "version": "0.83.1", - "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.83.1.tgz", - "integrity": "sha512-uVL1eAJcMFd2o2Q7dsbpg8COaxjZBBGaXqO2OHnivpCdfanraVL8dPmY6It9ZeqWLOihUKZ2yHW4b6soVCzH/Q==", + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.83.3.tgz", + "integrity": "sha512-M+X59lm7oBmJZamc96usuF1kusd5YimqG/q97g4Ac7slnJ3YiGglW5CsOlicTR5EWf8MQFxxjDoB6ytTqRe8Hw==", "license": "MIT", "dependencies": { "flow-enums-runtime": "^0.0.6", "lodash.throttle": "^4.1.1", - "metro-resolver": "0.83.1" + "metro-resolver": "0.83.3" }, "engines": { "node": ">=20.19.4" } }, "node_modules/metro-file-map": { - "version": "0.83.1", - "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.83.1.tgz", - "integrity": "sha512-Yu429lnexKl44PttKw3nhqgmpBR+6UQ/tRaYcxPeEShtcza9DWakCn7cjqDTQZtWR2A8xSNv139izJMyQ4CG+w==", + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.83.3.tgz", + "integrity": "sha512-jg5AcyE0Q9Xbbu/4NAwwZkmQn7doJCKGW0SLeSJmzNB9Z24jBe0AL2PHNMy4eu0JiKtNWHz9IiONGZWq7hjVTA==", "license": "MIT", "dependencies": { "debug": "^4.4.0", @@ -9858,9 +9774,9 @@ } }, "node_modules/metro-minify-terser": { - "version": "0.83.1", - "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.83.1.tgz", - "integrity": "sha512-kmooOxXLvKVxkh80IVSYO4weBdJDhCpg5NSPkjzzAnPJP43u6+usGXobkTWxxrAlq900bhzqKek4pBsUchlX6A==", + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.83.3.tgz", + "integrity": "sha512-O2BmfWj6FSfzBLrNCXt/rr2VYZdX5i6444QJU0fFoc7Ljg+Q+iqebwE3K0eTvkI6TRjELsXk1cjU+fXwAR4OjQ==", "license": "MIT", "dependencies": { "flow-enums-runtime": "^0.0.6", @@ -9871,9 +9787,9 @@ } }, "node_modules/metro-resolver": { - "version": "0.83.1", - "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.83.1.tgz", - "integrity": "sha512-t8j46kiILAqqFS5RNa+xpQyVjULxRxlvMidqUswPEk5nQVNdlJslqizDm/Et3v/JKwOtQGkYAQCHxP1zGStR/g==", + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.83.3.tgz", + "integrity": "sha512-0js+zwI5flFxb1ktmR///bxHYg7OLpRpWZlBBruYG8OKYxeMP7SV0xQ/o/hUelrEMdK4LJzqVtHAhBm25LVfAQ==", "license": "MIT", "dependencies": { "flow-enums-runtime": "^0.0.6" @@ -9883,9 +9799,9 @@ } }, "node_modules/metro-runtime": { - "version": "0.83.1", - "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.83.1.tgz", - "integrity": "sha512-3Ag8ZS4IwafL/JUKlaeM6/CbkooY+WcVeqdNlBG0m4S0Qz0om3rdFdy1y6fYBpl6AwXJwWeMuXrvZdMuByTcRA==", + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.83.3.tgz", + "integrity": "sha512-JHCJb9ebr9rfJ+LcssFYA2x1qPYuSD/bbePupIGhpMrsla7RCwC/VL3yJ9cSU+nUhU4c9Ixxy8tBta+JbDeZWw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.0", @@ -9896,9 +9812,9 @@ } }, "node_modules/metro-source-map": { - "version": "0.83.1", - "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.83.1.tgz", - "integrity": "sha512-De7Vbeo96fFZ2cqmI0fWwVJbtHIwPZv++LYlWSwzTiCzxBDJORncN0LcT48Vi2UlQLzXJg+/CuTAcy7NBVh69A==", + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.83.3.tgz", + "integrity": "sha512-xkC3qwUBh2psVZgVavo8+r2C9Igkk3DibiOXSAht1aYRRcztEZNFtAMtfSB7sdO2iFMx2Mlyu++cBxz/fhdzQg==", "license": "MIT", "dependencies": { "@babel/traverse": "^7.25.3", @@ -9906,9 +9822,9 @@ "@babel/types": "^7.25.2", "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", - "metro-symbolicate": "0.83.1", + "metro-symbolicate": "0.83.3", "nullthrows": "^1.1.1", - "ob1": "0.83.1", + "ob1": "0.83.3", "source-map": "^0.5.6", "vlq": "^1.0.0" }, @@ -9917,14 +9833,14 @@ } }, "node_modules/metro-symbolicate": { - "version": "0.83.1", - "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.83.1.tgz", - "integrity": "sha512-wPxYkONlq/Sv8Ji7vHEx5OzFouXAMQJjpcPW41ySKMLP/Ir18SsiJK2h4YkdKpYrTS1+0xf8oqF6nxCsT3uWtg==", + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.83.3.tgz", + "integrity": "sha512-F/YChgKd6KbFK3eUR5HdUsfBqVsanf5lNTwFd4Ca7uuxnHgBC3kR/Hba/RGkenR3pZaGNp5Bu9ZqqP52Wyhomw==", "license": "MIT", "dependencies": { "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", - "metro-source-map": "0.83.1", + "metro-source-map": "0.83.3", "nullthrows": "^1.1.1", "source-map": "^0.5.6", "vlq": "^1.0.0" @@ -9937,9 +9853,9 @@ } }, "node_modules/metro-transform-plugins": { - "version": "0.83.1", - "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.83.1.tgz", - "integrity": "sha512-1Y+I8oozXwhuS0qwC+ezaHXBf0jXW4oeYn4X39XWbZt9X2HfjodqY9bH9r6RUTsoiK7S4j8Ni2C91bUC+sktJQ==", + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.83.3.tgz", + "integrity": "sha512-eRGoKJU6jmqOakBMH5kUB7VitEWiNrDzBHpYbkBXW7C5fUGeOd2CyqrosEzbMK5VMiZYyOcNFEphvxk3OXey2A==", "license": "MIT", "dependencies": { "@babel/core": "^7.25.2", @@ -9954,9 +9870,9 @@ } }, "node_modules/metro-transform-worker": { - "version": "0.83.1", - "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.83.1.tgz", - "integrity": "sha512-owCrhPyUxdLgXEEEAL2b14GWTPZ2zYuab1VQXcfEy0sJE71iciD7fuMcrngoufh7e7UHDZ56q4ktXg8wgiYA1Q==", + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.83.3.tgz", + "integrity": "sha512-Ztekew9t/gOIMZX1tvJOgX7KlSLL5kWykl0Iwu2cL2vKMKVALRl1hysyhUw0vjpAvLFx+Kfq9VLjnHIkW32fPA==", "license": "MIT", "dependencies": { "@babel/core": "^7.25.2", @@ -9964,19 +9880,34 @@ "@babel/parser": "^7.25.3", "@babel/types": "^7.25.2", "flow-enums-runtime": "^0.0.6", - "metro": "0.83.1", - "metro-babel-transformer": "0.83.1", - "metro-cache": "0.83.1", - "metro-cache-key": "0.83.1", - "metro-minify-terser": "0.83.1", - "metro-source-map": "0.83.1", - "metro-transform-plugins": "0.83.1", + "metro": "0.83.3", + "metro-babel-transformer": "0.83.3", + "metro-cache": "0.83.3", + "metro-cache-key": "0.83.3", + "metro-minify-terser": "0.83.3", + "metro-source-map": "0.83.3", + "metro-transform-plugins": "0.83.3", "nullthrows": "^1.1.1" }, "engines": { "node": ">=20.19.4" } }, + "node_modules/metro/node_modules/hermes-estree": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.32.0.tgz", + "integrity": "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ==", + "license": "MIT" + }, + "node_modules/metro/node_modules/hermes-parser": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.32.0.tgz", + "integrity": "sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw==", + "license": "MIT", + "dependencies": { + "hermes-estree": "0.32.0" + } + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -10243,9 +10174,9 @@ "license": "MIT" }, "node_modules/ob1": { - "version": "0.83.1", - "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.83.1.tgz", - "integrity": "sha512-ngwqewtdUzFyycomdbdIhFLjePPSOt1awKMUXQ0L7iLHgWEPF3DsCerblzjzfAUHaXuvE9ccJymWQ/4PNNqvnQ==", + "version": "0.83.3", + "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.83.3.tgz", + "integrity": "sha512-egUxXCDwoWG06NGCS5s5AdcpnumHKJlfd3HH06P3m9TEMwwScfcY35wpQxbm9oHof+dM/lVH9Rfyu1elTVelSA==", "license": "MIT", "dependencies": { "flow-enums-runtime": "^0.0.6" @@ -10637,19 +10568,6 @@ "node": ">=6" } }, - "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "license": "MIT", - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/parse-png": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/parse-png/-/parse-png-2.1.0.tgz", @@ -11103,19 +11021,19 @@ "license": "MIT" }, "node_modules/react-native": { - "version": "0.81.4", - "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.81.4.tgz", - "integrity": "sha512-bt5bz3A/+Cv46KcjV0VQa+fo7MKxs17RCcpzjftINlen4ZDUl0I6Ut+brQ2FToa5oD0IB0xvQHfmsg2EDqsZdQ==", + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.81.5.tgz", + "integrity": "sha512-1w+/oSjEXZjMqsIvmkCRsOc8UBYv163bTWKTI8+1mxztvQPhCRYGTvZ/PL1w16xXHneIj/SLGfxWg2GWN2uexw==", "license": "MIT", "dependencies": { "@jest/create-cache-key-function": "^29.7.0", - "@react-native/assets-registry": "0.81.4", - "@react-native/codegen": "0.81.4", - "@react-native/community-cli-plugin": "0.81.4", - "@react-native/gradle-plugin": "0.81.4", - "@react-native/js-polyfills": "0.81.4", - "@react-native/normalize-colors": "0.81.4", - "@react-native/virtualized-lists": "0.81.4", + "@react-native/assets-registry": "0.81.5", + "@react-native/codegen": "0.81.5", + "@react-native/community-cli-plugin": "0.81.5", + "@react-native/gradle-plugin": "0.81.5", + "@react-native/js-polyfills": "0.81.5", + "@react-native/normalize-colors": "0.81.5", + "@react-native/virtualized-lists": "0.81.5", "abort-controller": "^3.0.0", "anser": "^1.4.9", "ansi-regex": "^5.0.0", @@ -11319,6 +11237,56 @@ "node": ">=10" } }, + "node_modules/react-native/node_modules/@react-native/codegen": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.81.5.tgz", + "integrity": "sha512-a2TDA03Up8lpSa9sh5VRGCQDXgCTOyDOFH+aqyinxp1HChG8uk89/G+nkJ9FPd0rqgi25eCTR16TWdS3b+fA6g==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/parser": "^7.25.3", + "glob": "^7.1.1", + "hermes-parser": "0.29.1", + "invariant": "^2.2.4", + "nullthrows": "^1.1.1", + "yargs": "^17.6.2" + }, + "engines": { + "node": ">= 20.19.4" + }, + "peerDependencies": { + "@babel/core": "*" + } + }, + "node_modules/react-native/node_modules/@react-native/normalize-colors": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.81.5.tgz", + "integrity": "sha512-0HuJ8YtqlTVRXGZuGeBejLE04wSQsibpTI+RGOyVqxZvgtlLLC/Ssw0UmbHhT4lYMp2fhdtvKZSs5emWB1zR/g==", + "license": "MIT" + }, + "node_modules/react-native/node_modules/@react-native/virtualized-lists": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.81.5.tgz", + "integrity": "sha512-UVXgV/db25OPIvwZySeToXD/9sKKhOdkcWmmf4Jh8iBZuyfML+/5CasaZ1E7Lqg6g3uqVQq75NqIwkYmORJMPw==", + "license": "MIT", + "dependencies": { + "invariant": "^2.2.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 20.19.4" + }, + "peerDependencies": { + "@types/react": "^19.1.0", + "react": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-native/node_modules/commander": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", diff --git a/package.json b/package.json index 61c9de3..d5576e5 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,9 @@ "@react-navigation/bottom-tabs": "^7.3.10", "@react-navigation/elements": "^2.3.8", "@react-navigation/native": "^7.1.6", - "expo": "~54.0.16", + "expo": "54.0.17", "expo-blur": "~15.0.7", - "expo-constants": "~18.0.9", + "expo-constants": "~18.0.10", "expo-font": "~14.0.8", "expo-haptics": "~15.0.7", "expo-image": "~3.0.10", @@ -28,11 +28,11 @@ "expo-splash-screen": "~31.0.10", "expo-status-bar": "~3.0.8", "expo-symbols": "~1.0.7", - "expo-system-ui": "~6.0.7", + "expo-system-ui": "~6.0.8", "expo-web-browser": "~15.0.8", "react": "19.1.0", "react-dom": "19.1.0", - "react-native": "0.81.4", + "react-native": "0.81.5", "react-native-gesture-handler": "~2.28.0", "react-native-reanimated": "~4.1.1", "react-native-safe-area-context": "~5.6.0",