From 29bde5e5e3c4514b93b85e47553e6e6bab967bb8 Mon Sep 17 00:00:00 2001 From: kamalalshinawi Date: Mon, 22 Jun 2026 18:54:44 +0300 Subject: [PATCH 1/6] feat: Add recurring countdown functionality with modern UI --- app/add.modal.tsx | 316 ++++++++- components/CounterItem.tsx | 672 +++++++++++++------- context/counterContext.tsx | 225 ++++++- package-lock.json | 1233 +++++++++++++++++++----------------- package.json | 9 +- types/counter.ts | 6 + 6 files changed, 1619 insertions(+), 842 deletions(-) diff --git a/app/add.modal.tsx b/app/add.modal.tsx index 76df3df..b5bf265 100644 --- a/app/add.modal.tsx +++ b/app/add.modal.tsx @@ -12,7 +12,7 @@ import { Button, Icon, TextInput } from "react-native-paper"; import FancyDatePicker from "@/components/FancyDatePicker"; import { useCounterContext } from "@/context/counterContext"; -import { CounterType } from "@/types/counter"; +import { CounterType, Recurrence } from "@/types/counter"; import { getMonthAsNum } from "@/types/date"; import { useNavigation } from "expo-router"; // Import useNavigation from expo-router import { @@ -49,6 +49,10 @@ export default function AddModalScreen() { const [date, setDate] = useState(new Date()); const [error, setError] = useState(""); const [showTimeExpanded, setShowTimeExpanded] = useState(false); + const [recurrence, setRecurrence] = useState("none"); + const [customDays, setCustomDays] = useState(""); + const [showRecurrencePicker, setShowRecurrencePicker] = + useState(false); const { addCounter } = useCounterContext(); @@ -165,8 +169,14 @@ export default function AddModalScreen() { addCounter({ name: newCounterName.trim(), - createdAt: date ? date.getTime() : Date.now(), // Use selected date or current time + + createdAt: date ? date.getTime() : Date.now(), type: type, + recurrence: type === "countdown" ? recurrence : "none", + customRecurrenceDays: + type === "countdown" && recurrence === "custom" + ? parseInt(customDays) || undefined + : undefined, }); // After adding, dismiss the modal navigation.goBack(); @@ -388,6 +398,209 @@ export default function AddModalScreen() { {/* */} + {/* Recurrence Picker - only show for countdown */} + {type === "countdown" && ( + + {/* Trigger Button */} + setShowRecurrencePicker(!showRecurrencePicker)} + style={[ + styles.recurrenceTrigger, + recurrence !== "none" && styles.recurrenceTriggerActive, + ]} + > + + + + + + + REPEATS + + + {recurrence === "none" + ? "Does not repeat" + : recurrence === "custom" + ? `Every ${customDays || "X"} days` + : recurrence.charAt(0).toUpperCase() + + recurrence.slice(1)} + + + + + + + {/* Options Panel */} + {showRecurrencePicker && ( + + {( + [ + "none", + "daily", + "weekly", + "monthly", + "yearly", + "custom", + ] as Recurrence[] + ).map((option) => { + const icons: Record = { + none: "close-circle-outline", + daily: "calendar-today", + weekly: "calendar-week", + monthly: "calendar-month", + yearly: "cake-variant", + custom: "calendar-edit", + }; + const labels: Record = { + none: "Does not repeat", + daily: "Daily", + weekly: "Weekly", + monthly: "Monthly", + yearly: "Yearly", + custom: "Custom", + }; + const descriptions: Record = { + none: "One-time event", + daily: "Every day", + weekly: "Every 7 days", + monthly: "Every month", + yearly: "Every year", + custom: "Set custom interval", + }; + const isSelected = recurrence === option; + + return ( + { + setRecurrence(option); + if (option !== "custom") { + setShowRecurrencePicker(false); + } + }} + style={[ + styles.recurrenceOptionModern, + isSelected && styles.recurrenceOptionModernActive, + ]} + > + + + + + + {labels[option]} + + + {descriptions[option]} + + + {isSelected && ( + + )} + + ); + })} + + {/* Custom days input */} + {recurrence === "custom" && ( + + + Repeat every + + + + days + + + )} + + )} + + )} + - {/* Right Side */} - - {formattedDate} - - {item.name} + + + + + item.id} + ListEmptyComponent={ + + + No counters {currentView === "archive" ? "archived" : "yet"}. + {currentView === "current" && !isDataLoaded && ( + + )} + {currentView === "current" && + isDataLoaded && + displayedCounters.length === 0 && ( + Press + to add one! + )} - - {/* Optional: Notification Bell Icon */} - {item.hasNotification && ( - - )} - - {/* Trash Icon */} - handleDeleteCounter(item.id)} - iconColor={theme.colors.onPrimary} - style={styles.deleteIcon} - /> - - ) : ( - - - {item.name.substring(0, 10)} - - handleDeleteCounter(item.id)} - iconColor={theme.colors.onPrimary} - style={styles.deleteIcon} - /> - - completed - - - )} - - - + } + contentContainerStyle={styles.listContent} + /> + + + ); -}; +} +// --- Styles --- const styles = StyleSheet.create({ + container: { + flex: 1, + }, + centered: { + flexGrow: 1, + justifyContent: "center", + alignItems: "center", + paddingHorizontal: 20, + paddingBottom: 50, + }, + centeredError: { + flex: 1, + justifyContent: "center", + alignItems: "center", + padding: 20, + }, + buttonLabel: { + // color: "#000", + fontSize: 15, + }, + topbtn: { + width: BUTTON_WIDTH, + padding: 5, + borderRadius: 30, + zIndex: 1, + }, + transparentButton: { + backgroundColor: "transparent", + }, + segmentContainer: { + flexDirection: "row", + width: TOP_BAR_WIDTH, // Fixed width + justifyContent: "center", // Center content + alignItems: "center", + marginBottom: 20, + gap: BUTTON_GAP, + position: "relative", + borderRadius: 10, + padding: 5, + alignSelf: "center", // Center the container itself + }, + sliderBackground: { + position: "absolute", + height: 2, + width: BUTTON_WIDTH - 3, + backgroundColor: "#4285F4", // Or any color you prefer for the slider + borderRadius: 30, // Match button border radius + left: 5, // Adjust for padding + top: 45, // Adjust for padding + elevation: 1, + zIndex: 0, + }, + segmentButtons: { + borderRadius: 10, + }, + segmentSelected: { + backgroundColor: "#FEC9CE", + }, + segmentUnselected: { + backgroundColor: "transparent", + }, + segmentSelectedLabel: { + fontFamily: "Roboto-Regular", + fontSize: 16, + color: "#333", + fontWeight: "600", + }, + segmentUnselectedLabel: { + fontFamily: "Roboto-Regular", + fontSize: 14, + color: "#555", + }, + listContent: { + paddingHorizontal: 15, + paddingBottom: 30, + paddingTop: 10, + flexGrow: 1, + }, cardContainer: { marginVertical: 7, borderRadius: 18, @@ -319,6 +556,13 @@ const styles = StyleSheet.create({ right: 5, zIndex: 1, }, + emptyText: { + textAlign: "center", + fontSize: 30, + fontFamily: "my-font", + color: "#777", + marginTop: 15, + lineHeight: 35, + fontWeight: "condensedBold", + }, }); - -export default memo(CounterItem); diff --git a/context/counterContext.tsx b/context/counterContext.tsx index 7066d81..f3d8f96 100644 --- a/context/counterContext.tsx +++ b/context/counterContext.tsx @@ -33,8 +33,46 @@ Notifications.setNotificationHandler({ }), }); +import { Recurrence } from "@/types/counter"; + const STORAGE_KEY = "@days_since_app_data_v2"; +// --- Helper: Calculate next recurrence date --- +function getNextRecurrenceDate( + currentTargetDate: number, + recurrence: Recurrence, + customDays?: number, +): number | null { + const date = new Date(currentTargetDate); + + switch (recurrence) { + case "daily": + date.setDate(date.getDate() + 1); + break; + case "weekly": + date.setDate(date.getDate() + 7); + break; + case "monthly": + date.setMonth(date.getMonth() + 1); + break; + case "yearly": + date.setFullYear(date.getFullYear() + 1); + break; + case "custom": + if (customDays && customDays > 0) { + date.setDate(date.getDate() + customDays); + } else { + return null; + } + break; + case "none": + default: + return null; + } + + return date.getTime(); +} + type CounterContextType = { counters: Counter[]; setCounters: Dispatch>; @@ -46,7 +84,8 @@ type CounterContextType = { | "completed" | "notificationId" | "todayNotificationId" - > & { createdAt: number } + | "nextRecurrenceDate" + > & { createdAt: number }, ) => void; updateCounter: (id: string, updates: Partial) => void; deleteCounter: (id: string) => void; @@ -124,22 +163,156 @@ export const CounterProvider = ({ } if (finalStatus !== "granted") { alert( - "Failed to get push token for push notification! You might miss countdown alerts." + "Failed to get push token for push notification! You might miss countdown alerts.", ); } })(); }, []); + // --- Helper: Schedule notifications for a countdown counter --- + const scheduleCountdownNotifications = useCallback( + async ( + counterName: string, + targetDate: number, + counterId: string, + ): Promise<{ exactId?: string; todayId?: string }> => { + const triggerDate = new Date(targetDate); + const now = new Date(); + let exactId: string | undefined; + let todayId: string | undefined; + + if (triggerDate.getTime() > now.getTime()) { + try { + exactId = await Notifications.scheduleNotificationAsync({ + content: { + title: "Countdown Finished!", + body: `${counterName.substring(0, 10)}`, + data: { counterId, notificationType: "exactTime" }, + }, + trigger: { + type: Notifications.SchedulableTriggerInputTypes.DATE, + date: triggerDate, + }, + }); + } catch (error) { + console.error("Error scheduling exact time notification:", error); + } + + const todayNotificationTime = new Date(triggerDate); + todayNotificationTime.setHours(21, 0, 0, 0); + + if ( + todayNotificationTime.getTime() > now.getTime() && + todayNotificationTime.getDate() === triggerDate.getDate() && + todayNotificationTime.getMonth() === triggerDate.getMonth() && + todayNotificationTime.getFullYear() === triggerDate.getFullYear() + ) { + try { + todayId = await Notifications.scheduleNotificationAsync({ + content: { + title: "Countdown Update!", + body: `${counterName} ends today at ${triggerDate.toLocaleTimeString( + [], + { + hour: "2-digit", + minute: "2-digit", + }, + )}!`, + data: { counterId, notificationType: "today" }, + vibrate: [2, 3, 4], + interruptionLevel: "active", + sticky: true, + }, + trigger: { + type: Notifications.SchedulableTriggerInputTypes.DATE, + date: todayNotificationTime, + }, + }); + } catch (error) { + console.error("Error scheduling 'today' notification:", error); + } + } + } + + return { exactId, todayId }; + }, + [], + ); + // Function to mark a counter as completed - const markCounterCompleted = useCallback((counterId: string) => { - setCounters((prevCounters) => - prevCounters.map((counter) => - counter.id === counterId - ? { ...counter, completed: true, isArchived: true } - : counter - ) - ); - }, []); + // If recurring, auto-reschedules to the next occurrence instead of archiving + const markCounterCompleted = useCallback( + (counterId: string) => { + setCounters((prevCounters) => { + const counter = prevCounters.find((c) => c.id === counterId); + if (!counter) return prevCounters; + + // If recurring countdown, reschedule instead of archiving + if ( + counter.type === "countdown" && + counter.recurrence && + counter.recurrence !== "none" + ) { + const nextDate = getNextRecurrenceDate( + counter.createdAt, + counter.recurrence, + counter.customRecurrenceDays, + ); + + if (nextDate) { + // Cancel old notifications + if (counter.notificationId) { + Notifications.cancelScheduledNotificationAsync( + counter.notificationId, + ).catch(() => {}); + } + if (counter.todayNotificationId) { + Notifications.cancelScheduledNotificationAsync( + counter.todayNotificationId, + ).catch(() => {}); + } + + // Schedule new notifications for next occurrence + scheduleCountdownNotifications( + counter.name, + nextDate, + counter.id, + ).then(({ exactId, todayId }) => { + setCounters((current) => + current.map((c) => + c.id === counterId + ? { + ...c, + notificationId: exactId, + todayNotificationId: todayId, + } + : c, + ), + ); + }); + + return prevCounters.map((c) => + c.id === counterId + ? { + ...c, + createdAt: nextDate, + completed: false, + isArchived: false, + nextRecurrenceDate: nextDate, + } + : c, + ); + } + } + + // Default: mark as completed and archived + return prevCounters.map((c) => + c.id === counterId ? { ...c, completed: true, isArchived: true } : c, + ); + }); + }, + [scheduleCountdownNotifications], + ); // Handle incoming notifications useEffect(() => { @@ -190,7 +363,7 @@ export const CounterProvider = ({ | "completed" | "notificationId" | "todayNotificationId" - > & { createdAt: number } + > & { createdAt: number }, ) => { const id = String(Date.now()); @@ -218,7 +391,7 @@ export const CounterProvider = ({ }, }); console.log( - `Exact time notification scheduled for ${newCounterData.name} with ID: ${exactTimeNotificationId}` + `Exact time notification scheduled for ${newCounterData.name} with ID: ${exactTimeNotificationId}`, ); } catch (error) { console.error("Error scheduling exact time notification:", error); @@ -259,7 +432,7 @@ export const CounterProvider = ({ }, }); console.log( - `"Today" notification scheduled for ${newCounterData.name} with ID: ${todayNotificationId}` + `"Today" notification scheduled for ${newCounterData.name} with ID: ${todayNotificationId}`, ); } catch (error) { console.error("Error scheduling 'today' notification:", error); @@ -283,7 +456,7 @@ export const CounterProvider = ({ title: "", body: `${newCounterData.name.substring( 0, - 10 + 10, )} has been reached`, data: { counterId: id, notificationType: "exactTime" }, interruptionLevel: "timeSensitive", @@ -291,7 +464,7 @@ export const CounterProvider = ({ trigger: null, // null trigger means immediate }); console.log( - `Immediate notification sent for ${newCounterData.name} with ID: ${exactTimeNotificationId}` + `Immediate notification sent for ${newCounterData.name} with ID: ${exactTimeNotificationId}`, ); markCounterCompleted(id); // Mark as completed immediately } catch (error) { @@ -312,14 +485,14 @@ export const CounterProvider = ({ setCounters((prevCounters) => [...prevCounters, newCounter]); }, - [markCounterCompleted] + [markCounterCompleted], ); // Depend on markCounterCompleted const updateCounter = useCallback((id: string, updates: Partial) => { setCounters((prevCounters) => prevCounters.map((counter) => - counter.id === id ? { ...counter, ...updates } : counter - ) + counter.id === id ? { ...counter, ...updates } : counter, + ), ); }, []); @@ -331,10 +504,10 @@ export const CounterProvider = ({ if (counterToDelete.notificationId) { try { await Notifications.cancelScheduledNotificationAsync( - counterToDelete.notificationId + counterToDelete.notificationId, ); console.log( - `Cancelled notification ${counterToDelete.notificationId}` + `Cancelled notification ${counterToDelete.notificationId}`, ); } catch (error) { console.error("Error cancelling notification:", error); @@ -343,10 +516,10 @@ export const CounterProvider = ({ if (counterToDelete.todayNotificationId) { try { await Notifications.cancelScheduledNotificationAsync( - counterToDelete.todayNotificationId + counterToDelete.todayNotificationId, ); console.log( - `Cancelled today notification ${counterToDelete.todayNotificationId}` + `Cancelled today notification ${counterToDelete.todayNotificationId}`, ); } catch (error) { console.error("Error cancelling today notification:", error); @@ -355,10 +528,10 @@ export const CounterProvider = ({ } setCounters((prevCounters) => - prevCounters.filter((counter) => counter.id !== id) + prevCounters.filter((counter) => counter.id !== id), ); }, - [counters] + [counters], ); const contextValue = useMemo( @@ -377,7 +550,7 @@ export const CounterProvider = ({ updateCounter, deleteCounter, markCounterCompleted, - ] + ], ); // Splash screen while loading diff --git a/package-lock.json b/package-lock.json index 2d55e3d..0d6a850 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,15 +13,16 @@ "@react-navigation/elements": "^2.6.3", "@react-navigation/native": "^7.1.8", "@react-navigation/stack": "^7.6.13", + "babel-preset-expo": "~54.0.10", "date-fns": "^4.1.0", "expo": "~54.0.30", "expo-build-properties": "~1.0.10", - "expo-constants": "~18.0.12", - "expo-font": "~14.0.10", + "expo-constants": "~18.0.13", + "expo-font": "~14.0.12", "expo-haptics": "~15.0.8", "expo-linear-gradient": "~15.0.8", - "expo-notifications": "~0.32.15", - "expo-router": "~6.0.21", + "expo-notifications": "~0.32.17", + "expo-router": "~6.0.24", "expo-splash-screen": "~31.0.13", "expo-status-bar": "~3.0.9", "expo-symbols": "~1.0.8", @@ -47,9 +48,9 @@ } }, "node_modules/@0no-co/graphql.web": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.2.0.tgz", - "integrity": "sha512-/1iHy9TTr63gE1YcR5idjx8UREz1s0kFhydf3bBLCXyqjhkIc6igAzTOx3zPifCwFR87tsh/4Pa9cNts6d2otw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.3.2.tgz", + "integrity": "sha512-Q1+pRlLhE31GOY/2c9BAEnFTNxO7Awtc6fhhEDlxyCBQ2N0IhD32cPVvPChrK9mwBNSgRdW/sF1kd2e0ojHj1Q==", "license": "MIT", "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" @@ -75,9 +76,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", - "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -114,13 +115,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -130,25 +131,25 @@ } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", - "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz", + "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==", "license": "MIT", "dependencies": { - "@babel/types": "^7.27.3" + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -158,17 +159,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", - "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz", + "integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-member-expression-to-functions": "^7.28.5", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.28.5", + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/traverse": "^7.29.7", "semver": "^6.3.1" }, "engines": { @@ -179,12 +180,12 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", - "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.29.7.tgz", + "integrity": "sha512-907Uymvqgg1dwUA+7IGwFAOSYzQOuzPXKNJ1yxzwPffzkYFg2q2eHi1fIOs6sXkG9NbIUMunnUlkYsfRFNvomg==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-annotate-as-pure": "^7.29.7", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, @@ -196,51 +197,51 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", - "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", + "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "debug": "^4.4.1", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "debug": "^4.4.3", "lodash.debounce": "^4.0.8", - "resolve": "^1.22.10" + "resolve": "^1.22.11" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", - "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz", + "integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -264,35 +265,35 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", - "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz", + "integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==", "license": "MIT", "dependencies": { - "@babel/types": "^7.27.1" + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", - "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.29.7.tgz", + "integrity": "sha512-16AMiW26DbXWBbr3B8wNozKM0ydMLB892vaOaJW/fPJdnT8vJk5sdkQcU/isqUxyCE0cEoa8wZOcbgDuC4b6Og==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-wrap-function": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-wrap-function": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -302,14 +303,14 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", - "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz", + "integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==", "license": "MIT", "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.27.1", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -319,54 +320,54 @@ } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", - "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz", + "integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", - "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.29.7.tgz", + "integrity": "sha512-iES0Skag9ERIF68aXadpO6dbXa03mNWK3sEqJaMnLNs/eC3l0lkImdfoy6Y09/SfkpawdAB4RjQ7PVA7TcVGdw==", "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.3", - "@babel/types": "^7.28.2" + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -472,12 +473,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", "license": "MIT", "dependencies": { - "@babel/types": "^7.28.5" + "@babel/types": "^7.29.7" }, "bin": { "parser": "bin/babel-parser.js" @@ -487,14 +488,14 @@ } }, "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.28.0.tgz", - "integrity": "sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.7.tgz", + "integrity": "sha512-EtU0Hi3GvrTqD56xKmZvV/uCXK2ZbwVNPNLAquVItcAZpUhkXwWlo3Fmj0c2LxgSf2I8IDULeAepwNP1OefLXg==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-syntax-decorators": "^7.27.1" + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-syntax-decorators": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -504,12 +505,12 @@ } }, "node_modules/@babel/plugin-proposal-export-default-from": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.27.1.tgz", - "integrity": "sha512-hjlsMBl1aJc5lp8MoCDEZCiYzlgdRAShOjAfRw6X+GlpLpUPU7c3XNLsKFZbQk/1cRzBlJ7CXg3xJAJMrFa1Uw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.29.7.tgz", + "integrity": "sha512-p+G5BNXDcy3bOXplhY4HybQ1GxH3i2Tppmdm/3epyRu2VgJJZuUlZ61MqRTg582Q7ZLBdP7fePYvsumSEkMxcQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -570,12 +571,12 @@ } }, "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.27.1.tgz", - "integrity": "sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.29.7.tgz", + "integrity": "sha512-9MTTLbF39X6sqM92JPEsoI7++26hjZvzkxKZy64aMhWLH2mPkJ/Q3AV4QLmls3R14FpSpkOwQQfUh962JGQxxg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -597,12 +598,12 @@ } }, "node_modules/@babel/plugin-syntax-export-default-from": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.27.1.tgz", - "integrity": "sha512-eBC/3KSekshx19+N40MzjWqJd7KTEdOoLesAfa4IDFI8eRz5a47i5Oszus6zG/cwIXN63YhgLOMSSNJx49sENg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.29.7.tgz", + "integrity": "sha512-foag0BB37ROhdeIX9O8G0jX7hw0UekJc04cHMrYLOnrErsnBKqJGHJ8eDRpoCFZBvEPPygmmtw4qyU97qa4oOw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -612,12 +613,12 @@ } }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.27.1.tgz", - "integrity": "sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.29.7.tgz", + "integrity": "sha512-ajMX6QPcyomotqwpzhkYGxcK2i/us0rs1Qo9QvUpa+Fca0FTmqrzKrctoIYLMxcOhGZldGT/BAVkRGTWBiR8gQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -666,12 +667,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -813,14 +814,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", - "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.7.tgz", + "integrity": "sha512-d98gXZkgswvkyohMBABkhm3GeXhYj8psWfwQ2C7gtfrKGTykQa/iOIi+JJhwMjPlZ6Vm2XN+DCf3Es1EoG4ZLA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-remap-async-to-generator": "^7.27.1", - "@babel/traverse": "^7.28.0" + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-remap-async-to-generator": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -830,14 +831,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", - "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.29.7.tgz", + "integrity": "sha512-pcUb2SS+RMo9TWVBwKGI5ShtoG7R+zBsFmCKDa6fe8c+hPr3XJlZgoE5j6i8W7gDjhyvy+85vmYexanvXh3d1w==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-remap-async-to-generator": "^7.27.1" + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-remap-async-to-generator": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -847,12 +848,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz", - "integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.29.7.tgz", + "integrity": "sha512-ONyr4+AZhKh8yKWInVxU9AXA9EbsyeLcL6V0dJy6M2/62vuvpGm29zzuymbTpdc451GEpDIdAyPLP3r+P61yKQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -878,13 +879,13 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", - "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.29.7.tgz", + "integrity": "sha512-kibJgmEdX2iMwsHY2tSZNDgj8PwIlCQz7FK9KuGKO8zsuoUwSEhoNnNVp/emKWrbY4HeO6kkXfdMqRKKKXBm2A==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -914,13 +915,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", - "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.29.7.tgz", + "integrity": "sha512-RK7/IyU5phpuCdBAuig5VkzG/EnbDaui5SQGdU9BFrHdV+mV4cUjLMQ9lJDjLNtWHsqtiefpGZUXQP2BiTYMsA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/template": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/template": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -930,13 +931,13 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", - "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.29.7.tgz", + "integrity": "sha512-iPX8aD6H9zV5s7ZsqTdNocPN/MGQ5sSMnElKrktxjJRMnB2jN/1p2+R7GkfD6CAYoVFqy5A4XnSIUeGgJzIWpg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.5" + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -946,12 +947,12 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", - "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.29.7.tgz", + "integrity": "sha512-24B2nOy2TeJSMheqwPD4DDQOV/elLSIlKxjZt4i05H5AgdPdWR3n18HnNrcJ+j76WJd9gbwb9jPjNYUy6RautA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -961,13 +962,13 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.27.1.tgz", - "integrity": "sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.29.7.tgz", + "integrity": "sha512-wRHeUjUjCZnMHmiO5bRgjFLcoEh7JyTdByOW11ahhwNa4V0bmeGEaIvt51yq0zQp2yWIpqfxXXPyUP6GFJZHOQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-syntax-flow": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-syntax-flow": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -977,13 +978,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", - "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.29.7.tgz", + "integrity": "sha512-zeSIHh0+E1Um1WJRXCFlHQYu2ieJNdivLLjlBEp+dIBu3S51n+SZZmIXjxnItw6pz56Cn+KvK68BIBVsxq2JiQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -993,14 +994,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", - "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.29.7.tgz", + "integrity": "sha512-otRWaHXE6fbAGkePvaj/kvs3HsqXfPhlnzwSOlnFgbqCPMd975dW+4wZ00WFBt+/YlBGcJwNrARQTOJOb4ZrIg==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1010,12 +1011,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", - "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.29.7.tgz", + "integrity": "sha512-DZ/oLP21ZuWx1vKqnoNv6/tvEK48AQOBRai40CX9dTjGluvT/YZCyY3rryDtyUqCEoyNroy5KKPwX2iQCiRvyw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1025,12 +1026,12 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz", - "integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.29.7.tgz", + "integrity": "sha512-A0H91hh6W8MFRkp5TqJmMr39jzGD1A1E1Ysiv2O06Sfbhkapm+XyIzxWCEh5kqwOZ1/8QZ0dY3SeQ7XBqfJd5Q==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1056,13 +1057,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.7.tgz", + "integrity": "sha512-vuFoLwr4qnv2xbZ16SQd6uPcH5FNrLHhk/Jzo++0XJFcaDsr4gjJVg6j398oMHiC+83k/GiBzviwF5KBJkPUtQ==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1087,12 +1088,12 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", - "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.29.7.tgz", + "integrity": "sha512-zR7fv/z14OjgHl4AgRtkDBvBMhIzCxqV/qN/2BCRC7LjFwvuzjYe7gDWxC4Wl/SNsLM6SE1IWvRPYMgSJaUvNw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1102,16 +1103,16 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", - "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.29.7.tgz", + "integrity": "sha512-Ld98jn4c0smUywL57m7SgsHq3OpThOa6LqZJif3G6jYOovPleoFhVrBJ1WegRApSFB2wu4+RelAj9AC9G08Z4A==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0", - "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/traverse": "^7.28.4" + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-transform-destructuring": "^7.29.7", + "@babel/plugin-transform-parameters": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1121,12 +1122,12 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", - "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.29.7.tgz", + "integrity": "sha512-sLsyndxK2VwX6yNUOakMb7Sh553ZTe/vVM1XJ+9Z5aW1ytsc8xOIwmyk05NNjN60vkc5/KqoTH6hB4V41LJhng==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1152,12 +1153,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.27.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", - "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.29.7.tgz", + "integrity": "sha512-ZDOBqV/qLYJI0YElr8DcENEyARsFQeESqWXH6gZlghYXuPPjvweuDhP4VyEi4BlUBlLRFZVjxoZDMjxhLW766g==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1167,13 +1168,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", - "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.29.7.tgz", + "integrity": "sha512-/6Rz4DK1ETDEM/bWHsPHcaEe7ZaT1EqSXjtSP/L0DijOYuaUhiRiOKcwpZ8P7zR4xXEHc2ITdiCgBm9Tpyv9ug==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1183,14 +1184,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", - "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.29.7.tgz", + "integrity": "sha512-+BNo06dnrzdNNqCm1X6YUaVv0DKk8Q+JYcoZfOkLhYWNCXzlwTSRq8zGWayT1csjcpNXV9CQTBRRbmTLZac5cA==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1200,12 +1201,12 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz", - "integrity": "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.29.7.tgz", + "integrity": "sha512-+1wdDMGNb4UPeY3Q4L5yLiYe6TXPXubs4NjrgRFw13hPRLJfEMw2Q5OXkee6/IfdqePIeW4Jjwe3aBh7SdKz4Q==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1215,16 +1216,16 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz", - "integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.29.7.tgz", + "integrity": "sha512-WsZulLVBUHXVj2cUcPVx6UE21TpalB6bHbSFErKT0Ib++ax24jjXe73FqlWvdylFOjiuPHYi6VCcgRad1ItN+A==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-syntax-jsx": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1234,12 +1235,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz", - "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.29.7.tgz", + "integrity": "sha512-Xfy3UVMF04+ypnFbkhvfqtmvwfe92qwQdbGZVonhE+6v35GzlofmOnA1szaZqzb9xYWr0nl1e5EMmzi0DNON1g==", "license": "MIT", "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.27.1" + "@babel/plugin-transform-react-jsx": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1249,12 +1250,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", - "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1264,12 +1265,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", - "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1279,13 +1280,13 @@ } }, "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz", - "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.29.7.tgz", + "integrity": "sha512-H5E+HBgDpr6Q5t+Aj11tL7XkIui1jhbIoArVQnqjgXo5/3YxkN7ZEBcWF4RQlB0T4rrxJQbXS6kiFV6B7XTqUA==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1295,12 +1296,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", - "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.7.tgz", + "integrity": "sha512-rNNFV0DBAJp988xW2DOntfDoYn1eR8GGF5AT5vYc+rjyfaQkM242c9tZUHHPe7KYaiJizXPWhQTzzdbXySyhBw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1310,13 +1311,13 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz", - "integrity": "sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.7.tgz", + "integrity": "sha512-xmAscdE/AsqRW7vutbPNoUmu/nF5SrLKPs7aoJgEjo35lLKA/Bc0i2rMv/hr1+Y0o1bQCiVtith3u2vdgRL39Q==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", @@ -1345,13 +1346,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", - "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.29.7.tgz", + "integrity": "sha512-/u5K1QWada7tbYNqTjMh96718g9NTwh9tfPJMsSmVsQwGT447FskV+KcfeXkXq2GWki4EM/MuTdmBec+hOuVTQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1361,12 +1362,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", - "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.29.7.tgz", + "integrity": "sha512-BCHzNYJGe9l7EpwwDBN/ztlL2NYFFq8hp9ddjtUEM9f2O7S7kKV/lL6Fwo7IF7NSkYhPK2vO+86nIGltA90MsA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1427,17 +1428,17 @@ } }, "node_modules/@babel/preset-react": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.28.5.tgz", - "integrity": "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.29.7.tgz", + "integrity": "sha512-C+PV1TFUPTmBQGoPBL8j2QmLpZ117YTCwxIZeJOM96GbYMFSc7/pOXU5lVykwnZxyTqQxRsvoRk6f2FktZgGHA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-transform-react-display-name": "^7.28.0", - "@babel/plugin-transform-react-jsx": "^7.27.1", - "@babel/plugin-transform-react-jsx-development": "^7.27.1", - "@babel/plugin-transform-react-pure-annotations": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "@babel/plugin-transform-react-display-name": "^7.29.7", + "@babel/plugin-transform-react-jsx": "^7.29.7", + "@babel/plugin-transform-react-jsx-development": "^7.29.7", + "@babel/plugin-transform-react-pure-annotations": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1475,31 +1476,45 @@ } }, "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", "debug": "^4.3.1" }, "engines": { @@ -1525,14 +1540,28 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -1751,13 +1780,12 @@ } }, "node_modules/@expo/code-signing-certificates": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.5.tgz", - "integrity": "sha512-BNhXkY1bblxKZpltzAx98G2Egj9g1Q+JRcvR7E99DOj862FTCX+ZPsAUtPTr7aHxwtrL7+fL3r0JSmM9kBm+Bw==", + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.6.tgz", + "integrity": "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w==", "license": "MIT", "dependencies": { - "node-forge": "^1.2.1", - "nullthrows": "^1.1.1" + "node-forge": "^1.3.3" } }, "node_modules/@expo/config": { @@ -1896,9 +1924,9 @@ } }, "node_modules/@expo/fingerprint": { - "version": "0.15.4", - "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.15.4.tgz", - "integrity": "sha512-eYlxcrGdR2/j2M6pEDXo9zU9KXXF1vhP+V+Tl+lyY+bU8lnzrN6c637mz6Ye3em2ANy8hhUR03Raf8VsT9Ogng==", + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.15.5.tgz", + "integrity": "sha512-mdVoAMcux1WlM6kd1RoWiHRNqKqS+J6mKmWQ/BKgeh937S/fcW58EE68O6nc4KDXtWi3PBeNHskOFcgyIuD4hw==", "license": "MIT", "dependencies": { "@expo/spawn-async": "^1.7.2", @@ -1908,7 +1936,7 @@ "getenv": "^2.0.0", "glob": "^13.0.0", "ignore": "^5.3.1", - "minimatch": "^9.0.0", + "minimatch": "^10.2.2", "p-limit": "^3.1.0", "resolve-from": "^5.0.0", "semver": "^7.6.0" @@ -1917,34 +1945,46 @@ "fingerprint": "bin/cli.js" } }, + "node_modules/@expo/fingerprint/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@expo/fingerprint/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@expo/fingerprint/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "license": "ISC", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@expo/fingerprint/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -2024,67 +2064,6 @@ "metro-transform-worker": "0.83.3" } }, - "node_modules/@expo/metro-config": { - "version": "54.0.12", - "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-54.0.12.tgz", - "integrity": "sha512-Xhv1z/ak/cuJWeLxlnWr2u22q2AM/klASbjpP5eE34y91lGWa2NUwrFWoS830MhJ6kuAqtGdoQhwyPa3TES7sA==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.20.0", - "@babel/core": "^7.20.0", - "@babel/generator": "^7.20.5", - "@expo/config": "~12.0.13", - "@expo/env": "~2.0.8", - "@expo/json-file": "~10.0.8", - "@expo/metro": "~54.2.0", - "@expo/spawn-async": "^1.7.2", - "browserslist": "^4.25.0", - "chalk": "^4.1.0", - "debug": "^4.3.2", - "dotenv": "~16.4.5", - "dotenv-expand": "~11.0.6", - "getenv": "^2.0.0", - "glob": "^13.0.0", - "hermes-parser": "^0.29.1", - "jsc-safe-url": "^0.2.4", - "lightningcss": "^1.30.1", - "minimatch": "^9.0.0", - "postcss": "~8.4.32", - "resolve-from": "^5.0.0" - }, - "peerDependencies": { - "expo": "*" - }, - "peerDependenciesMeta": { - "expo": { - "optional": true - } - } - }, - "node_modules/@expo/metro-config/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@expo/metro-config/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@expo/metro-runtime": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/@expo/metro-runtime/-/metro-runtime-6.1.2.tgz", @@ -2405,36 +2384,45 @@ } }, "node_modules/@expo/osascript": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.3.8.tgz", - "integrity": "sha512-/TuOZvSG7Nn0I8c+FcEaoHeBO07yu6vwDgk7rZVvAXoeAK5rkA09jRyjYsZo+0tMEFaToBeywA6pj50Mb3ny9w==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.6.0.tgz", + "integrity": "sha512-QvqDBlJXa8CS2vRORJ4wEflY1m0vVI07uSJdIRgBrLxRPBcsrXxrtU7+wXRXMqfq9zLwNP9XbvRsXF2omoDylg==", "license": "MIT", "dependencies": { - "@expo/spawn-async": "^1.7.2", - "exec-async": "^2.2.0" + "@expo/spawn-async": "^1.8.0" }, "engines": { "node": ">=12" } }, "node_modules/@expo/package-manager": { - "version": "1.9.9", - "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.9.9.tgz", - "integrity": "sha512-Nv5THOwXzPprMJwbnXU01iXSrCp3vJqly9M4EJ2GkKko9Ifer2ucpg7x6OUsE09/lw+npaoUnHMXwkw7gcKxlg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.12.1.tgz", + "integrity": "sha512-fQLiFAcFRWF53mtuLK32SUJQ1ahhrTcBZPZPedYTiUT5ha5FF+UO6bPtCc0Y/hgj0/m3HCGBAuSHjbg2kI9oPQ==", "license": "MIT", "dependencies": { - "@expo/json-file": "^10.0.8", - "@expo/spawn-async": "^1.7.2", + "@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" } }, + "node_modules/@expo/package-manager/node_modules/@expo/json-file": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.2.0.tgz", + "integrity": "sha512-S6XzKe3R9GQeHiUPXc3xJjOv2VJhOEwFYf7xdC2z2cUqt3kZJ9mSO877sNQloVdnW/SUCtPY3bexlM7nwq+CAQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.20.0", + "json5": "^2.2.3" + } + }, "node_modules/@expo/plist": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.4.8.tgz", - "integrity": "sha512-pfNtErGGzzRwHP+5+RqswzPDKkZrx+Cli0mzjQaus1ZWFsog5ibL+nVT3NcporW51o8ggnt7x813vtRbPiyOrQ==", + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.4.9.tgz", + "integrity": "sha512-MPVpmKGfnQEnrCzgxuXcmPP/y/t6AVm+DcSb2Myp21LKWv1N3l8uFxMggesfF4ixAxkRlGmMMx9GyDC9M+XklQ==", "license": "MIT", "dependencies": { "@xmldom/xmldom": "^0.8.8", @@ -2488,12 +2476,12 @@ "license": "MIT" }, "node_modules/@expo/spawn-async": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.7.2.tgz", - "integrity": "sha512-QdWi16+CHB9JYP7gma19OVVg0BFkvU8zNj9GjWorYI8Iv8FUxjOCcYRuAmX4s/h91e4e7BPsskc8cSrZYho9Ew==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.8.0.tgz", + "integrity": "sha512-eb9xxd/LbuEGSdua4NumCu/McVB9EM+F/JxB9pWgnERw4HQ9XyTNH1KapG6oqLWR8TuRK2LQfzJlmNi94CVobw==", "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.3" + "cross-spawn": "^7.0.6" }, "engines": { "node": ">=12" @@ -2523,29 +2511,19 @@ "license": "MIT" }, "node_modules/@expo/xcpretty": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.3.2.tgz", - "integrity": "sha512-ReZxZ8pdnoI3tP/dNnJdnmAk7uLT4FjsKDGW7YeDdvdOMz2XCQSmSCM9IWlrXuWtMF9zeSB6WJtEhCQ41gQOfw==", + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.4.4.tgz", + "integrity": "sha512-4aQzz9vgxcNXFfo/iyNgDDYfsU5XGKKxWxZopw0cVotHiW+U8IJbIxMaxsINs6bHhtkG3StKNPcOrn3eBuxKPw==", "license": "BSD-3-Clause", "dependencies": { - "@babel/code-frame": "7.10.4", + "@babel/code-frame": "^7.20.0", "chalk": "^4.1.0", - "find-up": "^5.0.0", "js-yaml": "^4.1.0" }, "bin": { "excpretty": "build/cli.js" } }, - "node_modules/@expo/xcpretty/node_modules/@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -4678,13 +4656,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", - "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", + "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.7", - "@babel/helper-define-polyfill-provider": "^0.6.5", + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", "semver": "^6.3.1" }, "peerDependencies": { @@ -4705,12 +4683,12 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", - "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.5" + "@babel/helper-define-polyfill-provider": "^0.6.8" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -4776,9 +4754,9 @@ } }, "node_modules/babel-preset-expo": { - "version": "54.0.9", - "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-54.0.9.tgz", - "integrity": "sha512-8J6hRdgEC2eJobjoft6mKJ294cLxmi3khCUy2JJQp4htOYYkllSLUq6vudWJkTJiIuGdVR4bR6xuz2EvJLWHNg==", + "version": "54.0.11", + "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-54.0.11.tgz", + "integrity": "sha512-dEpeFDtYEFzmWtWVwvt7sUCZH0fxXPfbJlgXd7XNZSQDa/Ki/hTOj9exMTzqR2oyPHDNcE9VxYCJ4oS6xw4Pjg==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.25.9", @@ -5389,12 +5367,12 @@ "license": "MIT" }, "node_modules/core-js-compat": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz", - "integrity": "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==", + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", "license": "MIT", "dependencies": { - "browserslist": "^4.28.0" + "browserslist": "^4.28.1" }, "funding": { "type": "opencollective", @@ -6382,36 +6360,30 @@ "node": ">=6" } }, - "node_modules/exec-async": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/exec-async/-/exec-async-2.2.0.tgz", - "integrity": "sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw==", - "license": "MIT" - }, "node_modules/expo": { - "version": "54.0.30", - "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.30.tgz", - "integrity": "sha512-6q+aFfKL0SpT8prfdpR3V8HcN51ov0mCGuwQTzyuk6eeO9rg7a7LWbgPv9rEVXGZEuyULstL8LGNwHqusand7Q==", + "version": "54.0.35", + "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.35.tgz", + "integrity": "sha512-E+tXpQwjGm5fK/uwa55p0Xx/kuo5dXDKfVJ95IargTNa5KiFt26lSTXXa9KnHbI4EDLwFD38/xTKZvzPTlGTdg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.0", - "@expo/cli": "54.0.20", + "@expo/cli": "54.0.25", "@expo/config": "~12.0.13", "@expo/config-plugins": "~54.0.4", "@expo/devtools": "0.1.8", - "@expo/fingerprint": "0.15.4", + "@expo/fingerprint": "0.15.5", "@expo/metro": "~54.2.0", - "@expo/metro-config": "54.0.12", + "@expo/metro-config": "54.0.16", "@expo/vector-icons": "^15.0.3", "@ungap/structured-clone": "^1.3.0", - "babel-preset-expo": "~54.0.9", - "expo-asset": "~12.0.12", - "expo-constants": "~18.0.12", - "expo-file-system": "~19.0.21", - "expo-font": "~14.0.10", + "babel-preset-expo": "~54.0.11", + "expo-asset": "~12.0.13", + "expo-constants": "~18.0.13", + "expo-file-system": "~19.0.23", + "expo-font": "~14.0.12", "expo-keep-awake": "~15.0.8", - "expo-modules-autolinking": "3.0.23", - "expo-modules-core": "3.0.29", + "expo-modules-autolinking": "3.0.26", + "expo-modules-core": "3.0.30", "pretty-format": "^29.7.0", "react-refresh": "^0.14.2", "whatwg-url-without-unicode": "8.0.0-3" @@ -6449,21 +6421,6 @@ "expo": "*" } }, - "node_modules/expo-asset": { - "version": "12.0.12", - "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-12.0.12.tgz", - "integrity": "sha512-CsXFCQbx2fElSMn0lyTdRIyKlSXOal6ilLJd+yeZ6xaC7I9AICQgscY5nj0QcwgA+KYYCCEQEBndMsmj7drOWQ==", - "license": "MIT", - "dependencies": { - "@expo/image-utils": "^0.8.8", - "expo-constants": "~18.0.12" - }, - "peerDependencies": { - "expo": "*", - "react": "*", - "react-native": "*" - } - }, "node_modules/expo-build-properties": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/expo-build-properties/-/expo-build-properties-1.0.10.tgz", @@ -6512,12 +6469,12 @@ } }, "node_modules/expo-constants": { - "version": "18.0.12", - "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.12.tgz", - "integrity": "sha512-WzcKYMVNRRu4NcSzfIVRD5aUQFnSpTZgXFrlWmm19xJoDa4S3/PQNi6PNTBRc49xz9h8FT7HMxRKaC8lr0gflA==", + "version": "18.0.13", + "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.13.tgz", + "integrity": "sha512-FnZn12E1dRYKDHlAdIyNFhBurKTS3F9CrfrBDJI5m3D7U17KBHMQ6JEfYlSj7LG7t+Ulr+IKaj58L1k5gBwTcQ==", "license": "MIT", "dependencies": { - "@expo/config": "~12.0.12", + "@expo/config": "~12.0.13", "@expo/env": "~2.0.8" }, "peerDependencies": { @@ -6525,20 +6482,10 @@ "react-native": "*" } }, - "node_modules/expo-file-system": { - "version": "19.0.21", - "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-19.0.21.tgz", - "integrity": "sha512-s3DlrDdiscBHtab/6W1osrjGL+C2bvoInPJD7sOwmxfJ5Woynv2oc+Fz1/xVXaE/V7HE/+xrHC/H45tu6lZzzg==", - "license": "MIT", - "peerDependencies": { - "expo": "*", - "react-native": "*" - } - }, "node_modules/expo-font": { - "version": "14.0.10", - "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.10.tgz", - "integrity": "sha512-UqyNaaLKRpj4pKAP4HZSLnuDQqueaO5tB1c/NWu5vh1/LF9ulItyyg2kF/IpeOp0DeOLk0GY0HrIXaKUMrwB+Q==", + "version": "14.0.12", + "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.12.tgz", + "integrity": "sha512-QQzunE2Mxk45AsCWm3tK7OpVljbtVnKD58q4/qliev+cbye1IOduUnRIdD+P7DyButw17G9MTX795kgaQiz5hQ==", "license": "MIT", "dependencies": { "fontfaceobserver": "^2.1.0" @@ -6580,13 +6527,13 @@ } }, "node_modules/expo-linking": { - "version": "8.0.11", - "resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-8.0.11.tgz", - "integrity": "sha512-+VSaNL5om3kOp/SSKO5qe6cFgfSIWnnQDSbA7XLs3ECkYzXRquk5unxNS3pg7eK5kNUmQ4kgLI7MhTggAEUBLA==", + "version": "8.0.12", + "resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-8.0.12.tgz", + "integrity": "sha512-FpXeIpFgZuxihwT9lBo86YD3y6LphBuAhN680MMxm/Y7fmsc57vimn2d3vFu68VI0+Z9w457t494mu2wvlgWTQ==", "license": "MIT", "peer": true, "dependencies": { - "expo-constants": "~18.0.12", + "expo-constants": "~18.0.13", "invariant": "^2.2.4" }, "peerDependencies": { @@ -6595,9 +6542,9 @@ } }, "node_modules/expo-modules-autolinking": { - "version": "3.0.23", - "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.23.tgz", - "integrity": "sha512-YZnaE0G+52xftjH5nsIRaWsoVBY38SQCECclpdgLisdbRY/6Mzo7ndokjauOv3mpFmzMZACHyJNu1YSAffQwTg==", + "version": "3.0.26", + "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.26.tgz", + "integrity": "sha512-WOaud6UKg16ciCOj8raKcMOoKFMHLXKI29U29yhgu1lf+Y7VxJyCktUcYo6AM+ccZ7zLD1uWZdMtgnpf+95OXA==", "license": "MIT", "dependencies": { "@expo/spawn-async": "^1.7.2", @@ -6611,9 +6558,9 @@ } }, "node_modules/expo-modules-core": { - "version": "3.0.29", - "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-3.0.29.tgz", - "integrity": "sha512-LzipcjGqk8gvkrOUf7O2mejNWugPkf3lmd9GkqL9WuNyeN2fRwU0Dn77e3ZUKI3k6sI+DNwjkq4Nu9fNN9WS7Q==", + "version": "3.0.30", + "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-3.0.30.tgz", + "integrity": "sha512-a6IrpAn/Jbmwxi9L+hMmXKpNqnkUpoF7WHOpn02rVLyax2J0gB1vvCVE5rNydplEnt41Q6WxQwvcOjZaIkcSUg==", "license": "MIT", "dependencies": { "invariant": "^2.2.4" @@ -6624,9 +6571,9 @@ } }, "node_modules/expo-notifications": { - "version": "0.32.15", - "resolved": "https://registry.npmjs.org/expo-notifications/-/expo-notifications-0.32.15.tgz", - "integrity": "sha512-gnJcauheC2S0Wl0RuJaFkaBRVzCG011j5hlG0TEbsuOCPBuB/F30YEk8yurK8Psv+zHkVfeiJ5AC+nL0LWk0WA==", + "version": "0.32.17", + "resolved": "https://registry.npmjs.org/expo-notifications/-/expo-notifications-0.32.17.tgz", + "integrity": "sha512-lwwzn7tImuzTzn9PAglZlS2VfZEvsfFGJTK9Eb8I4cqkGh2DI23YJFJH+WPEIu4QhDvk5JeBjklenJ8IZbmA4A==", "license": "MIT", "dependencies": { "@expo/image-utils": "^0.8.8", @@ -6635,7 +6582,7 @@ "assert": "^2.0.0", "badgin": "^1.1.5", "expo-application": "~7.0.8", - "expo-constants": "~18.0.12" + "expo-constants": "~18.0.13" }, "peerDependencies": { "expo": "*", @@ -6644,9 +6591,9 @@ } }, "node_modules/expo-router": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-6.0.21.tgz", - "integrity": "sha512-wjTUjrnWj6gRYjaYl1kYfcRnNE4ZAQ0kz0+sQf6/mzBd/OU6pnOdD7WrdAW3pTTpm52Q8sMoeX98tNQEddg2uA==", + "version": "6.0.24", + "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-6.0.24.tgz", + "integrity": "sha512-KIssKXnwjrdCxPWC8GsMTfKTwng40VrCsO16O9x6fKlfUwBW8itxY9PpCGyQeMJkiEADa+DUhtrDgl+uHg4/DA==", "license": "MIT", "dependencies": { "@expo/metro-runtime": "^6.1.2", @@ -6659,7 +6606,7 @@ "client-only": "^0.0.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", - "expo-server": "^1.0.5", + "expo-server": "^1.0.7", "fast-deep-equal": "^3.1.3", "invariant": "^2.2.4", "nanoid": "^3.3.8", @@ -6678,8 +6625,8 @@ "@react-navigation/drawer": "^7.5.0", "@testing-library/react-native": ">= 12.0.0", "expo": "*", - "expo-constants": "^18.0.12", - "expo-linking": "^8.0.11", + "expo-constants": "^18.0.13", + "expo-linking": "^8.0.12", "react": "*", "react-dom": "*", "react-native": "*", @@ -6688,7 +6635,7 @@ "react-native-safe-area-context": ">= 5.4.0", "react-native-screens": "*", "react-native-web": "*", - "react-server-dom-webpack": "~19.0.3 || ~19.1.4 || ~19.2.3" + "react-server-dom-webpack": "~19.0.4 || ~19.1.5 || ~19.2.4" }, "peerDependenciesMeta": { "@react-navigation/drawer": { @@ -6897,9 +6844,9 @@ } }, "node_modules/expo-server": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/expo-server/-/expo-server-1.0.5.tgz", - "integrity": "sha512-IGR++flYH70rhLyeXF0Phle56/k4cee87WeQ4mamS+MkVAVP+dDlOHf2nN06Z9Y2KhU0Gp1k+y61KkghF7HdhA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/expo-server/-/expo-server-1.0.7.tgz", + "integrity": "sha512-mcmyML3oXcqFUXUxtdtCL1O00ztNI2v76d+MdniXRUgHNxIcHZ05zo+DqBaOOT6LQnPk4vA4YHqQl7iGUfRb3g==", "license": "MIT", "engines": { "node": ">=20.16.0" @@ -6964,24 +6911,24 @@ } }, "node_modules/expo/node_modules/@expo/cli": { - "version": "54.0.20", - "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.20.tgz", - "integrity": "sha512-cwsXmhftvS0p9NNYOhXGnicBAZl9puWwRt19Qq5eQ6njLnaj8WvcR+kDZyADtgZxBsZiyVlrKXvnjt43HXywQA==", + "version": "54.0.25", + "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.25.tgz", + "integrity": "sha512-WnUqIb8oMBhtwSfIqdCHCzcaDIpLNXItRVd5miuvWi4GO0SGo89PSsAkbVJ+LJgcaY+v5rbgMELJS9I/CqOulA==", "license": "MIT", "dependencies": { "@0no-co/graphql.web": "^1.0.8", - "@expo/code-signing-certificates": "^0.0.5", + "@expo/code-signing-certificates": "^0.0.6", "@expo/config": "~12.0.13", "@expo/config-plugins": "~54.0.4", "@expo/devcert": "^1.2.1", "@expo/env": "~2.0.8", "@expo/image-utils": "^0.8.8", - "@expo/json-file": "^10.0.8", + "@expo/json-file": "^10.0.16", "@expo/metro": "~54.2.0", - "@expo/metro-config": "~54.0.12", + "@expo/metro-config": "~54.0.16", "@expo/osascript": "^2.3.8", - "@expo/package-manager": "^1.9.9", - "@expo/plist": "^0.4.8", + "@expo/package-manager": "^1.9.10", + "@expo/plist": "^0.4.9", "@expo/prebuild-config": "^54.0.8", "@expo/schema-utils": "^0.1.8", "@expo/spawn-async": "^1.7.2", @@ -7001,16 +6948,16 @@ "connect": "^3.7.0", "debug": "^4.3.4", "env-editor": "^0.4.1", - "expo-server": "^1.0.5", + "expo-server": "^1.0.7", "freeport-async": "^2.0.0", "getenv": "^2.0.0", "glob": "^13.0.0", - "lan-network": "^0.1.6", + "lan-network": "^0.2.1", "minimatch": "^9.0.0", - "node-forge": "^1.3.1", + "node-forge": "^1.3.3", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", - "picomatch": "^3.0.1", + "picomatch": "^4.0.3", "pretty-bytes": "^5.6.0", "pretty-format": "^29.7.0", "progress": "^2.0.3", @@ -7050,10 +6997,76 @@ } } }, + "node_modules/expo/node_modules/@expo/json-file": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.2.0.tgz", + "integrity": "sha512-S6XzKe3R9GQeHiUPXc3xJjOv2VJhOEwFYf7xdC2z2cUqt3kZJ9mSO877sNQloVdnW/SUCtPY3bexlM7nwq+CAQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.20.0", + "json5": "^2.2.3" + } + }, + "node_modules/expo/node_modules/@expo/metro-config": { + "version": "54.0.16", + "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-54.0.16.tgz", + "integrity": "sha512-3LLb9ZQl0VlqSlsalJ7+CYjfz60PBoSDHvpE1UF71aTM1Nx0Vb4LhXo7bCCC+PYP9q/GPB58LLbIROQ8PjKX2w==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.20.0", + "@babel/core": "^7.20.0", + "@babel/generator": "^7.20.5", + "@expo/config": "~12.0.13", + "@expo/env": "~2.0.8", + "@expo/json-file": "~10.0.16", + "@expo/metro": "~54.2.0", + "@expo/spawn-async": "^1.7.2", + "browserslist": "^4.25.0", + "chalk": "^4.1.0", + "debug": "^4.3.2", + "dotenv": "~16.4.5", + "dotenv-expand": "~11.0.6", + "getenv": "^2.0.0", + "glob": "^13.0.0", + "hermes-parser": "^0.29.1", + "jsc-safe-url": "^0.2.4", + "lightningcss": "^1.30.1", + "picomatch": "^4.0.3", + "postcss": "~8.4.32", + "resolve-from": "^5.0.0" + }, + "peerDependencies": { + "expo": "*" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + } + } + }, + "node_modules/expo/node_modules/@expo/metro-config/node_modules/@expo/json-file": { + "version": "10.0.16", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.16.tgz", + "integrity": "sha512-fcVkWEj+hLuP2yt5W0aw6LmDRqSPWDLUSxOMcmFeV+algmIF59sQVKCwB9btjQLd4V6x9N0pISkQEkBubUHrCw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "~7.10.4", + "json5": "^2.2.3" + } + }, + "node_modules/expo/node_modules/@expo/metro-config/node_modules/@expo/json-file/node_modules/@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, "node_modules/expo/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -7074,13 +7087,38 @@ "node": ">=8" } }, + "node_modules/expo/node_modules/expo-asset": { + "version": "12.0.13", + "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-12.0.13.tgz", + "integrity": "sha512-x/p7WvQUnkn6K43b9eL6SPeq5Vnf1E8BDe9bDrWrvMqzyUvJnUFvl+ctg3034s/+UHe7Ne2pAmc0+yzbl8CrDQ==", + "license": "MIT", + "dependencies": { + "@expo/image-utils": "^0.8.8", + "expo-constants": "~18.0.13" + }, + "peerDependencies": { + "expo": "*", + "react": "*", + "react-native": "*" + } + }, + "node_modules/expo/node_modules/expo-file-system": { + "version": "19.0.23", + "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-19.0.23.tgz", + "integrity": "sha512-MeGkid9OeNILfT/qonaXHp4f2c15xaB28U/bcN7pqZej0Kx0+6+V7e9ZIXpPHm07zVatxA+QkMTPQEGfmvVOxA==", + "license": "MIT", + "peerDependencies": { + "expo": "*", + "react-native": "*" + } + }, "node_modules/expo/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -7090,21 +7128,21 @@ } }, "node_modules/expo/node_modules/picomatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", - "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/expo/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -7114,9 +7152,9 @@ } }, "node_modules/expo/node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -7285,6 +7323,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, "license": "MIT", "dependencies": { "locate-path": "^6.0.0", @@ -8803,9 +8842,9 @@ } }, "node_modules/lan-network": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/lan-network/-/lan-network-0.1.7.tgz", - "integrity": "sha512-mnIlAEMu4OyEvUNdzco9xpuB9YVcPkQec+QsgycBCtPZvEqWPCDPfbAE4OJMdBBWpZWtpCn1xw9jJYlwjWI5zQ==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/lan-network/-/lan-network-0.2.1.tgz", + "integrity": "sha512-ONPnazC96VKDntab9j9JKwIWhZ4ZUceB4A9Epu4Ssg0hYFmtHZSeQ+n15nIwTFmcBUKtExOer8WTJ4GF9MO64A==", "license": "MIT", "bin": { "lan-network": "dist/lan-network-cli.js" @@ -8860,9 +8899,9 @@ "license": "MIT" }, "node_modules/lightningcss": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", - "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" @@ -8875,23 +8914,23 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-android-arm64": "1.30.2", - "lightningcss-darwin-arm64": "1.30.2", - "lightningcss-darwin-x64": "1.30.2", - "lightningcss-freebsd-x64": "1.30.2", - "lightningcss-linux-arm-gnueabihf": "1.30.2", - "lightningcss-linux-arm64-gnu": "1.30.2", - "lightningcss-linux-arm64-musl": "1.30.2", - "lightningcss-linux-x64-gnu": "1.30.2", - "lightningcss-linux-x64-musl": "1.30.2", - "lightningcss-win32-arm64-msvc": "1.30.2", - "lightningcss-win32-x64-msvc": "1.30.2" + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" } }, "node_modules/lightningcss-android-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", - "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", "cpu": [ "arm64" ], @@ -8909,9 +8948,9 @@ } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", - "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", "cpu": [ "arm64" ], @@ -8929,9 +8968,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", - "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", "cpu": [ "x64" ], @@ -8949,9 +8988,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", - "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", "cpu": [ "x64" ], @@ -8969,9 +9008,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", - "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", "cpu": [ "arm" ], @@ -8989,9 +9028,9 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", - "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", "cpu": [ "arm64" ], @@ -9009,9 +9048,9 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", - "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", "cpu": [ "arm64" ], @@ -9029,9 +9068,9 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", - "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", "cpu": [ "x64" ], @@ -9049,9 +9088,9 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", - "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", "cpu": [ "x64" ], @@ -9069,9 +9108,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", - "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", "cpu": [ "arm64" ], @@ -9089,9 +9128,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", - "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", "cpu": [ "x64" ], @@ -9118,6 +9157,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, "license": "MIT", "dependencies": { "p-locate": "^5.0.0" @@ -9802,9 +9842,9 @@ } }, "node_modules/node-forge": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz", - "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", + "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" @@ -9847,9 +9887,9 @@ } }, "node_modules/npm-package-arg/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -10234,6 +10274,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, "license": "MIT", "dependencies": { "p-limit": "^3.0.2" @@ -12187,9 +12228,9 @@ } }, "node_modules/tar": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.7.tgz", - "integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==", + "version": "7.5.16", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.16.tgz", + "integrity": "sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/fs-minipass": "^4.0.0", @@ -12620,9 +12661,9 @@ } }, "node_modules/undici": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz", - "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==", + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz", + "integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==", "license": "MIT", "engines": { "node": ">=18.17" @@ -13249,9 +13290,9 @@ } }, "node_modules/wonka": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.5.tgz", - "integrity": "sha512-SSil+ecw6B4/Dm7Pf2sAshKQ5hWFvfyGlfPbEd6A14dOH6VDjrmbY86u6nZvy9omGwwIPFR8V41+of1EezgoUw==", + "version": "6.3.6", + "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.6.tgz", + "integrity": "sha512-MXH+6mDHAZ2GuMpgKS055FR6v0xVP3XwquxIMYXgiW+FejHQlMGlvVRZT4qMCxR+bEo/FCtIdKxwej9WV3YQag==", "license": "MIT" }, "node_modules/word-wrap": { diff --git a/package.json b/package.json index d552848..6fa1a32 100644 --- a/package.json +++ b/package.json @@ -16,15 +16,16 @@ "@react-navigation/elements": "^2.6.3", "@react-navigation/native": "^7.1.8", "@react-navigation/stack": "^7.6.13", + "babel-preset-expo": "~54.0.10", "date-fns": "^4.1.0", "expo": "~54.0.30", "expo-build-properties": "~1.0.10", - "expo-constants": "~18.0.12", - "expo-font": "~14.0.10", + "expo-constants": "~18.0.13", + "expo-font": "~14.0.12", "expo-haptics": "~15.0.8", "expo-linear-gradient": "~15.0.8", - "expo-notifications": "~0.32.15", - "expo-router": "~6.0.21", + "expo-notifications": "~0.32.17", + "expo-router": "~6.0.24", "expo-splash-screen": "~31.0.13", "expo-status-bar": "~3.0.9", "expo-symbols": "~1.0.8", diff --git a/types/counter.ts b/types/counter.ts index edb2234..357f8ae 100644 --- a/types/counter.ts +++ b/types/counter.ts @@ -1,3 +1,6 @@ +// --- Recurrence Type --- +export type Recurrence = "none" | "daily" | "weekly" | "monthly" | "yearly" | "custom"; + // --- Counter Interface --- export interface Counter { id: string; @@ -9,6 +12,9 @@ export interface Counter { completed: boolean; notificationId: string | undefined; todayNotificationId?: string; + recurrence: Recurrence; + customRecurrenceDays?: number; + nextRecurrenceDate?: number; } export enum CounterType { From 1b70664813558f2c1bee989b11b10b79271b164f Mon Sep 17 00:00:00 2001 From: kamalalshinawi Date: Tue, 23 Jun 2026 14:57:36 +0300 Subject: [PATCH 2/6] Fix add modal styles --- app/add.modal.tsx | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/app/add.modal.tsx b/app/add.modal.tsx index b5bf265..d0102a8 100644 --- a/app/add.modal.tsx +++ b/app/add.modal.tsx @@ -722,7 +722,7 @@ export const styles = StyleSheet.create({ recurrenceTrigger: { flexDirection: "row", alignItems: "center", - padding: normalize(16), + padding: 16, backgroundColor: "rgba(255, 255, 255, 0.15)", borderRadius: 12, borderWidth: 1, @@ -733,9 +733,9 @@ export const styles = StyleSheet.create({ borderColor: "#4285F4", }, recurrenceTriggerIcon: { - width: normalize(36), - height: normalize(36), - borderRadius: normalize(18), + width: 36, + height: 36, + borderRadius: 18, backgroundColor: "rgba(0, 0, 0, 0.1)", alignItems: "center", justifyContent: "center", @@ -746,35 +746,35 @@ export const styles = StyleSheet.create({ recurrenceTriggerLabel: { fontFamily: "Roboto-Regular", color: "#666", - fontSize: normalize(10), + fontSize: 10, marginBottom: 2, }, recurrenceTriggerValue: { fontFamily: "Roboto-Bold", color: "#000", - fontSize: normalize(14), + fontSize: 14, }, recurrencePanel: { - marginTop: normalize(8), + marginTop: 8, backgroundColor: "rgba(255, 255, 255, 0.12)", borderRadius: 12, - padding: normalize(8), + padding: 8, }, recurrenceOptionModern: { flexDirection: "row", alignItems: "center", - paddingVertical: normalize(12), - paddingHorizontal: normalize(12), + paddingVertical: 12, + paddingHorizontal: 12, borderRadius: 10, - marginBottom: normalize(4), + marginBottom: 4, }, recurrenceOptionModernActive: { backgroundColor: "#4285F4", }, recurrenceOptionIconWrapper: { - width: normalize(32), - height: normalize(32), - borderRadius: normalize(16), + width: 32, + height: 32, + borderRadius: 16, backgroundColor: "rgba(0, 0, 0, 0.08)", alignItems: "center", justifyContent: "center", @@ -785,7 +785,7 @@ export const styles = StyleSheet.create({ recurrenceOptionLabelModern: { fontFamily: "Roboto-Bold", color: "#000", - fontSize: normalize(13), + fontSize: 13, }, recurrenceOptionLabelModernActive: { color: "#fff", @@ -793,7 +793,7 @@ export const styles = StyleSheet.create({ recurrenceOptionDescModern: { fontFamily: "Roboto-Regular", color: "#666", - fontSize: normalize(10), + fontSize: 10, marginTop: 2, }, recurrenceOptionDescModernActive: { @@ -803,19 +803,20 @@ export const styles = StyleSheet.create({ flexDirection: "row", alignItems: "center", justifyContent: "space-between", - paddingVertical: normalize(12), - paddingHorizontal: normalize(12), + paddingVertical: 12, + paddingHorizontal: 12, borderTopWidth: 1, borderTopColor: "rgba(0, 0, 0, 0.08)", - marginTop: normalize(8), + marginTop: 8, }, customDaysLabel: { fontFamily: "Roboto-Regular", color: "#000", }, customDaysInput: { - width: normalize(60), - height: normalize(36), - paddingHorizontal: normalize(12), + width: 60, + height: 36, + paddingHorizontal: 12, + marginBottom: 4, }, }); From 730e1f617e94029d5a6e9d24c13b1d83c2db17f4 Mon Sep 17 00:00:00 2001 From: kamalalshinawi Date: Tue, 23 Jun 2026 14:58:09 +0300 Subject: [PATCH 3/6] Restore counter item card --- components/CounterItem.tsx | 678 ++++++++++--------------------------- 1 file changed, 187 insertions(+), 491 deletions(-) diff --git a/components/CounterItem.tsx b/components/CounterItem.tsx index e1fc552..f5f9880 100644 --- a/components/CounterItem.tsx +++ b/components/CounterItem.tsx @@ -1,484 +1,184 @@ -import CounterItem from "@/components/CounterItem"; -import { useCounterContext } from "@/context/counterContext"; -import { useThemeContext } from "@/context/ThemeContext"; import { Counter } from "@/types/counter"; -import AsyncStorage from "@react-native-async-storage/async-storage"; -import { useFonts } from "expo-font"; +import { Ionicons } from "@expo/vector-icons"; +import { LinearGradient } from "expo-linear-gradient"; import { useRouter } from "expo-router"; -import * as SplashScreen from "expo-splash-screen"; -import React, { useCallback, useEffect, useMemo, useState } from "react"; -import { - ActivityIndicator, - Alert, - FlatList, - StyleSheet, - ToastAndroid, - View, -} from "react-native"; -import { - Directions, - Gesture, - GestureDetector, -} from "react-native-gesture-handler"; -import { Appbar, Button, Text, useTheme } from "react-native-paper"; -import Animated, { - Easing, - runOnJS, - useAnimatedStyle, - useSharedValue, - withTiming, -} from "react-native-reanimated"; -import { SafeAreaView } from "react-native-safe-area-context"; - -// Keep splash screen visible while fonts load or data loads -SplashScreen.preventAutoHideAsync(); - -// --- AsyncStorage Key --- -const STORAGE_KEY = "@days_since_app_data_v2"; // Use versioned key - -type themeModeType = "light" | "dark" | "system"; - -const BUTTON_WIDTH = 120; -const BUTTON_GAP = 90; -const LEFT_POSITION = 0; -const RIGHT_POSITION = BUTTON_WIDTH + BUTTON_GAP; -const TOP_BAR_WIDTH = BUTTON_WIDTH * 2 + BUTTON_GAP; - -export default function Index() { - const { themeMode } = useThemeContext(); - const { toggleTheme, setTheme } = useThemeContext(); - const theme = useTheme(); // Access theme colors - const { counters, setCounters, markCounterCompleted, deleteCounter } = - useCounterContext(); - - const [isDataLoaded, setIsDataLoaded] = useState(false); - const [currentView, setCurrentView] = useState<"current" | "archive">( - "current", - ); - - const router = useRouter(); // Initialize router - - // Shared value for the slider's translateX position - const sliderTranslateX = useSharedValue(LEFT_POSITION); - - useEffect(() => { - if (currentView === "current") { - sliderTranslateX.value = withTiming(LEFT_POSITION, { - duration: 170, - easing: Easing.linear, - }); - } else { - sliderTranslateX.value = withTiming(RIGHT_POSITION, { - duration: 170, - easing: Easing.linear, - }); - } - }, [currentView]); - - const animatedSliderStyle = useAnimatedStyle(() => { +import React, { memo, useMemo } from "react"; +import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; + +type CounterItemProps = { + item: Counter; + handleDeleteCounter: (id: string) => void; + handleArchiveToggle: (id: string) => void; + handleComplete: (id: string) => void; +}; + +const getTimeParts = (item: Counter) => { + const now = Date.now(); + const diff = + item.type === "countdown" + ? Math.max(0, item.createdAt - now) + : Math.max(0, now - item.createdAt); + + const totalSeconds = Math.floor(diff / 1000); + const totalMinutes = Math.floor(totalSeconds / 60); + const totalHours = Math.floor(totalMinutes / 60); + const totalDays = Math.floor(totalHours / 24); + + if (totalDays > 0) { return { - transform: [{ translateX: sliderTranslateX.value }], + value: String(totalDays), + label: + item.type === "countdown" + ? totalDays === 1 + ? "day to" + : "days to" + : totalDays === 1 + ? "day since" + : "days since", }; - }); - - useEffect(() => { - const themesetter = async () => { - const storedTheme = await AsyncStorage.getItem("theme"); - if (storedTheme) setTheme(storedTheme as themeModeType); - }; - themesetter(); - // setDate(undefined); // Removed: Date state is now in add.modal.tsx - }, []); - - // --- Font Loading --- - const [loaded, error] = useFonts({ - "Roboto-Regular": require("@/assets/fonts/roboto.ttf"), - "Roboto-Bold": require("@/assets/fonts/boldonse.ttf"), // Ensure this path is correct - "my-font": require("@/assets/fonts/myfont.ttf"), - "bung-ee": require("@/assets/fonts/bungee.ttf"), - }); + } - // --- Load Counters from Storage --- - useEffect(() => { - const loadCounters = async () => { - try { - const storedCounters = await AsyncStorage.getItem(STORAGE_KEY); - if (storedCounters !== null) { - const parsedCounters: Partial[] = JSON.parse(storedCounters); - const correctedCounters: Counter[] = parsedCounters.map( - (c, index) => ({ - id: c.id || `${Date.now()}-${index}`, - name: c.name || "Unnamed Counter", - createdAt: c.createdAt || Date.now(), - isArchived: c.isArchived === true, - hasNotification: c.hasNotification === true, - type: c.type || "countup", - completed: c.completed || false, - notificationId: c.notificationId, - todayNotificationId: c.todayNotificationId, - recurrence: c.recurrence || "none", - customRecurrenceDays: c.customRecurrenceDays, - nextRecurrenceDate: c.nextRecurrenceDate, - }), - ); - setCounters(correctedCounters); - } - } catch (e) { - console.error("Failed to load counters.", e); - Alert.alert("Error", "Could not load saved counters."); - } finally { - setIsDataLoaded(true); - } + if (totalHours > 0) { + return { + value: String(totalHours), + label: item.type === "countdown" ? "hours to" : "hours since", }; - loadCounters(); - }, []); // Empty dependency array means this runs once on mount - - // --- Hide Splash Screen --- - useEffect(() => { - if ((loaded || error) && isDataLoaded) { - SplashScreen.hideAsync(); - } - }, [loaded, error, isDataLoaded]); + } - // --- Save Counters to Storage --- - useEffect(() => { - if (!isDataLoaded) { - return; - } - const saveCounters = async () => { - try { - await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(counters)); - } catch (e) { - console.error("Failed to save counters.", e); - } + if (totalMinutes > 0) { + return { + value: String(totalMinutes), + label: item.type === "countdown" ? "minutes to" : "minutes since", }; - saveCounters(); - }, [counters, isDataLoaded]); + } - // helper function for setting state of view - const handleFlingDirection = (direction: "left" | "right") => { - if (direction === "right") { - setCurrentView("current"); - } else if (direction === "left") { - setCurrentView("archive"); - } + return { + value: String(totalSeconds), + label: item.type === "countdown" ? "seconds to" : "seconds since", }; - - // listners of gesture - const flingRightGesture = Gesture.Fling() - .direction(Directions.RIGHT) - .onStart(() => { - runOnJS(handleFlingDirection)("right"); - }); - - const flingLeftGesture = Gesture.Fling() - .direction(Directions.LEFT) - .onStart(() => { - runOnJS(handleFlingDirection)("left"); - }); - - // --- Filtered Counters for Display --- - const displayedCounters = useMemo(() => { - return counters.filter((c) => - currentView === "current" ? !c.isArchived : c.isArchived, - ); - }, [counters, currentView]); - - const handleDeleteCounter = useCallback( - (id: string) => { - const counterToDelete = counters.find((c) => c.id === id); - Alert.alert( - "Delete Counter", - `Are you sure you want to delete "${ - counterToDelete?.name || "this counter" - }"? This cannot be undone.`, - [ - { text: "Cancel", style: "cancel" }, - { - text: "Delete", - style: "destructive", - onPress: () => { - deleteCounter(id); - }, - }, - ], - ); - }, - [counters, deleteCounter], - ); - - const handleArchiveToggle = useCallback( - (id: string) => { - const targetCounter = counters.find((c) => c.id === id); - if (!targetCounter || targetCounter.completed === true) return; - - const nextIsArchived = !targetCounter.isArchived; - setCounters((prevCounters) => - prevCounters.map((counter) => - counter.id === id - ? { ...counter, isArchived: nextIsArchived } - : counter, - ), - ); - ToastAndroid.show( - `"${targetCounter.name}" moved to ${ - nextIsArchived ? "Past" : "Current" - }.`, - 1000, - ); - }, - [counters, setCounters], - ); - - const handleComplete = useCallback( - (id: string) => { - const targetCounter = counters.find((c) => c.id === id); - if (!targetCounter) return; - - markCounterCompleted(id); - ToastAndroid.show(`"${targetCounter.name}" moved to ${"Past"}.`, 1000); - }, - [counters, markCounterCompleted], - ); - - // --- Render Item for FlatList --- - const renderCounterItem = useCallback( - ({ item }: { item: Counter }) => { - return ( - - ); - }, - [handleDeleteCounter, handleArchiveToggle, handleComplete], +}; + +function CounterItem({ + item, + handleDeleteCounter, + handleArchiveToggle, + handleComplete, +}: CounterItemProps) { + const router = useRouter(); + const { value, label } = getTimeParts(item); + + const formattedDate = useMemo( + () => + new Date(item.createdAt).toLocaleDateString("en-US", { + month: "short", + day: "numeric", + year: "numeric", + }), + [item.createdAt], ); - // --- Main Render --- - if (error) { - console.error("Font loading error:", error); - return ( - - - - Error loading fonts. - - - {error?.message || "Unknown error"} - - - - ); - } - - if (!loaded || !isDataLoaded) { - return ( - - - - - - ); - } + const gradientColors = + item.type === "countdown" + ? (["#E0E0E0", "#4285F4"] as const) + : (["#FEC9CE", "#FF96A1"] as const); + + const openDetails = () => { + router.push({ + pathname: "/details", + params: { + id: item.id, + name: item.name, + creation: String(item.createdAt), + type: item.type, + completed: String(item.completed), + }, + }); + }; return ( - - {/* Custom Header */} - - toggleTheme()} /> - - - {/* { - router.push("/CounterWidgetPreview"); - }} - /> */} - { - // Removed direct modal state management - router.push("/add.modal"); // Navigate to the add.modal screen - }} - /> - - - - - - - - - - - item.id} - ListEmptyComponent={ - - - No counters {currentView === "archive" ? "archived" : "yet"}. - - {currentView === "current" && !isDataLoaded && ( - - )} - {currentView === "current" && - isDataLoaded && - displayedCounters.length === 0 && ( - Press + to add one! - )} - - } - contentContainerStyle={styles.listContent} - /> + + + 3 && styles.compactValueText, + ]} + numberOfLines={1} + > + {value} + + {label} + + + + {formattedDate} + + {item.name} + + + + {item.hasNotification && ( + + )} + + handleDeleteCounter(item.id)} + style={styles.deleteIcon} + > + + + + {!item.completed && item.type === "countdown" && ( + handleComplete(item.id)} + style={styles.completeIcon} + > + + + )} + + {!item.completed && ( + handleArchiveToggle(item.id)} + style={styles.archiveIcon} + > + + + )} - - + + ); } -// --- Styles --- +export default memo(CounterItem); + const styles = StyleSheet.create({ - container: { - flex: 1, - }, - centered: { - flexGrow: 1, - justifyContent: "center", - alignItems: "center", - paddingHorizontal: 20, - paddingBottom: 50, - }, - centeredError: { - flex: 1, - justifyContent: "center", - alignItems: "center", - padding: 20, - }, - buttonLabel: { - // color: "#000", - fontSize: 15, - }, - topbtn: { - width: BUTTON_WIDTH, - padding: 5, - borderRadius: 30, - zIndex: 1, - }, - transparentButton: { - backgroundColor: "transparent", - }, - segmentContainer: { - flexDirection: "row", - width: TOP_BAR_WIDTH, // Fixed width - justifyContent: "center", // Center content - alignItems: "center", - marginBottom: 20, - gap: BUTTON_GAP, - position: "relative", - borderRadius: 10, - padding: 5, - alignSelf: "center", // Center the container itself - }, - sliderBackground: { - position: "absolute", - height: 2, - width: BUTTON_WIDTH - 3, - backgroundColor: "#4285F4", // Or any color you prefer for the slider - borderRadius: 30, // Match button border radius - left: 5, // Adjust for padding - top: 45, // Adjust for padding - elevation: 1, - zIndex: 0, - }, - segmentButtons: { - borderRadius: 10, - }, - segmentSelected: { - backgroundColor: "#FEC9CE", - }, - segmentUnselected: { - backgroundColor: "transparent", - }, - segmentSelectedLabel: { - fontFamily: "Roboto-Regular", - fontSize: 16, - color: "#333", - fontWeight: "600", - }, - segmentUnselectedLabel: { - fontFamily: "Roboto-Regular", - fontSize: 14, - color: "#555", - }, - listContent: { - paddingHorizontal: 15, - paddingBottom: 30, - paddingTop: 10, - flexGrow: 1, - }, cardContainer: { marginVertical: 7, borderRadius: 18, @@ -488,45 +188,39 @@ const styles = StyleSheet.create({ overflow: "hidden", }, cardContent: { + minHeight: 130, flexDirection: "row", alignItems: "center", paddingVertical: 15, - paddingHorizontal: 10, + paddingHorizontal: 12, position: "relative", }, leftColumn: { - flex: 1, + width: 138, alignItems: "center", justifyContent: "center", - maxWidth: 145, }, rightColumn: { flex: 1, justifyContent: "center", - alignItems: "baseline", - marginBottom: 30, + alignItems: "flex-start", + paddingRight: 70, }, - daysNumber: { + valueText: { fontSize: 55, fontFamily: "bung-ee", color: "#000", - lineHeight: 70, + lineHeight: 68, textAlign: "center", }, - hoursMinutesSecondsNumber: { - fontSize: 55, - fontFamily: "bung-ee", - color: "#111", - lineHeight: 70, - textAlign: "center", + compactValueText: { + fontSize: 42, }, - daysLabel: { + labelText: { fontSize: 10, fontFamily: "my-font", color: "#333", - letterSpacing: 1.2, fontWeight: "900", - marginTop: 4, textTransform: "uppercase", textAlign: "center", }, @@ -542,27 +236,29 @@ const styles = StyleSheet.create({ fontFamily: "Roboto-Regular", fontWeight: "bold", color: "#000", - lineHeight: 20, + lineHeight: 24, }, notificationIcon: { position: "absolute", - top: 5, - right: 35, - zIndex: 1, + top: 8, + right: 90, }, deleteIcon: { position: "absolute", - top: 5, - right: 5, - zIndex: 1, + top: 8, + right: 8, + padding: 6, }, - emptyText: { - textAlign: "center", - fontSize: 30, - fontFamily: "my-font", - color: "#777", - marginTop: 15, - lineHeight: 35, - fontWeight: "condensedBold", + completeIcon: { + position: "absolute", + bottom: 8, + right: 8, + padding: 6, + }, + archiveIcon: { + position: "absolute", + top: 8, + right: 42, + padding: 6, }, }); From e07b0b6d338a1f839625f9aa882a8ca0abd0a820 Mon Sep 17 00:00:00 2001 From: kamalalshinawi Date: Tue, 23 Jun 2026 14:58:29 +0300 Subject: [PATCH 4/6] Fix TypeScript compatibility errors --- app/index.tsx | 3 ++ components/FancyDatePicker.tsx | 7 ++--- context/counterContext.tsx | 53 ++++++++++++++++++++-------------- widget/CounterList.tsx | 9 +++--- 4 files changed, 41 insertions(+), 31 deletions(-) diff --git a/app/index.tsx b/app/index.tsx index 9feaf7f..e1fc552 100644 --- a/app/index.tsx +++ b/app/index.tsx @@ -116,6 +116,9 @@ export default function Index() { completed: c.completed || false, notificationId: c.notificationId, todayNotificationId: c.todayNotificationId, + recurrence: c.recurrence || "none", + customRecurrenceDays: c.customRecurrenceDays, + nextRecurrenceDate: c.nextRecurrenceDate, }), ); setCounters(correctedCounters); diff --git a/components/FancyDatePicker.tsx b/components/FancyDatePicker.tsx index 26b79ba..812129c 100644 --- a/components/FancyDatePicker.tsx +++ b/components/FancyDatePicker.tsx @@ -106,10 +106,7 @@ const WheelPicker = React.forwardRef( const isFirstRender = useRef(true); // Expose ref - React.useImperativeHandle(ref, () => ({ - ...carouselRef.current!, - scrollTo: carouselRef.current?.scrollTo, - })); + React.useImperativeHandle(ref, () => carouselRef.current!); // Sync selectedIndex changes from parent (e.g. date clamping) useEffect(() => { @@ -145,7 +142,7 @@ const WheelPicker = React.forwardRef( defaultIndex={safeIndex} pagingEnabled snapEnabled - onScrollBegin={() => { + onScrollStart={() => { isScrolling.current = true; }} onScrollEnd={(index) => { diff --git a/context/counterContext.tsx b/context/counterContext.tsx index f3d8f96..8c6cb08 100644 --- a/context/counterContext.tsx +++ b/context/counterContext.tsx @@ -1,4 +1,4 @@ -import { Counter } from "@/types/counter"; +import { Counter, Recurrence } from "@/types/counter"; import { MyWidget } from "@/widget/CounterList"; import AsyncStorage from "@react-native-async-storage/async-storage"; import * as Notifications from "expo-notifications"; @@ -33,10 +33,24 @@ Notifications.setNotificationHandler({ }), }); -import { Recurrence } from "@/types/counter"; - const STORAGE_KEY = "@days_since_app_data_v2"; +type NotificationData = { + counterId?: unknown; + notificationType?: unknown; +}; + +const getExactTimeCounterId = (data: NotificationData): string | null => { + if ( + typeof data.counterId === "string" && + data.notificationType === "exactTime" + ) { + return data.counterId; + } + + return null; +}; + // --- Helper: Calculate next recurrence date --- function getNextRecurrenceDate( currentTargetDate: number, @@ -319,36 +333,33 @@ export const CounterProvider = ({ const notificationReceivedListener = Notifications.addNotificationReceivedListener((notification) => { console.log("Notification received in foreground:", notification); - const notificationData = notification.request.content.data; - if (notificationData && notificationData.counterId) { - // Only mark complete if it's the final 'exact time' notification - if (notificationData.notificationType === "exactTime") { - markCounterCompleted(notificationData.counterId); - } + const counterId = getExactTimeCounterId( + notification.request.content.data, + ); + if (counterId) { + markCounterCompleted(counterId); } }); const notificationResponseListener = Notifications.addNotificationResponseReceivedListener((response) => { console.log("Notification response received (user tapped):", response); - const notificationData = response.notification.request.content.data; - if (notificationData && notificationData.counterId) { - if (notificationData.notificationType === "exactTime") { - markCounterCompleted(notificationData.counterId); - } - // You might want to navigate to the counter's detail page here - // if the user taps the notification. + const counterId = getExactTimeCounterId( + response.notification.request.content.data, + ); + if (counterId) { + markCounterCompleted(counterId); } }); Notifications.getLastNotificationResponseAsync().then((response) => { if (response && response.notification) { console.log("App launched from notification:", response.notification); - const notificationData = response.notification.request.content.data; - if (notificationData && notificationData.counterId) { - if (notificationData.notificationType === "exactTime") { - markCounterCompleted(notificationData.counterId); - } + const counterId = getExactTimeCounterId( + response.notification.request.content.data, + ); + if (counterId) { + markCounterCompleted(counterId); } } }); diff --git a/widget/CounterList.tsx b/widget/CounterList.tsx index ad564ce..a524eff 100644 --- a/widget/CounterList.tsx +++ b/widget/CounterList.tsx @@ -66,8 +66,8 @@ const calculateTime = (item: Counter) => { export function MyWidget({ data, theme }: counterprops) { const isDark = theme === "dark"; - const backgroundColor = isDark ? "#1b1b1bff" : "#FFFFFF"; - const textColor = isDark ? "#FFFFFF" : "#000000"; + const backgroundColor: `#${string}` = isDark ? "#1b1b1bff" : "#FFFFFF"; + const textColor: `#${string}` = isDark ? "#FFFFFF" : "#000000"; return ( {data?.map((counter: Counter, i) => { @@ -138,8 +137,8 @@ export function MyWidget({ data, theme }: counterprops) { // Gradient colors based on type const gradientColors = counter.type === "countdown" - ? { from: "#E0E0E0", to: "#4285F4" } - : { from: "#FEC9CE", to: "#FF96A1" }; + ? ({ from: "#E0E0E0", to: "#4285F4" } as const) + : ({ from: "#FEC9CE", to: "#FF96A1" } as const); return ( Date: Tue, 23 Jun 2026 15:11:42 +0300 Subject: [PATCH 5/6] Make repeat options scrollable --- app/add.modal.tsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/app/add.modal.tsx b/app/add.modal.tsx index d0102a8..9041254 100644 --- a/app/add.modal.tsx +++ b/app/add.modal.tsx @@ -2,6 +2,7 @@ import { LinearGradient } from "expo-linear-gradient"; import React, { useCallback, useEffect, useState } from "react"; import { BackHandler, + ScrollView, StyleSheet, Text, TouchableOpacity, @@ -231,7 +232,12 @@ export default function AddModalScreen() { - + */} - + ); @@ -655,12 +661,18 @@ export const styles = StyleSheet.create({ alignItems: "center", // Center content horizontally paddingVertical: 20, }, + modalScroll: { + flex: 1, + width: "100%", + }, innerContentContainer: { // This is now your actual modal content, without the gradient - flex: 1, // Ensure it expands within the gradient + flexGrow: 1, // Keep short content centered while allowing overflow to scroll justifyContent: "center", width: "100%", alignItems: "center", + paddingTop: 50, + paddingBottom: 60, }, modalTitle: { marginBottom: 10, From e5fd1dff86b97b96794d289c0508f4f993e83090 Mon Sep 17 00:00:00 2001 From: kamalalshinawi Date: Tue, 23 Jun 2026 15:16:18 +0300 Subject: [PATCH 6/6] chor: edit inputCustomDays Color --- app/add.modal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/add.modal.tsx b/app/add.modal.tsx index 9041254..a0bd802 100644 --- a/app/add.modal.tsx +++ b/app/add.modal.tsx @@ -579,7 +579,7 @@ export default function AddModalScreen() {