From 95159446f94f8c9c8842a281677f06f4e2cd9048 Mon Sep 17 00:00:00 2001 From: yashwin-foxy Date: Fri, 3 Oct 2025 18:17:10 +0530 Subject: [PATCH] now deep linking completed and loader also added for the app --- App.tsx | 364 ++- FCM_NOTIFICATION_IMPLEMENTATION_GUIDE.md | 384 +++ android/app/build.gradle | 21 + android/app/google-services.json | 29 + android/app/src/main/AndroidManifest.xml | 14 + android/app/src/main/playstore.png | Bin 0 -> 55755 bytes .../src/main/res/drawable/ic_notification.xml | 11 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 3056 -> 2912 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 5024 -> 2912 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 2096 -> 1834 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 2858 -> 1834 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 4569 -> 4122 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 7098 -> 4122 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 6464 -> 7133 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 10676 -> 7133 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 9250 -> 11090 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 15523 -> 11090 bytes android/app/src/main/res/values/styles.xml | 1 + .../main/res/xml/network_security_config.xml | 14 + android/build.gradle | 1 + android/gradle.properties | 4 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- package-lock.json | 2285 ++++++++++++++++- package.json | 32 +- utilities/README.md | 134 + utilities/constants.ts | 45 + utilities/cookieUtils.ts | 247 ++ utilities/deepLinkUtils.ts | 242 ++ utilities/fcmUtils.ts | 357 +++ utilities/loaderUtils.tsx | 387 +++ utilities/notificationUtils.ts | 152 ++ utilities/permissionUtils.ts | 279 ++ utilities/webViewUtils.ts | 233 ++ 33 files changed, 5072 insertions(+), 166 deletions(-) create mode 100644 FCM_NOTIFICATION_IMPLEMENTATION_GUIDE.md create mode 100644 android/app/google-services.json create mode 100644 android/app/src/main/playstore.png create mode 100644 android/app/src/main/res/drawable/ic_notification.xml create mode 100644 android/app/src/main/res/xml/network_security_config.xml create mode 100644 utilities/README.md create mode 100644 utilities/constants.ts create mode 100644 utilities/cookieUtils.ts create mode 100644 utilities/deepLinkUtils.ts create mode 100644 utilities/fcmUtils.ts create mode 100644 utilities/loaderUtils.tsx create mode 100644 utilities/notificationUtils.ts create mode 100644 utilities/permissionUtils.ts create mode 100644 utilities/webViewUtils.ts diff --git a/App.tsx b/App.tsx index 7d8838a..74b4123 100644 --- a/App.tsx +++ b/App.tsx @@ -1,131 +1,269 @@ +import React, { JSX, useEffect, useState } from 'react'; +import { SafeAreaView, StyleSheet, Platform, StatusBar, AppState, View, Text, ActivityIndicator, Animated } from 'react-native'; +import { WebView } from 'react-native-webview'; + +// Utility imports +import { + createNotificationChannel, + configureNotificationSettings, + testNotification +} from './utilities/notificationUtils'; +import { + createDeepLinkHandler, + NotificationData +} from './utilities/deepLinkUtils'; +import { + createWebViewHandler +} from './utilities/webViewUtils'; +import { + createCookieHandler +} from './utilities/cookieUtils'; +import { + createFCMHandler, + NotificationCallbacks +} from './utilities/fcmUtils'; +import { ALLOWED_DOMAIN } from './utilities/constants'; +import { CustomLoader, createOdooLoader, createNavigationLoader, createChatLoader } from './utilities/loaderUtils'; + +// Suppress Firebase deprecation warnings (temporary until Firebase v22+ is stable) +const originalWarn = console.warn; +console.warn = (...args) => { + if (args[0] && typeof args[0] === 'string' && + args[0].includes('This method is deprecated') && + args[0].includes('Firebase')) { + return; // Suppress only Firebase deprecation warnings + } + originalWarn.apply(console, args); +}; +// @ts-ignore +import PushNotification from 'react-native-push-notification'; + /** - * Sample React Native App - * https://github.com/facebook/react-native - * - * @format + * Main App Component + * Handles FCM notifications, WebView management, and deep linking */ +export default function App(): JSX.Element { + + // Track app state to avoid duplicate notifications + const [appState, setAppState] = React.useState(AppState.currentState); -import React from 'react'; -import type {PropsWithChildren} from 'react'; -import { - ScrollView, - StatusBar, - StyleSheet, - Text, - useColorScheme, - View, -} from 'react-native'; + // WebView reference for accessing cookies + const webViewRef = React.useRef(null); + + // Deep linking state + const [currentChannel, setCurrentChannel] = React.useState(null); + const webViewUrlRef = React.useRef(`${ALLOWED_DOMAIN}/web`); + const [webViewKey, setWebViewKey] = React.useState(0); // Force re-render when URL changes + const [isNavigating, setIsNavigating] = React.useState(false); + const [navigationAttempts, setNavigationAttempts] = React.useState(0); -import { - Colors, - DebugInstructions, - Header, - LearnMoreLinks, - ReloadInstructions, -} from 'react-native/Libraries/NewAppScreen'; + // State to store cookies + const [webViewCookies, setWebViewCookies] = React.useState(null); -type SectionProps = PropsWithChildren<{ - title: string; -}>; + // Loading state + const [isLoading, setIsLoading] = useState(true); + const [loadingText, setLoadingText] = useState('Connecting to T4B...'); + const [loaderType, setLoaderType] = useState<'odoo' | 'navigation' | 'chat'>('odoo'); -function Section({children, title}: SectionProps): React.JSX.Element { - const isDarkMode = useColorScheme() === 'dark'; - return ( - - - {title} - - - {children} - - - ); -} - -function App(): React.JSX.Element { - const isDarkMode = useColorScheme() === 'dark'; - - const backgroundStyle = { - backgroundColor: isDarkMode ? Colors.darker : Colors.lighter, + // Helper function to update WebView URL immediately (without loader) + const updateWebViewUrl = (newUrl: string) => { + console.log('๐Ÿ”— Updating WebView URL immediately:', newUrl); + // Don't show loader for navigation to avoid flickering + webViewUrlRef.current = newUrl; + setWebViewKey(prev => prev + 1); // Force WebView re-render + console.log('โœ… WebView URL updated:', newUrl); }; - /* - * To keep the template simple and small we're adding padding to prevent view - * from rendering under the System UI. - * For bigger apps the recommendation is to use `react-native-safe-area-context`: - * https://github.com/AppAndFlow/react-native-safe-area-context - * - * You can read more about it here: - * https://github.com/react-native-community/discussions-and-proposals/discussions/827 - */ - const safePadding = '5%'; + // Create utility handlers + const cookieHandler = createCookieHandler(setWebViewCookies); + const webViewHandler = createWebViewHandler(webViewRef, updateWebViewUrl, { + currentChannel, + isNavigating + }); + + // Navigation state for deep link handler + const navigationState = { + currentChannel, + isNavigating, + navigationAttempts + }; + + const deepLinkHandler = createDeepLinkHandler( + updateWebViewUrl, + setIsNavigating, + setCurrentChannel, + setNavigationAttempts, + navigationState + ); + + // FCM notification callbacks + const fcmCallbacks: NotificationCallbacks = { + onForegroundNotification: (data: NotificationData) => { + deepLinkHandler.handleForegroundBackgroundDeepLink(data); + }, + onBackgroundNotification: (data: NotificationData) => { + deepLinkHandler.handleForegroundBackgroundDeepLink(data); + }, + onKilledAppNotification: (data: NotificationData) => { + deepLinkHandler.handleKilledAppDeepLink(data); + } + }; + + const fcmHandler = createFCMHandler( + () => cookieHandler.getWebViewCookies(), + fcmCallbacks + ); + + // Handle app state changes + useEffect(() => { + const handleAppStateChange = (nextAppState: any) => { + console.log('App state changed:', appState, '->', nextAppState); + setAppState(nextAppState); + }; + + const subscription = AppState.addEventListener('change', handleAppStateChange); + return () => subscription?.remove(); + }, [appState]); + + // Initialize FCM and WebView + useEffect(() => { + // Configure push notifications + createNotificationChannel(); + configureNotificationSettings(); + + // Initialize FCM notifications + fcmHandler.initializeNotifications(); + + // Start periodic cookie refresh + const cleanupCookieRefresh = cookieHandler.refreshWebViewCookies(); + + // Setup FCM message listeners + const cleanupFCMListeners = fcmHandler.setupMessageListeners(appState); + + // Setup test functions for debugging + setupTestFunctions(); + + return () => { + cleanupCookieRefresh(); + cleanupFCMListeners(); + }; + }, []); + + // Setup test functions for debugging + const setupTestFunctions = () => { + if (typeof global !== 'undefined') { + (global as any).testNotification = testNotification; + (global as any).refreshCookies = () => { + console.log('๐Ÿ”„ Manual cookie refresh triggered'); + cookieHandler.getWebViewCookies(); + }; + (global as any).checkCookies = () => { + console.log('๐Ÿ” Current cookie state:', webViewCookies); + console.log('๐Ÿ” WebView ref available:', !!webViewRef.current); + cookieHandler.getWebViewCookies(); + }; + (global as any).testDeepLink = (channelId: string) => { + console.log('๐Ÿ”— Testing deep link for channel:', channelId); + deepLinkHandler.navigateToChannel(channelId); + }; + (global as any).testDeepLinkUrl = (deepLink: string) => { + console.log('๐Ÿ”— Testing deep link URL:', deepLink); + deepLinkHandler.handleDeepLink(deepLink); + }; + (global as any).simulateNotification = (channelId: string) => { + console.log('๐Ÿ”— Simulating notification tap for channel:', channelId); + setTimeout(() => { + deepLinkHandler.handleForegroundBackgroundDeepLink({ channel_id: channelId }); + }, 100); + }; + (global as any).testWebViewUrlUpdate = (channelId: string) => { + console.log('๐Ÿ”— Testing WebView URL update for channel:', channelId); + deepLinkHandler.handleForegroundBackgroundDeepLink({ channel_id: channelId }); + }; + (global as any).debugWebView = () => { + webViewHandler.injectDebugScript(); + }; + (global as any).navigateToChannel = (channelId: string) => { + console.log('๐Ÿ”— Direct navigation to channel:', channelId); + deepLinkHandler.navigateToChannel(channelId); + }; + (global as any).updateWebViewUrl = (url: string) => { + console.log('๐Ÿ”— Direct WebView URL update:', url); + updateWebViewUrl(url); + }; + + console.log('๐Ÿงช Test functions available:'); + console.log(' - global.testNotification()'); + console.log(' - global.refreshCookies()'); + console.log(' - global.checkCookies()'); + console.log(' - global.testDeepLink(channelId) - For killed app deep linking'); + console.log(' - global.testWebViewUrlUpdate(channelId) - For foreground/background URL update'); + console.log(' - global.testDeepLinkUrl("myapp://chat/123")'); + console.log(' - global.simulateNotification(channelId)'); + console.log(' - global.debugWebView() - Debug WebView state and elements'); + console.log(' - global.navigateToChannel(channelId) - Direct navigation using WebView URL update'); + console.log(' - global.updateWebViewUrl(url) - Immediate WebView URL update'); + } + }; + + // Handle WebView navigation + const handleNavigation = (request: any): boolean => { + return webViewHandler.handleNavigation(request); + }; + + + // Handle WebView messages + const handleWebViewMessage = (event: any) => { + webViewHandler.handleWebViewMessage(event, setWebViewCookies); + }; return ( - - + { + console.log('๐Ÿ”„ WebView started loading'); + // Don't show loader during WebView navigation to avoid flickering + }} + onLoadEnd={() => { + console.log('โœ… WebView finished loading'); + setIsLoading(false); // Only hide initial loader + webViewHandler.handleWebViewLoadEnd(currentChannel, isNavigating); + }} + onError={(error) => { + console.error('โŒ WebView error:', error); + setIsLoading(false); + setLoadingText('Connection error'); + }} + //@ts-ignore + onConsoleMessage={(event: any) => { + console.log('๐ŸŒ WebView Console:', event.nativeEvent.message); + }} /> - - -
- - -
- Edit App.tsx to change this - screen and then come back to see your edits. -
-
- -
-
- -
-
- Read the docs to discover what to do next: -
- -
- - + + {/* Dynamic Beautiful Custom Loader */} + {loaderType === 'odoo' && createOdooLoader(isLoading, loadingText)} + {loaderType === 'navigation' && createNavigationLoader(isLoading, loadingText)} + {loaderType === 'chat' && createChatLoader(isLoading, loadingText)} + ); } const styles = StyleSheet.create({ - sectionContainer: { - marginTop: 32, - paddingHorizontal: 24, + container: { + flex: 1, + // paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight ?? 0 : 0, }, - sectionTitle: { - fontSize: 24, - fontWeight: '600', - }, - sectionDescription: { - marginTop: 8, - fontSize: 18, - fontWeight: '400', - }, - highlight: { - fontWeight: '700', + webview: { + flex: 1, }, }); - -export default App; diff --git a/FCM_NOTIFICATION_IMPLEMENTATION_GUIDE.md b/FCM_NOTIFICATION_IMPLEMENTATION_GUIDE.md new file mode 100644 index 0000000..357da18 --- /dev/null +++ b/FCM_NOTIFICATION_IMPLEMENTATION_GUIDE.md @@ -0,0 +1,384 @@ +# FCM Notification Module Implementation Guide + +This document contains all the changes made to implement Firebase Cloud Messaging (FCM) notifications in the T4B_Chat React Native app. Use this guide to replicate the implementation in your production project. + +## ๐Ÿ“ฆ Package Dependencies Added + +### package.json Dependencies +```json +{ + "dependencies": { + "@react-native-firebase/app": "^23.4.0", + "@react-native-firebase/messaging": "^23.4.0", + "@react-native-cookies/cookies": "^6.2.0", + "react-native-device-info": "^10.11.0", + "react-native-permissions": "^5.2.4", + "react-native-push-notification": "^8.1.1" + } +} +``` + +### Installation Commands +```bash +npm install @react-native-firebase/app @react-native-firebase/messaging +npm install @react-native-cookies/cookies +npm install react-native-device-info +npm install react-native-permissions +npm install react-native-push-notification +``` + +## ๐Ÿ”ง Android Configuration + +### 1. Root build.gradle (android/build.gradle) +```gradle +buildscript { + ext { + buildToolsVersion = "35.0.0" + minSdkVersion = 24 + compileSdkVersion = 35 + targetSdkVersion = 35 + ndkVersion = "27.1.12297006" + kotlinVersion = "2.0.21" + } + repositories { + google() + mavenCentral() + } + dependencies { + classpath("com.android.tools.build:gradle") + classpath("com.facebook.react:react-native-gradle-plugin") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin") + classpath("com.google.gms:google-services:4.3.15") // โ† ADD THIS + } +} +``` + +### 2. App build.gradle (android/app/build.gradle) +```gradle +apply plugin: "com.android.application" +apply plugin: "org.jetbrains.kotlin.android" +apply plugin: "com.facebook.react" +apply plugin: 'com.google.gms.google-services' // โ† ADD THIS + +android { + // ... existing config ... + + // Fix for react-native-push-notification duplicate classes + configurations.all { + exclude group: 'com.android.support', module: 'support-compat' + exclude group: 'com.android.support', module: 'support-annotations' + } + + defaultConfig { + applicationId "com.t4b_chat" + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion + versionCode 1 + versionName "1.0" + } +} + +dependencies { + implementation("com.facebook.react:react-android") + + // AndroidX dependencies for react-native-push-notification compatibility + implementation 'androidx.core:core:1.16.0' + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.11.0' + + // ... rest of dependencies ... +} +``` + +### 3. AndroidManifest.xml (android/app/src/main/AndroidManifest.xml) +```xml + + + + + + + + + + + + + + + + + + + + + + + +``` + +### 4. Google Services Configuration +- Add `google-services.json` file to `android/app/` directory +- This file comes from your Firebase project console + +## ๐Ÿ“ฑ iOS Configuration + +### 1. Podfile (ios/Podfile) +```ruby +# Resolve react_native_pods.rb with node to allow for hoisting +require Pod::Executable.execute_command('node', ['-p', + 'require.resolve( + "react-native/scripts/react_native_pods.rb", + {paths: [process.argv[1]]}, + )', __dir__]).strip + +platform :ios, min_ios_version_supported +prepare_react_native_project! + +linkage = ENV['USE_FRAMEWORKS'] +if linkage != nil + Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green + use_frameworks! :linkage => linkage.to_sym +end + +target 'T4B_Chat' do + config = use_native_modules! + + use_react_native!( + :path => config[:reactNativePath], + :app_path => "#{Pod::Config.instance.installation_root}/.." + ) + + post_install do |installer| + react_native_post_install( + installer, + config[:reactNativePath], + :mac_catalyst_enabled => false, + ) + end +end +``` + +### 2. iOS Google Services Configuration +- Add `GoogleService-Info.plist` to your iOS project +- This file comes from your Firebase project console + +## ๐Ÿ“ New Utility Files Created + +### 1. utilities/permissionUtils.ts +Complete permission management utility for handling notification permissions across platforms. + +Key functions: +- `needsNotificationPermission()` - Check if device needs explicit permission +- `requestNotificationPermission()` - Request notification permission +- `checkNotificationPermission()` - Check current permission status +- `showPermissionExplanation()` - Show user-friendly explanation dialog +- `showSettingsDialog()` - Direct user to app settings + +### 2. utilities/notificationUtils.ts +Complete notification management utility for handling local notifications. + +Key functions: +- `createNotificationChannel()` - Create Android notification channel +- `configureNotificationSettings()` - Configure push notification settings +- `showLocalNotification()` - Display local notifications +- `shouldShowCustomNotification()` - Determine when to show notifications +- `testNotification()` - Test notification function +- `cancelAllNotifications()` - Cancel all pending notifications + +## ๐Ÿ”„ App.tsx Changes + +### Key Imports Added +```typescript +import messaging, { FirebaseMessagingTypes, AuthorizationStatus } from '@react-native-firebase/messaging'; +import { getApp } from '@react-native-firebase/app'; +import { + requestNotificationPermission, + checkNotificationPermission, + needsNotificationPermission, + showPermissionExplanation, + showSettingsDialog, + PermissionResult +} from './utilities/permissionUtils'; +import { RESULTS } from 'react-native-permissions'; +import { + showLocalNotification, + createNotificationChannel, + configureNotificationSettings, + shouldShowCustomNotification, + testNotification +} from './utilities/notificationUtils'; +import PushNotification from 'react-native-push-notification'; +``` + +### Key Features Implemented + +1. **App State Tracking** + - Tracks app state changes to avoid duplicate notifications + - Uses `AppState.addEventListener` for state monitoring + +2. **FCM Message Handling** + - `onMessage` listener for foreground messages + - `getInitialNotification` for app launch from notification + - `onNotificationOpenedApp` for background notification taps + +3. **Permission Management** + - Comprehensive permission checking and requesting + - Platform-specific permission handling (Android 13+ vs older versions) + - User-friendly permission explanation dialogs + +4. **Token Management** + - FCM token retrieval and refresh handling + - Token sending to backend (commented out - needs implementation) + +5. **Notification Display** + - Custom notification display when app is active + - Fallback to system notifications when app is backgrounded + - Test notification functionality for debugging + +6. **Firebase Warning Suppression** + - Temporary suppression of Firebase deprecation warnings + +## ๐Ÿš€ Setup Instructions for Production + +### 1. Install Dependencies +```bash +npm install @react-native-firebase/app @react-native-firebase/messaging +npm install react-native-permissions +npm install react-native-push-notification +``` + +### 2. Firebase Project Setup +1. Create Firebase project at https://console.firebase.google.com +2. Add Android app with package name matching your `applicationId` +3. Add iOS app with bundle identifier +4. Download configuration files: + - `google-services.json` for Android + - `GoogleService-Info.plist` for iOS + +### 3. Android Setup +1. Add Google Services plugin to build.gradle files +2. Add permissions to AndroidManifest.xml +3. Add FCM service to AndroidManifest.xml +4. Add AndroidX dependencies for compatibility + +### 4. iOS Setup +1. Add GoogleService-Info.plist to Xcode project +2. Run `cd ios && pod install` +3. Enable Push Notifications capability in Xcode + +### 5. Code Integration +1. Copy both utility files to your project +2. Integrate App.tsx changes +3. Update package.json dependencies +4. Test notification functionality + +## ๐Ÿงช Testing + +### Test Notification Function +The implementation includes a test notification function accessible via: +- URL navigation to `test-notification` endpoint +- Global function `global.testNotification()` in development +- Console logging for debugging + +### Debug Features +- Comprehensive console logging throughout the notification flow +- Permission status logging +- FCM token logging +- App state change logging + +## ๐Ÿ”— Backend Integration + +### FCM Token Registration +The app automatically sends FCM tokens to your Odoo backend using the following endpoint: + +**Endpoint**: `POST https://your-odoo.com/fcm/register` + +**Headers**: +```json +{ + "Content-Type": "application/json", + "Cookie": "session_id=YOUR_SESSION_COOKIE" +} +``` + +**Request Body**: +```json +{ + "token": "FCM_TOKEN_STRING", + "device_name": "iPhone 12", + "device_type": "ios", + "app_version": "1.0.0", + "os_version": "15.0" +} +``` + +### Device Information Collection +The implementation automatically collects device information using `react-native-device-info`: +- `device_name`: Device model name (e.g., "iPhone 12", "Samsung Galaxy S21") +- `device_type`: Platform ("ios" or "android") +- `app_version`: App version from package.json +- `os_version`: Operating system version + +### Session Management +**Native Cookie Extraction**: The implementation uses `@react-native-cookies/cookies` to automatically extract session cookies from the native cookie store. The `getWebViewCookies()` function: + +1. **Accesses native cookie store** using `@react-native-cookies/cookies` library +2. **Retrieves all cookies** for the Odoo domain +3. **Filters and extracts session_id** from available cookies +4. **Updates automatically** every 30 seconds to keep cookies fresh +5. **Validates cookies** before sending FCM token registration + +The system automatically handles session management without manual intervention and is much more reliable than JavaScript injection methods. + +### Token Refresh Handling +The app automatically handles FCM token refresh and sends updated tokens to the backend whenever they change. + +## โš ๏ธ Important Notes + +1. **Backend Integration**: The `sendTokenToBackend()` function is implemented and automatically sends FCM tokens to your Odoo backend at `/fcm/register` endpoint. + +2. **Session Management**: The implementation automatically extracts session cookies from the WebView, so no manual session management is required. + +3. **Device Information**: The implementation uses `react-native-device-info` to automatically collect device information (device name, type, app version, OS version). + +4. **Firebase Warnings**: Temporary warning suppression is in place until Firebase v22+ is stable. + +5. **Permission Handling**: The implementation handles Android 13+ permission requirements automatically. + +6. **Production Considerations**: + - Update signing configuration for release builds + - Test on both Android and iOS devices + - Verify notification delivery in all app states + - Ensure WebView loads and user can log in to extract session cookies + +## ๐Ÿ“‹ Checklist for Production Migration + +- [ ] Install all required npm packages +- [ ] Add Google Services configuration files +- [ ] Update Android build.gradle files +- [ ] Update AndroidManifest.xml with permissions and FCM service +- [ ] Copy utility files (permissionUtils.ts, notificationUtils.ts) +- [ ] Integrate App.tsx changes +- [ ] Test on Android device (API 33+ for permission testing) +- [ ] Test on iOS device +- [ ] Implement backend token registration +- [ ] Test notification delivery in all app states +- [ ] Remove debug/test code before production release + +This implementation provides a complete FCM notification system with proper permission handling, platform-specific optimizations, and comprehensive error handling. diff --git a/android/app/build.gradle b/android/app/build.gradle index b87eb39..e933bdf 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,6 +1,7 @@ apply plugin: "com.android.application" apply plugin: "org.jetbrains.kotlin.android" apply plugin: "com.facebook.react" +apply plugin: 'com.google.gms.google-services' /** * This is the configuration block to customize your React Native Android app. @@ -58,6 +59,7 @@ react { * Set this to true to Run Proguard on Release builds to minify the Java bytecode. */ def enableProguardInReleaseBuilds = false +def enableSeparateBuildPerCPUArchitecture = true /** * The preferred build flavor of JavaScriptCore (JSC) @@ -78,6 +80,19 @@ android { compileSdk rootProject.ext.compileSdkVersion namespace "com.t4b_chat" + + // Fix for react-native-push-notification duplicate classes + configurations.all { + exclude group: 'com.android.support', module: 'support-compat' + exclude group: 'com.android.support', module: 'support-annotations' + } + splits { + abi { + enable true + include 'armeabi-v7a', 'arm64-v8a', 'x86' + universalApk false + } + } defaultConfig { applicationId "com.t4b_chat" minSdkVersion rootProject.ext.minSdkVersion @@ -110,6 +125,11 @@ android { dependencies { // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") + + // AndroidX dependencies for react-native-push-notification compatibility + implementation 'androidx.core:core:1.16.0' + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.11.0' if (hermesEnabled.toBoolean()) { implementation("com.facebook.react:hermes-android") @@ -117,3 +137,4 @@ dependencies { implementation jscFlavor } } +apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle") \ No newline at end of file diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..f6d9d0d --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "640541795037", + "project_id": "t4b-chat", + "storage_bucket": "t4b-chat.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:640541795037:android:b40cb90983466cdafd3134", + "android_client_info": { + "package_name": "com.t4b_chat" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyCQ1zgB0uVL3VgRnsPrbdYQOneOJzc2AAM" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index e189252..b6b3b92 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,6 +1,9 @@ + + + + + + + + + + diff --git a/android/app/src/main/playstore.png b/android/app/src/main/playstore.png new file mode 100644 index 0000000000000000000000000000000000000000..df0beb3f5d2c9b81dbf571c772d039c8d510fe61 GIT binary patch literal 55755 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 + + + diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index a2f5908281d070150700378b64a84c7db1f97aa1..1c9e419f7a1a61720388b4c252599c922282f596 100644 GIT binary patch delta 2905 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 diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png index 1b523998081149a985cef0cdf89045b9ed29964a..1c9e419f7a1a61720388b4c252599c922282f596 100644 GIT binary patch delta 2906 zcmV-g3#Ig+C*T&4BYz7ONkl5Yd7qCQs1AWT#Y+~n1gH*yI>k#Cv;?RQfjY%Y7PJJY4uLwwjaramKT`LdCN69K zQx-gbjY_Fupx=SwlIA}f1k`p0(6y1;0Ca6QChWan6GVLs{oYN0zX=k)t@>DARVTv} zw009Z=ct!)>3>_s=vucC!Ag!FR1_RHm*eL)Z+iJT^P{Ph)&t~9H7{8EjiBS=Fj%(v z! zmjE*pK!1J+C{00?r=d!dHZEyMyeMfA%NbXc&1ZcS#sSxZdDj{sE-8TH_-)Fxbvk;} zl}>!!_Z`!-+Cg#Bf#WzVZ$R`CD&xh`!EJH*(1Wrd%C3>&Nl$iq()?OxrExO-SDoZ` zLb(P?B`D7r^X~HuPF-)*WY(ytXb8Zl!njfSVSj@arK6^zZdP$6ZObITJZ;P=>x|NgQKczk`!6yqP8u~aXwcnfl26=g%$oBJA#q-g z;iTVAQWQgZj*bSOkIMsJW=57Gct{&YPkuH6Na_@lWatr)4&+cu=`$};$PFt@3{poc z%6|Re5)X;uq+PhV9+2>Vq#TS%0b-hAyN?|&u2t^T=A`FFck(!|xMpa2Yu@=8w zA$yR0vfqj77!u}36o&UJlnU(o7G=)4jP2P6zy&Kx!nraD;be52eI+XI`yzmYl&ouB zIIPq73o{*$JZ4NWha`5<(`T@(2P!)N#eXfNa)UTV`Qb|b2+M~L06{18=BuFJ^HG?d zRUjyCzeyk}fffaVV!Q~#0wRXd4A8LxYH|d$797)eZLB=YMh`)aABNuee(DN9C*bx6 zEF)A8qoFdcN%DuI(%w6mxr-7wnql2jD%Ptc9m%h<*XZn1iY`d^o~~6s%gGVU#D7t! z6I9L54MB-UUWcOK1~BX22YuFiVcNR@@iihs5lB|00^qoS)=;Bwvi-^WmpqOkeUCF7 z9spLZgFgFGw&jup6cpD*ICPdq&rFny;g^8;@62QcXod})Qn`_eG8%u}!G}%IW|Z=v z#tv!ZhBV>K3KK_lP5kAVKUhgiJ%3U5b&XNB6T@A7F3c%s0(8Wn14n7PYCW_dCqpo_ zLIFTYpKpy*>2o%nH2(zJ`etC|40msay{4;ji%o7s_))eC`}bLmF|0}QBz}BY$=j>PUKv1c z(5Q(cP-6$7CJt9DC&N1kk$>aTC(#GduOetCxJc{q{sSD3ZL8yqRzvBtCY!f=pU&>s zr^k2iVWa(Y$PZ{e`4d8s`7=N*lz2muMK@HDmF&LN@$fIB>Fw7>g`J;?3Ohc%0A0tr z*F=R~_gH625aPT|XD>|msW2T@qQXzzxa$;Z*uu79tv?Z+wUqt2K+ zSBR}B0X_D4@77T}N8{T44w@)p;M&~;=Rs# z!dXYHh3?w`v+68hY79>QGf=O+2owt(CbOS^_EFNuLdMLqjrg5K!C~7)0g?e1BbNgz zWZaB}BNo$pI>0++BY$8{+XzKR?d*860;fPfhQoq^o++DL2tX+EIoX(LxDEb9goeQk?^ zLG@@pAQ{-D1Gdjgl4xzE1E|IP%zQslI)LVzQHzx|ACPAhDmQ=lUpSf%NT~1y8h8%` z`ec8R6D?zWGtDT zSgS-*07Q$a!VyR!2qZ#-M^JKaWFNg+15xt%#P$#>Wh9F|jDZkZonHNBj|? zNm`T^92vLyfFfm_7aoQC=(qU7{yCVA6+qW1uz!ykyzC1QYdt{> zIaGcG?$Zw<^Z5P1$N6&ZmZQaXTSwentCYx*EMVb_PV>uF>jxfjm%tuS5ybgyO^ zpMUP@pQL(PN)J$N#rCrgUzTy(Au7Us?l;K%?%PlU|Ah5TT`OxfQwh@tR9m)eJLLlW zUZ%#6zyH<&tf$wCxo;l0hRF~_e1KyKakmazd?D71t(OVoAF_c77U;~&dYIhoZTB0`@aK}j-YZh9TX>089BwjT=ZNpfR2Y=ii$7a8*wcQc^zjOlkV1JLB@c>!AxjC5>09gi=*8Nasueka6f^Tw}^pN$J4W()5m7<7nU} zp!f?SI7rd5>~}DMBXJS4(>a~y4;vTb^8VkJXSUxI$8X$53woGyI7-PWP$U#6B8jJ} zW&+~74OwgXwIn)x7m)mcsZmOxh*KCvOF)r{)YMEswK3(vYKjSgA`&PfX0_g#1|Xr3 zJ{Xxr14;`}%UaCw%>E4k0RR8oU_T%L000I_L_t&o02E5N+_!BR{{R3007*qoM6N<$ Ef|JvA-~a#s literal 5024 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 O0000(qIcLT*6MTahk;ZXIp&_cE7n+nN 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⁣ zwiG+x#%j}{0gU~J8;<|!B1@-XaB@{KORFwrYg_8rOv({b0EO#DbeQRm;B6_9=mXGf z-x|VL{zd`)#@yN}HkCSJbjbNlE|zL3Wm9Q8HY`sV)}3%pgN>cL^67{Z;PPL(*wT8N zUjXU{@|*hvm}({wsAC=x0^ok0%UAz0;sogW{B!nDqk|JJ5x~4NfTDgP49^zeu`csl?5mY@JdQdISc zFs!E{^grmkLnUk9 zny~m)1vws@5BFI<-0Tuo2JWX(0v`W|t(wg;s--L47WTvTMz-8l#TL^=OJNRS2?_Qj z3AKT+gvbyBi#H*-tJ%tWD|>EV3wy|8qxfzS!5RW;Jpl5*zo&^UBU=fG#2}UvRyNkK zA06Dy9;K1ca@r2T>yThYgI!ont$(G{6q#2QT+00r_x0(b)gsE`lBB?2gr55gq^D3Fi&p%E(p9>U%bv zkg1Jco(RbyTX7FDHOnl7-O@ zI$AaIl?9NJKPm(WiBP`1-#CB1QzU>&hKm)fpa5DKE{2$X0hGz-0uZ?cyTk(YC!Y&| zL=1VrNERSA5NA2jq7FACfX4JfPyj5XXl1yv0>~s;eF7L2$>&oMqeTFT2m$y7FlkON z_yurD1yIOvA;5C6016pyxBznGUt0kJ&k5r#;&>Jow`r)sp9R~PmK~lz$3xH%LT*1U zJdOyABZ3!FvNoR*vN$5ykHS8f`jA4zV+|L}i1C4`B2c{R0;UdYxaU|H)2avz@ z=mEYc|2S<+(B2Tj+FkX+2D+yFI!k9lWMA61DJ{)e;lum$(;O87?vGJJe!KtK04+N_ zI*P~t@dUb>9Xh{dbyl{-ZQ(UMgz7$|QfL5XSPkskt^NgctYC#;4WcZB1@%@wy@2t3 z2z0DI7&%b$*Aw~abe?GxE`ez@+6hOh-6*8fHRV{1os$EL@}uUZeG4h1&Be`98q*7j z=3-v+lhIjfWVo12!<>%V^a6lTgW3+_#W6n|p*~==zOH7z$0{LSZk(Tpd7EaD04hnA zL;#fxS0aD{`5^&D`}>0Uq?byDD-l2=!wm_bLcUl4gc(% za1p|itVANvFF>hghAS07Im1;IK;|b*W)}VDyI;BIp2=K*yu2a)j?B|f<44NI$NbmJ z#dE0>jI$fMr&@>4kN8MLFb4&2O9fEKaQg%(QO$4_1rVQywG^CmBLh#}_7gKW3vd?| z2?1^&KWq8}8I^_S0|)MowU_pw$q@nl@Nkn$z>BQq_KA^9yaR`(R3u{{Ig;cwt z@AJ^{ODQCm^neroM9nKNUAXi9RCK`OsP_LuR0PUR(YZCCX5dNF6VzcoK&=b^r`W?ltt|*F zpkoae%ZT{C1h~EcFui~b7fF`vb<<~j_VquuUA$}QqIKYELPp#;{u?q8Dz}WAG-(3; zjrm$i%7UbyZMM(Y{>!uJ#vNB?R~B{6Htp=>e*<{fQQ5W7V(1coCWlOON!MzZxhum| ztZBQpGR z;~#ur^&PockKdV{Q6R>o`Pl{0x!DEbpZ7y9Y;*ZvE!*gU`V1W3znva{f=?WO5I&>B z&hw6}tjECtaghm5z|C#%M;Yf_*pI^};h}Vl=^r9EN=tVDj86D;C$jIJ?K7VP+00000NkvXXu0mjf D5i!M* diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png index 459ca609d3ae0d3943ab44cdc27feef9256dc6d7..ba479f3a8feefc0d6001c6c44efeae9f32a9401b 100644 GIT binary patch literal 4122 zcmV+#5asWQP)(+p*lqHdpC)l zyL&f#=Pq|Ozx$mzcjlaLe!uU0=giFRI%xkim4UVZO{E`b3(yvz$qY2P`}PQE3(#Z+ zn%sSR1hfTcG6PNSzC8lk0yLR{CU^g8!wsp-;GcG6cka(--aDGjTwjCtjb>BZN3#RB9B}Xa=7{srZ;v>45r4LC#QpQ{ z=Tf(RF_+!&ySWa%C712qmCLTbIhP%{DVOctlgswslFJPIPA)U}fm~+z_i~wyx8*Wd z{Xs7CYah&I-ucJ5%$D18nX5mX%WVEgF0=LST>6^3a_MV7noDo{ST4Q&o?QC+zsRL; zxG$I9buY`bd-mp>k32Hs+`Vtax$9Bd@9uX$_SgaUo*#^+ZvUUrY~P;I4)vbVY<9=! z;%m5m+4~)touet$^ZQjk>*lrY1KF?)IRuqc&lp|yV2pwZ4FLVdvy4}v@X0eZtb=;I6^W&} zfp_}<0NWxPL|s4hvaaK54hjzFaOzno*RYZu$rTVG{peZ`v;6}R@s0~9)+=^lv_dJb zkm*wT#t*CD&d;mx=DX}Z=BE_=vVsm3LSG^9l?nr8%hi2^m1sX$s8{?hLbXoQN;@6h z$_#I1dp;l{h!5b8kgMrqX%1%KY6O4sPcZMki6Z0y<$wnhYKcGym34LH+*3jD>Ob=2 z2|{?Gsc(~>>pK#VhQ-5t=#PDiCrMcVdjXXa^t*n8DRw>7{3MiDfGW>d!Lnb1D$PPo z{{qTr=pBEE;E(P#itV_h>72AHGq7{C^L9W+2Zggf;LUz`!7AnGaQdY09sO$_y`Ny@@N$x?2v97@h?sm8Lblnw8+ylWFq^K8qLL{jNKQXK%J8ii^4 z!Dzo+zj3|vFUL-thUwk_z4JDpnF!L{5T+! zHOV%ETVSr*4zq3mkU2ndJ?m{*tj_>sv`QdgZhVpWw#{n4w(V+J>IG_kAy{AoV2qT` z0-Lr01DiMkgP0q+W{XiLa&~DLbwuPB93;`2}JN zQ$|($x3=28lw+VUaj8$KLxKM1$2Ia7wOKc)P2aHQ0waWxyze@Jcl040O#KH5V1Bc! zLKYj_8WBLT>tmswdO{V8j+&oMsluG23i;PS>I60Q^Rh39>sT&InKo`?ekK}KLMBIq znj3@SG85@8AWO))-maEBs1he$nf&FL>GM!Czkte5ss&%-cEw6RwU9bNwXQhtDDiJ@ z%27_%LH7n1Zq^OFliv=*v47?@pC=lQe70dX$9^vTBX%GR%O}67rw=@@XAkA{%)wkZ z^D=EM4su^mQ#UL7F<$052YHNqFZR#~+xS_SKYf-F$#gbhI68m=gHBMI2Doa1jD!x} z-BJwRX~U$_Fr0@>&ww%gZ-)uy=k&}=&xf-IN5roMNI$i(ecJxR*!Nl138r6sK^ISs z2L6dh!{E$=r0Eo)iMqEpJ8-!INV|~;q4%s`K76lVe&qq;{-FHI{bK9GVSDW2a}Ix; z`}Y`c>`Cxx2b9uwdDzhltlPk)CdplY70lo}VK!bD%@6P39I^FA=xw)v%VC3x2UEIu z+%F%wKPW|g_*e8RI)?pPe-@5C@_=7Fcwgw9{v5D^k9x-}v|?8poYawGCH+UHjY zFRM)Fq!5nYVPpC>!t@igkm%+r#q@GcpdjcQrWl)HoD`fBIXFLm(kR~KDLyfxFC&Eb z^#bj3eS41Q9w92kif=0+fH)*&PPcc@)uehxhw<{&UN;_td?S@$|Q9lfca*N&}iou8<=1pG@?|RQ2 zg!}B*;T&U-%Dj-yMt*QT9~F}SnN$IQ4hmq?4G9q4wpB6eixdPbVdur_oww^dhumJVA-}=Y21!%H{ z2^XN9f|?f}PDV$Cvy(CwF z*UbT(h#Bp6RYa04>D)&ZvTq@yf!`y|Iivw%R_oN{3cz;(hU6L&DgZ6yb)>b7bg>fk zVi!SD6CtT+wODMRpX3UVs!c&8RH8aYm2e{h#dTu2AEhFuAQ7tpVpi+a1Pj0vVo9w= zJINKoK?|w3h`uuvL;x8Pww?mCM?hmSr1{7}aynu{ExDWrXiXI$@nAVZG)f{NL;wod zm%mdMQht0QMPDwlN1*>Fngr0mq*;sjuyYbM(iMzX34vtBR6V zszQL1uOVQ`m&g||1+mVsu001d8bOjm<}Sj0@(W1)|L35_j=}T{0iBYT__~s#Ac}gf zjN*}C>nMa+NnMTlunOlVcLc~UW~E4Ub{*82mymk&LAXEq5+HxDEon*8Op5aZBOZhy z>4p{}Mn*;gzgqlMjnMpk>FmA2pK5?OL}MZ z@ihf-+j9UJT%k=wkoUlyy+EY|_nH4f>XFYtop=GJdp#f!LF9i$PzXb`m!T`f{i0^% z7j@;OOJ^U{(*%S;${aqGKJGt!daaB$M@`lasmQB-5=cdBqnkB7_jk z)TB=2klOcmaG(B9$iFa0q5KTao;q))b(YS35tjg7bqa&2gplWsZoy2hP6C%H(gYFF?$(q$M{6boE1>Jp}i; zZ!lNIUnbYC9RY-6NlPMx+zX_+OqIHXV{Hi#lPzhfCE_0mei|B+xyJ3<904sP+8P!> zwL}tHg969|AkQsSOU%M+NB~Pbpwel6C~b;o(E>lME&$WaCE|H43OblL) zdGfCa*?63oP2_5#cosdZMCeGLC zU?L8y60fSnYcCAW{lqID_>5mZ@^P)_zDO^BOk5z|lK=6>c2{(36#*6#Z~Q`7dG&{0 z@xUho@7O1x3tuKH^3VCkX#+wLEwLqB0C~0`sm4)IX~!6EI`mFF=9TvURp6ieOQ7^s zvMi})idNE%qLqz;iAg>ZE`X~@d`6qX#h`NJ;Yw-$CxYP2UcmofQu`7yOUOS`RkX6T z4DsTuAi)AS4s?DzC?EccUwZL@(7*6$Abf;QA13ArA-iRXr~h_Kq5zUg_;TyQ<6bFu zZy1h$mc)OD-X0^0glsKOyj+AJi2{gUMEN;>2=TAdmI)zUz@psgifMf$SO9pWSC*2s zq)Xai_1f8zEI`cinj<~FFtM#5fcUv)(H7uMqU(QdAI7f)tS=AhH53iU?Q%B}x&gA$2B`o|*LCD1jhW zSQpS0{*?u3iXtkY?&2<)$@#zc%$?qDlF1T~d7k&lWaiv^&wbx>zVm(GIrof<%iY)A zm%|rhEg~Z$Te<*wd9Cb1SB{RkOI$-=MBtc%k*xtvYC~Uito}R@3fRUqJvco z|Bt2r9pSOcJocAEd)UN^Tz-82GUZlqsU;wb|2Q_1!4Rms&HO1Xyquft~#6lJoR z`$|}VSy@{k6U652FJ~bnD9(X%>CS6Wp6U>sn;f}te}%WL`rg)qE4Q=4OOhk^@ykw( ziKr^LHnAd4M?#&SQhw8zaC05q#Mc66K^mxY!dZ=W+#Bq1B}cQ6Y8FWd(n>#%{8Di_8$CHibtvP z-x#-g;~Q?y0vJA*8TW>ZxF?fAy1DuFy7%O1ylLF(t=ah7LjZ$=p!;8(ZLjXAhwEkCR{wF`L=hwm>|vLK2=gR&KM1ZEG9R~53yNCZdabQoQ%VsolX zS#WlesPcpJ)7XLo6>Ly$im38oxyiizP&&>***e@KqUk3q3y+LQN^-v?ZmO>9O{Oq@ z{{He$*Z=Kf_FPR>El3iB*FULYFMnLa#Fl^l&|bFg$Omlh{xVVJ7uHm=4WE6)NflH6 z=>z4w{GV&8#MNnEY3*B7pXU!$9v-tZvdjO}9O=9r{3Wxq2QB}(n%%YI$)pS~NEd}U z)n#nv-V)K}kz9M0$hogDLsa<(OS0Hf5^WUKO-%WbR1W1ID$NpAegxHH;em?U$Eyn1 zU{&J2@WqSUn0tav=jR&&taR9XbV+Izb*PwFn|?cv0mksBdOWeGxNb~oR;`~>#w3bp zrOrEQ+BiW_*f&GARyW|nE}~oh0R>>AOH^>NHNKe%%sXLgWRu1Sy3yW0Q#L{8Y6=3d zKd=By=Nb8?#W6|LrpZm>8Ro)`@cLmU;D`d64nKT~6Z!aLOS{m`@oYwD`9yily@}%yr0A>P!6O4G|ImNbBzI`LJ0@=TfLt^f`M07vw_PvXvN{nx%4 zD8vS>8*2N}`lD>M{`v?2!nYnf%+`GRK3`_i+yq#1a1Yx~_1o~-$2@{=r~q11r0oR* zqBhFFVZFx!U0!2CcItqLs)C;|hZ|9zt3k^(2g32!KB-|(RhKbq-vh|uT>jT@tX8dN zH`TT5iytrZT#&8u=9qt=oV`NjC)2gWl%KJ;n63WwAe%-)iz&bK{k`lTSAP`hr)H$Q`Yq8-A4PBBuP*-G#hSKrnmduy6}G zrc+mcVrrxM0WZ__Y#*1$mVa2y=2I`TQ%3Vhk&=y!-?<4~iq8`XxeRG!q?@l&cG8;X zQ(qH=@6{T$$qk~l?Z0@I4HGeTG?fWL67KN#-&&CWpW0fUm}{sBGUm)Xe#=*#W{h_i zohQ=S{=n3jDc1b{h6oTy=gI!(N%ni~O$!nBUig}9u1b^uI8SJ9GS7L#s!j;Xy*CO>N(o6z){ND5WTew%1lr? znp&*SAdJb5{L}y7q#NHbY;N_1vn!a^3TGRzCKjw?i_%$0d2%AR73CwHf z`h4QFmE-7G=psYnw)B!_Cw^{=!UNZeR{(s47|V$`3;-*gneX=;O+eN@+Efd_Zt=@H3T@v&o^%H z7QgDF8g>X~$4t9pv35G{a_8Io>#>uGRHV{2PSk#Ea~^V8!n@9C)ZH#87~ z#{~PUaRR~4K*m4*PI16)rvzdaP|7sE8SyMQYI6!t(%JNebR%?lc$={$s?VBI0Qk!A zvrE4|#asTZA|5tB{>!7BcxOezR?QIo4U_LU?&9Im-liGSc|TrJ>;1=;W?gG)0pQaw z|6o7&I&PH!*Z=c7pNPkp)1(4W`9Z01*QKv44FkvF^2Kdz3gDNpV=A6R;Q}~V-_sZY zB9DB)F8%iFEjK?Gf4$Cwu_hA$98&pkrJM!7{l+}osR_aU2PEx!1CRCKsS`0v$LlKq z{Pg#ZeoBMv@6BcmK$-*|S9nv50or*2&EV`L7PfW$2J7R1!9Q(1SSe42eSWZ5sYU?g z2v{_QB^^jfh$)L?+|M`u-E7D=Hb?7@9O89!bRUSI7uD?Mxh63j5!4e(v)Kc&TUEqy z8;f`#(hwrIeW);FA0CK%YHz6;(WfJz^<&W#y0N3O2&Qh_yxHu?*8z1y9Ua}rECL!5 z7L1AEXx83h^}+)cY*Ko{`^0g3GtTuMP>b$kq;Aqo+2d&+48mc#DP;Sv z*UL^nR*K7J968xR0_eTaZ`N`u_c#9bFUjTj-}0+_57(gtEJT|7PA12W=2Z>#_a z&Wg@_b=$d~wonN3h~?)gS`qxx<4J&`dI*rH9!mTSiQj(0rF-{YoNJRnOqd5IbP7p} ztDaPu$A;#osxf=z2zVe4>tpa(knS_Mp67nKcE<>Cj$G2orP(Z$Oc4;4DPwbXYZsS^ z;b>59s(LgYmx|tkRD?U{+9VZ$T}{S}L6>lQNR^a|&5joAFXtOrI07Do!vk(e$mu@Y zNdN!djB`Hq1*T8mrC@S)MLwZ`&8aM8YYtVj7i)IY{g&D1sJaY`3e=1DSFnjO+jEHH zj+|@r$$4RtpuJ!8=C`n5X;5BjU2slP9VV&m0gr+{O(I}9pYF32AMU?n$k$=x;X^E# zOb-x}p1_`@IOXAj3>HFxnmvBV9M^^9CfD7UlfuH*y^aOD?X6D82p_r*c>DF)m=9>o zgv_SDeSF6WkoVOI<_mX};FlW9rk3WgQP|vr-eVo8!wH!TiX)aiw+I|dBWJX=H6zxx z_tSI2$ChOM+?XlJwEz3!juYU6Z_b+vP-Y|m1!|ahw>Kpjrii-M_wmO@f@7;aK(I;p zqWgn+X^onc-*f)V9Vfu?AHLHHK!p2|M`R&@4H0x4hD5#l1##Plb8KsgqGZ{`d+1Ns zQ7N(V#t49wYIm9drzw`;WSa|+W+VW8Zbbx*Z+aXHSoa!c!@3F_yVww58NPH2->~Ls z2++`lSrKF(rBZLZ5_ts6_LbZG-W-3fDq^qI>|rzbc@21?)H>!?7O*!D?dKlL z6J@yulp7;Yk6Bdytq*J1JaR1!pXZz4aXQ{qfLu0;TyPWebr3|*EzCk5%ImpjUI4cP z7A$bJvo4(n2km-2JTfRKBjI9$mnJG@)LjjE9dnG&O=S;fC)@nq9K&eUHAL%yAPX7OFuD$pb_H9nhd{iE0OiI4#F-);A|&YT z|A3tvFLfR`5NYUkE?Rfr&PyUeFX-VHzcss2i*w06vn4{k1R%1_1+Ygx2oFt*HwfT> zd=PFdfFtrP1+YRs0AVr{YVp4Bnw2HQX-|P$M^9&P7pY6XSC-8;O2Ia4c{=t{NRD=z z0DeYUO3n;p%k zNEmBntbNac&5o#&fkY1QSYA4tKqBb=w~c6yktzjyk_Po)A|?nn8>HdA31amaOf7jX z2qillM8t8V#qv5>19Cg_X`mlU*O5|C#X-kfAXAHAD*q%6+z%IK(*H6olm-N4%Ic)5 zL`?wQgXfD&qQRxWskoO^Ylb>`jelq;*~ZIwKw|#BQjOSLkgc2uy7|oFEVhC?pcnU+ z^7qz}Z2%F!WOp%JO3y*&_7t;uRfU>)drR1q)c7lX?;A1-TuLTR zyr(`7O19`eW{ev;L%`;BvOzh?m|)Rh?W8&I$KVvUTo?@f@K!du&vf=o6kKb?hA z%e6$T0jWS7doVkN%^_k3QOksfV?aC$Ge$a)z(!C@UVs*@qzDw*OFd*JfX#>5LCXjE z_vfUrLF7D`K$U2Ld#OCnh9U!;r7%GlKo$e__Il-oba06ER{H&f#J&W@x^^5j;y$0` zs2`m6pf+{UiDb{Mjsb$rH+MCM6G_wX92so96`ODFYKD>!Xz^0y@U7Tc1uON4L<>2f-oPe%FRPEZ@S#-yd7Md-i?v z)$Kgtq;%4g@>Kap3Nl2I&jnCIfGmRmcF4CXfF1H}3SfhLg8=!a0ucGaUk&c3*Ykgl z2X_L84cs+FD#cjf-nMJkVDH%XzOoh5!X-Q$K5VZx-hGF7MQ=XKBjhZZQ@1Sh zO^vY`WQ`zi21z-+01na%<^niMFIWm-n|!?hm4X2HEHkba4YS|+HRoIR=`#Xck@PFXaPjnP z=hC4A*0lumS+gpK=TUN!G;{WqICbMz-V=-lTP^@a#C|E!qH;T00SZh7u#?+?08g0< zV1s%-U-`T@8wGh!3pO^`zUIY{nAED7kBqg!qi&GfOp>57f2PGTV19m z0qU@1PYkf%4z_%;Sq4IY94rS+ie~pwT@O3+tg?#k_=5PIk6tV@< zwLoqM0wBVLkI#`|1w=eYMnc^aRR!t?lnUng>WekR#X!!9mYXL3g^gC7`)S7mmo{y} z9*N!d$s32Nu{cZp#O|UxEZK7eY<7hGcI=lc;HrSVL|HA|S$rhhu_DBT&l+`75d`Sj3LaM~H)P zZuk2&jor6yipafklSsPL-vMo?0yAYXpH3=LveBhkno-3{4VLWL16I-@!RM$Po>&}} zm&PX3-$i>$*yx-THZmvK2q`8Qm7B`(NMR;>VSgoGw}W|G6Xd6v04Zf;HIZ0DZU?@- z39vPe0N8w(9kl$2?eG4T?tLgY5V&aFl%~g;2)aSpi!dl?{hDgsz|3<-M(gPtwP_!n z2aB4tV?d0k+>X`+(HMYfK@qtfDK|mIJeg+A<_i-n+5wkrexFs#V0N&~+{+qJ(wggC*52o2daaRwcu7r;S!!KwguB3!Ei7?IEY ze4V$m{8B4Q^(VK4~Ea!V@@}Gs0HGbR5 zy~WI*21hZuoiK`=O$2a|Uce-Zi2%A*pB|?{gv)n8+_B+i&u8Ys)ePY+UwhBDlzbC& z+N00*-?a8DTC26*(3pKgeMO`fOau^-+c6Qqq}3-dpTsEEH}ds! zT^}8XAWO>c5%+qF%#M8#x_0gC+N%q8h6-%w;qidS%gai<T)vpfYuCHXRx6O-TbC|fnj87X zBESvn(9XlXFMj6%{&BaNQ&;xixaKP)+jJ|%u&?HXvYficY}{%hf?0rNDS-X-0_Jcr zjfj~n?T;~RL#sd4ZED2Jf{*Vj+*1eP9-H+~8X^#Jb?HHabLY)EH{QD@Yh-$M`XXt@3_f-L8nBo~*C?L4~n6M92PCuzX=KFgM*j!B66er$F! z+*M(Wkk`UI@uhrL#IUz-C{K@@xtd&n-PQz%kc}7YeE{{&$?}-*yW$eG*E4jp>B_U!2`2oZuvvitN& z%RN>tE$+Yhtqb1q+xQHbp=W4uKSiIj_LZppR0=hEiVj>P0^Vcr^hu2+#Hqum+}zzo znqZ|M4oD|qd=y&JX-qob`=uqt?o%FJPIVY2w0M7BH>#sx>s#OM#9JF1(3LxMAe-vi ztJeU*G)aksP`5sP9_%|~>Pp{NmMMcay>&D+cI%H}$uSx{Su(yz$)2e$*pS%*+!Zo>DNp(P7 zI%w^D2ceEFUGCtQPKfsKr`x%^dy;Rh>lMKuhA^btz=071W=vV`_xz&m;cvd0`|!3+ z2M6uga6CNvy)%Pjw_X}5+xf###jc+?=>6chZI{BMH=haH^7ipT>(?9{weF3apk<4; z_nZFsi`@oFBXCZE^k9B1x+cH2)~9d(MnfEm;GJxG*IB zU@ly{cOTWk*K1ryX+T7m!6A>VwB-*qfH;b>`AUP19lLSA9HbfppW!={L0K)??SymOCA^V>=tOBLn2c5e ksm9QK-qMKdW>5J419kFO%DdQj-T(jq07*qoM6N<$f+5oB`~Uy| diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 8ca12fe024be86e868d14e91120a6902f8e88ac6..25c15a1dc8d7534f4a92f837200fd1e4c7d00315 100644 GIT binary patch literal 7133 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 TI*G{{00000NkvXXu0mjf9n8OH literal 6464 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 B0*L?s diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png index 8e19b410a1b15ff180f3dacac19395fe3046cdec..25c15a1dc8d7534f4a92f837200fd1e4c7d00315 100644 GIT binary patch literal 7133 zcmV<38zSV1P)yUO68CI5yus~ zDi{Ylg`HIJnc!3$JH`PF1bDI$RAC2m7?2de0&yb*lF+fcZ;$uhOn1KDo|(6AmtC~l zeS6NR=KK1bp6*|N=GQ&*R=WYpf29ScV1W{#DHyLj6(|8JDVUN4N`R(hzVhS}ppt

tCj#Qn5mqdfs_Evj@=i`Rc9Wc1!KB$AhJLSkgQN@(iSKInzZT46J>!CAX%Z* zq%BYaG-=b7C&~gPK(a!qNn4-5}>&@BlE03B|!6R!sc3c zOMvFujLftClmN}M37c!(EdiQqGcwQm(@ua4#~zl#e6T^==DlqV5gbP)b5LcUfYCOv zoTs)N?Epxg2Uxs(V-y{CNfaG>Q53Dc_{ds)akO~D@8Hzmy9}pO3Ue_XtvY>kgk_tf zMJH~KmYi|~oyu}*SuUQtY%HC%Ia<}KbC}L_9K)v0-5eb^TIX$!jvuY_eI7PmIy?sU z9j9J;S+xFLmqe@2yf|8Vvc`FFgypo!YQ`sGo9U{v?!qWK?$VBqb?0UDq;r=gCKI#+ zAm2vlR-Y9uKKp0UqBHM~7M;HJ4b^q#)(9K7nzKHASMaePYzcnIRWC@&TH%SXDb9Kq^7)-dGEo7rh16v zfh6AdbC^hNGHn=+Arl6u4+eJQI|HoU6dkjq>Sh^;NKlFvbo_#6D*2^)o|9M^2 zpEkk4bVf=2#oOY>%Rd3oK}{JRwt+w&ZIC)sP3&tGxJC^yA;$aX91wQEzHKvWm`n^t zABJTCo3RaGs1I)WS|k_!1sYdg4g2=XS)1)t4+2RYu)KUiM`&ZFGcj(G;W);MkI3V7 z5-LA03ytz5rhOXAB>H1=Do6gz$tm-g9ppKYtxB@(i_)q5=6i#iLySsT&EB!AER-_z`%1*m32yN``6- z!ku^)u>K5~pgP?|twb;0tq9hNIkVxB+O$FqFhBb|$Zq;b-eHM_jig^<#Y_(Ne;xrsOLKpAf)~N0J8k_tzwU?ry_}PY| zy#N9G61)G7tY71{ZBKhIP^01LSOtLG0HqtzFq@q9iFQ;S=XPZxNd@DPvI~P z%s>xsgnr-uW?wlb#YfAJhvV>LIkX4vP3IxG{IB4au7J0Pzwy{?TMoj*?S!*E&(>=@ zzse@JQ+p^5h@Wjb#+~Fzv@fdbHr{`avjd#r(6EhRH))uRYjA5$rs(?n_S0wskWnYD zKGx@C$s1J<0Eb_NTSAb||2UFMKLdO6IpCg(by!amP46`V2%ks$5fIai3pC|rq4HVo z&l@9dI0o*0xTLOw_lN?5H^Rinklipfj$II~*ucJj7Ea5d+A{5!62gNhuy$}?edzJ8 z0Lep~3&F!dGSQt zXVN5@dRD)lf@B0z&t8JG3iiB@_`QW&e>xC12omcE0E(*T{ZVqk zr(id}1E>$uV6@ekdny(k@z5rd>!GXnHEK`%Bha{)r|hP<;o@hTk9Gr;uz!6G``Vpw zn!(H`8yZ9tam=xBbp599HGlxfm@={#jqF1ix>YrL6O~aT>a&hd^G-JONCL_9(yJ{c zNbh(*VY-5MHTNjmU+B)(MC`umNX+-(_&Co|DDM+>0!voG3~=AY zc5@g!5WcU3R(+G$=jNCg_jQ@?>nfB8jOjlJGt>`v&gHOYyobQ@dc4^nyV0OWanR$_ z)^N2(4>=$T1&0qg zaSA2nNs3E~6GnH;YIyH9!2MQp47|SY?|6MxeqKkR(z%#c-{q0}4#J&$F6>(`2IxdQ zz!Qgv@X*eNd*<5CZ`-(6kLxcohZo@IG#%3e5U@9n_uih}LB>zo;-$dK^)P&rlIJiq zxFIxY*vC6isxll)D$6xix$;!bkPsP(OPjos>sk(b+Ix6szZY)Vnih~^!c56C3Xn{C zY?riwmS;+rIM!?MNhyqg&ZYD|Juu#*WY_fL;I)0Iyj-n$d0b&$t}sihJ*k&Z*eg$f zJ@aBalNnC-+Ny>WR4};C{x# zEqLT%6lM}U-UBdg=&=mnH@U^fK#$?6m(2Tnq>z2_W68rK)R#As7wznZ-SpdhLR-aa z(lf%)c;g*h?@ULKG+wy1(b)4n)_RsYNNFw@Oy4mb0I9d!OvJm89Jt3gULxwSZs{5r z!NZ9)BLK<`+mAHAZyc~>_`HtdsR0-?aDpB@_a= zvx{$%PxYI6bS&as&LxVV7{2^e`|1a{?MG zeQ91+$JBa#TI~$i(Ru9aAUEm+5q$7)T>e2v(`sZW!^5*be^K}Z%U`8re+JWk1k-d0 z(XY+)gBI0o(Chx8-b6+kzWb_ZYdoJ!P7GvpAC7Si-QB9&f0!Pz4~Q1Qt=y3AkHQe( zQU&dcTAvqq$iuFfB??L1%Y=kf8vW}W`A?VxghE%vd$2jD}2TfuivTFG=X zdU&G1+MZ_`wI}lzg?#_!fA(jZruFsB2CvU*TMm~oyqe(9okrhN4fHq+RV`h*ml^6C z5$5>{RhCQX@uWIODpMVLCPzVHAJPfqMZFE3A6U*(eW^0eZ4-uUtD|DE(d zc`xWC(tS%GhQlh*;1VKGoR%uWV;m55z;*MfO)ozA=`B~^FIi@jzQ^y1d$->h_l+E1!oI6-lKLtsPoeT8#d9ewDXlPoM{iF0 zAHTIexZ_&b{<~;oz3UlZI4egm%~$1&;E;_E+!)6%T^GlDz8lB8zmtqoo~KY6uUz>m zm-4v6R;f(N^1hqIFMrcE_HO~Wzd=Ac7zQ0c)CK=UwwR!Be}N?gWZ7|W%h$oJSkHG> z8-Ud(1IO}vyESj-TkTD7d=cu_GCb)VxQ)LFtT-Ne`)zvmJKK2mR$l8{NxYla-2EN( zAs6#Tj9K~0Qz$7umQpV!^Kf`)} z*L%R2&KD8tCE#M9YbnsZ99Xgf&TC~e?(_NL5napRypDn6yC0`>7IpJn=F=mAn{4y+ zFA?mx)0w@`05&luT%>m|Qyd>AdcJHan{v(N2xsw_34r8Fy1cv}Q#?i$Wip`MuOsD0{XB|jge0ivI=xrRI*vt#t5Ny8_W{>8N=F{Un43fm^ zM(N`ib=OJEakfKNB=PVwyz${*U`Y&yG34^fH$lHJ*AP0tVzt15gdFX**TA`B% zQXRg3aeNJ7c0Z2rp_>pq_bd4C!aO(t{3A6GMWhH#p(y`?0u0pA13~b3@8Xv&dYdI& z#yl*;-o}>;96`4Hc!1yRo4vabKJX(1Puv6WTYq$P0eq~_;VlDh000YyNklEjUDCME;pSLxq%m+f^*Hza0Oqxq zfDUfF!;TD`!a0~D+B`U7jfGGljJyYOd|cOlN6Q(wg!v~dz3W-U_d0yj9Q^7=gj>G} z^U`Agy%st;2@avj_Bji|6zv{E(C!B3WP2e&@E$1jJRTfMC`=BZy0oNl1AEA==fI1}OHh;@nqkeYQ71fZ#!sXTu?3zPtjXPGj8LKY|invj{wO5<6e1ZX_Vl=%~~Knc)< z%v4qy&jKYt<5{N6pO6I#0+9c0X%jL?S!se6$f^|sppc`D76E~V>zI%jl*g1UAd619 zk-6Uh35xiQe7G1;XaaV*gos9%@*zu3xskcwKn76M0qAQDd83eVqn?)_$qJKIK>(t8 zJT&w|@<0MfX(@w zsRtU4a~TsVM)34|g1qM7nC3v2is6Cut6g$P=zaX7 ze3lkOes7eeTg#yTR49;|kNxFFdo;7f07ws7TB>qLnsIp>dL5?or45XyVp$HGevyLm zn;?xgV{y~P0EiyQdzu^w50U^$;X%YWP|(W=w-d!p6$91L`IP1_8X+M-MZA$0L>(d*lZo!weVtAmCn;=bg6Bt6EI3e*%6+@`pOJ$Ugr_iX* zus2HchU*igutN|1(j2;JW~M7M2++(7XxyuKATlsKJi{QQfH19mNp%%UIb4kAOJCC~ zF)sy)5P^`U7cUe@g#k#A_)W3k$Q2SONom3$FQa-=3I@x4Sr#guNp;gY1W%B`6$+g6 zUO_?jKq2=)1jT9ZLr}oDR|Z2GCnU`>LgDKuq?+{@_xWkv)FY+wIJaoQ!oqkU?=1pu zoars(VYCbh01ro62#lIntK zgc)qjbC}jO3aEkr#66IfA5FNz9Hy2~faHQ8@nr-lug^R!d1)Qx6E0szA=3qfM?;!9k4yp6U#P#yZ1~@l)&TJUhD>0P(vp zzgZ?Mf=HeuO>^QsJOXF52omcLL()>70i~rcZHw*9vx#q4cZ&m1{s=G6LkXm&Ct})z zBA6tlo65lVS&!9*FmwpK!t;@1Zy)?;&}3fyK5|SM{2b7b2rYJc46sB z{nH%LKo6oju0?d~mtgii4Yza^oPO!1ewK&Oc#xW*K%odl3X$R&B+L_JsnVrSz_y!$&p(RrrY|DA`&+(q2r<1NnGX z&!?5or!h8BEOgS*76hOq{oT;|BPu5Fe;XsZ;cpQ9>SiuwA>5KxK&WMn5)|?@3MqM) zRD@9ZxmcEaA|IyqEZk>70Ltby|5d+T%V3835#IYfL^pmO!E+D7{~0L#!MPwzVUlOc zVQC3HO!7i4c~HFE17$`oLSX5ULV_ZY_P>DewrddG{uSWRZojNSp2~y7|7OtYZ&V%bKL8GS&zlx*6e*xj))bffHPMe-vnML>aUNe2ZP=g|$* z?~g1zEFFsw?7Wxzqt79@@B45rfm=$D^d>u`H}Vh>rlY&Uf~g%Wn2}7!K(wq0CVC?z z3BvntKy(8^($^x3m%x85l0&4QIhu|>%<(o$fF?3Q`pbs;&1Kpj_3Y!4_H{08R{?u> z(Hmu7i%g`Q1z4v9=x8QY`=f}<)gtbXUfhA`rZ2$%{ndd(fHv1h)7Ap18!V7<%-k@v zq-km6yCVb+rN`R(1 z-`XGPYmsQG4b9KLUX%dM+o_uy9WMcz@;u~k6k(>^)I4mU1ZdKemV*<~hCvX=CZ2Rt z^Y}y#ejfLJ=DW`CxiWB!z%j7);Lb+<@oRv-m$UA$P8KUbPy#fuNhTB?90SuKo5eQX z_h_TOVft%UPVXAP4j8V8jAH{$(a7+e{8%i3l+}9Y|_LW9$=QTF&y^(GG zFZBdf0z@N}M{0qQ;JCOisqem<;QT{ef9hIm`)^~l`>98%=cr!FQZs(c_6181G-3wy zt*Dl&z!)x7#x)KmjTi2$4L)*p+<4}ntsS_7)gPd?Q!h~cR3X9PxcyNAN2Z3?+@UD31@qeoiK6+Ksc;$M) z-p#^?DQ%ATGOSbOF@^<-1Q0z<29EYOCU7=6_*kR%*md=x9aksGf$!5k_fi69C&T?z zgDQ_Vus~4&B0T)6!E}UxY1m}n!}Z$sYYERaHaT`lv!bigWyvK8gSkjnjC}+Wy-ad5F?GoaY(p9gYBFv^*wjfrSo` z>>@}GG4c$hcQ}I#%cD&eC;~t-mG(Azq7qC>muiy*iULrZ%vCls+5#m&qb*XVkIDii zKu2Y+vNABz1|>iv?NO$V(gGzwM`^IK`bZ1>KL7v#|NmoN(UbrH00v1!K~w_(kO3|r TI*G{{00000NkvXXu0mjf9n8OH literal 10676 zcmV;lDNELgP)um}xpNhCM7m0FQ}4}N1loz9~lvx)@N$zJd<6*u{W9aHJztU)8d8y;?3WdPz&A7QJeFUv+{E$_OFb457DPov zKYK{O^DFs{ApSuA{FLNz6?vik@>8e5x#1eBfU?k4&SP;lt`%BTxnkw{sDSls^$yvr#7NA*&s?gZVd_>Rv*NEb*6Zkcn zTpQm5+>7kJN$=MTQ_~#;5b!%>j&UU=HX-HtFNaj*ZO3v3%R?+kD&@Hn5iL5pzkc<} z!}Vjz^MoN~xma>UAg`3?HmDQH_r$-+6~29-ynfB8BlXkvm55}{k7TadH<~V$bhW)OZXK@1)CrIKcRnSY`tG*oX}4YC&HgKz~^u7 zD?#%P?L~p~dt3#y(89y}P;ij|-Z#KC;98PvlJCjf6TQbsznsL8#78n~B_kaQl}nsm zLHr7z%-FAGd=-!e?C{q62x5i4g4hNuh)LeqTa4ynfC4h(k*e>okrBlLv;YG%yf8!6 zcN)a^5>rp^4L+myO70z(0m`D}$C(eqfV1GpzM+%$6s6$?xF>~%Gzx|$BUZ$=;f)B8 zoQUrc!zB4kT!wqSvJ=ywY-W)3364w!`U>J+49ZE`H~+{!gaM)zFV!?!H+)k8BnOj3 zGvU93auN}g?X^8c`+PFv|EH=R%m)iUN7gssWyTD~uv7prl1iRfRaCFeJUuA@$(p&K z?D+cmhxf`n9B~!?S#d*TeLb^(q~VYS$3KhjfwfMWtZx&PlTZ(i@5HJ?of_Q)0YX99 z35b?W>?=vlb6gtK1ydcF4<@aH|Hgj8r?~QNOPx(YoKT^Xn=?Q%=1uA&-G(}mXdtsT zQuKACS|@G@uBW(SY(cH%% zq+xr%bpGqOGHyw3=8K7;J&hp^g1UsyG zYT24BGeGQukP?&TlOBE2H$2oH>U#E>GtI-fmc)17uc`7FRxJ3A!c%ADN^Z^oi6tYp zjzE+a{r&jt6z^scbd(feWPVEE!lV1I4lfdLhQ|yLdx&1IEV%l1erB&H8X}3=8lIcc zCNPUis-KRbCC z20@WYl&vVEZo!fLXxXs?{|<|Z=>0^-iX;y6{DT$lSo8b|@FZM3U$+W37(A_9<)fnq zP~11?(AKlHI-Lh(`?-@S?(1{t16bc7ESX->9twFP@t8_XK$XxuSFF#R(g7H(U%XvWa zm}J>%4-suYL=gX7-_MsjD27o?I!G888fxV$koLCfOv+Da&OVTG*@(aC9lz_e>*UGS zrX6f-45hd55ya-p_O{FbHEG%Ee9~i(H-B3RZkv`0ZDn$!>MigMZX06&y3RSk-WnL-{cM1 z1TZr|rc*Xaf|_^y&YLc4KK3<@aWfge2jARbRRg1DfJ~%pV9L_@$UADw3EXC_n%p0v zQO*{=88K@W{T?$wCR#S!M!e+R$aDL~EzovN7pbOBvrk&&ASS=Z43No|jrc>}aXXO5 zrd1<|Qypq-h#J*iORN@8YRc&`17u=lqo&L&YV%p#hL%P*WfIfH%ZUC^o#`?IWWr?w zQ^?EgP7!lqlq}ZM}d*sSVz(mqeQrA_huV@M4iwXa>k+%O-ZHW44JrRxLJy zLoHTuEqw(sMcO38n*lQ6ve97<&+Y50NNmVpW{hed@5EgrWfI~ITFJ0D(<|k)ag-~cV z0@-#S9z8&EUfBL7C_53YJ$)2ix^)vhsH;Q&KDdwe{q{2oJ#~b@#Qr?YGHrh;`rz<> z)F&rNr}J@}p8^N(8hLRH`=jpeT@y z2v7WETpnG{qixxkWWyK7(3QJ)RF-$=`O^k3+oY;O;rNnl^kVc*(j(Jb_99(Dw1w;T z4K8fsKDzn|epoWT|5{~*3bCC1>nd5;@=5lApq%3>^U_gQD>5j-O@WH;uEG+4MSBjJkdgtP;JG2`S&&Sa#_w33(yyAux~lnp7>wMXzD4yy_2#Vh+7&WMkWFl9Ohq06ifTiMWIC(|1Fe(3n}U_0(+jGC_(1c@X4vzk6y`)qzH+WXtj>dhI3=)~1Oi0Omh z^vp^i61ge1rO8;F~ncj_=tk zIvnwqFB-?)jER5LdQ?Hi=Kv5dgPZx%XSjc8VLCd4yYK4E88pIi4AGWzwdmrFf6&AF zI-`N3cpnf!Klj%)afJEC-x{^po?kDKD0@>6(}1f2xkCOMS49E?+5^EenLUrqK%EANgiQdAy8BW0e}Fvw`>)CTcvBeX6ZgjWC~(KdFE9hv+M6*t z?loxF7N3yv+}r*v(>9DX;0V1TP3G)L5r}m~e)RO*pc zv#tyehrK*U7ilRPA zk!aAmm9v3`z|hH7+WJ41!*h~g<2G1sUubFoL9b?dbp>%)pHzUZ-n)Z)W(6jh>jY-3 zUq&n%9=y?`ajN7rr3`t68sL^H^MG_rUDQw2$gj4Jb8MXgAW99^EbKmu9*Pv4Rh3=;vUVF30sUrdj!_n0*+m?WCbo^8q2fo|;?vH3OFh4__< zyaqNQdP4&Q+6R)%gv|^b#b|oW*XMMKLhEgy7(3D!poW*Tk`Qn4f*HUBD@U4+eOL|4 zh+hT+hl`Hx6+v(dZi=hGf|lF9JV};bs&Bm{THmunMOu))>8UdnTYV%TFdKB!dzN+?+5S+WYI><_z_6eDC z+WvMv78tB-j%G_;_de;{^Q7!t>Khj7gp^izaCK?7PmUiHevBXbk=s8{114AjWHDj{ z_(0ZvDUl`5mu8_cWw}Ba6$W+4RbZ4H97I^qQrq9Yd$5A!1wSqDNaUXf_sQ%GF7*wX zXFhfrz!d7zZiDhtgk#HcP(aukNVacB**=V7u3*Xwp&aR_R8vnbd1PGG6$}j(F_VMA?KUK~Jd?J)TjC!h3~KL|i&IYtL40AFtv zb_DC5Vt8aT6JhF5fEI0_FM#^zCX2>a=A#}FVOKjnH_(#+q}Ggy0kU*_?=3Ifjr+H$ z0D{~ZO<8+Sll*k^U-Y6DvsCpBP|v8XH*H@U(US~mumH%)dBJRde1f|G&@1J+MvVi( zla}?vMV%}C?xRQOryKvG8`v3bs)mPaL*v7}=z1;z?uq)tAg6HwY9Ihbhu^awAJU&S zK#m{H4)PVmJ!}eqpy%MRP$Pe(&D;?N7($!Oz=8uTxRyl1Wg*V=gE z5PBge1q~I%qmY6Ol#1^O?u~P=44?CDh*GEXjSmoi`y;!_V+I2o>H!jms@u4HII9l^ z=&`W@f)v#1KQ8O!bY@+=fC3VBA@A7jQt^q~fz}*7i0(grY=jujW3=vAHS&qyN!B3* z;l=MjJrW~O7Sz5xp2Z?EtA`naLM239gw8Ub=%IHPY<00fb5 zozf%j+(s|urpUn~5r5pE7yi0taDcx4`#K81u*kwAk(cvQ$vx_F{wd}8h=eKDCE$M(iD9_QGJh zr0e(Z>QuRZ+`ff^GZPu%;bA#_^$&vsboSa6V!jmN0SV4dBKN4v`C)aESBtZV7J~U( zOc3e47Zx3Ux67y(o?#7;!=y1jxEueEF#$^c_PoxG_pq)GZLU2`d>%!3rdJjkrAK!2 z!2>jNPceo_9v)xpmu)_EgxsU9*GT^QoERVik+LSzH$Z{Ax7_GFY+!HA0MSfDyXT(k z?vob%yRiU**{7No8PKK&w77Z?8j#9IJ#hv1O^!lS%kt0n7@x79#}+R-TuINbiBfotv)O^y=kD0AkUNhrP$U_@qXE zYpkIR$Zgi=#6Os0^$m7rt1kV3&R~;r&xn%>8xzDHk!yob^vyrl^*R$4R_u5eYdHc> zk}^bkAIjLe{t{-Q8+D@9&dz9Q;o$+RGT7l8sx<~c5IBs*Dp_bAwqQRM2olfEe}Vk4 zc9Vt3hx$Z%0|;xNF=aW(Z*%CEmg_ z-riR#1Wjb9t+D^_K$%|E`_m#&XHzQ*&~vzFCzYIJB6Ieap%urgb=%UsC<9^hC4{(B z(3+*N>|JNdhT54KE$HT~okqq-teADE3Vn9^sA!>%+fb|98XIO zePvP!J8>9Ao~cC(u@>UqZhO(v+C!ob_m!fdtCwsACbR*lqtAwwQ@{hCy1%pm)*>|2 z*4U}vUNFO;Lw9~?Rw9)osm$D4f)?XmUvN$e8eWjjsm+Gr-@$~6iMgqWH+%YAV1gAu z7NbW)FU+RvtZ75ADtlW83vAW@YkP-BMr{8tV}A+L9?({@=u8(K9O&F z4CiS*&nHDa>J}36GR;VAs~I41Kfit308jVeg0#zIVj;(cr8EHqE6<OP0C9kbOl`)daY)$O<0J;;?A%Ve z&#H!_rNfB84*1o6aD2oLL(Ywd^#ZTmyK9Dlqg=at2TjDGCcH@qymjUqbf4FvGxc*ap|#6x@}Ug@+NK z6j_PV43T(wmxf+(J5kT~r++|VKw>6X0o1~R#{);Yll!>QeP1cfzTvOK0-Ndpf;nGz znqZirxrk&)Llzz-fKnnEL_I{Lt#O<8-0}IX?!m#sfdv{wY{3p7aF*=sI^w@wUdl;1 zOaQ`8mA(OjeI_2&*O_79989c3v-g+F!6OGyYBVD}5>W|JMvMsd5c6BV0+zUQBP_6V zpc@@&KR+A%>NFy5N0^}idafWHEjUnt=I<|KC5!NPqrW(T!j9Ll{*5Zxa^f&K*Ftjr zawS=CfJrKpWc85)DE8bbv=YBAz#5gkRLaSR_+g6q@-*6f>L^-JT`4CEtE*JX@Z1zF z0E&{AR0fE|??ogjZqfU3(3!I1@j9|~pd0<5UcI0vX5Z_hd1HMA@j|Yv)N2|G^GS;q zXYi@WB9s-#b)He4kH+MtvHHF`8K0kl-oxkemC0RJl}RX;os2R(GXc%6Dn>&D@rZ}- zPb!J(Btl-2B2W+9n6vkmpjV4Bl?F&viUK%NfXXmH_#u%8D2iDWAcFW0m@khVp9{N9 z7&DbP(1Gk7XhlD$GZqiugk2XTu>nJ*bAY;J1CcQR(gq#?Wq4+yGC*3wqY5A{@Bl2z z0I7yYB2tLJe5Lb|+h?DCkK5jdFd$~3g?0d0ShVgG6l4p2kXQKH?S=$M3{jLui1Y>! zz77*W+QP#K5C?de0OAUdGC-Q)A%ZOd%_kz}%W2+>L}>etfq`~pMyi$o5kJUY><4vq zdT;7z-}KnW2H$K&gE`X+Kok~5fVjY;1Q17f6amr&9##OQG7B#?nzXIwwheWiM!)a| zv^^L9r_m3B3^W^?E?~yI`Qf!(wU9Ow3)Pu3odJ?DRk8qag@-*r>fw?ty;X?M?5GeGW6VdRS@X}kbfC>Ph0tSHC!=o7> zcJP1%;)e#h-i!cg0S|z}2#|Ws1LjKvukP!X{cY{zF$mh+!rtD7tND^MV;y)-ur`c4 zFKkU>&&+tOw*1y*YwVu5X8==z0UVItNs(wyMIoAiwTI+0%@V;VuNP&ZIh92y2&-(k zMi0;exUrZe67@)CmgjR)(0ttRFy~A9c}gUif~+K|%mVQAO^-$M_Lq|w4!my^J_<}z zA?b<|Lu5*2A)0rv67|lAMLqF*s7KWjivr(f4{^A5$f4qjg zmxyepp;Y!W2-Y|f2|IZNMV_rib8+3xIZ#3BP@Ul4G|a88M6V}A)%k~vnh0%eYirwy zYwt@rDs5q5-M(vANBrvba>DMCi52-;ZT+q5*4X2*N*nu4*&?uY&0IEM1_>fN{*6zdU!wDfFIgPxZWn<9+^rhhu0i5u{>8eHa7)5yJ`s} z&wJ6fw${~r$vM*&uCCxryLOp0cDzs0u6k{{^!ivQ8f-O~8dg3KgU_SbRiA)C08Qiv zzKj+=kD{M5JWJLGV(;@P`ZkfJkBl^sz+u>GVaJz7K;+rg z!o@{r=UEY;R%DelCy0#G3URLBevOL)`* zqy;>(0F74#5KDMKCSwZ$ri&3ES$H7!lg1Z%!6v&4XYGNurEM%p9@7gz5@*`VqGLzU zLT+15_Xc^?TikPBx22wj=^SZ zs}Z0G&hW4Wh|SoR5uCl&CJhu&k`der5ui5sCU4Xu6TeIXd)x3=z%U;RBc ztv*7s+cIP7jSY}0h}ev6NdZcX;0%u}Krp$FD?Ca7=>U&BKrt%d;n#!acKLYTY21bZ zv@JUu!uL_#BXe+Yf|!Brh+$)}DSJRnnTjC}Ljoio_TWn)VmmNO0IF00kQSrrFee?R z7Bc~)&8WJ1fTFY-RVM%)WCnDP(H}A& zhBl&Y)kS8&w1q_z9gU_85|G-ofg9`TvUE|dcg!}aDQgOV5Q)DNUCuQ)WYLDoh0la$WgJ4Rotv zl73SGB!!5ft4;u_0)Tewlu1aIlv4$e7NhEr2*wDImhcdODhmiee(7;S&)u7m^TJuj zaGUfdZDVciLfWbcO&60EYDq)jov~-{4mK7`pYEYc&w@icvLv$}mP~63fQaCyo2Ss* zQVo!HDH$pO(lRB35g-omfawMe^nP_^y$^poa`|Z9SFjm3X%lhVbe0*eXklR@hpazj z*S1q9FNjjxxVQ}d->$7c!mNdD=TFtot*O#!`|xS|OHuf_lO(fI+uy#9pUO$a*#sOA z$Rylwv>Hv8d{!)xY^h8tQ6spaLFVi$MVo35lV#;3pFwgMqm(I19?9JSfizUeB!pxz zcn=V0Ex3&Ey6Qwt{o0znXyk^^eztLT9tLee+r-Wk{2opI5JWWXJ32UktqpML9XRs6 z#MobUojQtE)E=tWWgF@baOJ{w)?sH(aQZ!{b=ZagG!MYD6E_&Z4eyD-|6~MGQ5j`# z30VOQ`vMH%@f}La~!CD6da+o0vbz|)znwna{EC?cc;6-Qy+!o+g*weOYZHn;7XD^B!GzUq~%s$X>)e$w?x< z)Z{%y9JjKLLjf7F$S-*}(L4YTB*B9jlapkLL@J3tktnH*$W0;n%wWo3O+r{wMM+Xs z312FZ01r9LkcJA*uaczmNv}$!;O~IX;}g9Njo7gI5`{<7<8q*FVrk0oC=PXy=|H#u zKz|QgXXl|oYge50=7$rDoC!A zwmuJZ)k$wFA`CfyIQN20w{F8JJU+C?)xnrU75an-ynV+u_V&K`HPF)1vY*SRA5?qo z4wJ-*MB1#|r!Rm&z+V6}B?l0Pe4bzc2%Dl|*~vO(62cT4m?6OkkScgmqa{JY29NC< zP`3p$kKj5U0CjC6u5(A)29~DgG_&oQS$!%!~kOnUbLrAa(Fytpgg!eRC*soc&G_uG_vu^N8!(Nuj&` z#K5BpB1am;3cv;J?KETBHutTeLYRx~!*UT%eFH@HlYnR~Xd#ZtV2l89$md}MNCP~) z#NEhk{c@q>)Yl@QPDyT$xQ-p4baOh=17y<6kArSxF%WmxdX1ad1CA`8-MhaZCnN0!T$BAvIYd$Ypk2y6B4Si@|dVJW!`?+j>!lxq~SM z3ias|wWr-lH!C{=QINH>!!YMh<{ktaPS&W&jIB2|K;l(L3bab7U{MCX3JClZr|>x|SL)ShO73*>(Um3?TLG`qsoXZfidM1G@Xto|+)Gp=VaS;Q^9D6v=9A zD>#=4Ano&cVAicz1Lcqje*g}Ec0HrKfAs*ZXNAq1<|_lpmo==DKZL81tN)a z-G$7_Zqvrk!pe$hqqYtX!@JFyp6HMtm!DR zlY%zt)46}pc&GU@O5HcDdK3`1gJ_^hRfR&SkCYK(7=R>uMx>}8RhI`yOL*WM)W?DK zd0>f^Fa5DbD2!_Kr?c<^^IC=K{kB<@x5 zk$1vQb~leE3UKtFT;Jvph*;*-lWW8bLCF!qLW$cXy+TXr@ad&Qi)bp0anoS zpc={A)@G=~8PB3aVN#6)WyEEr;5gAbX#X_(I$X6; zYpSX{&_t+i#6PmJ^0%_Jm6*0ZSo(JyIABWG_ol_VE?acLZPV(9(0h|=CK;f}D(n=h zH}=5R*n3cbAWn;2{Pym{R zy1w&fY{!B9--3Im@f>2Rti&3}gO=5fmc5Nk_uLGR9zYUnB;q6423g?ViKSTj!bo(N z;35C#KI82u-qJ4{Gf19eyVUlUW%|^ zZnCIfP7;y+_-`g5|IbPi^%ca4`U?_-{WBAUA;nq3Pmb&tjVjJW{j(BKKdjOErbeS) zu{%)Dotu!~`sIJ|mMlEx{_fPMF3&yt4!*}{=)Lxad&l5N;yDtHBLSza865qC)RtDR zEzNTQ$I=Twxjl$hva*tBC1{|2c0A9QyeEzMpx1&~aRXK^t{J*{-KFPtZ@v9|LL_>( zFq5pc7*d#lFa&5!Sq>Ugk%wTXYPEvD6H=0eMi-=`m$Q@5wh937R(}&TIUbMRpz@FH=p^muMS&k8rPW&v5Uw3|(oN%o@i?AX(9{eMj0e z=|;zbye%X!HEJd)P*|Sr9279#aqQ@Y0n?{$9=Lcxs@J0TE4-I}RLfhl^rG*&<(K_F zUwy@Y^V+`y!q?sCv2DYDAOYd)Z}@Ln_qX4s&#w5cTltGm=(3C6OBdC;FPKx|J8x!c z@AsyKx#Dxexm&kxJ(ymrFTJ)z(*WQ-$UTbhwHv+nPP8mmW^jxPQY+dck!Yn(GBCl| zkS7UDcIeQPG+ujYNI(&)epEv|1C8I--hO0z57$xcyu3ne{CQ(R;BWX0{zm~B2aNYrwV0HSx8{J;1$)?@1OKiJ7vbWif-(1RyDDC0Urd(C)7@ec}NqAJW4iP}%mf zbm-iNbeE}?u#}fR3L^cV^!xa?mYqBIAtni6fpfz(#K5@GYdg|=k%dN4+nB*IQJC7% zz*}ePoH|fP)rD#VciPxq#I!);i-%JJsPv!`K;iJCfOym2c+zupr{{E{*RZ44w4wK4 zhUN){sTFNBOX{3j)0j#J>OV=q>OxJ619fN}DGajWNdM=ZG3C0HJC*5|F-luRx+T-!eR#IDS=86u9ga*$qLhV6wmY2 a9sdtN6eHRrdyqB&0000I_?AR+?xsb{T0? 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 NuBQIOiu=&e{{lYZa9#ia literal 9250 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 diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index 4c19a13c239cb67b8a2134ddd5f325db1d2d5bee..bbb92732f19d12c3fedd045db3fa31dc3379daa2 100644 GIT binary patch literal 11090 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 NuBQIOiu=&e{{lYZa9#ia literal 15523 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 BIP(Ai diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index 7ba83a2..cbde07f 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -4,6 +4,7 @@ diff --git a/android/app/src/main/res/xml/network_security_config.xml b/android/app/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..46b1d37 --- /dev/null +++ b/android/app/src/main/res/xml/network_security_config.xml @@ -0,0 +1,14 @@ + + + + + + + + + + 192.168.1.12 + localhost + 10.0.2.2 + + \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index 9766946..342626f 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -15,6 +15,7 @@ buildscript { classpath("com.android.tools.build:gradle") classpath("com.facebook.react:react-native-gradle-plugin") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin") + classpath("com.google.gms:google-services:4.3.15") } } diff --git a/android/gradle.properties b/android/gradle.properties index 5e24e3a..a46a5b9 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -21,6 +21,8 @@ org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m # Android operating system, and which are packaged with your app's APK # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true +# Automatically convert third-party libraries to use AndroidX +android.enableJetifier=true # Use this property to specify which architecture you want to build. # You can also override it from the CLI using @@ -32,7 +34,7 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 # your application. You should enable this flag either if you want # to write custom TurboModules/Fabric components OR use libraries that # are providing them. -newArchEnabled=true +newArchEnabled=false # Use this property to enable or disable the Hermes JS engine. # If set to false, you will be using JSC instead. diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 37f853b..df97d72 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/package-lock.json b/package-lock.json index d28258f..48db886 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,36 @@ "name": "T4B_Chat", "version": "0.0.1", "dependencies": { + "@react-native-async-storage/async-storage": "^2.2.0", + "@react-native-community/netinfo": "^11.4.1", + "@react-native-cookies/cookies": "^6.2.1", + "@react-native-firebase/app": "^23.4.0", + "@react-native-firebase/messaging": "^23.4.0", + "@react-native-vector-icons/common": "^12.3.0", + "@react-navigation/bottom-tabs": "^7.4.7", + "@react-navigation/native": "^7.1.17", + "@react-navigation/native-stack": "^7.3.26", + "@react-navigation/stack": "^7.4.8", + "@reduxjs/toolkit": "^2.9.0", + "apisauce": "^3.2.0", "react": "19.0.0", - "react-native": "0.79.0" + "react-native": "0.79.0", + "react-native-device-info": "^10.3.0", + "react-native-element-dropdown": "^2.12.4", + "react-native-gesture-handler": "^2.28.0", + "react-native-linear-gradient": "^2.8.3", + "react-native-permissions": "^5.2.4", + "react-native-push-notification": "^8.1.1", + "react-native-raw-bottom-sheet": "^3.0.0", + "react-native-reanimated": "^3.19.1", + "react-native-safe-area-context": "^5.6.1", + "react-native-screens": "^4.16.0", + "react-native-svg": "^15.12.1", + "react-native-toast-message": "^2.2.1", + "react-native-vector-icons": "^10.3.0", + "react-native-webview": "^13.16.0", + "react-redux": "^9.2.0", + "redux-persist": "^6.0.0" }, "devDependencies": { "@babel/core": "^7.25.2", @@ -127,7 +155,6 @@ "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==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.27.3" @@ -156,7 +183,6 @@ "version": "7.28.3", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz", "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -178,7 +204,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", @@ -222,7 +247,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -266,7 +290,6 @@ "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==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.27.1" @@ -306,7 +329,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", @@ -324,7 +346,6 @@ "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==", - "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -672,7 +693,6 @@ "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==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -790,7 +810,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -823,7 +842,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -907,7 +925,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", @@ -941,7 +958,6 @@ "version": "7.28.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -1244,7 +1260,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.27.1", @@ -1330,7 +1345,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1415,7 +1429,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -1637,7 +1650,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1686,7 +1698,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1718,7 +1729,6 @@ "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz", "integrity": "sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -1771,7 +1781,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", @@ -1901,6 +1910,25 @@ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/@babel/preset-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz", + "integrity": "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/runtime": { "version": "7.28.4", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", @@ -1981,6 +2009,18 @@ "dev": true, "license": "MIT" }, + "node_modules/@egjs/hammerjs": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", + "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==", + "license": "MIT", + "dependencies": { + "@types/hammerjs": "^2.0.36" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", @@ -2081,6 +2121,827 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@firebase/ai": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-2.2.1.tgz", + "integrity": "sha512-0VWlkGB18oDhwMqsgxpt/usMsyjnH3a7hTvQPcAbk7VhFg0QZMDX60mQKfLTFKrB5VwmlaIdVsSZznsTY2S0wA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/ai/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/analytics": { + "version": "0.10.18", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.18.tgz", + "integrity": "sha512-iN7IgLvM06iFk8BeFoWqvVpRFW3Z70f+Qe2PfCJ7vPIgLPjHXDE774DhCT5Y2/ZU/ZbXPDPD60x/XPWEoZLNdg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/analytics-compat": { + "version": "0.2.24", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.24.tgz", + "integrity": "sha512-jE+kJnPG86XSqGQGhXXYt1tpTbCTED8OQJ/PQ90SEw14CuxRxx/H+lFbWA1rlFtFSsTCptAJtgyRBwr/f00vsw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/analytics": "0.10.18", + "@firebase/analytics-types": "0.8.3", + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/analytics-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/analytics-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", + "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/analytics/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/app": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.14.2.tgz", + "integrity": "sha512-Ecx2ig/JLC9ayIQwZHqm41Tzlf4c1WUuFhFUZB1y+JIJqDRE579x7Uil7tKT8MwDpOPwrK5ZtpxdSsrfy/LF8Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.11.0.tgz", + "integrity": "sha512-XAvALQayUMBJo58U/rxW02IhsesaxxfWVmVkauZvGEz3vOAjMEQnzFlyblqkc2iAaO82uJ2ZVyZv9XzPfxjJ6w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/app-check-compat": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.4.0.tgz", + "integrity": "sha512-UfK2Q8RJNjYM/8MFORltZRG9lJj11k0nW84rrffiKvcJxLf1jf6IEjCIkCamykHE73C6BwqhVfhIBs69GXQV0g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check": "0.11.0", + "@firebase/app-check-types": "0.5.3", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/app-check-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-check-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", + "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-check/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/app-compat": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.5.2.tgz", + "integrity": "sha512-cn+U27GDaBS/irsbvrfnPZdcCzeZPRGKieSlyb7vV6LSOL6mdECnB86PgYjYGxSNg8+U48L/NeevTV1odU+mOQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app": "0.14.2", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/app-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/app-types": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/auth-compat": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.6.0.tgz", + "integrity": "sha512-J0lGSxXlG/lYVi45wbpPhcWiWUMXevY4fvLZsN1GHh+po7TZVng+figdHBVhFheaiipU8HZyc7ljw1jNojM2nw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth": "1.11.0", + "@firebase/auth-types": "0.13.0", + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-compat/node_modules/@firebase/auth": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.11.0.tgz", + "integrity": "sha512-5j7+ua93X+IRcJ1oMDTClTo85l7Xe40WSkoJ+shzPrX7OISlVWLdE1mKC57PSD+/LfAbdhJmvKixINBw2ESK6w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/@firebase/auth-compat/node_modules/@react-native-async-storage/async-storage": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.24.0.tgz", + "integrity": "sha512-W4/vbwUOYOjco0x3toB8QCr7EjIP6nE9G7o8PMguvvjYT5Awg09lyV4enACRx4s++PPulBiBSjL0KTFx2u0Z/g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "merge-options": "^3.0.4" + }, + "peerDependencies": { + "react-native": "^0.0.0-0 || >=0.60 <1.0" + } + }, + "node_modules/@firebase/auth-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth-types": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz", + "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.0.tgz", + "integrity": "sha512-wR9En2A+WESUHexjmRHkqtaVH94WLNKt6rmeqZhSLBybg4Wyf0Umk04SZsS6sBq4102ZsDBFwoqMqJYj2IoDSg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/component/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/data-connect": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.3.11.tgz", + "integrity": "sha512-G258eLzAD6im9Bsw+Qm1Z+P4x0PGNQ45yeUuuqe5M9B1rn0RJvvsQCRHXgE52Z+n9+WX1OJd/crcuunvOGc7Vw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/data-connect/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/database": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.1.0.tgz", + "integrity": "sha512-gM6MJFae3pTyNLoc9VcJNuaUDej0ctdjn3cVtILo3D5lpp0dmUHHLFN/pUKe7ImyeB1KAvRlEYxvIHNF04Filg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.1.0.tgz", + "integrity": "sha512-8nYc43RqxScsePVd1qe1xxvWNf0OBnbwHxmXJ7MHSuuTVYFO3eLyLW3PiCKJ9fHnmIz4p4LbieXwz+qtr9PZDg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/database": "1.1.0", + "@firebase/database-types": "1.0.16", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/database-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/database-types": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.16.tgz", + "integrity": "sha512-xkQLQfU5De7+SPhEGAXFBnDryUWhhlFXelEg2YeZOQMCdoe7dL64DDAd77SQsR+6uoXIZY5MB4y/inCs4GTfcw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.13.0" + } + }, + "node_modules/@firebase/database/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/firestore": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.9.1.tgz", + "integrity": "sha512-PYVUTkhC9y8pydrqC3O1Oc4AMfkGSWdmuH9xgPJjiEbpUIUPQ4J8wJhyuash+o2u+axmyNRFP8ULNUKb+WzBzQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "@firebase/webchannel-wrapper": "1.0.4", + "@grpc/grpc-js": "~1.9.0", + "@grpc/proto-loader": "^0.7.8", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/firestore-compat": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.4.1.tgz", + "integrity": "sha512-BjalPTDh/K0vmR/M/DE148dpIqbcfvtFVTietbUDWDWYIl9YH0TTVp/EwXRbZwswPxyjx4GdHW61GB2AYVz1SQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/firestore": "4.9.1", + "@firebase/firestore-types": "3.0.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/firestore-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/firestore-types": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", + "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/firestore/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/functions": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.13.1.tgz", + "integrity": "sha512-sUeWSb0rw5T+6wuV2o9XNmh9yHxjFI9zVGFnjFi+n7drTEWpl7ZTz1nROgGrSu472r+LAaj+2YaSicD4R8wfbw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.7.0", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/functions-compat": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.4.1.tgz", + "integrity": "sha512-AxxUBXKuPrWaVNQ8o1cG1GaCAtXT8a0eaTDfqgS5VsRYLAR0ALcfqDLwo/QyijZj1w8Qf8n3Qrfy/+Im245hOQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/functions": "0.13.1", + "@firebase/functions-types": "0.6.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/functions-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/functions-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", + "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/functions/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/installations": { + "version": "0.6.19", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.19.tgz", + "integrity": "sha512-nGDmiwKLI1lerhwfwSHvMR9RZuIH5/8E3kgUWnVRqqL7kGVSktjLTWEMva7oh5yxQ3zXfIlIwJwMcaM5bK5j8Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/installations-compat": { + "version": "0.2.19", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.19.tgz", + "integrity": "sha512-khfzIY3EI5LePePo7vT19/VEIH1E3iYsHknI/6ek9T8QCozAZshWT9CjlwOzZrKvTHMeNcbpo/VSOSIWDSjWdQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/installations-types": "0.5.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/installations-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/installations-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", + "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/installations/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/logger": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.5.0.tgz", + "integrity": "sha512-cGskaAvkrnh42b3BA3doDWeBmuHFO/Mx5A83rbRDYakPjO9bJtRL3dX7javzc2Rr/JHZf4HlterTW2lUkfeN4g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/logger/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/messaging": { + "version": "0.12.23", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.23.tgz", + "integrity": "sha512-cfuzv47XxqW4HH/OcR5rM+AlQd1xL/VhuaeW/wzMW1LFrsFcTn0GND/hak1vkQc2th8UisBcrkVcQAnOnKwYxg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.13.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/messaging-compat": { + "version": "0.2.23", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.23.tgz", + "integrity": "sha512-SN857v/kBUvlQ9X/UjAqBoQ2FEaL1ZozpnmL1ByTe57iXkmnVVFm9KqAsTfmf+OEwWI4kJJe9NObtN/w22lUgg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/messaging": "0.12.23", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/messaging-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/messaging-interop-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", + "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/messaging/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/performance": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.7.9.tgz", + "integrity": "sha512-UzybENl1EdM2I1sjYm74xGt/0JzRnU/0VmfMAKo2LSpHJzaj77FCLZXmYQ4oOuE+Pxtt8Wy2BVJEENiZkaZAzQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0", + "web-vitals": "^4.2.4" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/performance-compat": { + "version": "0.2.22", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.22.tgz", + "integrity": "sha512-xLKxaSAl/FVi10wDX/CHIYEUP13jXUjinL+UaNXT9ByIvxII5Ne5150mx6IgM8G6Q3V+sPiw9C8/kygkyHUVxg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/performance": "0.7.9", + "@firebase/performance-types": "0.2.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/performance-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/performance-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", + "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/performance/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/remote-config": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.6.6.tgz", + "integrity": "sha512-Yelp5xd8hM4NO1G1SuWrIk4h5K42mNwC98eWZ9YLVu6Z0S6hFk1mxotAdCRmH2luH8FASlYgLLq6OQLZ4nbnCA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/installations": "0.6.19", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat": { + "version": "0.2.19", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.19.tgz", + "integrity": "sha512-y7PZAb0l5+5oIgLJr88TNSelxuASGlXyAKj+3pUc4fDuRIdPNBoONMHaIUa9rlffBR5dErmaD2wUBJ7Z1a513Q==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/remote-config": "0.6.6", + "@firebase/remote-config-types": "0.4.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", + "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/remote-config/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/storage": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.14.0.tgz", + "integrity": "sha512-xWWbb15o6/pWEw8H01UQ1dC5U3rf8QTAzOChYyCpafV6Xki7KVp3Yaw2nSklUwHEziSWE9KoZJS7iYeyqWnYFA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/storage-compat": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.4.0.tgz", + "integrity": "sha512-vDzhgGczr1OfcOy285YAPur5pWDEvD67w4thyeCUh6Ys0izN9fNYtA1MJERmNBfqjqu0lg0FM5GLbw0Il21M+g==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/storage": "0.14.0", + "@firebase/storage-types": "0.8.3", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/storage-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/storage-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", + "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/storage/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/util": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.13.0.tgz", + "integrity": "sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/util/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.4.tgz", + "integrity": "sha512-6m8+P+dE/RPl4OPzjTxcTbQ0rGeRyeTvAi9KwIffBVCiAMKrfXfLZaqD1F+m8t4B5/Q5aHsMozOgirkH1F5oMQ==", + "license": "Apache-2.0" + }, + "node_modules/@grpc/grpc-js": { + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", + "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", + "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -2714,6 +3575,82 @@ "node": ">= 8" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@react-native-async-storage/async-storage": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.2.0.tgz", + "integrity": "sha512-gvRvjR5JAaUZF8tv2Kcq/Gbt3JHwbKFYfmb445rhOj6NUMx3qPLixmDx5pZAyb9at1bYvJ4/eTUipU5aki45xw==", + "license": "MIT", + "dependencies": { + "merge-options": "^3.0.4" + }, + "peerDependencies": { + "react-native": "^0.0.0-0 || >=0.65 <1.0" + } + }, "node_modules/@react-native-community/cli": { "version": "18.0.0", "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-18.0.0.tgz", @@ -2947,6 +3884,185 @@ "node": ">=10" } }, + "node_modules/@react-native-community/netinfo": { + "version": "11.4.1", + "resolved": "https://registry.npmjs.org/@react-native-community/netinfo/-/netinfo-11.4.1.tgz", + "integrity": "sha512-B0BYAkghz3Q2V09BF88RA601XursIEA111tnc2JOaN7axJWmNefmfjZqw/KdSxKZp7CZUuPpjBmz/WCR9uaHYg==", + "license": "MIT", + "peerDependencies": { + "react-native": ">=0.59" + } + }, + "node_modules/@react-native-community/push-notification-ios": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@react-native-community/push-notification-ios/-/push-notification-ios-1.11.0.tgz", + "integrity": "sha512-nfkUs8P2FeydOCR4r7BNmtGxAxI22YuGP6RmqWt6c8EEMUpqvIhNKWkRSFF3pHjkgJk2tpRb9wQhbezsqTyBvA==", + "license": "MIT", + "peer": true, + "dependencies": { + "invariant": "^2.2.4" + }, + "peerDependencies": { + "react": ">=16.6.3", + "react-native": ">=0.58.4" + } + }, + "node_modules/@react-native-cookies/cookies": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@react-native-cookies/cookies/-/cookies-6.2.1.tgz", + "integrity": "sha512-D17wCA0DXJkGJIxkL74Qs9sZ3sA+c+kCoGmXVknW7bVw/W+Vv1m/7mWTNi9DLBZSRddhzYw8SU0aJapIaM/g5w==", + "license": "MIT", + "dependencies": { + "invariant": "^2.2.4" + }, + "peerDependencies": { + "react-native": ">= 0.60.2" + } + }, + "node_modules/@react-native-firebase/app": { + "version": "23.4.0", + "resolved": "https://registry.npmjs.org/@react-native-firebase/app/-/app-23.4.0.tgz", + "integrity": "sha512-HaHFrr5D2o5EAKbDOds579Vp8f6QtH3pMeteZuIj/0UaHYD2wdTutNWOsiiJ1tmNJZi7kbfgY0qL/cSgzBGZjw==", + "license": "Apache-2.0", + "dependencies": { + "firebase": "12.2.1" + }, + "peerDependencies": { + "expo": ">=47.0.0", + "react": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + } + } + }, + "node_modules/@react-native-firebase/messaging": { + "version": "23.4.0", + "resolved": "https://registry.npmjs.org/@react-native-firebase/messaging/-/messaging-23.4.0.tgz", + "integrity": "sha512-wxdgl6teo+OsS4nG3KBQM8bFwmZNY4ZzR6UAYB0e7vvp0J/dMfduErkZ6uzEkEjjt2UsOeWB2PBLcgxKjYsX4A==", + "license": "Apache-2.0", + "peerDependencies": { + "@react-native-firebase/app": "23.4.0", + "expo": ">=47.0.0" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + } + } + }, + "node_modules/@react-native-vector-icons/common": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@react-native-vector-icons/common/-/common-12.3.0.tgz", + "integrity": "sha512-5GMBcLBkA0MuciweYcrSyvi9fYGanfVnE2J+pwHx1QiaVgTaoCm4rylJgSS77MVI5qUiGh7aJpqq5afSz2U4bw==", + "license": "MIT", + "dependencies": { + "find-up": "^7.0.0", + "picocolors": "^1.1.1", + "plist": "^3.1.0" + }, + "bin": { + "rnvi-update-plist": "lib/commonjs/scripts/updatePlist.js" + }, + "engines": { + "node": ">= 18.0.0" + }, + "peerDependencies": { + "@react-native-vector-icons/get-image": "^12.2.0", + "react": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "@react-native-vector-icons/get-image": { + "optional": true + } + } + }, + "node_modules/@react-native-vector-icons/common/node_modules/find-up": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", + "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", + "license": "MIT", + "dependencies": { + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-native-vector-icons/common/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-native-vector-icons/common/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-native-vector-icons/common/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-native-vector-icons/common/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/@react-native-vector-icons/common/node_modules/yocto-queue": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz", + "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@react-native/assets-registry": { "version": "0.79.0", "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.79.0.tgz", @@ -3281,6 +4397,157 @@ "dev": true, "license": "MIT" }, + "node_modules/@react-navigation/bottom-tabs": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-7.4.7.tgz", + "integrity": "sha512-SQ4KuYV9yr3SV/thefpLWhAD0CU2CrBMG1l0w/QKl3GYuGWdN5OQmdQdmaPZGtsjjVOb+N9Qo7Tf6210P4TlpA==", + "license": "MIT", + "dependencies": { + "@react-navigation/elements": "^2.6.4", + "color": "^4.2.3" + }, + "peerDependencies": { + "@react-navigation/native": "^7.1.17", + "react": ">= 18.2.0", + "react-native": "*", + "react-native-safe-area-context": ">= 4.0.0", + "react-native-screens": ">= 4.0.0" + } + }, + "node_modules/@react-navigation/core": { + "version": "7.12.4", + "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-7.12.4.tgz", + "integrity": "sha512-xLFho76FA7v500XID5z/8YfGTvjQPw7/fXsq4BIrVSqetNe/o/v+KAocEw4ots6kyv3XvSTyiWKh2g3pN6xZ9Q==", + "license": "MIT", + "dependencies": { + "@react-navigation/routers": "^7.5.1", + "escape-string-regexp": "^4.0.0", + "nanoid": "^3.3.11", + "query-string": "^7.1.3", + "react-is": "^19.1.0", + "use-latest-callback": "^0.2.4", + "use-sync-external-store": "^1.5.0" + }, + "peerDependencies": { + "react": ">= 18.2.0" + } + }, + "node_modules/@react-navigation/core/node_modules/react-is": { + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.1.tgz", + "integrity": "sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==", + "license": "MIT" + }, + "node_modules/@react-navigation/elements": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-2.6.4.tgz", + "integrity": "sha512-O3X9vWXOEhAO56zkQS7KaDzL8BvjlwZ0LGSteKpt1/k6w6HONG+2Wkblrb057iKmehTkEkQMzMLkXiuLmN5x9Q==", + "license": "MIT", + "dependencies": { + "color": "^4.2.3", + "use-latest-callback": "^0.2.4", + "use-sync-external-store": "^1.5.0" + }, + "peerDependencies": { + "@react-native-masked-view/masked-view": ">= 0.2.0", + "@react-navigation/native": "^7.1.17", + "react": ">= 18.2.0", + "react-native": "*", + "react-native-safe-area-context": ">= 4.0.0" + }, + "peerDependenciesMeta": { + "@react-native-masked-view/masked-view": { + "optional": true + } + } + }, + "node_modules/@react-navigation/native": { + "version": "7.1.17", + "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.1.17.tgz", + "integrity": "sha512-uEcYWi1NV+2Qe1oELfp9b5hTYekqWATv2cuwcOAg5EvsIsUPtzFrKIasgUXLBRGb9P7yR5ifoJ+ug4u6jdqSTQ==", + "license": "MIT", + "dependencies": { + "@react-navigation/core": "^7.12.4", + "escape-string-regexp": "^4.0.0", + "fast-deep-equal": "^3.1.3", + "nanoid": "^3.3.11", + "use-latest-callback": "^0.2.4" + }, + "peerDependencies": { + "react": ">= 18.2.0", + "react-native": "*" + } + }, + "node_modules/@react-navigation/native-stack": { + "version": "7.3.26", + "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-7.3.26.tgz", + "integrity": "sha512-EjaBWzLZ76HJGOOcWCFf+h/M+Zg7M1RalYioDOb6ZdXHz7AwYNidruT3OUAQgSzg3gVLqvu5OYO0jFsNDPCZxQ==", + "license": "MIT", + "dependencies": { + "@react-navigation/elements": "^2.6.4", + "warn-once": "^0.1.1" + }, + "peerDependencies": { + "@react-navigation/native": "^7.1.17", + "react": ">= 18.2.0", + "react-native": "*", + "react-native-safe-area-context": ">= 4.0.0", + "react-native-screens": ">= 4.0.0" + } + }, + "node_modules/@react-navigation/routers": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-7.5.1.tgz", + "integrity": "sha512-pxipMW/iEBSUrjxz2cDD7fNwkqR4xoi0E/PcfTQGCcdJwLoaxzab5kSadBLj1MTJyT0YRrOXL9umHpXtp+Dv4w==", + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11" + } + }, + "node_modules/@react-navigation/stack": { + "version": "7.4.8", + "resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-7.4.8.tgz", + "integrity": "sha512-zZsX52Nw1gsq33Hx4aNgGV2RmDJgVJM71udomCi3OdlntqXDguav3J2t5oe/Acf/9uU8JiJE9W8JGtoRZ6nXIg==", + "license": "MIT", + "dependencies": { + "@react-navigation/elements": "^2.6.4", + "color": "^4.2.3" + }, + "peerDependencies": { + "@react-navigation/native": "^7.1.17", + "react": ">= 18.2.0", + "react-native": "*", + "react-native-gesture-handler": ">= 2.0.0", + "react-native-safe-area-context": ">= 4.0.0", + "react-native-screens": ">= 4.0.0" + } + }, + "node_modules/@reduxjs/toolkit": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.9.0.tgz", + "integrity": "sha512-fSfQlSRu9Z5yBkvsNhYF2rPS8cGXn/TZVrlwN1948QyZ8xMZ0JvP50S2acZNaf+o63u6aEeMjipFyksjIcWrog==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, "node_modules/@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", @@ -3329,6 +4596,18 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -3379,6 +4658,12 @@ "@types/node": "*" } }, + "node_modules/@types/hammerjs": { + "version": "2.0.46", + "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.46.tgz", + "integrity": "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==", + "license": "MIT" + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -3498,6 +4783,12 @@ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "license": "MIT" }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, "node_modules/@types/yargs": { "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", @@ -3746,6 +5037,15 @@ "devOptional": true, "license": "MIT" }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.11", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz", + "integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -3935,6 +5235,15 @@ "node": ">= 8" } }, + "node_modules/apisauce": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/apisauce/-/apisauce-3.2.0.tgz", + "integrity": "sha512-uEvNyBl86g9znFzb5DsBN0kaC9cs9Seo6Ztippf1lJgMEj/mcwE7YMsv4NZeKHjpxGOQ4AHDPItnDRiEgNIdDA==", + "license": "MIT", + "dependencies": { + "axios": "^1.10.0" + } + }, "node_modules/appdirsjs": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/appdirsjs/-/appdirsjs-1.2.7.tgz", @@ -4129,6 +5438,12 @@ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", "license": "MIT" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -4145,6 +5460,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/axios": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -4405,6 +5731,12 @@ "devOptional": true, "license": "MIT" }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, "node_modules/brace-expansion": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", @@ -4533,7 +5865,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "devOptional": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -4804,6 +6135,19 @@ "dev": true, "license": "MIT" }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -4822,6 +6166,16 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/colorette": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", @@ -4829,6 +6183,18 @@ "devOptional": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/command-exists": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", @@ -5025,6 +6391,47 @@ "node": ">= 8" } }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -5120,6 +6527,15 @@ "node": ">=0.10.0" } }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, "node_modules/dedent": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", @@ -5201,6 +6617,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -5266,11 +6691,65 @@ "node": ">=6.0.0" } }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "devOptional": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -5321,6 +6800,18 @@ "node": ">= 0.8" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -5449,7 +6940,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -5459,7 +6949,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -5497,7 +6986,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "devOptional": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -5510,7 +6998,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -6232,7 +7719,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, "license": "MIT" }, "node_modules/fast-glob": { @@ -6307,6 +7793,18 @@ "reusify": "^1.0.4" } }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -6341,6 +7839,15 @@ "node": ">=8" } }, + "node_modules/filter-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", + "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -6403,6 +7910,86 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/firebase": { + "version": "12.2.1", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-12.2.1.tgz", + "integrity": "sha512-UkuW2ZYaq/QuOQ24bfaqmkVqoBFhkA/ptATfPuRtc5vdm+zhwc3mfZBwFe6LqH9yrCN/6rAblgxKz2/0tDvA7w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/ai": "2.2.1", + "@firebase/analytics": "0.10.18", + "@firebase/analytics-compat": "0.2.24", + "@firebase/app": "0.14.2", + "@firebase/app-check": "0.11.0", + "@firebase/app-check-compat": "0.4.0", + "@firebase/app-compat": "0.5.2", + "@firebase/app-types": "0.9.3", + "@firebase/auth": "1.11.0", + "@firebase/auth-compat": "0.6.0", + "@firebase/data-connect": "0.3.11", + "@firebase/database": "1.1.0", + "@firebase/database-compat": "2.1.0", + "@firebase/firestore": "4.9.1", + "@firebase/firestore-compat": "0.4.1", + "@firebase/functions": "0.13.1", + "@firebase/functions-compat": "0.4.1", + "@firebase/installations": "0.6.19", + "@firebase/installations-compat": "0.2.19", + "@firebase/messaging": "0.12.23", + "@firebase/messaging-compat": "0.2.23", + "@firebase/performance": "0.7.9", + "@firebase/performance-compat": "0.2.22", + "@firebase/remote-config": "0.6.6", + "@firebase/remote-config-compat": "0.2.19", + "@firebase/storage": "0.14.0", + "@firebase/storage-compat": "0.4.0", + "@firebase/util": "1.13.0" + } + }, + "node_modules/firebase/node_modules/@firebase/auth": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.11.0.tgz", + "integrity": "sha512-5j7+ua93X+IRcJ1oMDTClTo85l7Xe40WSkoJ+shzPrX7OISlVWLdE1mKC57PSD+/LfAbdhJmvKixINBw2ESK6w==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/firebase/node_modules/@react-native-async-storage/async-storage": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.24.0.tgz", + "integrity": "sha512-W4/vbwUOYOjco0x3toB8QCr7EjIP6nE9G7o8PMguvvjYT5Awg09lyV4enACRx4s++PPulBiBSjL0KTFx2u0Z/g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "merge-options": "^3.0.4" + }, + "peerDependencies": { + "react-native": "^0.0.0-0 || >=0.60 <1.0" + } + }, + "node_modules/firebase/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/flat-cache": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", @@ -6431,6 +8018,26 @@ "integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==", "license": "MIT" }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", @@ -6447,6 +8054,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -6495,7 +8118,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "devOptional": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6554,7 +8176,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "devOptional": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -6588,7 +8209,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "devOptional": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -6743,7 +8363,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -6820,7 +8439,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -6833,7 +8451,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -6849,7 +8466,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "devOptional": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -6873,6 +8489,21 @@ "hermes-estree": "0.25.1" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -6905,6 +8536,12 @@ "node": ">= 0.8" } }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "license": "MIT" + }, "node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -6941,6 +8578,12 @@ "node": ">=0.10.0" } }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "license": "ISC" + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -6987,6 +8630,16 @@ "node": ">=16.x" } }, + "node_modules/immer": { + "version": "10.1.3", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.3.tgz", + "integrity": "sha512-tmjF/k8QDKydUlm3mZU+tjM6zeq9/fFpPqH9SzWmBnVVKsPBg/V66qsMwb3/Bo90cgUN+ghdVBess+hPsxUyRw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -7389,6 +9042,15 @@ "node": ">=8" } }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -8808,7 +10470,12 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, + "license": "MIT" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "license": "MIT" }, "node_modules/lodash.debounce": { @@ -8990,6 +10657,12 @@ "node": ">=6" } }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -9059,12 +10732,17 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, + "node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "license": "CC0-1.0" + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -9081,6 +10759,18 @@ "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", "license": "MIT" }, + "node_modules/merge-options": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", + "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==", + "license": "MIT", + "dependencies": { + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -9623,6 +11313,24 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -9698,6 +11406,18 @@ "node": ">=8" } }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/nullthrows": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", @@ -9720,7 +11440,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -10167,6 +11886,20 @@ "node": ">=8" } }, + "node_modules/plist": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", @@ -10273,7 +12006,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -10285,7 +12017,36 @@ "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, + "license": "MIT" + }, + "node_modules/protobufjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, "node_modules/punycode": { @@ -10331,6 +12092,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/query-string": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", + "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", + "license": "MIT", + "dependencies": { + "decode-uri-component": "^0.2.2", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/queue": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", @@ -10426,6 +12205,18 @@ } } }, + "node_modules/react-freeze": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.4.tgz", + "integrity": "sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=17.0.0" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -10492,6 +12283,252 @@ } } }, + "node_modules/react-native-device-info": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/react-native-device-info/-/react-native-device-info-10.3.0.tgz", + "integrity": "sha512-/ziZN1sA1REbJTv5mQZ4tXggcTvSbct+u5kCaze8BmN//lbxcTvWsU6NQd4IihLt89VkbX+14IGc9sVApSxd/w==", + "license": "MIT", + "peerDependencies": { + "react-native": "*" + } + }, + "node_modules/react-native-element-dropdown": { + "version": "2.12.4", + "resolved": "https://registry.npmjs.org/react-native-element-dropdown/-/react-native-element-dropdown-2.12.4.tgz", + "integrity": "sha512-abZc5SVji9FIt7fjojRYrbuvp03CoeZJrgvezQoDoSOrpiTqkX69ix5m+j06W2AVncA0VWvbT+vCMam8SoVadw==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + }, + "engines": { + "node": ">= 16.0.0" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-gesture-handler": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.28.0.tgz", + "integrity": "sha512-0msfJ1vRxXKVgTgvL+1ZOoYw3/0z1R+Ked0+udoJhyplC2jbVKIJ8Z1bzWdpQRCV3QcQ87Op0zJVE5DhKK2A0A==", + "license": "MIT", + "dependencies": { + "@egjs/hammerjs": "^2.0.17", + "hoist-non-react-statics": "^3.3.0", + "invariant": "^2.2.4" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-is-edge-to-edge": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.1.7.tgz", + "integrity": "sha512-EH6i7E8epJGIcu7KpfXYXiV2JFIYITtq+rVS8uEb+92naMRBdxhTuS8Wn2Q7j9sqyO0B+Xbaaf9VdipIAmGW4w==", + "license": "MIT", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-linear-gradient": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz", + "integrity": "sha512-KflAXZcEg54PXkLyflaSZQ3PJp4uC4whM7nT/Uot9m0e/qxFV3p6uor1983D1YOBJbJN7rrWdqIjq0T42jOJyA==", + "license": "MIT", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-permissions": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/react-native-permissions/-/react-native-permissions-5.4.2.tgz", + "integrity": "sha512-XNMoG1fxrB9q73MLn/ZfTaP7pS8qPu0KWypbeFKVTvoR+JJ3O7uedMOTH/mts9bTG+GKhShOoZ+k0CR63q9jwA==", + "license": "MIT", + "peerDependencies": { + "react": ">=18.1.0", + "react-native": ">=0.70.0", + "react-native-windows": ">=0.70.0" + }, + "peerDependenciesMeta": { + "react-native-windows": { + "optional": true + } + } + }, + "node_modules/react-native-push-notification": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/react-native-push-notification/-/react-native-push-notification-8.1.1.tgz", + "integrity": "sha512-XpBtG/w+a6WXTxu6l1dNYyTiHnbgnvjoc3KxPTxYkaIABRmvuJZkFxqruyGvfCw7ELAlZEAJO+dthdTabCe1XA==", + "license": "MIT", + "peerDependencies": { + "@react-native-community/push-notification-ios": "^1.10.1", + "react-native": ">=0.33" + } + }, + "node_modules/react-native-raw-bottom-sheet": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-native-raw-bottom-sheet/-/react-native-raw-bottom-sheet-3.0.0.tgz", + "integrity": "sha512-kHR7j2ExCLqf/AO3MECozMJXi48O1+YxUYSRgRo/5Ftm7mEcrxJEzvjqMmqUbVhhKlfk5hLCGFnEQ5Z9OHCUtg==", + "license": "MIT" + }, + "node_modules/react-native-reanimated": { + "version": "3.19.1", + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.19.1.tgz", + "integrity": "sha512-ILL0FSNzSVIg6WuawrsMBvNxk2yJFiTUcahimXDAeNiE/09eagVUlHhYWXAAmH0umvAOafBaGjO7YfBhUrf5ZQ==", + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-arrow-functions": "^7.0.0-0", + "@babel/plugin-transform-class-properties": "^7.0.0-0", + "@babel/plugin-transform-classes": "^7.0.0-0", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.0.0-0", + "@babel/plugin-transform-optional-chaining": "^7.0.0-0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0-0", + "@babel/plugin-transform-template-literals": "^7.0.0-0", + "@babel/plugin-transform-unicode-regex": "^7.0.0-0", + "@babel/preset-typescript": "^7.16.7", + "convert-source-map": "^2.0.0", + "invariant": "^2.2.4", + "react-native-is-edge-to-edge": "1.1.7" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0", + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-safe-area-context": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.1.tgz", + "integrity": "sha512-/wJE58HLEAkATzhhX1xSr+fostLsK8Q97EfpfMDKo8jlOc1QKESSX/FQrhk7HhQH/2uSaox4Y86sNaI02kteiA==", + "license": "MIT", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-screens": { + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.16.0.tgz", + "integrity": "sha512-yIAyh7F/9uWkOzCi1/2FqvNvK6Wb9Y1+Kzn16SuGfN9YFJDTbwlzGRvePCNTOX0recpLQF3kc2FmvMUhyTCH1Q==", + "license": "MIT", + "dependencies": { + "react-freeze": "^1.0.0", + "react-native-is-edge-to-edge": "^1.2.1", + "warn-once": "^0.1.0" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-screens/node_modules/react-native-is-edge-to-edge": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.2.1.tgz", + "integrity": "sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q==", + "license": "MIT", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-svg": { + "version": "15.13.0", + "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.13.0.tgz", + "integrity": "sha512-/YPK+PAAXg4T0x2d2vYPvqqAhOYid2bRKxUVT7STIyd1p2JxWmsGQkfZxXCkEFN7TwLfIyVlT5RimT91Pj/qXw==", + "license": "MIT", + "dependencies": { + "css-select": "^5.1.0", + "css-tree": "^1.1.3", + "warn-once": "0.1.1" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-toast-message": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/react-native-toast-message/-/react-native-toast-message-2.3.3.tgz", + "integrity": "sha512-4IIUHwUPvKHu4gjD0Vj2aGQzqPATiblL1ey8tOqsxOWRPGGu52iIbL8M/mCz4uyqecvPdIcMY38AfwRuUADfQQ==", + "license": "MIT", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-vector-icons": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-10.3.0.tgz", + "integrity": "sha512-IFQ0RE57819hOUdFvgK4FowM5aMXg7C7XKsuGLevqXkkIJatc3QopN0wYrb2IrzUgmdpfP+QVIbI3S6h7M0btw==", + "deprecated": "react-native-vector-icons package has moved to a new model of per-icon-family packages. See the https://github.com/oblador/react-native-vector-icons/blob/master/MIGRATION.md on how to migrate", + "license": "MIT", + "dependencies": { + "prop-types": "^15.7.2", + "yargs": "^16.1.1" + }, + "bin": { + "fa-upgrade.sh": "bin/fa-upgrade.sh", + "fa5-upgrade": "bin/fa5-upgrade.sh", + "fa6-upgrade": "bin/fa6-upgrade.sh", + "generate-icon": "bin/generate-icon.js" + } + }, + "node_modules/react-native-vector-icons/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/react-native-vector-icons/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/react-native-vector-icons/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/react-native-webview": { + "version": "13.16.0", + "resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.16.0.tgz", + "integrity": "sha512-Nh13xKZWW35C0dbOskD7OX01nQQavOzHbCw9XoZmar4eXCo7AvrYJ0jlUfRVVIJzqINxHlpECYLdmAdFsl9xDA==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^4.0.0", + "invariant": "2.2.4" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native/node_modules/@react-native/virtualized-lists": { "version": "0.79.0", "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.79.0.tgz", @@ -10568,6 +12605,29 @@ "node": ">=10" } }, + "node_modules/react-redux": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", + "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, "node_modules/react-refresh": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", @@ -10613,6 +12673,30 @@ "node": ">= 6" } }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-persist": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz", + "integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==", + "license": "MIT", + "peerDependencies": { + "redux": ">4.0.0" + } + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -10640,14 +12724,12 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true, "license": "MIT" }, "node_modules/regenerate-unicode-properties": { "version": "10.2.2", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", - "dev": true, "license": "MIT", "dependencies": { "regenerate": "^1.4.2" @@ -10687,7 +12769,6 @@ "version": "6.4.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", - "dev": true, "license": "MIT", "dependencies": { "regenerate": "^1.4.2", @@ -10705,14 +12786,12 @@ "version": "0.8.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", - "dev": true, "license": "MIT" }, "node_modules/regjsparser": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "jsesc": "~3.1.0" @@ -10737,6 +12816,12 @@ "devOptional": true, "license": "ISC" }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -10890,7 +12975,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "devOptional": true, "funding": [ { "type": "github", @@ -11236,6 +13320,21 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "license": "ISC" }, + "node_modules/simple-swizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "license": "MIT" + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -11317,6 +13416,15 @@ "source-map": "^0.6.0" } }, + "node_modules/split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -11394,6 +13502,15 @@ "node": ">= 0.4" } }, + "node_modules/strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -11945,7 +14062,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -11955,7 +14071,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", @@ -11969,7 +14084,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -11979,12 +14093,23 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -12044,6 +14169,24 @@ "punycode": "^2.1.0" } }, + "node_modules/use-latest-callback": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.2.4.tgz", + "integrity": "sha512-LS2s2n1usUUnDq4oVh1ca6JFX9uSqUncTfAm44WMg0v6TxL7POUTk1B044NH8TeLkFbNajIsgDHcgNpNzZucdg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", + "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -12100,6 +14243,12 @@ "makeerror": "1.0.12" } }, + "node_modules/warn-once": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/warn-once/-/warn-once-0.1.1.tgz", + "integrity": "sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q==", + "license": "MIT" + }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", @@ -12110,6 +14259,35 @@ "defaults": "^1.0.3" } }, + "node_modules/web-vitals": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", + "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", + "license": "Apache-2.0" + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/whatwg-fetch": { "version": "3.6.20", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", @@ -12283,6 +14461,15 @@ "async-limiter": "~1.0.0" } }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "license": "MIT", + "engines": { + "node": ">=8.0" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 1f3578e..d9d3493 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,36 @@ "test": "jest" }, "dependencies": { + "@react-native-async-storage/async-storage": "^2.2.0", + "@react-native-community/netinfo": "^11.4.1", + "@react-native-cookies/cookies": "^6.2.1", + "@react-native-firebase/app": "^23.4.0", + "@react-native-firebase/messaging": "^23.4.0", + "@react-native-vector-icons/common": "^12.3.0", + "@react-navigation/bottom-tabs": "^7.4.7", + "@react-navigation/native": "^7.1.17", + "@react-navigation/native-stack": "^7.3.26", + "@react-navigation/stack": "^7.4.8", + "@reduxjs/toolkit": "^2.9.0", + "apisauce": "^3.2.0", "react": "19.0.0", - "react-native": "0.79.0" + "react-native": "0.79.0", + "react-native-device-info": "^10.3.0", + "react-native-element-dropdown": "^2.12.4", + "react-native-gesture-handler": "^2.28.0", + "react-native-linear-gradient": "^2.8.3", + "react-native-permissions": "^5.2.4", + "react-native-push-notification": "^8.1.1", + "react-native-raw-bottom-sheet": "^3.0.0", + "react-native-reanimated": "^3.19.1", + "react-native-safe-area-context": "^5.6.1", + "react-native-screens": "^4.16.0", + "react-native-svg": "^15.12.1", + "react-native-toast-message": "^2.2.1", + "react-native-vector-icons": "^10.3.0", + "react-native-webview": "^13.16.0", + "react-redux": "^9.2.0", + "redux-persist": "^6.0.0" }, "devDependencies": { "@babel/core": "^7.25.2", @@ -36,4 +64,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/utilities/README.md b/utilities/README.md new file mode 100644 index 0000000..a7d38ea --- /dev/null +++ b/utilities/README.md @@ -0,0 +1,134 @@ +# Utilities + +This directory contains organized utility functions and modules for the T4B Chat application. + +## Files + +### notificationUtils.ts +Contains utility functions for creating notification channels, configuring settings, and showing local notifications. + +### permissionUtils.ts +Handles notification permission requests and checks for Android and iOS platforms. + +### deepLinkUtils.ts +Handles deep linking functionality for FCM notifications and chat navigation. +- `DeepLinkHandler` class for managing deep links +- Methods for handling killed app, foreground, and background deep links +- Channel ID extraction and URL building utilities + +### webViewUtils.ts +Manages WebView functionality, navigation, and message handling. +- `WebViewHandler` class for WebView management +- Navigation request handling and validation +- Message processing and debug script injection + +### cookieUtils.ts +Handles cookie management for WebView authentication. +- `CookieHandler` class for cookie operations +- Platform-specific cookie retrieval (iOS/Android) +- Session cookie validation and refresh functionality + +### fcmUtils.ts +Manages Firebase Cloud Messaging (FCM) functionality. +- `FCMHandler` class for FCM operations +- Token management and backend communication +- Message handling for different app states + +### constants.ts +Centralized configuration constants for the entire application. +- Domain configuration +- FCM endpoints +- Navigation delays +- URL patterns +- Platform configuration +- Notification settings + +### loaderUtils.tsx +Beautiful custom loading components with animations and chat icons. +- `CustomLoader` - Main animated loader component +- `ProgressLoader` - Loader with progress indicator +- Predefined loader configurations for different scenarios +- Smooth animations and transitions + +## Usage + +Import the utilities you need in your components: + +```typescript +import { showLocalNotification, createNotificationChannel } from './utilities/notificationUtils'; +import { requestNotificationPermission, checkNotificationPermission } from './utilities/permissionUtils'; +import { createDeepLinkHandler } from './utilities/deepLinkUtils'; +import { createWebViewHandler } from './utilities/webViewUtils'; +import { createCookieHandler } from './utilities/cookieUtils'; +import { createFCMHandler } from './utilities/fcmUtils'; +import { ALLOWED_DOMAIN, NAVIGATION_DELAYS, URL_PATTERNS } from './utilities/constants'; +import { CustomLoader, createOdooLoader, createChatLoader } from './utilities/loaderUtils'; +``` + +## Classes and Methods + +### Deep Link Handler +- `handleKilledAppDeepLink(data)` - Handle deep links from killed app +- `handleForegroundBackgroundDeepLink(data)` - Handle deep links from foreground/background +- `navigateToChannel(channelId)` - Navigate to specific channel +- `handleDeepLink(deepLink)` - Process deep link URLs + +### WebView Handler +- `handleNavigation(request)` - Handle WebView navigation requests +- `handleWebViewMessage(event, setWebViewCookies)` - Process WebView messages +- `handleWebViewLoadEnd(currentChannel, isNavigating)` - Handle load completion +- `injectDebugScript()` - Inject debug script into WebView + +### Cookie Handler +- `getWebViewCookies()` - Get authentication cookies +- `refreshWebViewCookies()` - Set up periodic cookie refresh +- `getCookiesForUrl(url)` - Get cookies for specific URL +- `setCookiesForUrl(url, cookies)` - Set cookies for specific URL +- `clearAllCookies()` - Clear all cookies +- `isValidSessionCookie(cookies)` - Validate session cookies + +### FCM Handler +- `initializeNotifications()` - Initialize FCM notifications +- `requestUserPermission()` - Request notification permissions +- `getFcmToken()` - Get FCM token +- `sendTokenToBackend(token)` - Send token to backend +- `setupMessageListeners(appState)` - Setup FCM message listeners + +### Constants +- `ALLOWED_DOMAIN` - Base domain for the application +- `NAVIGATION_DELAYS` - Timing constants for navigation delays +- `URL_PATTERNS` - URL pattern templates +- `FCM_REGISTER_ENDPOINT` - FCM registration endpoint +- `COOKIE_REFRESH_INTERVAL` - Cookie refresh timing +- `NOTIFICATION_CONFIG` - Notification channel configuration + +### Loader Components +- `CustomLoader` - Main animated loader with chat icon +- `ProgressLoader` - Loader with progress indicator +- `createOdooLoader()` - Pre-configured Odoo loader +- `createChatLoader()` - Pre-configured chat loader +- `createNavigationLoader()` - Pre-configured navigation loader +- `LOADER_CONFIGS` - Predefined loader configurations + +### Notification Utils +- `createNotificationChannel()` - Creates Android notification channel +- `configureNotificationSettings()` - Configures notification settings +- `showLocalNotification(options)` - Shows local notification +- `shouldShowCustomNotification(appState)` - Checks if custom notification should be shown +- `testNotification()` - Test notification function + +### Permission Utils +- `requestNotificationPermission()` - Requests notification permission +- `checkNotificationPermission()` - Checks current permission status +- `needsNotificationPermission()` - Checks if permission is needed +- `showPermissionExplanation()` - Shows permission explanation dialog +- `showSettingsDialog()` - Shows settings dialog for denied permissions + +## Architecture Benefits + +1. **Separation of Concerns**: Each utility handles a specific domain +2. **Reusability**: Utilities can be easily reused across components +3. **Maintainability**: Code is organized and easy to understand +4. **Testability**: Each utility can be tested independently +5. **Type Safety**: Proper TypeScript interfaces and types +6. **Documentation**: Comprehensive JSDoc comments throughout \ No newline at end of file diff --git a/utilities/constants.ts b/utilities/constants.ts new file mode 100644 index 0000000..2b5cf7a --- /dev/null +++ b/utilities/constants.ts @@ -0,0 +1,45 @@ +/** + * Common Constants + * Centralized configuration constants for the T4B Chat application + */ + +// Domain Configuration +export const ALLOWED_DOMAIN = 'http://192.168.1.12:8069'; + +// FCM Configuration +export const FCM_REGISTER_ENDPOINT = '/fcm/register'; + +// Cookie Configuration +export const COOKIE_REFRESH_INTERVAL = 30000; // 30 seconds +export const INITIAL_COOKIE_DELAY = 10000; // 10 seconds + +// Navigation Configuration +export const NAVIGATION_DELAYS = { + FOREGROUND: 100, // Minimal delay for foreground notifications + BACKGROUND: 200, // Minimal delay for background notifications + KILLED_APP: 100, // Minimal delay for killed app notifications + TWO_STEP_NAVIGATION: 300, // Delay between two-step navigation + NAVIGATION_RESET: 500, // Delay before resetting navigation state + KILLED_APP_RESET: 800, // Delay before resetting killed app navigation state +} as const; + +// URL Patterns +export const URL_PATTERNS = { + MAIL_APP: '#action=106&cids=1&menu_id=73', + CHAT_CHANNEL: (channelId: string) => `&active_id=mail.channel_${channelId}`, +} as const; + +// Deep Link Configuration +export const DEEP_LINK_PREFIX = 'myapp://chat/'; + +// Platform Configuration +export const PLATFORM_CONFIG = { + ANDROID_MIN_VERSION_FOR_PERMISSIONS: 33, // Android 13+ +} as const; + +// Notification Configuration +export const NOTIFICATION_CONFIG = { + CHANNEL_ID: 't4b_chat_channel', + CHANNEL_NAME: 'T4B Chat Notifications', + CHANNEL_DESCRIPTION: 'Notifications for T4B Chat messages', +} as const; diff --git a/utilities/cookieUtils.ts b/utilities/cookieUtils.ts new file mode 100644 index 0000000..7eb6a9e --- /dev/null +++ b/utilities/cookieUtils.ts @@ -0,0 +1,247 @@ +/** + * Cookie Utilities + * Handles cookie management for WebView authentication + */ + +import CookieManager from '@react-native-cookies/cookies'; +import { Platform } from 'react-native'; +import { ALLOWED_DOMAIN, COOKIE_REFRESH_INTERVAL, INITIAL_COOKIE_DELAY } from './constants'; + +/** + * Interface for cookie data + */ +export interface CookieData { + [key: string]: any; +} + +/** + * Cookie Handler Class + */ +export class CookieHandler { + private setWebViewCookies: (cookies: string | null) => void; + + constructor(setWebViewCookies: (cookies: string | null) => void) { + this.setWebViewCookies = setWebViewCookies; + } + + /** + * Get WebView cookies for authentication + * @returns Promise - Cookie string or null if not found + */ + async getWebViewCookies(): Promise { + try { + console.log('๐Ÿช Requesting cookies using @react-native-cookies/cookies...'); + + const baseUrl = `${ALLOWED_DOMAIN}`; + console.log('๐Ÿช Getting cookies for URL:', baseUrl); + + let cookieString = ''; + + // Platform-specific cookie handling + if (Platform.OS === 'ios') { + // iOS: Can use getAll() + try { + const cookies = await CookieManager.getAll(); + console.log('๐Ÿช iOS - All cookies retrieved:', cookies); + + // Filter cookies for our domain + const domainCookies = Object.keys(cookies).filter(key => + key.includes(baseUrl) || key.includes(ALLOWED_DOMAIN.replace('/', '')) + ); + + console.log('๐Ÿช iOS - Domain cookies found:', domainCookies); + + for (const cookieKey of domainCookies) { + const cookie = cookies[cookieKey]; + console.log('๐Ÿช iOS - Checking cookie:', cookieKey, cookie); + + if (cookie && typeof cookie === 'object') { + const cookieValue = cookie.value || cookie; + if (cookieValue && typeof cookieValue === 'string' && cookieValue.includes('session_id=')) { + const sessionMatch = cookieValue.match(/session_id=([^;]+)/); + if (sessionMatch) { + console.log('โœ… iOS - Found session_id in cookie:', sessionMatch[1]); + } + } + + if (typeof cookie === 'object' && cookie.name && cookie.value) { + cookieString += `${cookie.name}=${cookie.value}; `; + } else if (typeof cookie === 'string') { + cookieString += cookie + '; '; + } + } + } + } catch (iosError) { + console.log('โš ๏ธ iOS getAll() failed, trying direct method:', iosError); + } + } + + // Both platforms: Try getting cookies directly for the domain + try { + console.log('๐Ÿช Getting direct cookies for domain:', baseUrl); + const directCookies = await CookieManager.get(baseUrl); + console.log('๐Ÿช Direct cookies for domain:', directCookies); + + if (directCookies && Object.keys(directCookies).length > 0) { + // Convert to cookie string format + const directCookieString = Object.entries(directCookies) + .map(([name, value]) => `${name}=${value}`) + .join('; '); + + console.log('๐Ÿช Direct cookie string:', directCookieString); + + if (directCookieString && directCookieString.includes('session_id')) { + cookieString = directCookieString; + console.log('โœ… Found session_id in direct cookies:', cookieString); + } else { + console.warn('โš ๏ธ Direct cookies found but no session_id:', directCookieString); + } + } else { + console.warn('โš ๏ธ No direct cookies found for domain'); + } + } catch (directError) { + console.log('โš ๏ธ Could not get direct cookies:', directError); + } + + // Fallback: Try getting cookies for the WebView URL + try { + const webViewUrl = `${ALLOWED_DOMAIN}/web`; + console.log('๐Ÿช Fallback - Getting cookies for WebView URL:', webViewUrl); + const webViewCookies = await CookieManager.get(webViewUrl); + console.log('๐Ÿช WebView cookies:', webViewCookies); + + if (webViewCookies && Object.keys(webViewCookies).length > 0) { + const webViewCookieString = Object.entries(webViewCookies) + .map(([name, value]) => `${name}=${value}`) + .join('; '); + + if (webViewCookieString && webViewCookieString.includes('session_id')) { + cookieString = webViewCookieString; + console.log('โœ… Found session_id in WebView cookies:', cookieString); + } + } + } catch (webViewError) { + console.log('โš ๏ธ Could not get WebView cookies:', webViewError); + } + + if (cookieString && cookieString.includes('session_id')) { + console.log('โœ… Valid session cookies found:', cookieString); + this.setWebViewCookies(cookieString); + return cookieString; + } else { + console.warn('โš ๏ธ No session_id found in any cookie method'); + console.warn('โš ๏ธ Final cookie string:', cookieString); + this.setWebViewCookies(null); + return null; + } + } catch (error) { + console.error('โŒ Error getting cookies with @react-native-cookies/cookies:', error); + this.setWebViewCookies(null); + return null; + } + } + + /** + * Refresh WebView cookies periodically + * @returns Function to clear the interval + */ + refreshWebViewCookies(): () => void { + // Initial cookie request after a longer delay to ensure WebView is fully loaded and user is logged in + setTimeout(() => { + console.log('๐Ÿ”„ Initial cookie refresh after WebView load'); + this.getWebViewCookies(); + }, INITIAL_COOKIE_DELAY); + + // Set up periodic cookie refresh + const cookieRefreshInterval = setInterval(() => { + console.log('๐Ÿ”„ Periodic cookie refresh'); + this.getWebViewCookies(); + }, COOKIE_REFRESH_INTERVAL); + + // Return cleanup function + return () => clearInterval(cookieRefreshInterval); + } + + /** + * Get cookies for a specific URL + * @param url - URL to get cookies for + * @returns Promise - Cookie data or null + */ + async getCookiesForUrl(url: string): Promise { + try { + console.log('๐Ÿช Getting cookies for URL:', url); + const cookies = await CookieManager.get(url); + console.log('๐Ÿช Cookies for URL:', cookies); + return cookies; + } catch (error) { + console.error('โŒ Error getting cookies for URL:', url, error); + return null; + } + } + + /** + * Set cookies for a specific URL + * @param url - URL to set cookies for + * @param cookies - Cookie data to set + * @returns Promise - Success status + */ + async setCookiesForUrl(url: string, cookies: any): Promise { + try { + console.log('๐Ÿช Setting cookies for URL:', url, cookies); + await CookieManager.set(url, cookies); + console.log('โœ… Cookies set successfully for URL:', url); + return true; + } catch (error) { + console.error('โŒ Error setting cookies for URL:', url, error); + return false; + } + } + + /** + * Clear all cookies + * @returns Promise - Success status + */ + async clearAllCookies(): Promise { + try { + console.log('๐Ÿช Clearing all cookies'); + await CookieManager.clearAll(); + console.log('โœ… All cookies cleared successfully'); + this.setWebViewCookies(null); + return true; + } catch (error) { + console.error('โŒ Error clearing cookies:', error); + return false; + } + } + + /** + * Check if session cookies are valid + * @param cookies - Cookie string to validate + * @returns boolean - Whether cookies are valid + */ + isValidSessionCookie(cookies: string | null): boolean { + if (!cookies) { + return false; + } + + const hasSessionId = cookies.includes('session_id='); + const hasValidFormat = cookies.includes('=') && cookies.includes(';'); + + console.log('๐Ÿช Cookie validation:', { + hasSessionId, + hasValidFormat, + cookieLength: cookies.length + }); + + return hasSessionId && hasValidFormat; + } +} + +/** + * Create cookie handler instance + */ +export function createCookieHandler( + setWebViewCookies: (cookies: string | null) => void +): CookieHandler { + return new CookieHandler(setWebViewCookies); +} diff --git a/utilities/deepLinkUtils.ts b/utilities/deepLinkUtils.ts new file mode 100644 index 0000000..79ac25b --- /dev/null +++ b/utilities/deepLinkUtils.ts @@ -0,0 +1,242 @@ +/** + * Deep Link Utilities + * Handles deep linking functionality for FCM notifications and chat navigation + */ + +import { Platform } from 'react-native'; +import { + ALLOWED_DOMAIN, + NAVIGATION_DELAYS, + URL_PATTERNS, + DEEP_LINK_PREFIX +} from './constants'; + +/** + * Interface for notification data + */ +export interface NotificationData { + channel_id?: string; + conversation_id?: string; + deep_link?: string; + title?: string; + body?: string; + channel_name?: string; + author_name?: string; + notification_type?: string; +} + +/** + * Interface for navigation state + */ +export interface NavigationState { + currentChannel: string | null; + isNavigating: boolean; + navigationAttempts: number; +} + +/** + * Deep Link Handler Class + */ +export class DeepLinkHandler { + private updateWebViewUrl: (url: string) => void; + private setIsNavigating: (navigating: boolean) => void; + private setCurrentChannel: (channel: string | null) => void; + private setNavigationAttempts: (attempts: number) => void; + private navigationState: NavigationState; + + constructor( + updateWebViewUrl: (url: string) => void, + setIsNavigating: (navigating: boolean) => void, + setCurrentChannel: (channel: string | null) => void, + setNavigationAttempts: (attempts: number) => void, + navigationState: NavigationState + ) { + this.updateWebViewUrl = updateWebViewUrl; + this.setIsNavigating = setIsNavigating; + this.setCurrentChannel = setCurrentChannel; + this.setNavigationAttempts = setNavigationAttempts; + this.navigationState = navigationState; + } + + /** + * Handle deep linking from notifications (killed app case) + * @param data - Notification data containing channel information + */ + handleKilledAppDeepLink(data: NotificationData): void { + console.log('๐Ÿ”— Processing deep link from notification (killed app case):', data); + + const channelId = this.extractChannelId(data); + if (!channelId) { + console.warn('โš ๏ธ No channel ID found in deep link data:', data); + return; + } + + // Minimal delay for killed app initialization + setTimeout(() => { + console.log('๐Ÿ”— Setting initial WebView URL for killed app navigation to channel:', channelId); + + // Set navigation state + this.setIsNavigating(true); + this.setCurrentChannel(channelId); + + // Construct and set the target URL directly (works better for killed app) + const chatUrl = this.buildChatUrl(channelId); + console.log('๐Ÿ”— Initial chat URL for killed app:', chatUrl); + this.updateWebViewUrl(chatUrl); + + // Reset navigation state after shorter delay + setTimeout(() => { + this.setIsNavigating(false); + }, NAVIGATION_DELAYS.KILLED_APP_RESET); + }, NAVIGATION_DELAYS.KILLED_APP); + } + + /** + * Handle WebView URL update from notification (foreground/background) + * @param data - Notification data containing channel information + */ + handleForegroundBackgroundDeepLink(data: NotificationData): void { + console.log('๐Ÿ”— Updating WebView URL from notification:', data); + + const channelId = this.extractChannelId(data); + if (!channelId) { + console.warn('โš ๏ธ No channel ID found in notification data:', data); + return; + } + + // Check if we're already navigating to this channel + if (this.navigationState.isNavigating && this.navigationState.currentChannel === channelId) { + console.log('๐Ÿ”— Already navigating to channel:', channelId); + return; + } + + console.log('๐Ÿ”— Navigating to channel via WebView URL update:', channelId); + + // Set navigation state to prevent loops + this.setIsNavigating(true); + this.setNavigationAttempts(0); + this.setCurrentChannel(channelId); + + // Step 1: First navigate to mail app (without specific channel) + const mailAppUrl = `${ALLOWED_DOMAIN}/web${URL_PATTERNS.MAIL_APP}`; + console.log('๐Ÿ”— Step 1: Navigating to mail app:', mailAppUrl); + this.updateWebViewUrl(mailAppUrl); + + // Step 2: After a minimal delay, navigate to specific channel + setTimeout(() => { + const chatUrl = this.buildChatUrl(channelId); + console.log('๐Ÿ”— Step 2: Navigating to specific channel:', chatUrl); + this.updateWebViewUrl(chatUrl); + + // Reset navigation state after final navigation + setTimeout(() => { + this.setIsNavigating(false); + }, NAVIGATION_DELAYS.NAVIGATION_RESET); + }, NAVIGATION_DELAYS.TWO_STEP_NAVIGATION); + + console.log('โœ… WebView navigation sequence started'); + } + + /** + * Navigate to specific channel (direct navigation for killed app) + * @param channelId - Channel ID to navigate to + */ + navigateToChannel(channelId: string): void { + if (!channelId) { + console.warn('โš ๏ธ No channel ID provided for navigation'); + return; + } + + // Check if we're already navigating to this channel + if (this.navigationState.isNavigating && this.navigationState.currentChannel === channelId) { + console.log('๐Ÿ”— Already navigating to channel:', channelId); + return; + } + + console.log('๐Ÿ”— Navigating to channel (killed app - direct navigation):', channelId); + this.setCurrentChannel(channelId); + this.setIsNavigating(true); + this.setNavigationAttempts(0); + + // For killed app case, direct navigation works better + const chatUrl = this.buildChatUrl(channelId); + console.log('๐Ÿ”— Chat URL (direct):', chatUrl); + + // Update WebView URL directly - this works well for killed app + this.updateWebViewUrl(chatUrl); + + console.log('โœ… WebView URL updated (direct navigation)'); + + // Reset navigation state after delay + setTimeout(() => { + this.setIsNavigating(false); + }, NAVIGATION_DELAYS.KILLED_APP); + } + + /** + * Handle deep link URLs + * @param deepLink - Deep link URL to process + */ + handleDeepLink(deepLink: string): void { + console.log('๐Ÿ”— Processing deep link:', deepLink); + + // Parse deep link: myapp://chat/{channel_id} + if (deepLink.startsWith(DEEP_LINK_PREFIX)) { + const channelId = deepLink.replace(DEEP_LINK_PREFIX, ''); + console.log('๐Ÿ”— Extracted channel ID:', channelId); + this.navigateToChannel(channelId); + } else { + console.warn('โš ๏ธ Unknown deep link format:', deepLink); + } + } + + /** + * Extract channel ID from notification data + * @param data - Notification data + * @returns Channel ID or null if not found + */ + private extractChannelId(data: NotificationData): string | null { + // Extract channel ID from different possible fields + if (data.channel_id) { + console.log('๐Ÿ”— Found channel_id:', data.channel_id); + return data.channel_id; + } else if (data.conversation_id) { + console.log('๐Ÿ”— Found conversation_id:', data.conversation_id); + return data.conversation_id; + } else if (data.deep_link && data.deep_link.includes('chat/')) { + const channelId = data.deep_link.replace(DEEP_LINK_PREFIX, ''); + console.log('๐Ÿ”— Extracted channel_id from deep_link:', channelId); + return channelId; + } + + return null; + } + + /** + * Build chat URL for specific channel + * @param channelId - Channel ID + * @returns Complete chat URL + */ + private buildChatUrl(channelId: string): string { + return `${ALLOWED_DOMAIN}/web${URL_PATTERNS.MAIL_APP}${URL_PATTERNS.CHAT_CHANNEL(channelId)}`; + } +} + +/** + * Create deep link handler instance + */ +export function createDeepLinkHandler( + updateWebViewUrl: (url: string) => void, + setIsNavigating: (navigating: boolean) => void, + setCurrentChannel: (channel: string | null) => void, + setNavigationAttempts: (attempts: number) => void, + navigationState: NavigationState +): DeepLinkHandler { + return new DeepLinkHandler( + updateWebViewUrl, + setIsNavigating, + setCurrentChannel, + setNavigationAttempts, + navigationState + ); +} diff --git a/utilities/fcmUtils.ts b/utilities/fcmUtils.ts new file mode 100644 index 0000000..e2ff508 --- /dev/null +++ b/utilities/fcmUtils.ts @@ -0,0 +1,357 @@ +/** + * FCM (Firebase Cloud Messaging) Utilities + * Handles FCM token management, messaging, and backend communication + */ + +import messaging, { FirebaseMessagingTypes } from '@react-native-firebase/messaging'; +import { Platform } from 'react-native'; +import { + requestNotificationPermission, + checkNotificationPermission, + needsNotificationPermission, + showPermissionExplanation, + showSettingsDialog, + PermissionResult +} from './permissionUtils'; +import { RESULTS } from 'react-native-permissions'; +import { showLocalNotification } from './notificationUtils'; +import { ALLOWED_DOMAIN, FCM_REGISTER_ENDPOINT, NAVIGATION_DELAYS } from './constants'; + +/** + * Interface for FCM token data + */ +export interface FCMTokenData { + token: string; + deviceName: string; + deviceType: string; + appVersion: string; + osVersion: string; + sessionCookies: string | null; +} + +/** + * Interface for notification callback functions + */ +export interface NotificationCallbacks { + onForegroundNotification: (data: any) => void; + onBackgroundNotification: (data: any) => void; + onKilledAppNotification: (data: any) => void; +} + +/** + * FCM Handler Class + */ +export class FCMHandler { + private getWebViewCookies: () => Promise; + private callbacks: NotificationCallbacks; + + constructor( + getWebViewCookies: () => Promise, + callbacks: NotificationCallbacks + ) { + this.getWebViewCookies = getWebViewCookies; + this.callbacks = callbacks; + } + + /** + * Initialize FCM notifications + */ + async initializeNotifications(): Promise { + try { + console.log('Initializing notifications...'); + + // Request permission first + await this.requestUserPermission(); + + // Then get FCM token + await this.getFcmToken(); + + console.log('Notification initialization completed'); + } catch (error) { + console.error('Error initializing notifications:', error); + } + } + + /** + * Request user permission for notifications + */ + async requestUserPermission(): Promise { + try { + console.log('Checking notification permission requirements...'); + + // Check if permission is needed based on platform and version + const needsPermission = needsNotificationPermission(); + console.log('Permission needed:', needsPermission); + + if (!needsPermission) { + console.log('No explicit permission required for this Android version'); + return; + } + + // Check current permission status first + const currentStatus = await checkNotificationPermission(); + console.log('Current permission status:', currentStatus); + + if (currentStatus.granted) { + console.log('Notification permission already granted'); + return; + } + + // Show explanation dialog for Android users + if (Platform.OS === 'android') { + const userWantsPermission = await showPermissionExplanation(); + if (!userWantsPermission) { + console.log('User declined permission request'); + return; + } + } + + // Request permission + const result: PermissionResult = await requestNotificationPermission(); + console.log('๐Ÿ“‹ Permission request result:', JSON.stringify(result, null, 2)); + + if (result.granted) { + console.log('โœ… Notification permission granted successfully'); + } else { + console.log('โŒ Notification permission denied'); + console.log('๐Ÿ“‹ Denial details:', { + status: result.status, + platform: result.platform, + androidVersion: result.androidVersion + }); + + // Check for different denial scenarios + if (Platform.OS === 'android') { + if (result.status === RESULTS.DENIED) { + console.log('๐Ÿšซ Permission denied by user'); + showSettingsDialog(); + } else if (result.status === RESULTS.BLOCKED) { + console.log('๐Ÿšซ Permission blocked by user'); + showSettingsDialog(); + } else if (result.status === RESULTS.UNAVAILABLE) { + console.log('โš ๏ธ Permission not available on this device'); + } else { + console.log('โ“ Unknown permission status:', result.status); + } + } + } + } catch (error) { + console.error('Error requesting permission:', error); + } + } + + /** + * Get FCM token + */ + async getFcmToken(): Promise { + try { + console.log('๐Ÿ”‘ Attempting to get FCM token...'); + + // Check if we have permission before trying to get token + const permissionStatus = await checkNotificationPermission(); + console.log('๐Ÿ” Permission status for token:', JSON.stringify(permissionStatus, null, 2)); + + if (!permissionStatus.granted && needsNotificationPermission()) { + console.log('โŒ Cannot get FCM token: notification permission not granted'); + return; + } + + console.log('โœ… Permission check passed, requesting FCM token...'); + const token = await messaging().getToken(); + console.log('๐ŸŽซ FCM Token received:', token ? 'YES' : 'NO'); + + if (token) { + console.log('๐Ÿ“ค FCM Token:', token); + // Send FCM token to Odoo backend + await this.sendTokenToBackend(token); + } else { + console.log('โš ๏ธ No FCM token available'); + } + } catch (err) { + console.error('โŒ Error getting FCM token:', err); + } + } + + /** + * Send FCM token to backend + * @param token - FCM token to send + */ + async sendTokenToBackend(token: string): Promise { + try { + // Import react-native-device-info + const DeviceInfo = require('react-native-device-info'); + + // Get device information + const deviceName = await DeviceInfo.getDeviceName(); + const deviceType = Platform.OS; + const appVersion = await DeviceInfo.getVersion(); + const osVersion = await DeviceInfo.getSystemVersion(); + + // Get session cookies from WebView + const sessionCookies = await this.getWebViewCookies(); + + console.log('๐Ÿ“ค Sending FCM token to backend:', { + token: token ? token.substring(0, 20) + '...' : 'NO', + deviceName, + deviceType, + appVersion, + osVersion, + hasSessionCookies: !!sessionCookies + }); + + if (!sessionCookies) { + console.warn('โš ๏ธ No session cookies found - user may not be logged in'); + return; + } + + const response = await fetch(`${ALLOWED_DOMAIN}${FCM_REGISTER_ENDPOINT}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Cookie': sessionCookies, + }, + body: JSON.stringify({ + token: token, + device_name: deviceName, + device_type: deviceType, + app_version: appVersion, + os_version: osVersion, + }), + }); + + if (response.ok) { + const result = await response.json(); + console.log('โœ… FCM token registered successfully:', result); + } else { + console.error('โŒ Failed to register FCM token:', response.status, response.statusText); + } + } catch (err) { + console.error('โŒ Error sending token to backend:', err); + } + } + + /** + * Handle FCM messages when app is in foreground + * @param remoteMessage - FCM message received + * @param appState - Current app state + */ + handleForegroundMessage( + remoteMessage: FirebaseMessagingTypes.RemoteMessage, + appState: string + ): void { + console.log('๐Ÿ“จ FCM Message received:', JSON.stringify(remoteMessage, null, 2)); + console.log('๐Ÿ“ฑ Current app state:', appState); + + // Always show notification in foreground - FCM doesn't show notifications automatically in foreground + console.log('๐Ÿ“ค Showing foreground notification'); + + if (remoteMessage.notification) { + console.log('๐Ÿ“ค Showing notification with payload'); + showLocalNotification({ + title: remoteMessage.notification.title || 'New Message', + message: remoteMessage.notification.body || 'You have a new message', + }); + + // For foreground: Update WebView URL directly based on notification data + if (remoteMessage.data) { + console.log('๐Ÿ”— Processing notification data for WebView URL update (foreground):', remoteMessage.data); + setTimeout(() => { + this.callbacks.onForegroundNotification(remoteMessage.data); + }, NAVIGATION_DELAYS.FOREGROUND); + } + } else if (remoteMessage.data) { + console.log('๐Ÿ“ค Showing notification with data only'); + + // Extract notification info from data payload + const title = String(remoteMessage.data.title || 'Odoo Chat'); + const body = String(remoteMessage.data.body || 'New message received'); + + showLocalNotification({ + title: title, + message: body, + }); + + // For foreground: Update WebView URL directly based on notification data + console.log('๐Ÿ”— Processing data payload for WebView URL update (foreground):', remoteMessage.data); + setTimeout(() => { + this.callbacks.onForegroundNotification(remoteMessage.data); + }, NAVIGATION_DELAYS.FOREGROUND); + } else { + console.log('โš ๏ธ No notification content available'); + } + } + + /** + * Handle FCM messages when app is opened from background + * @param remoteMessage - FCM message received + */ + handleBackgroundMessage(remoteMessage: FirebaseMessagingTypes.RemoteMessage): void { + if (remoteMessage?.data) { + console.log('๐Ÿ”— App opened from background with notification (using WebView URL update):', remoteMessage.data); + // For background state: Update WebView URL directly + setTimeout(() => { + this.callbacks.onBackgroundNotification(remoteMessage.data); + }, NAVIGATION_DELAYS.BACKGROUND); + } + } + + /** + * Handle FCM messages when app is opened from quit state + * @param remoteMessage - FCM message received + */ + handleKilledAppMessage(remoteMessage: FirebaseMessagingTypes.RemoteMessage): void { + if (remoteMessage?.data) { + console.log('๐Ÿ”— App opened from quit state with notification (using deep linking):', remoteMessage.data); + // For quit state: Use proper deep linking approach + setTimeout(() => { + this.callbacks.onKilledAppNotification(remoteMessage.data); + }, NAVIGATION_DELAYS.KILLED_APP); + } + } + + /** + * Setup FCM message listeners + * @param appState - Current app state + * @returns Function to unsubscribe from listeners + */ + setupMessageListeners(appState: string): () => void { + // Handle FCM messages when app is in foreground + const unsubscribe = messaging().onMessage(async (remoteMessage: FirebaseMessagingTypes.RemoteMessage) => { + this.handleForegroundMessage(remoteMessage, appState); + }); + + // Handle background/quit state notifications with deep linking + messaging() + .getInitialNotification() + .then((remoteMessage: FirebaseMessagingTypes.RemoteMessage | null) => { + if (remoteMessage) { + this.handleKilledAppMessage(remoteMessage); + } + }); + + messaging().onNotificationOpenedApp((remoteMessage: FirebaseMessagingTypes.RemoteMessage) => { + this.handleBackgroundMessage(remoteMessage); + }); + + // Listen for token refresh + const unsubscribeTokenRefresh = messaging().onTokenRefresh(async (token) => { + console.log('๐Ÿ”„ FCM Token refreshed:', token); + await this.sendTokenToBackend(token); + }); + + return () => { + unsubscribe(); + unsubscribeTokenRefresh(); + }; + } +} + +/** + * Create FCM handler instance + */ +export function createFCMHandler( + getWebViewCookies: () => Promise, + callbacks: NotificationCallbacks +): FCMHandler { + return new FCMHandler(getWebViewCookies, callbacks); +} diff --git a/utilities/loaderUtils.tsx b/utilities/loaderUtils.tsx new file mode 100644 index 0000000..4a2e444 --- /dev/null +++ b/utilities/loaderUtils.tsx @@ -0,0 +1,387 @@ +/** + * Loader Utilities + * Beautiful custom loading component with chat icon and animations + */ + +import React, { useEffect, useRef } from 'react'; +import { + View, + Text, + ActivityIndicator, + Animated, + StyleSheet, + Dimensions +} from 'react-native'; +//@ts-ignore +import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; + +// Get screen dimensions +const { width, height } = Dimensions.get('window'); + +/** + * Interface for loader props + */ +export interface LoaderProps { + isLoading: boolean; + loadingText?: string; + showChatIcon?: boolean; + iconName?: string; + iconSize?: number; + backgroundColor?: string; + primaryColor?: string; + textColor?: string; +} + +/** + * Beautiful Custom Loader Component + */ +export const CustomLoader: React.FC = ({ + isLoading, + loadingText = 'Loading...', + showChatIcon = true, + iconName = 'chat-processing', + iconSize = 40, + backgroundColor = 'rgba(255, 255, 255, 1)', // Pure white + primaryColor = '#007AFF', + textColor = '#333333' +}) => { + // Animation values + const fadeAnim = useRef(new Animated.Value(0)).current; + const scaleAnim = useRef(new Animated.Value(0.8)).current; + const pulseAnim = useRef(new Animated.Value(1)).current; + + useEffect(() => { + if (isLoading) { + // Instant animations for better UX during navigation + Animated.parallel([ + Animated.timing(fadeAnim, { + toValue: 1, + duration: 0, + useNativeDriver: true, + }), + Animated.timing(scaleAnim, { + toValue: 1, + duration: 0, + useNativeDriver: true, + }), + ]).start(); + + // Pulse animation with reduced intensity + const pulseAnimation = Animated.loop( + Animated.sequence([ + Animated.timing(pulseAnim, { + toValue: 1.05, + duration: 800, + useNativeDriver: true, + }), + Animated.timing(pulseAnim, { + toValue: 1, + duration: 800, + useNativeDriver: true, + }), + ]) + ); + pulseAnimation.start(); + + return () => { + pulseAnimation.stop(); + }; + } else { + // Instant hide animations for better UX during navigation + Animated.parallel([ + Animated.timing(fadeAnim, { + toValue: 0, + duration: 0, + useNativeDriver: true, + }), + Animated.timing(scaleAnim, { + toValue: 0.8, + duration: 0, + useNativeDriver: true, + }), + ]).start(); + } + }, [isLoading]); + + if (!isLoading) return null; + + return ( + + + {/* Chat Icon */} + {showChatIcon && ( + + + + )} + + {/* Loading Spinner */} + + + + + {/* Loading Text */} + + {loadingText} + + + {/* Loading Dots Animation */} + + {[0, 1, 2].map((index) => ( + + ))} + + + + ); +}; + + +/** + * Enhanced Loader with Progress + */ +export const ProgressLoader: React.FC = ({ + isLoading, + loadingText = 'Loading...', + progress = 0, + ...props +}) => { + const progressAnim = useRef(new Animated.Value(0)).current; + + useEffect(() => { + Animated.timing(progressAnim, { + toValue: progress, + duration: 300, + useNativeDriver: false, + }).start(); + }, [progress]); + + return ( + + ); +}; + +/** + * Create loader styles + */ +const styles = StyleSheet.create({ + loaderContainer: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + zIndex: 9999, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: 'rgba(255, 255, 255, 1)', // Pure white background + }, + loaderContent: { + alignItems: 'center', + justifyContent: 'center', + paddingHorizontal: 40, + paddingVertical: 30, + borderRadius: 20, + shadowColor: '#000', + shadowOffset: { + width: 0, + height: 4, + }, + shadowOpacity: 0.15, + shadowRadius: 4.65, + elevation: 8, + backgroundColor: 'rgba(255, 255, 255, 1)', + borderWidth: 1, + borderColor: 'rgba(0, 0, 0, 0.05)', + }, + chatIconContainer: { + width: 80, + height: 80, + borderRadius: 40, + justifyContent: 'center', + alignItems: 'center', + marginBottom: 20, + shadowColor: '#007AFF', + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.25, + shadowRadius: 3.84, + elevation: 5, + }, + spinnerContainer: { + marginBottom: 20, + }, + spinner: { + transform: [{ scale: 1.2 }], + }, + loadingText: { + fontSize: 18, + fontWeight: '600', + textAlign: 'center', + marginBottom: 15, + letterSpacing: 0.5, + }, + dotsContainer: { + flexDirection: 'row', + justifyContent: 'center', + alignItems: 'center', + }, + dot: { + width: 8, + height: 8, + borderRadius: 4, + marginHorizontal: 4, + }, +}); + +/** + * Predefined loader configurations with vector icons + */ +export const LOADER_CONFIGS = { + CHAT: { + loadingText: 'Connecting to chat...', + showChatIcon: true, + iconName: 'chat-processing' as const, + iconSize: 40, + primaryColor: '#007AFF', + }, + ODOO: { + loadingText: 'Loading T4B...', + showChatIcon: true, + iconName: 'chat-processing' as const, + iconSize: 40, + primaryColor: '#875A7B', + }, + NAVIGATION: { + loadingText: 'Navigating...', + showChatIcon: true, + iconName: 'navigation' as const, + iconSize: 40, + primaryColor: '#28A745', + }, + MESSAGE: { + loadingText: 'Sending message...', + showChatIcon: true, + iconName: 'message-text' as const, + iconSize: 40, + primaryColor: '#FF6B35', + }, + SYNC: { + loadingText: 'Synchronizing...', + showChatIcon: true, + iconName: 'sync' as const, + iconSize: 40, + primaryColor: '#9C27B0', + }, + DEFAULT: { + loadingText: 'Loading...', + showChatIcon: true, + iconName: 'loading' as const, + iconSize: 40, + primaryColor: '#007AFF', + }, +} as const; + +/** + * Quick loader functions with vector icons + */ +export const createChatLoader = (isLoading: boolean, text?: string) => ( + +); + +export const createOdooLoader = (isLoading: boolean, text?: string) => ( + +); + +export const createNavigationLoader = (isLoading: boolean, text?: string) => ( + +); + +export const createMessageLoader = (isLoading: boolean, text?: string) => ( + +); + +export const createSyncLoader = (isLoading: boolean, text?: string) => ( + +); + +export const createDefaultLoader = (isLoading: boolean, text?: string) => ( + +); diff --git a/utilities/notificationUtils.ts b/utilities/notificationUtils.ts new file mode 100644 index 0000000..6fc8081 --- /dev/null +++ b/utilities/notificationUtils.ts @@ -0,0 +1,152 @@ +// @ts-ignore +import PushNotification from 'react-native-push-notification'; +import { AppState, AppStateStatus } from 'react-native'; + +/** + * Creates a notification channel for Android + */ +export const createNotificationChannel = (): void => { + PushNotification.createChannel( + { + channelId: 'default-channel-id', + channelName: 'Default Channel', + channelDescription: 'A default channel for notifications', + playSound: true, + soundName: 'default', + importance: 4, // High importance + vibrate: true, + }, + (created: boolean) => console.log(`Notification channel created: ${created}`) + ); +}; + +/** + * Configures notification settings + */ +export const configureNotificationSettings = (): void => { + PushNotification.configure({ + // (optional) Called when Token is generated (iOS and Android) + onRegister: function (token: any) { + console.log('TOKEN:', token); + }, + + // (required) Called when a remote is received or opened, or local notification is opened + onNotification: function (notification: any) { + console.log('NOTIFICATION:', notification); + }, + + // (optional) Called when Registered Action is pressed and invokeApp is false, if true onNotification will be called (Android) + onAction: function (notification: any) { + console.log('ACTION:', notification.action); + console.log('NOTIFICATION:', notification); + }, + + // (optional) Called when the user fails to register for remote notifications. Typically occurs when APNS is having issues, or the device is a simulator. (iOS) + onRegistrationError: function (err: any) { + console.error(err.message, err); + }, + + // IOS ONLY (optional): default: all - Permissions to register. + permissions: { + alert: true, + badge: true, + sound: true, + }, + + // Should the initial notification be popped automatically + // default: true + popInitialNotification: true, + + /** + * (optional) default: true + * - Specified if permissions (ios) and token (android and ios) will requested or not, + * - if not, you must call PushNotificationsHandler.requestPermissions() later + * - if you are not using remote notification or do not have Firebase installed, use this: + * requestPermissions: Platform.OS === 'ios' + */ + requestPermissions: true, + }); +}; + +/** + * Shows a local notification + */ +export const showLocalNotification = (notificationData: { + title: string; + message: string; + channelId?: string; + playSound?: boolean; + soundName?: string; + vibrate?: boolean; + priority?: 'min' | 'low' | 'default' | 'high' | 'max'; + visibility?: 'private' | 'public' | 'secret'; +}): void => { + PushNotification.localNotification({ + channelId: notificationData.channelId || 'default-channel-id', + title: notificationData.title, + message: notificationData.message, + playSound: notificationData.playSound !== false, + soundName: notificationData.soundName || 'default', + vibrate: notificationData.vibrate !== false, + priority: notificationData.priority || 'high', + visibility: notificationData.visibility || 'private', + importance: 'high', + }); +}; + +/** + * Determines if a custom notification should be shown based on app state + */ +export const shouldShowCustomNotification = (appState: AppStateStatus): boolean => { + // Show notification when app is in background or inactive + return appState !== 'active'; +}; + +/** + * Test function to trigger a sample notification + */ +export const testNotification = (): void => { + showLocalNotification({ + title: 'Test Notification', + message: 'This is a test notification from T4B Chat app', + channelId: 'default-channel-id', + playSound: true, + vibrate: true, + }); +}; + +/** + * Cancels all notifications + */ +export const cancelAllNotifications = (): void => { + PushNotification.cancelAllLocalNotifications(); +}; + +/** + * Cancels a specific notification by ID + */ +export const cancelNotification = (notificationId: string): void => { + PushNotification.cancelLocalNotifications({ id: notificationId }); +}; + +/** + * Gets the notification count + */ +export const getNotificationCount = (callback: (count: number) => void): void => { + PushNotification.getApplicationIconBadgeNumber(callback); +}; + +/** + * Sets the notification count + */ +export const setNotificationCount = (count: number): void => { + PushNotification.setApplicationIconBadgeNumber(count); +}; + +/** + * Clears all notifications and badge count + */ +export const clearAllNotifications = (): void => { + cancelAllNotifications(); + setNotificationCount(0); +}; diff --git a/utilities/permissionUtils.ts b/utilities/permissionUtils.ts new file mode 100644 index 0000000..7c234f0 --- /dev/null +++ b/utilities/permissionUtils.ts @@ -0,0 +1,279 @@ +import { Platform, Alert } from 'react-native'; +import messaging, { AuthorizationStatus } from '@react-native-firebase/messaging'; +import { request, PERMISSIONS, RESULTS, Permission } from 'react-native-permissions'; + +export interface PermissionResult { + granted: boolean; + status: string; + needsRequest: boolean; + platform: string; + androidVersion?: number; +} + +/** + * Check if the device requires explicit notification permission request + * Android 13+ (API 33+) requires POST_NOTIFICATIONS permission + * Older Android versions don't need explicit permission for notifications + */ +export function needsNotificationPermission(): boolean { + if (Platform.OS === 'ios') { + return true; // iOS always requires permission + } + + if (Platform.OS === 'android') { + // Android 13+ (API level 33+) requires POST_NOTIFICATIONS permission + return Platform.Version >= 33; + } + + return false; +} + +/** + * Get the appropriate notification permission constant based on platform + */ +export function getNotificationPermission(): Permission | null { + if (Platform.OS === 'android') { + //@ts-ignore + return 'android.permission.POST_NOTIFICATIONS'; + } + + // iOS uses Firebase messaging permission, not react-native-permissions + return null; +} + +/** + * Request notification permission for Android 13+ + * Returns permission status information + */ +export async function requestNotificationPermission(): Promise { + + + if (Platform.OS === 'ios') { + // iOS uses Firebase messaging permission + try { + + const authStatus = await messaging().requestPermission(); + const granted = authStatus === AuthorizationStatus.AUTHORIZED || + authStatus === AuthorizationStatus.PROVISIONAL; + + + + return { + granted, + status: AuthorizationStatus[authStatus], + needsRequest: true, + platform: 'ios' + }; + } catch (error) { + + return { + granted: false, + status: 'ERROR', + needsRequest: true, + platform: 'ios' + }; + } + } + + if (Platform.OS === 'android') { + const androidVersion = Platform.Version as number; + const permission = getNotificationPermission(); + + + + if (!permission) { + // Older Android versions don't need explicit permission + + return { + granted: true, + status: 'GRANTED', + needsRequest: false, + platform: 'android', + androidVersion + }; + } + + try { + + const result = await request(permission); + + + + return { + granted: result === RESULTS.GRANTED, + status: result, + needsRequest: true, + platform: 'android', + androidVersion + }; + } catch (error) { + + return { + granted: false, + status: 'ERROR', + needsRequest: true, + platform: 'android', + androidVersion + }; + } + } + + return { + granted: false, + status: 'UNSUPPORTED', + needsRequest: false, + platform: 'unknown' + }; +} + +/** + * Check current notification permission status + */ +export async function checkNotificationPermission(): Promise { + + + if (Platform.OS === 'ios') { + try { + + const authStatus = await messaging().hasPermission(); + const granted = authStatus === AuthorizationStatus.AUTHORIZED || + authStatus === AuthorizationStatus.PROVISIONAL; + + + + return { + granted, + status: AuthorizationStatus[authStatus], + needsRequest: !granted, + platform: 'ios' + }; + } catch (error) { + + return { + granted: false, + status: 'ERROR', + needsRequest: true, + platform: 'ios' + }; + } + } + + if (Platform.OS === 'android') { + const androidVersion = Platform.Version as number; + const permission = getNotificationPermission(); + + + if (!permission) { + // Older Android versions - assume granted + + return { + granted: true, + status: 'GRANTED', + needsRequest: false, + platform: 'android', + androidVersion + }; + } + + try { + + const { check } = require('react-native-permissions'); + const result = await check(permission); + + + + + return { + granted: result === RESULTS.GRANTED, + status: result, + needsRequest: result !== RESULTS.GRANTED, + platform: 'android', + androidVersion + }; + } catch (error) { + + return { + granted: false, + status: 'ERROR', + needsRequest: true, + platform: 'android', + androidVersion + }; + } + } + + return { + granted: false, + status: 'UNSUPPORTED', + needsRequest: false, + platform: 'unknown' + }; +} + +/** + * Show permission explanation dialog for Android + */ +export function showPermissionExplanation(): Promise { + return new Promise((resolve) => { + Alert.alert( + 'Notification Permission', + 'This app needs notification permission to send you chat messages and updates. You can change this later in your device settings.', + [ + { + text: 'Cancel', + style: 'cancel', + onPress: () => resolve(false), + }, + { + text: 'Allow', + onPress: () => resolve(true), + }, + ] + ); + }); +} + +/** + * Show settings redirect dialog when permission is denied + */ +export function showSettingsDialog(): void { + Alert.alert( + 'Permission Required', + 'Notification permission is required for this app to work properly. Please enable it in your device settings.', + [ + { + text: 'Cancel', + style: 'cancel', + }, + { + text: 'Open Settings', + onPress: () => { + // You can use react-native-permissions to open settings + // Linking.openSettings(); + }, + }, + ] + ); +} + +/** + * Debug function to test permission flow + * Call this from your app to see detailed permission information + */ +export async function debugPermissionFlow(): Promise { + + + const permission = getNotificationPermission(); + + + const currentStatus = await checkNotificationPermission(); + + + if (!currentStatus.granted && currentStatus.needsRequest) { + + const requestResult = await requestNotificationPermission(); +; + } + + console.log('๐Ÿ”ง === END DEBUG ==='); +} diff --git a/utilities/webViewUtils.ts b/utilities/webViewUtils.ts new file mode 100644 index 0000000..91e2624 --- /dev/null +++ b/utilities/webViewUtils.ts @@ -0,0 +1,233 @@ +/** + * WebView Utilities + * Handles WebView management, navigation, and message handling + */ + +import { WebViewNavigation } from 'react-native-webview'; +import { Linking, Platform } from 'react-native'; +import { ALLOWED_DOMAIN } from './constants'; + +/** + * Interface for WebView message data + */ +export interface WebViewMessageData { + type?: string; + cookies?: string; + [key: string]: any; +} + +/** + * Interface for WebView navigation state + */ +export interface WebViewNavigationState { + currentChannel: string | null; + isNavigating: boolean; +} + +/** + * WebView Handler Class + */ +export class WebViewHandler { + private webViewRef: React.RefObject; + private updateWebViewUrl: (url: string) => void; + private navigationState: WebViewNavigationState; + + constructor( + webViewRef: React.RefObject, + updateWebViewUrl: (url: string) => void, + navigationState: WebViewNavigationState + ) { + this.webViewRef = webViewRef; + this.updateWebViewUrl = updateWebViewUrl; + this.navigationState = navigationState; + } + + /** + * Handle WebView navigation requests + * @param request - Navigation request from WebView + * @returns boolean indicating whether to allow navigation + */ + handleNavigation(request: WebViewNavigation): boolean { + const { url } = request; + + console.log('๐Ÿงญ Navigation to:', url); + + // Validate URL before processing + try { + new URL(url); + } catch (error) { + console.error("โŒ Invalid URL detected:", url, error); + return false; // Block invalid URLs + } + + // ๐Ÿงช Test notification when navigating to specific URL (temporary for testing) + if (url.includes('test-notification')) { + console.log('๐Ÿงช Test notification triggered via URL'); + // You can trigger test notification here if needed + return false; + } + + // โœ… Stay inside Odoo instance + if ( + url.startsWith(`${ALLOWED_DOMAIN}`) || + url.startsWith(`${ALLOWED_DOMAIN}`) + ) { + return true; + } + + // ๐ŸŒ Open external links in default browser + Linking.openURL(url).catch((err) => + console.error("Couldn't open external link", err) + ); + + return false; // block WebView from handling it + } + + /** + * Handle messages from WebView + * @param event - Message event from WebView + * @param setWebViewCookies - Function to set cookies + */ + handleWebViewMessage( + event: any, + setWebViewCookies: (cookies: string | null) => void + ): void { + try { + const messageData = event.nativeEvent.data; + + // Try to parse as JSON first + try { + const data: WebViewMessageData = JSON.parse(messageData); + console.log('๐Ÿ“จ WebView JSON message received:', data); + + // Handle cookie extraction (if needed) + if (data.type === 'cookies') { + console.log('๐Ÿช Cookies from WebView:', data.cookies); + setWebViewCookies(data.cookies || null); + } + } catch (jsonError) { + // If JSON parsing fails, treat as plain text message + console.log('๐Ÿ“จ WebView text message received:', messageData); + + // Handle navigation feedback messages + if (messageData.startsWith('NAVIGATION_RESULT:')) { + const result = messageData.replace('NAVIGATION_RESULT:', ''); + console.log('๐Ÿ”— Navigation Result:', result); + } + // Handle other plain text messages here if needed + } + } catch (error) { + console.error('โŒ Error handling WebView message:', error); + } + } + + /** + * Handle WebView load completion + * @param currentChannel - Current channel being navigated to + * @param isNavigating - Whether navigation is in progress + */ + handleWebViewLoadEnd(currentChannel: string | null, isNavigating: boolean): void { + console.log('๐Ÿ”— WebView loaded, current channel:', currentChannel, 'isNavigating:', isNavigating); + + // Check if we successfully navigated to the target channel + if (currentChannel && this.webViewRef.current) { + console.log('๐Ÿ”— WebView loaded - checking if navigation was successful'); + + // Add a simple debug script to check current URL + const checkScript = ` + (function() { + try { + console.log('๐Ÿ”— WebView loaded - Current URL:', window.location.href); + console.log('๐Ÿ”— WebView loaded - Current hash:', window.location.hash); + + // Check if we're on the target channel page + if (window.location.hash.includes('mail.channel_${currentChannel}')) { + console.log('โœ… Successfully navigated to channel ${currentChannel}'); + if (window.ReactNativeWebView) { + window.ReactNativeWebView.postMessage('NAVIGATION_RESULT:Successfully navigated to channel ${currentChannel}'); + } + } else { + console.log('โš ๏ธ Not on target channel page yet'); + console.log('๐Ÿ”— Expected: mail.channel_${currentChannel}'); + console.log('๐Ÿ”— Actual hash:', window.location.hash); + } + + } catch (error) { + console.error('โŒ Error in check script:', error); + } + })(); + true; + `; + + this.webViewRef.current.injectJavaScript(checkScript); + } + + // If we're navigating and have a current channel, we might need to retry + if (currentChannel && isNavigating) { + console.log('๐Ÿ”— Navigation in progress - checking if retry needed'); + // Don't retry immediately, let the two-step navigation complete + } else if (currentChannel && !isNavigating) { + console.log('๐Ÿ”— Navigation complete - no retry needed'); + } else { + console.log('๐Ÿ”— No active navigation'); + } + } + + /** + * Inject debug script into WebView + */ + injectDebugScript(): void { + if (this.webViewRef.current) { + const debugScript = ` + (function() { + console.log('๐Ÿ” WebView Debug Info:'); + console.log(' - Current URL:', window.location.href); + console.log(' - Current hash:', window.location.hash); + console.log(' - Document ready state:', document.readyState); + console.log(' - Available chat elements:', document.querySelectorAll('[class*="mail"], [class*="chat"], [data-model*="mail"]').length); + console.log(' - Available channel elements:', document.querySelectorAll('[data-channel-id], [data-id*="mail.channel"], [data-oe-id*="mail.channel"]').length); + + // List all elements with channel-related attributes + const channelElements = document.querySelectorAll('[data-channel-id], [data-id*="mail.channel"], [data-oe-id*="mail.channel"], a[href*="mail.channel"]'); + console.log('๐Ÿ” Channel elements found:', channelElements.length); + channelElements.forEach((el, index) => { + console.log(\` \${index + 1}. \${el.tagName} - \${el.className} - \${el.getAttribute('data-channel-id') || el.getAttribute('data-id') || el.getAttribute('href')}\`); + }); + + // Check Odoo availability + console.log('๐Ÿ” Odoo Debug:'); + console.log(' - window.odoo exists:', !!window.odoo); + console.log(' - odoo.loader exists:', !!(window.odoo && window.odoo.loader)); + console.log(' - odoo.services exists:', !!(window.odoo && window.odoo.services)); + console.log(' - odoo.__DEBUG__ exists:', !!(window.odoo && window.odoo.__DEBUG__)); + + if (window.odoo && window.odoo.__DEBUG__) { + const services = Object.keys(window.odoo.__DEBUG__.services || {}); + console.log(' - Available services:', services); + } + })(); + true; + `; + this.webViewRef.current.injectJavaScript(debugScript); + } + } + + /** + * Get WebView console messages + * @param event - Console message event + */ + handleConsoleMessage(event: any): void { + console.log('๐ŸŒ WebView Console:', event.nativeEvent.message); + } +} + +/** + * Create WebView handler instance + */ +export function createWebViewHandler( + webViewRef: React.RefObject, + updateWebViewUrl: (url: string) => void, + navigationState: WebViewNavigationState +): WebViewHandler { + return new WebViewHandler(webViewRef, updateWebViewUrl, navigationState); +}