Compare commits

26 Commits

Author SHA1 Message Date
0ba5c4b309 encountered weird network error. 2025-03-17 06:56:05 -07:00
e61fb43ee3 give up on downloader idea. Use file from assets. 2025-03-16 07:45:59 -07:00
123933d459 attempt to use part/copy idea. 2025-03-14 06:54:06 -07:00
f0a722b3fb add expo-audio. work on memory issue when reading file. 2025-03-11 18:35:37 -07:00
dca3987e18 work on downloading some more. 2025-03-11 07:26:49 -07:00
8f67d0421b did more of the knex -> sqlite migration. 2025-03-10 10:32:27 -07:00
3616592896 bring back sqlite3 and migrations. 2025-03-09 20:16:54 -07:00
e9c04a7b39 add straight lang-flags. Try to resolve expo dialect error. 2025-03-09 19:39:49 -07:00
918d651638 add knex-expo-sqlite-dialect submodule. migrate to expo (possibly a mistake) 2025-03-09 06:57:41 -07:00
5352ae8eb1 add more mocking 2025-03-04 07:20:00 -08:00
61e54ded3c start mock of file bytes. 2025-03-03 17:28:35 -08:00
75b76efd33 add jest mocking for settings. 2025-03-03 06:52:57 -08:00
1492a38e0b resolve merge. 2025-03-03 05:47:11 -08:00
d15916f3e3 resolve merge 2025-03-03 05:46:00 -08:00
a9b5ccf84f updating code using knex. 2025-03-02 20:15:27 -08:00
d00e6d62ff add readme. fix downloader operation. 2025-02-28 14:38:36 -08:00
4549442bd8 detemine root cause of download issue. 2025-02-28 07:13:45 -08:00
87446784ae improve tests, especially for navigation. 2025-02-27 08:23:27 -08:00
6f941c56d1 try to fix navigation some more. 2025-02-24 09:09:20 -08:00
c3d543be39 work on stack. 2025-02-23 19:53:20 -08:00
eb7599bfe8 work on navigation component workflow. 2025-02-22 18:28:10 -08:00
6673663883 mock expo file system. 2025-02-19 06:13:10 -08:00
b3c2e09987 refactor stack. Add details to example tests. 2025-02-18 16:56:19 -08:00
bc3d481d25 add whisper download utils. add react-navigator. 2025-02-16 19:55:26 -08:00
081ac367ba add ollama files. Fix unit tests (finally). TODO: handle static file downloading and screens. 2025-02-14 15:23:22 -08:00
68cc052417 fix some sqlite errors. 2025-02-13 07:48:32 -08:00
56 changed files with 4441 additions and 1169 deletions

1
.gitignore vendored
View File

@ -36,3 +36,4 @@ yarn-error.*
*.tsbuildinfo *.tsbuildinfo
coverage/**/* coverage/**/*
assets/whisper

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "langs-flags-list"] [submodule "langs-flags-list"]
path = langs-flags-list path = langs-flags-list
url = https://github.com/martinsik/langs-flags-list.git url = https://github.com/martinsik/langs-flags-list.git
[submodule "knex-expo-sqlite-dialect"]
path = knex-expo-sqlite-dialect
url = https://github.com/expo/knex-expo-sqlite-dialect.git

View File

@ -0,0 +1,39 @@
/**
* NOTE: this file is for ollama. The AI assistant should
* follow this format, but modify it according to the user's prompt.
*/
/**
* Import any necessary packages
**/
import { StyleSheet } from "react-native";
type ExampleComponentProps = {
/**
* Declare any properties here
*/
}
/**
* Don't include the typing when defiining the function. Define it normally.
*/
const ISpeakButton = (props : ExampleComponentProps) => {
// Do any housekeeping up here, like `useState`, `useEffect`, etc.
// Return the TSX component below
return (
<></>
)
}
// Create style sheets here
const styles = StyleSheet.create({
})
// Export the component
export default ISpeakButton;

View File

@ -0,0 +1,37 @@
/**
* NOTE: this file is for ollama. The AI assistant should
* follow this format, but modify it according to the user's prompt.
*/
/**
* Import any necessary packages
**/
import React, { act } from 'react';
import { render, screen } from '@testing-library/react-native'
import { MyComponent } from '@/app/component/MyComponent';
/**
* IMPORTANT NOTE: If you need to use jest mock, remember that
* you cannot include any external components in the mock.
* You absolutely must use `jest.requireActual` to import the
* component *within* the jest.mock callback.
*/
jest.mock('@/app/component/index.tsx', () => {
// Require-actual the component
const { Text } = jest.requireActual('react-native');
// Use the component.
return () => <Text>Index</Text>
});
describe('Message Component', () => {
beforeEach(() => {
// do any set up here
});
it('A test that renders a widget', async () => {
render(<MyComponent />);
// IMPORTANT: use jest.expect(...) functions for assertions.
expect(await screen.findByText("something")).toBeOnTheScreen();
});
});

View File

@ -1,3 +1,2 @@
{ {
"jestTestExplorer.pathToJest": "./node_modules/.bin/jest"
} }

226
README.md
View File

@ -1,195 +1,81 @@
# react-native-linear-gradient # Translation Terrace
A `<LinearGradient>` element for React Native Translation Terrace is an Expo/React-Native application designed for a translation kiosk. It leverages an offline Whisper speech-to-text model and interfaces with a LibreTranslate server to provide seamless translation services.
[![ci][1]][2] ## Project Structure
[![npm version][3]][4]
[![npm downloads][5]][4]
<p align="center"> ```
<img src="https://github.com/react-native-linear-gradient/react-native-linear-gradient/assets/743291/8ff2a78b-f0b1-463a-aa5b-555df2e71360" width="300"> <img src="https://github.com/react-native-linear-gradient/react-native-linear-gradient/assets/743291/9c738be3-6fba-43d5-9c9f-1db1c10fd377" width="300"> translation-terraces/
</p> ├── expo-file-system/
│ └── next.js
## Table of Contents ├── @react-native-async-storage/
│ └── async-storage.ts
- [Installation](#installation) ├── .ollama/
- [Usage and Examples](#examples) │ ├── ExampleComponent.tsx
- [Props](#props) │ └── ExampleTest.spec.tsx
- [Example App](#an-example-app) ├── package.json
- [Troubleshooting](#troubleshooting) ├── README.md
- [Other Platforms](#other-platforms) └── ...
## Installation
```sh
yarn add react-native-linear-gradient
``` ```
Or, using npm: `npm install react-native-linear-gradient` ## Technologies Used
## Examples - **React-Native**: Core framework for building the application.
- **Whisper Speech-to-Text Model**: Offline model for converting spoken language to text.
- **LibreTranslate Server**: Interface for translation services.
[react-native-login](https://github.com/brentvatne/react-native-login) is a ## Installation Instructions
legacy component which showcases the use of `<LinearGradient>`.
### Simple 1. **Install Packages**: Run `npm install` to install all necessary dependencies as listed in `package.json`.
2. **Prebuild Android**: Since this project cannot be run using Expo Go, prebuild the Android app by running `npm run android`.
3. **Run Unit Tests**: Execute Jest unit tests with `npm run test`.
The following code will produce something like this: ## Usage Examples
![Example code result](https://raw.githubusercontent.com/react-native-community/react-native-linear-gradient/HEAD/images/example.png) ### Example 1: Initializing Whisper Model
```javascript ```javascript
import LinearGradient from 'react-native-linear-gradient'; import { initializeWhisper } from './path/to/whisper';
// Within your render function const initModel = async () => {
<LinearGradient colors={['#4c669f', '#3b5998', '#192f6a']} style={styles.linearGradient}> try {
<Text style={styles.buttonText}> await initializeWhisper();
Sign in with Facebook console.log('Whisper model initialized successfully.');
</Text> } catch (error) {
</LinearGradient> console.error('Error initializing Whisper model:', error);
}
};
// Later on in your styles.. initModel();
var styles = StyleSheet.create({
linearGradient: {
flex: 1,
paddingLeft: 15,
paddingRight: 15,
borderRadius: 5
},
buttonText: {
fontSize: 18,
fontFamily: 'Gill Sans',
textAlign: 'center',
margin: 10,
color: '#ffffff',
backgroundColor: 'transparent',
},
});
``` ```
### Horizontal gradient ### Example 2: Translating Text
Using the styles from above, set `start` and `end` like this to make the gradient go from left to right, instead of from top to bottom:
```javascript ```javascript
<LinearGradient start={{x: 0, y: 0}} end={{x: 1, y: 0}} colors={['#4c669f', '#3b5998', '#192f6a']} style={styles.linearGradient}> import { translateText } from './path/to/libreTranslate';
<Text style={styles.buttonText}>
Sign in with Facebook const translate = async () => {
</Text> try {
</LinearGradient> const translatedText = await translateText('Hello, world!', 'en', 'es');
console.log('Translated text:', translatedText);
} catch (error) {
console.error('Error translating text:', error);
}
};
translate();
``` ```
### Text gradient (iOS) ## Contributing Guidelines
On iOS you can use the `MaskedViewIOS` to display text with a gradient. The trick here is to render the text twice; once for the mask, and once to let the gradient have the correct size (hence the `opacity: 0`): 1. **Create Feature Branch**: Use the naming convention `<year>-<work week>_<username>_<feature_description>` for your feature branch.
2. **Initiate Pull Request (PR)**: Open a PR and provide a detailed description of the changes made.
3. **Discuss Features**: Suggest new features or improvements in GitTea issues.
```jsx ## License Information
<MaskedViewIOS maskElement={<Text style={styles.text} />}>
<LinearGradient colors={['#f00', '#0f0']} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }}>
<Text style={[styles.text, { opacity: 0 }]} />
</LinearGradient>
</MaskedViewIOS>
```
### Animated Gradient This project is licensed under the MIT License. For more details, please refer to the [LICENSE](LICENSE) file.
Check out the [example app](https://github.com/react-native-linear-gradient/react-native-linear-gradient/tree/HEAD/example/) (`git clone` this project, cd into it, npm install, open in Xcode and run) to see how this is done: ---
![Example with extra props](https://raw.githubusercontent.com/react-native-community/react-native-linear-gradient/HEAD/images/example-animated.gif) Feel free to explore the codebase and contribute to Translation Terrace! If you have any questions or need further assistance, feel free to reach out.
*This gif was created using [licecap](http://www.cockos.com/licecap/) - a great piece of free OSS*
### Transparent Gradient
The use of `transparent` color will most likely not lead to the expected result. `transparent` is actually a transparent black color (`rgba(0, 0, 0, 0)`). If you need a gradient in which the color is "fading", you need to have the same color with changing alpha channel. Example:
```jsx
// RGBA
<LinearGradient colors={['rgba(255, 255, 255, 0)', 'rgba(255, 255, 255, 1)']} {...otherGradientProps} />
// Hex
<LinearGradient colors={['#FFFFFF00', '#FFFFFF']} {...otherGradientProps} />
```
## Props
In addition to regular `View` props, you can also provide additional props to customize your gradient look:
#### colors
An array of at least two color values that represent gradient colors. Example: `['red', 'blue']` sets gradient from red to blue.
#### start
An optional object of the following type: `{ x: number, y: number }`. Coordinates declare the position that the gradient starts at, as a fraction of the overall size of the gradient, starting from the top left corner. Example: `{ x: 0.1, y: 0.1 }` means that the gradient will start 10% from the top and 10% from the left.
#### end
Same as start, but for the end of the gradient.
#### locations
An optional array of numbers defining the location of each gradient color stop, mapping to the color with the same index in `colors` prop. Example: `[0.1, 0.75, 1]` means that first color will take 0% - 10%, second color will take 10% - 75% and finally third color will occupy 75% - 100%.
```javascript
<LinearGradient
start={{x: 0.0, y: 0.25}} end={{x: 0.5, y: 1.0}}
locations={[0,0.5,0.6]}
colors={['#4c669f', '#3b5998', '#192f6a']}
style={styles.linearGradient}>
<Text style={styles.buttonText}>
Sign in with Facebook
</Text>
</LinearGradient>
```
![Example with extra props](https://raw.githubusercontent.com/react-native-community/react-native-linear-gradient/HEAD/images/example-other-props.png)
#### useAngle / angle / angleCenter
You may want to achieve an angled gradient effect, similar to those in image editors like Photoshop.
One issue is that you have to calculate the angle based on the view's size, which only happens asynchronously and will cause unwanted flickr.
In order to do that correctly you can set `useAngle={true} angle={45} angleCenter={{x:0.5,y:0.5}}`, to achieve a gradient with a 45 degrees angle, with its center positioned in the view's exact center.
`useAngle` is used to turn on/off angle based calculation (as opposed to `start`/`end`).
`angle` is the angle in degrees.
`angleCenter` is the center point of the angle (will control the weight and stretch of the gradient like it does in photoshop.
## An example app
You can see this component in action in [brentvatne/react-native-login](https://github.com/brentvatne/react-native-login/blob/HEAD/App/Screens/LoginScreen.js#L58-L62).
## Troubleshooting
### iOS build fails: library not found, "BVLinearGradient" was not found in the UIManager
1. Ensure to run `pod install` before running the app on iOS
2. Ensure you use `ios/**.xcworkspace` file instead of `ios./**.xcodeproj`
### Other
Clearing build caches and reinstalling dependencies sometimes solve some issues. Try next steps:
1. Reinstalling `node_modules` with `rm -rf node_modules && yarn`
2. Clearing Android Gradle cache with `(cd android && ./gradlew clean)`
3. Reinstalling iOS CocoaPods with `(cd ios && rm -rf ./ios/Pods/**) && npx pod-install`
4. Clearing Xcode Build cache (open Xcode and go to Product -> Clean Build Folder)
For other troubleshooting issues, go to [React Native Troubleshooting](https://reactnative.dev/docs/troubleshooting.html)
## Other platforms
- Web: [react-native-web-community/react-native-web-linear-gradient](https://github.com/react-native-web-community/react-native-web-linear-gradient)
## License
MIT
[1]: https://github.com/react-native-linear-gradient/react-native-linear-gradient/workflows/ci/badge.svg
[2]: https://github.com/react-native-linear-gradient/react-native-linear-gradient/actions
[3]: https://img.shields.io/npm/v/react-native-linear-gradient.svg
[4]: https://www.npmjs.com/package/react-native-linear-gradient
[5]: https://img.shields.io/npm/dm/react-native-linear-gradient.svg

44
__mocks__/api.ts Normal file
View File

@ -0,0 +1,44 @@
// __mocks__/api.ts
import { language_matrix, language_matrix_entry } from "@/app/i18n/api";
// Import the actual API module to extend its functionality
const origApi = jest.requireActual('@/app/i18n/api.ts');
class LanguageServer {
constructor(...args: any[]) { }
fetchLanguages(): language_matrix {
return {
"en" : { code: "en", name: "English", targets: ['fr', 'es'] },
"fr" : { code: "fr", name: "French", targets: ["en", "es"] },
"es": { code: "es", name: "Spanish", targets: ['fr', 'en'] },
}
}
static getDefault() {
return new LanguageServer("http://localhost:5002");
}
}
class Translator {
constructor(...args : any []) {}
translate(message : string, target : string) {
return message;
}
static getDefault(code : string) {
return new Translator(code);
}
}
class CachedTranslator extends Translator{
}
module.exports = {
...origApi,
LanguageServer,
Translator,
CachedTranslator,
// Mock the specific functions you want to override
fetchData: jest.fn(() => Promise.resolve({ data: 'mocked data' })),
// Add more mock implementations as needed
};

11
__mocks__/db.ts Normal file
View File

@ -0,0 +1,11 @@
export default {
getDb: jest.fn(() => {
return {
runAsync: jest.fn((statement: string, ... values: string []) => {}),
runSync: jest.fn((statement: string, ... values : string []) => {}),
getFirstAsync: jest.fn((statement: string, value: string) => {
return [];
}),
};
}),
};

View File

@ -0,0 +1,4 @@
export const File = jest.fn();
export const Paths = {
join: jest.fn(),
};

View File

@ -1,44 +0,0 @@
// __mocks__/expo-sqlite.js
const sqlite3 = require('sqlite3').verbose();
class SQLiteDatabase {
constructor(name) {
this.db = new sqlite3.Database(':memory:');
}
runAsync(sql, params = []) {
return new Promise((resolve, reject) => {
this.db.run(sql, params, function (err) {
if (err) {
reject(err);
} else {
resolve({ changes: this.changes });
}
});
});
}
execAsync(sql) {
return new Promise((resolve, reject) => {
this.db.exec(sql, err => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
}
closeAsync() {
return new Promise(resolve => {
this.db.close(() => resolve());
});
}
}
const SQLite = {
openDatabaseAsync: jest.fn(name => new SQLiteDatabase(name)),
};
module.exports = SQLite;

16
__mocks__/settings.ts Normal file
View File

@ -0,0 +1,16 @@
const originalModule = jest.requireActual("@/app/lib/settings");
class MockSettings {
public constructor(public db = {}) {}
public setHostLanguage = jest.fn((val: string) => {});
public setLibretranslateBaseUrl(val: string) {}
getHostLanguage = jest.fn(() => {
return "en";
});
getLibretranslateBaseUrl = jest.fn(() => {
return "http://localhost:5004";
});
}
export default {
...originalModule,
Settings: MockSettings,
};

View File

@ -12,3 +12,5 @@
-keep class com.facebook.react.turbomodule.** { *; } -keep class com.facebook.react.turbomodule.** { *; }
# Add any project specific keep options here: # Add any project specific keep options here:
# whisper.rn
-keep class com.rnwhisper.** { *; }

View File

@ -3,5 +3,5 @@
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" tools:replace="android:usesCleartextTraffic" /> <application android:largeHeap="true" android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" tools:replace="android:usesCleartextTraffic" />
</manifest> </manifest>

View File

@ -1,8 +1,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<queries> <queries>
<intent> <intent>
@ -11,11 +15,11 @@
<data android:scheme="https"/> <data android:scheme="https"/>
</intent> </intent>
</queries> </queries>
<application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:supportsRtl="true"> <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:supportsRtl="true" android:largeHeap="true">
<meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/> <meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/>
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/> <meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/> <meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
<activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="portrait"> <activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="landscape">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>

View File

@ -6,7 +6,7 @@ buildscript {
minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '24') minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '24')
compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '35') compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '35')
targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '34') targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '34')
kotlinVersion = findProperty('android.kotlinVersion') ?: '1.9.24' kotlinVersion = findProperty('android.kotlinVersion') ?: '1.9.25'
ndkVersion = "26.1.10909125" ndkVersion = "26.1.10909125"
} }

View File

@ -3,7 +3,7 @@
"name": "translation-terrace", "name": "translation-terrace",
"slug": "translation-terrace", "slug": "translation-terrace",
"version": "1.0.0", "version": "1.0.0",
"orientation": "portrait", "orientation": "landscape",
"icon": "./assets/images/icon.png", "icon": "./assets/images/icon.png",
"scheme": "myapp", "scheme": "myapp",
"userInterfaceStyle": "automatic", "userInterfaceStyle": "automatic",
@ -30,7 +30,7 @@
[ [
"expo-screen-orientation", "expo-screen-orientation",
{ {
"initialOrientation": "LANDSCAPE" "orientation": "landscape"
} }
], ],
[ [
@ -48,18 +48,17 @@
"enableFTS": true, "enableFTS": true,
"useSQLCipher": true, "useSQLCipher": true,
"android": { "android": {
// Override the shared configuration for Android
"enableFTS": false, "enableFTS": false,
"useSQLCipher": false "useSQLCipher": false
}, },
"ios": { "ios": {
// You can also override the shared configurations for iOS
"customBuildFlags": [ "customBuildFlags": [
"-DSQLITE_ENABLE_DBSTAT_VTAB=1 -DSQLITE_ENABLE_SNAPSHOT=1" "-DSQLITE_ENABLE_DBSTAT_VTAB=1 -DSQLITE_ENABLE_SNAPSHOT=1"
] ]
} }
} }
] ],
"expo-audio"
], ],
"experiments": { "experiments": {
"typedRoutes": true "typedRoutes": true

View File

@ -1,19 +1,21 @@
import { Stack } from 'expo-router'; import * as React from "react";
import TTNavStack from "@/components/TTNavStack";
import * as ScreenOrientation from "expo-screen-orientation";
import { NavigationContainer } from "@react-navigation/native";
import { migrateDb } from "./lib/db";
import { Text } from "react-native";
export default function Layout() { export default function Layout() {
return ( const [loaded, setLoaded] = React.useState<boolean>(true);
<Stack React.useEffect(() => {
screenOptions={{ (async function () {
headerStyle: { await migrateDb();
backgroundColor: '#f4511e', await ScreenOrientation.unlockAsync();
}, await ScreenOrientation.lockAsync(
headerTintColor: '#fff', ScreenOrientation.OrientationLock.LANDSCAPE_LEFT
headerTitleStyle: { );
fontWeight: 'bold', setLoaded(true);
}, })();
}} });
> return loaded ? <TTNavStack /> : <Text>Loading...</Text>;
</Stack>
);
} }

View File

@ -1,90 +1,155 @@
import { Cache } from "react-native-cache"; import { Cache } from "react-native-cache";
import { LIBRETRANSLATE_BASE_URL } from "@/constants/api"; import { LIBRETRANSLATE_BASE_URL } from "@/constants/api";
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from "@react-native-async-storage/async-storage";
import { Settings } from "../lib/settings";
type language_t = string; type language_t = string;
const cache = new Cache({ const cache = new Cache({
namespace: "translation_terrace", namespace: "translation_terrace",
policy: { policy: {
maxEntries: 50000, // if unspecified, it can have unlimited entries maxEntries: 50000, // if unspecified, it can have unlimited entries
stdTTL: 0 // the standard ttl as number in seconds, default: 0 (unlimited) stdTTL: 0, // the standard ttl as number in seconds, default: 0 (unlimited)
}, },
backend: AsyncStorage backend: AsyncStorage,
}); });
export type language_matrix_entry = { export type language_matrix_entry = {
code: string, code: string;
name: string, name: string;
targets: string [] targets: string[];
} };
export type language_matrix = { export type language_matrix = {
[key:string] : language_matrix_entry [key: string]: language_matrix_entry;
};
export async function fetchWithTimeout(
url: string,
options: RequestInit,
timeout = 5000
): Promise<Response> {
return Promise.race([
fetch(url, options),
new Promise((_, reject) =>
setTimeout(() => reject(new Error("timeout")), timeout)
),
]);
}
export class LanguageServer {
constructor(public baseUrl: string) {}
async fetchLanguages(timeout = 500): Promise<language_matrix> {
let data = {};
const res = await fetchWithTimeout(
this.baseUrl + "/languages",
{
headers: {
"Content-Type": "application/json",
},
},
timeout
);
try {
data = await res.json();
} catch (e) {
throw new Error(`Parsing data from ${await res.text()}: ${e}`);
}
try {
return Object.fromEntries(
Object.values(data as language_matrix_entry[]).map(
(obj: language_matrix_entry) => {
return [obj["code"], obj];
}
)
);
} catch (e) {
throw new Error(
`Can't extract values from data: ${JSON.stringify(data)}`
);
}
}
static async getDefault() {
const settings = await Settings.getDefault();
return new LanguageServer(
(await settings.getLibretranslateBaseUrl()) || LIBRETRANSLATE_BASE_URL
);
}
} }
export class Translator { export class Translator {
constructor(public source : language_t, public defaultTarget : string = "en", private baseUrl = LIBRETRANSLATE_BASE_URL) { constructor(
public source: language_t,
public defaultTarget: string = "en",
private _languageServer: LanguageServer
) {}
get languageServer() {
return this._languageServer;
}
async translate(text: string, target: string | undefined = undefined) {
const url = this._languageServer.baseUrl + `/translate`;
console.log(url);
const postData = {
method: "POST",
body: JSON.stringify({
q: text,
source: this.source,
target: target || this.defaultTarget,
format: "text",
alternatives: 3,
api_key: "",
}),
headers: { "Content-Type": "application/json" },
};
console.debug("Requesting %s with %o", url, postData);
const res = await fetch(url, postData);
const data = await res.json();
if (res.status === 200) {
console.log(data);
return data.translatedText;
} else {
console.error("Status %d: %s", res.status, JSON.stringify(data));
} }
}
async fetchLanguages() : Promise<language_matrix> { static async getDefault(defaultTarget: string | undefined = undefined) {
let data = {}; const settings = await Settings.getDefault();
const res = await fetch(this.baseUrl + "/languages", { const source = await settings.getHostLanguage() || "en";
headers: { return new Translator(
"Content-Type": "application/json" source,
} defaultTarget,
}); await LanguageServer.getDefault()
try { );
data = await res.json(); }
} catch (e) {
throw new Error(`Parsing data from ${await res.text()}: ${e}`)
}
try {
return Object.fromEntries(
Object.values(data as language_matrix_entry []).map((obj : language_matrix_entry) => {
return [
obj["code"],
obj,
]
})
)
} catch(e) {
throw new Error(`Can't extract values from data: ${JSON.stringify(data)}`)
}
}
async translate(text : string, target : string|undefined = undefined) {
const url = LIBRETRANSLATE_BASE_URL + `/translate`;
const res = await fetch(url, {
method: "POST",
body: JSON.stringify({
q: text,
source: this.source,
target: target || this.defaultTarget,
format: "text",
alternatives: 3,
api_key: ""
}),
headers: { "Content-Type": "application/json" }
});
const data = await res.json();
console.log(data)
return data.translatedText
}
} }
export class CachedTranslator extends Translator { export class CachedTranslator extends Translator {
async translate (text : string, target : string|undefined = undefined) { async translate(text: string, target: string | undefined = undefined) {
const targetKey = target || this.defaultTarget; const targetKey = target || this.defaultTarget;
// console.debug(`Translating from ${this.source} -> ${targetKey}`) // console.debug(`Translating from ${this.source} -> ${targetKey}`)
const key1 = `${this.source}::${targetKey}::${text}` const key1 = `${this.source}::${targetKey}::${text}`;
const tr1 = await cache.get(key1); const tr1 = await cache.get(key1);
if (tr1) return tr1; if (tr1) return tr1;
const tr2 = await super.translate(text, target); const tr2 = await super.translate(text, target);
const key2 = `${this.source}::${targetKey}::${text}` const key2 = `${this.source}::${targetKey}::${text}`;
await cache.set(key2, tr2); await cache.set(key2, tr2);
return tr2; return tr2;
} }
static async getDefault(defaultTarget: string | undefined = undefined) {
const settings = await Settings.getDefault();
const source = await settings.getHostLanguage() || "en";
return new CachedTranslator(
source,
defaultTarget,
await LanguageServer.getDefault()
);
}
} }

View File

@ -1,5 +1,5 @@
import _countries from "@/assets/countries.min.json"; import _countries from "@/assets/countries.min.json";
import LANG_FLAGS from "@/langs-flags-list/lang-flags.json" import LANG_FLAGS from "./lang-flags.json"
import { language_matrix_entry } from "./api"; import { language_matrix_entry } from "./api";
import { lang_a2_a3 } from "./lang"; import { lang_a2_a3 } from "./lang";
@ -12,7 +12,7 @@ export function chooseCountry(lang_a2 : string) {
c => c.languages.includes(lang_a3.alpha3) c => c.languages.includes(lang_a3.alpha3)
); );
console.log("cc = %x, ", cs.map(c => c.alpha2)) // console.log("cc = %x, ", cs.map(c => c.alpha2))
return cs.filter(cc => Object.keys(LANG_FLAGS).includes(cc.alpha2.toLowerCase())).map(c => c.alpha2.toLowerCase()); return cs.filter(cc => Object.keys(LANG_FLAGS).includes(cc.alpha2.toLowerCase())).map(c => c.alpha2.toLowerCase());
} }

72
app/i18n/lang-flags.json Normal file
View File

@ -0,0 +1,72 @@
{
"af": ["za"],
"am": ["et"],
"ar": ["eg", "sa", "ae"],
"az": ["az"],
"be": ["by"],
"bg": ["bg"],
"bn": ["bd", "in"],
"bs": ["ba"],
"ca": ["es"],
"cs": ["cz"],
"cy": ["gb"],
"da": ["dk"],
"de": ["de", "at", "ch"],
"el": ["gr"],
"en": ["us", "gb", "au"],
"es": ["es", "mx", "ar"],
"et": ["ee"],
"fa": ["ir"],
"fi": ["fi"],
"fr": ["fr", "ca", "be"],
"ga": ["ie"],
"gl": ["es"],
"gu": ["in"],
"he": ["il"],
"hi": ["in"],
"hr": ["hr"],
"ht": ["ht"],
"hu": ["hu"],
"hy": ["am"],
"id": ["id"],
"is": ["is"],
"it": ["it", "ch", "sm"],
"ja": ["jp"],
"ka": ["ge"],
"kn": ["in"],
"ko": ["kr"],
"ku": ["tr"],
"lv": ["lv"],
"mk": ["mk"],
"ml": ["in"],
"mn": ["mn"],
"mr": ["in"],
"ms": ["my"],
"mt": ["mt"],
"nb": ["no"],
"ne": ["np"],
"nl": ["nl", "be"],
"or": ["in"],
"pa": ["in", "pk"],
"pl": ["pl"],
"pt": ["pt", "br"],
"ro": ["ro"],
"ru": ["ru", "ua", "by"],
"si": ["lk"],
"sk": ["sk"],
"sl": ["si"],
"sq": ["al"],
"sr": ["rs"],
"sv": ["se", "no", "fi"],
"sw": ["tz"],
"ta": ["in", "lk", "sg"],
"te": ["in"],
"th": ["th"],
"tr": ["tr"],
"uk": ["ua"],
"ur": ["pk"],
"uz": ["uz"],
"vi": ["vn"],
"zh": ["cn", "tw", "hk"]
}

View File

@ -1,10 +1,12 @@
import _LANG_FLAGS from "@/langs-flags-list/lang-flags.json" import _LANG_FLAGS from "./lang-flags.json"
import _LANGUAGES from "@/assets/languages.min.json" import _LANGUAGES from "@/assets/languages.min.json"
export const LANG_FLAGS = _LANG_FLAGS export const LANG_FLAGS = _LANG_FLAGS
export function longLang(shortLang : string) { export function longLang(shortLang : string) {
return ((LANG_FLAGS as any)[shortLang] as any)["nameEnglish"] as string const obj = LANG_FLAGS[shortLang];
if (!obj) return undefined;
return obj["name"] as string;
} }
export function lang_a3_a2(a3 : string) { export function lang_a3_a2(a3 : string) {

View File

@ -1,10 +1,10 @@
import { LanguageSelection } from "@/components/LanguageSelection"; import { useNavigation } from '@react-navigation/native';
import { Link, Stack } from "expo-router";
import { useState } from "react"; import { useState } from "react";
import { Image, Text, View, StyleSheet, Button, Pressable } from "react-native"; import { Image, Text, View, StyleSheet, Button, Pressable } from "react-native";
import { Translator, language_matrix_entry } from "./i18n/api"; import { LanguageServer, Translator, language_matrix_entry } from "./i18n/api";
import ConversationThread from "@/components/ConversationThread";
import { Conversation } from "./lib/conversation"; import { Conversation } from "./lib/conversation";
import { LanguageSelection } from "@/components/LanguageSelection";
import { Link } from 'expo-router';
function LogoTitle() { function LogoTitle() {
return ( return (
@ -16,21 +16,25 @@ function LogoTitle() {
} }
export default function Home() { export default function Home() {
const navigation = useNavigation();
const [lang, setLang] = useState<language_matrix_entry | undefined>(); const [lang, setLang] = useState<language_matrix_entry | undefined>();
const [conversation, setConversation] = useState<Conversation | undefined>(); const [conversation, setConversation] = useState<Conversation | undefined>();
const [setShowSettings, showSettings] = useState<boolean>(false); const [setShowSettings, showSettings] = useState<boolean>(false);
function onLangSelected(lang: language_matrix_entry | undefined) { async function onLangSelected(lang: language_matrix_entry) {
console.log("Language %s selected", lang?.code); console.log("Language %s selected", lang.code);
setLang(lang); setLang(lang);
if (!lang?.code) return; if (!lang?.code) return;
setConversation( const langServer = await LanguageServer.getDefault();
new Conversation( const conversation = new Conversation(
new Translator("en", lang.code), new Translator("en", lang.code, langServer),
{ id: "host", language: "en" }, { id: "host", language: "en" },
{ id: "guest", language: lang.code } { id: "guest", language: lang.code }
)
); );
navigation.navigate("Conversation", {
conversation,
});
} }
function onGoBack() { function onGoBack() {
@ -39,9 +43,10 @@ export default function Home() {
return ( return (
<View style={styles.container}> <View style={styles.container}>
<Stack.Screen name="index" /> <Pressable onPress={() => navigation.navigate("Settings")}>
<Stack.Screen name="settings" /> <Text>Settings</Text>
<Stack.Screen name="conversation" /> </Pressable>
<LanguageSelection onLangSelected={onLangSelected} />
</View> </View>
); );
} }

View File

@ -1,14 +1,15 @@
// conversation.test.ts // conversation.test.ts
import { Translator } from '@/app/i18n/api'; import { LanguageServer, Translator } from '@/app/i18n/api';
import { Conversation, Message, Speaker } from '@/app/lib/conversation'; import { Conversation, Message, Speaker } from '@/app/lib/conversation';
import { LIBRETRANSLATE_BASE_URL } from '@/constants/api';
import { describe, beforeEach, it, expect, test } from '@jest/globals'; import { describe, beforeEach, it, expect, test } from '@jest/globals';
describe('Conversation', () => { describe('Conversation', () => {
let conversation: Conversation; let conversation: Conversation;
beforeEach(() => { beforeEach(() => {
const translator = new Translator("en", "es"); const translator = new Translator("en", "es", new LanguageServer(LIBRETRANSLATE_BASE_URL));
const s1: Speaker = { language: "en", id: "host" }; const s1: Speaker = { language: "en", id: "host" };
const s2: Speaker = { id: "guest", language: "es" } const s2: Speaker = { id: "guest", language: "es" }
conversation = new Conversation(translator, s1, s2); conversation = new Conversation(translator, s1, s2);

View File

@ -1,37 +1,33 @@
import {describe, expect, beforeEach} from '@jest/globals'; import { Settings } from '@/app/lib/settings';
import {Settings} from '@/app/lib/settings'; import { getDb, migrateDb } from '@/app/lib/db';
import { getDb } from '@/app/lib/db'; import { SQLiteDatabase } from 'expo-sqlite';
describe('Settings', () => { describe('Settings', () => {
let settings: Settings; let settings: Settings;
let db: SQLiteDatabase;
beforeEach(async () => { beforeEach(async () => {
// Initialize your Settings class here with a fresh database instance db = await getDb("development");
settings = new Settings(await getDb()); await migrateDb("development");
settings = new Settings(db);
}); });
afterEach(async () => { afterEach(async () => {
// Clean up the database after each test await migrateDb("development", "down");
await settings.db.executeSql('DELETE FROM settings');
}); });
describe('setHostLanguage', () => { it('should set the host language in the database', async () => {
it('should set the host language in the database', async () => { const value = 'en';
const value = 'en'; await settings.setHostLanguage(value);
await settings.setHostLanguage(value);
const result = await settings.getHostLanguage(); const result = await settings.getHostLanguage();
expect(result).toEqual(value); expect(result).toEqual(value);
});
}); });
describe('getHostLanguage', () => { describe('getHostLanguage', () => {
it('should return the host language from the database', async () => { it('should return the host language from the database', async () => {
const value = 'fr'; const value = 'fr';
await settings.db.executeSql( await settings.setHostLanguage(value);
`INSERT INTO settings (host_language) VALUES (?)`,
[value]
);
const result = await settings.getHostLanguage(); const result = await settings.getHostLanguage();
expect(result).toEqual(value); expect(result).toEqual(value);
@ -39,14 +35,14 @@ describe('Settings', () => {
it('should return null if the host language is not set', async () => { it('should return null if the host language is not set', async () => {
const result = await settings.getHostLanguage(); const result = await settings.getHostLanguage();
expect(result).not.toBeNull(); expect(result).toBeUndefined();
}); });
}); });
describe('setLibretranslateBaseUrl', () => { describe('setLibretranslateBaseUrl', () => {
it('should set the LibreTranslate base URL in the database', async () => { it('should set the LibreTranslate base URL in the database', async () => {
const value = 'https://example.com'; const value = 'https://example.com';
await settings.setLibetransalteBaseUrl(value); await settings.setLibretranslateBaseUrl(value);
const result = await settings.getLibretranslateBaseUrl(); const result = await settings.getLibretranslateBaseUrl();
expect(result).toEqual(value); expect(result).toEqual(value);
@ -54,20 +50,36 @@ describe('Settings', () => {
}); });
describe('getLibretranslateBaseUrl', () => { describe('getLibretranslateBaseUrl', () => {
it('should return the LibreTranslate base URL from the database', async () => {
const value = 'https://another-example.com';
await settings.db.executeSql(
`INSERT INTO settings (libetransalte_base_url) VALUES (?)`,
[value]
);
const result = await settings.getLibretranslateBaseUrl();
expect(result).toEqual(value);
});
it('should return null if the LibreTranslate base URL is not set', async () => { it('should return null if the LibreTranslate base URL is not set', async () => {
const result = await settings.getLibretranslateBaseUrl(); const result = await settings.getLibretranslateBaseUrl();
expect(result).not.toBeNull(); expect(result).toBeUndefined();
}); });
}); });
describe('setWhisperModel', () => {
it('should set the Whisper model in the database', async () => {
const value = 'base';
await settings.setWhisperModel(value);
const result = await settings.getWhisperModel();
expect(result).toEqual(value);
});
});
describe('setWhisperModel', () => {
it('should set the Whisper model in the database', async () => {
const value = 'base';
await settings.setWhisperModel(value);
const result = await settings.getWhisperModel();
expect(result).toEqual(value);
});
});
describe('getWhisperModel', () => {
it('should return null if the Whisper model is not set', async () => {
const result = await settings.getWhisperModel();
expect(result).toBeUndefined();
});
});
}); });

View File

@ -0,0 +1,170 @@
// app/lib/__tests__/whisper.spec.tsx
import React from "react";
import { getDb } from "@/app/lib/db";
import { WhisperFile, WhisperModelTag } from "@/app/lib/whisper"; // Corrected to use WhisperFile and WhisperModelTag instead of WhisperDownloader
import { Settings } from "@/app/lib/settings";
import { File } from "expo-file-system/next";
jest.mock('expo-file-system');
import * as FileSystem from 'expo-file-system';
jest.mock("@/app/lib/db", () => ({
getDb: jest.fn().mockResolvedValue({
runAsync: jest.fn(),
upsert: jest.fn(), // Mock the upsert method used in addToDatabase
}),
}));
jest.mock("@/app/lib/settings", () => ({
Settings: {
getDefault: jest.fn(() => ({
getValue: jest.fn((key) => {
switch (key) {
case "whisper_model":
return "base";
default:
throw new Error(`Invalid setting: '${key}'`);
}
}),
})),
},
}));
jest.mock("expo-file-system/next", () => {
const _next = jest.requireActual("expo-file-system/next");
return {
..._next,
File: jest.fn().mockImplementation(() => ({
..._next.File,
text: jest.fn(() => {
return new String("text");
}),
})),
};
});
describe("WhisperFile", () => {
// Corrected to use WhisperFile instead of WhisperDownloader
let whisperFile: WhisperFile;
beforeEach(async () => {
whisperFile = new WhisperFile("small");
});
it("should create a download resumable with existing data if available", async () => {
const mockExistingData = "mockExistingData";
jest.spyOn(whisperFile, "doesTargetExist").mockResolvedValue(true);
await whisperFile.createDownloadResumable();
// expect(whisperFile.targetFileName).toEqual("small.bin");
expect(whisperFile.targetPath).toContain("small.bin");
expect(FileSystem.createDownloadResumable).toHaveBeenCalledWith(
"https://huggingface.co/openai/whisper-small/resolve/main/pytorch_model.bin",
"file:///whisper/small.bin",
{},
expect.any(Function),
expect.anything(),
);
});
// it("should create a download resumable without existing data if not available", async () => {
// jest.spyOn(whisperFile, "doesTargetExist").mockResolvedValue(false);
// await whisperFile.createDownloadResumable(); // Updated to use createDownloadResumable instead of download
// expect(FileSystem.createDownloadResumable).toHaveBeenCalledWith(
// "http://mock.model.com/model",
// "mockTargetPath",
// {},
// expect.any(Function),
// undefined
// );
// });
// it("should update the download status in the database", async () => {
// const mockRunAsync = jest.fn();
// (getDb as jest.Mock).mockResolvedValue({ runAsync: mockRunAsync });
// const downloadable = await whisperFile.createDownloadResumable(); // Updated to use createDownloadResumable instead of download
// await downloadable.resumeAsync();
// jest.advanceTimersByTime(1000);
// expect(mockRunAsync).toHaveBeenCalled();
// });
// it("should record the latest target hash after downloading", async () => {
// const mockRecordLatestTargetHash = jest.spyOn(
// whisperFile,
// "recordLatestTargetHash"
// );
// await whisperFile.createDownloadResumable(); // Updated to use createDownloadResumable instead of download
// expect(mockRecordLatestTargetHash).toHaveBeenCalled();
// });
// it("should call the onData callback if provided", async () => {
// const mockOnData = jest.fn();
// const options = { onData: mockOnData };
// await whisperFile.createDownloadResumable(options); // Updated to use createDownloadResumable instead of download
// expect(mockOnData).toHaveBeenCalledWith(expect.any(Object));
// });
// describe("getDownloadStatus", () => {
// it("should return the correct download status when model size is known and download has started", async () => {
// whisperFile.size = 1024;
// jest.spyOn(whisperFile, "doesTargetExist").mockResolvedValue(true);
// jest.spyOn(whisperFile, "isDownloadComplete").mockResolvedValue(false);
// jest.spyOn(whisperFile, "targetFile").mockReturnValue({
// size: 512,
// });
// const status = await whisperFile.getDownloadStatus();
// expect(status).toEqual({
// doesTargetExist: true,
// isDownloadComplete: false,
// hasDownloadStarted: true,
// progress: {
// current: 512,
// total: 1024,
// remaining: 512,
// percentRemaining: 50.0,
// },
// });
// });
// it("should return the correct download status when model size is known and download is complete", async () => {
// whisperFile.size = 1024;
// jest.spyOn(whisperFile, "doesTargetExist").mockResolvedValue(true);
// jest.spyOn(whisperFile, "isDownloadComplete").mockResolvedValue(true);
// const status = await whisperFile.getDownloadStatus();
// expect(status).toEqual({
// doesTargetExist: true,
// isDownloadComplete: true,
// hasDownloadStarted: false,
// progress: undefined,
// });
// });
// it("should return the correct download status when model size is unknown", async () => {
// jest.spyOn(whisperFile, "doesTargetExist").mockResolvedValue(false);
// const status = await whisperFile.getDownloadStatus();
// expect(status).toEqual({
// doesTargetExist: false,
// isDownloadComplete: false,
// hasDownloadStarted: false,
// progress: undefined,
// });
// });
// });
});

View File

@ -31,11 +31,15 @@ export class Message {
} }
} }
type conversation_event_t = "add_message" | "translation_done"
type conversation_callback_t = (conversation : Conversation) => any;
export class Conversation extends Array<Message> { export class Conversation extends Array<Message> {
public onAddMessage? : (conversation : Conversation) => any; public onAddMessage? : (conversation : Conversation) => any;
public onTranslationDone? : (conversation : Conversation) => any; public onTranslationDone? : (conversation : Conversation) => any;
constructor ( constructor (
public translator : Translator, public translator : Translator,
public host : Speaker, public host : Speaker,
@ -44,6 +48,15 @@ export class Conversation extends Array<Message> {
super(); super();
} }
public on(event : conversation_event_t, callback : conversation_callback_t) {
if (event === "add_message") {
this.onAddMessage = callback;
}
if (event === "translation_done") {
this.onTranslationDone = callback;
}
}
public addMessage(speaker : Speaker, text? : string) { public addMessage(speaker : Speaker, text? : string) {
this.push(new Message(this, speaker, text)); this.push(new Message(this, speaker, text));
} }

View File

@ -1,30 +1,28 @@
import * as SQLite from 'expo-sqlite'; import * as SQLite from "expo-sqlite";
import { MIGRATE_UP, MIGRATE_DOWN } from "./migrations";
export const MIGRATE_UP = { export type db_mode = "development" | "staging" | "production";
1: [
`CREATE TABLE IF NOT EXIST settings ( export async function getDb(mode : db_mode = "production") {
host_language TEXT, return await SQLite.openDatabaseAsync(`translation_terrace_${mode}`);
libretranslate_base_url TEXT,
ui_direction INTEGER
)`,
]
} }
export const MIGRATE_DOWN = {
1: [
`DROP TABLE IF EXISTS settings`
]
}
export async function getDb(migrationDirection : "up" | "down" = "up") { export async function migrateDb(mode : db_mode = "production", direction: "up" | "down" = "up") {
const db = await SQLite.openDatabaseAsync('translation_terrace');
for (let [migration, statements] of Object.entries(MIGRATE_UP)) { const db = await getDb(mode);
for (let statement of statements) {
console.log(statement) const m = direction === "up" ? MIGRATE_UP : MIGRATE_DOWN;
await db.runAsync(statement);
} for (let [migration, statements] of Object.entries(m)) {
for (let statement of statements) {
console.log(statement);
try {
const result = await db.runAsync(statement);
console.log(result);
} catch (err) {
console.error(err);
}
} }
}
return db;
} }

24
app/lib/migrations.ts Normal file
View File

@ -0,0 +1,24 @@
export const MIGRATE_UP = {
1: [
`CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT
)`,
],
2: [
`CREATE TABLE IF NOT EXISTS whisper_models (
model TEXT PRIMARY KEY,
download_status STRING(255),
expected_size INTEGER,
last_hash STRING(1024),
bytes_done INTEGER,
bytes_total INTEGER
)`,
],
};
export const MIGRATE_DOWN = {
1: [`DROP TABLE IF EXISTS settings`],
2: [`DROP TABLE IF EXISTS whisper_models`],
};

0
app/lib/models.ts Normal file
View File

61
app/lib/readstream.ts Normal file
View File

@ -0,0 +1,61 @@
/* eslint-disable unicorn/no-null */
import * as fs from 'expo-file-system';
import { Readable } from 'readable-stream';
class ExpoReadStream extends Readable {
private readonly fileUri: string;
private fileSize: number;
private currentPosition: number;
private readonly chunkSize: number;
constructor(fileUri: string, options: fs.ReadingOptions) {
super();
this.fileUri = fileUri;
this.fileSize = 0; // Initialize file size (could be fetched if necessary)
this.currentPosition = options.position ?? 0;
/**
* Default chunk size in bytes. React Native Expo will OOM at 110MB, so we set this to 1/100 of it to balance speed and memory usage and importantly the feedback for user.
* If this is too large, the progress bar will be stuck when down stream processing this chunk.
*/
this.chunkSize = options.length ?? 1024 * 1024;
void this._init();
}
async _init() {
try {
const fileInfo = await fs.getInfoAsync(this.fileUri, { size: true });
if (fileInfo.exists) {
this.fileSize = fileInfo.size ?? 0;
} else {
this.fileSize = 0;
}
} catch (error) {
this.emit('error', error);
}
}
_read() {
const readingOptions = {
encoding: fs.EncodingType.Base64,
position: this.currentPosition,
length: this.chunkSize,
} satisfies fs.ReadingOptions;
fs.readAsStringAsync(this.fileUri, readingOptions).then(chunk => {
if (chunk.length === 0) {
// End of the stream
this.emit('progress', 1);
this.push(null);
} else {
this.currentPosition = Math.min(this.chunkSize + this.currentPosition, this.fileSize);
this.emit('progress', this.fileSize === 0 ? 0.5 : (this.currentPosition / this.fileSize));
this.push(Buffer.from(chunk, 'base64'));
}
}).catch(error => {
this.emit('error', error);
});
}
}
export function createReadStream(fileUri: string, options: { encoding?: fs.EncodingType; end?: number; highWaterMark?: number; start?: number } = {}): ExpoReadStream {
return new ExpoReadStream(fileUri, options);
}

View File

@ -1,4 +1,6 @@
import { SQLiteDatabase } from "expo-sqlite"; import { SQLiteDatabase } from "expo-sqlite";
import { getDb } from "./db";
import { WhisperFile, whisper_model_tag_t } from "./whisper";
export class Settings { export class Settings {
@ -6,6 +8,7 @@ export class Settings {
"host_language", "host_language",
"libretranslate_base_url", "libretranslate_base_url",
'ui_direction', 'ui_direction',
"whisper_model",
] ]
constructor(public db: SQLiteDatabase) { constructor(public db: SQLiteDatabase) {
@ -18,25 +21,23 @@ export class Settings {
throw new Error(`Invalid setting: '${key}'`) throw new Error(`Invalid setting: '${key}'`)
} }
const query = ` const row: { value: string } | null = this.db.getFirstSync(`SELECT value FROM settings WHERE key = ?`, key)
SELECT ?
FROM settings
LIMIT 1`
const result = await this.db.getFirstAsync(
query
);
return result ? (result as any)[key] : null; return row?.value;
} }
private async setValue(key: string, value: any) { private async setValue(key: string, value: any) {
if (!Settings.KEYS.includes(key)) { if (!Settings.KEYS.includes(key)) {
throw new Error(`Invalid setting: '${key}'`) throw new Error(`Invalid setting: '${key}'`);
} }
const statement = `INSERT INTO settings (${key})
SELECT '?' // Check if the key already exists
ON CONFLICT DO UPDATE SET ${key} = ?` this.db.runSync(`INSERT OR REPLACE INTO
await this.db.runAsync(statement, [value, value]); settings
(key, value)
VALUES
(?, ?)`, key, value);
} }
async setHostLanguage(value: string) { async setHostLanguage(value: string) {
@ -47,12 +48,23 @@ ON CONFLICT DO UPDATE SET ${key} = ?`
return await this.getValue("host_language") return await this.getValue("host_language")
} }
async setLibetransalteBaseUrl(value : string) { async setLibretranslateBaseUrl(value: string) {
await this.setValue("libretranslate_base_url", value) await this.setValue("libretranslate_base_url", value)
} }
async getLibretranslateBaseUrl() { async getLibretranslateBaseUrl() {
await this.getValue("libretranslate_base_url") return await this.getValue("libretranslate_base_url")
} }
async setWhisperModel(value: string) {
await this.setValue("whisper_model", value);
}
async getWhisperModel() {
return await this.getValue("whisper_model") as whisper_model_tag_t;
}
static async getDefault() {
return new Settings(await getDb())
}
} }

9
app/lib/util.ts Normal file
View File

@ -0,0 +1,9 @@
import { TextDecoder } from "util";
export function arrbufToStr(arrayBuffer : ArrayBuffer) {
return new TextDecoder().decode(new Uint8Array(arrayBuffer));
}
export function strToArrBuf(input : string) : Uint8Array<ArrayBufferLike> {
return new TextEncoder().encode(input)
}

14
app/lib/whisper.ts Normal file
View File

@ -0,0 +1,14 @@
import { File, Paths } from "expo-file-system/next";
import FileSystem from "expo-file-system"
import { pathToFileURLString } from "expo-file-system/src/next/pathUtilities/url";
export const WHISPER_MODEL_PATH = Paths.join("..", "..", "assets", "whisper");
export const WHISPER_MODEL_DIR = new File(WHISPER_MODEL_PATH);
export const WHISPER_MODEL_SMALL_PATH = "file://../../assets/whisper/whisper-small.bin";
export async function whisperModelExists() {
const file = new File(WHISPER_MODEL_PATH);
return file.exists;
}

36
app/service/download.ts Normal file
View File

@ -0,0 +1,36 @@
import { useState, useEffect, useRef } from 'react';
import { Text, View, Button, Platform } from 'react-native';
import * as Device from 'expo-device';
import * as Notifications from 'expo-notifications';
import Constants from 'expo-constants';
export function initNotifications() {
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: true,
shouldSetBadge: true,
}),
});
}
async function sendPushNotification(expoPushToken: string) {
const message = {
to: expoPushToken,
sound: 'default',
title: 'Original Title',
body: 'And here is the body!',
data: { someData: 'goes here' },
};
await fetch('https://exp.host/--/api/v2/push/send', {
method: 'POST',
headers: {
Accept: 'application/json',
'Accept-encoding': 'gzip, deflate',
'Content-Type': 'application/json',
},
body: JSON.stringify(message),
});
}

8
babel.config.js Normal file
View File

@ -0,0 +1,8 @@
module.exports = function (api) {
api.cache.forever();
return {
presets: [
'babel-preset-expo', 'module:@expo/knex-expo-sqlite-dialect/babel-preset',
],
};
};

View File

@ -1,72 +1,200 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { ScrollView, Text, TouchableHighlight, View } from "react-native"; import {
Alert,
ScrollView,
StyleSheet,
Text,
TouchableHighlight,
View,
} from "react-native";
import { useNavigation, Route } from "@react-navigation/native";
import { Conversation, Message } from "@/app/lib/conversation"; import { Conversation, Message } from "@/app/lib/conversation";
import MessageBubble from "@/components/ui/MessageBubble"; import MessageBubble from "@/components/ui/MessageBubble";
import { WhisperContext } from "whisper.rn";
import { NavigationProp, ParamListBase } from "@react-navigation/native";
import { import {
CachedTranslator, CachedTranslator,
LanguageServer,
language_matrix_entry, language_matrix_entry,
Translator,
} from "@/app/i18n/api"; } from "@/app/i18n/api";
import { getDb } from "@/app/lib/db"; import {
import LiveAudioStream from 'react-native-live-audio-stream'; WHISPER_MODEL_SMALL_PATH,
whisperModelExists,
} from "@/app/lib/whisper";
import { initWhisper, WhisperContext } from "whisper.rn";
import { useAudioRecorder, AudioModule, RecordingPresets } from "expo-audio";
import FileSystem from "expo-file-system";
const lasOptions = { const lasOptions = {
sampleRate: 32000, // default is 44100 but 32000 is adequate for accurate voice recognition sampleRate: 32000, // default is 44100 but 32000 is adequate for accurate voice recognition
channels: 1, // 1 or 2, default 1 channels: 1, // 1 or 2, default 1
bitsPerSample: 16, // 8 or 16, default 16 bitsPerSample: 16, // 8 or 16, default 16
audioSource: 6, // android only (see below) audioSource: 6, // android only (see below)
bufferSize: 4096 // default is 2048 bufferSize: 4096, // default is 2048
}; };
// LiveAudioStream.init(lasOptions as any); // LiveAudioStream.init(lasOptions as any);
interface ConversationThreadProps { const ConversationThread = ({
conversation: Conversation; route,
whisperContext: WhisperContext; }: {
onGoBack?: () => any; route?: Route<"Conversation", { conversation: Conversation }>;
} }) => {
const navigation = useNavigation();
if (!route) {
return (
<View>
<Text>Missing Params!</Text>
</View>
);
}
/* 2. Get the param */
const { conversation } = route?.params;
const ConversationThread = (p: ConversationThreadProps) => {
const [messages, setMessages] = useState<Message[]>([]); const [messages, setMessages] = useState<Message[]>([]);
const [guestSpeak, setGuestSpeak] = useState<string | undefined>(); const [guestSpeak, setGuestSpeak] = useState<string | undefined>();
const [guestSpeakLoaded, setGuestSpeakLoaded] = useState<boolean>(false); const [guestSpeakLoaded, setGuestSpeakLoaded] = useState<boolean>(false);
const ct = new CachedTranslator("en", p.conversation.guest.language); const [whisperContext, setWhisperContext] = useState<
WhisperContext | undefined
>();
const [cachedTranslator, setCachedTranslator] = useState<
undefined | CachedTranslator
>();
const [languageLabels, setLanguageLabels] = useState<
| undefined
| {
hostNative: {
host: string;
guest: string;
};
guestNative: {
host: string;
guest: string;
};
}
>();
// recorder settings
const audioRecorder = useAudioRecorder(RecordingPresets.HIGH_QUALITY);
const record = async () => {
await audioRecorder.prepareToRecordAsync();
audioRecorder.record();
};
const stopRecording = async () => {
// The recording will be available on `audioRecorder.uri`.
await audioRecorder.stop();
};
useEffect(() => { useEffect(() => {
(async function () {
const languageServer = await LanguageServer.getDefault();
try {
const languages = await languageServer.fetchLanguages(5000);
const cachedTranslator = new CachedTranslator(
"en",
conversation.guest.language,
languageServer
);
console.log("Set cached translator from %s", languageServer.baseUrl);
setCachedTranslator(cachedTranslator);
try {
if (!(await whisperModelExists())) {
throw new Error(`${WHISPER_MODEL_SMALL_PATH} does not exist`);
}
} catch (err) {
console.error(
`Could not determine if %s exists: %s`,
WHISPER_MODEL_SMALL_PATH,
err
);
throw err;
}
try {
setWhisperContext(
await initWhisper({
filePath: WHISPER_MODEL_SMALL_PATH,
})
);
} catch (err) {
console.error(err);
throw err;
}
// recorder settings
(async () => {
const status = await AudioModule.requestRecordingPermissionsAsync();
if (!status.granted) {
Alert.alert("Permission to access microphone was denied");
}
})();
setGuestSpeak(await cachedTranslator.translate("Speak"));
const hostLang1 = languages[conversation.host.language].name;
const guestLang1 = languages[conversation.host.language].name;
const hostLang2 = await cachedTranslator.translate(
languages[conversation.host.language].name
);
const guestLang2 = await cachedTranslator.translate(
languages[conversation.host.language].name
);
setLanguageLabels({
hostNative: {
host: hostLang1,
guest: guestLang1,
},
guestNative: {
host: hostLang2,
guest: guestLang2,
},
});
} catch (err) {
console.error(
"Could not set translator from %s: %s",
languageServer.baseUrl,
err
);
}
})();
const updateMessages = (c: Conversation) => { const updateMessages = (c: Conversation) => {
setMessages([...c]); setMessages([...c]);
}; };
p.conversation.onAddMessage = updateMessages; if (!conversation) {
p.conversation.onTranslationDone = updateMessages; console.warn("Conversation is null or undefined.");
return () => {
p.conversation.onAddMessage = undefined;
p.conversation.onTranslationDone = undefined;
};
}, [p.conversation, guestSpeak]);
useEffect(() => {
const fetchData = async () => {
setGuestSpeak(await ct.translate("Speak"));
} }
fetchData(); conversation.on("add_message", updateMessages);
}, [guestSpeak]) conversation.on("translation_done", updateMessages);
// return () => {
// conversation.on("add_message", undefined);
// conversation.on("translation_done", undefined);
// };
}, [conversation, guestSpeak]);
const renderMessages = () => const renderMessages = () =>
messages.map((message, index) => ( messages.map((message, index) => (
<MessageBubble key={index} message={message} /> <MessageBubble key={index} message={message} />
)); ));
function onGoBack() { return cachedTranslator ? (
p.onGoBack && p.onGoBack();
}
return (
<View style={{ flex: 1, flexDirection: "column" }}> <View style={{ flex: 1, flexDirection: "column" }}>
{languageLabels && (
<View style={styles.languageLabels}>
<Text style={styles.nativeHostLabel}>
{languageLabels.hostNative.host} / {languageLabels.hostNative.guest}
</Text>
<Text style={styles.nativeGuestLabel}>
{languageLabels.guestNative.host} /{" "}
{languageLabels.guestNative.guest}
</Text>
</View>
)}
<ScrollView <ScrollView
style={{ style={{
borderColor: "black", borderColor: "black",
@ -85,7 +213,7 @@ const ConversationThread = (p: ConversationThreadProps) => {
</TouchableHighlight> </TouchableHighlight>
<TouchableHighlight <TouchableHighlight
style={{ backgroundColor: "gray", padding: 3, borderRadius: 5 }} style={{ backgroundColor: "gray", padding: 3, borderRadius: 5 }}
onPress={onGoBack} onPress={navigation.goBack}
> >
<Text style={{ color: "white", fontSize: 30 }}>Go Back</Text> <Text style={{ color: "white", fontSize: 30 }}>Go Back</Text>
</TouchableHighlight> </TouchableHighlight>
@ -98,7 +226,17 @@ const ConversationThread = (p: ConversationThreadProps) => {
</TouchableHighlight> </TouchableHighlight>
</View> </View>
</View> </View>
) : (
<View>
<Text>Loading...</Text>
</View>
); );
}; };
const styles = StyleSheet.create({
languageLabels: {},
nativeHostLabel: {},
nativeGuestLabel: {},
});
export default ConversationThread; export default ConversationThread;

View File

@ -1,23 +1,28 @@
import { CachedTranslator, Translator, language_matrix, language_matrix_entry } from "@/app/i18n/api"; import { CachedTranslator, LanguageServer, Translator, language_matrix, language_matrix_entry } from "@/app/i18n/api";
import { LIBRETRANSLATE_BASE_URL } from "@/constants/api"; import { LIBRETRANSLATE_BASE_URL } from "@/constants/api";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import ISpeakButton from "./ui/ISpeakButton"; import ISpeakButton from "./ui/ISpeakButton";
import { LANG_FLAGS } from "@/app/i18n/lang"; import { LANG_FLAGS } from "@/app/i18n/lang";
import { ScrollView, StyleSheet, Text, View } from "react-native"; import { Pressable, ScrollView, StyleSheet, Text, View } from "react-native";
import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context"; import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context";
import { Conversation, Speaker } from "@/app/lib/conversation"; import { Conversation, Speaker } from "@/app/lib/conversation";
import { NavigationProp, ParamListBase } from "@react-navigation/native"; import { NavigationProp, ParamListBase } from "@react-navigation/native";
import { Link, useNavigation } from "expo-router";
import { migrateDb } from "@/app/lib/db";
export function LanguageSelection(props: { export function LanguageSelection(props: {
navigation?: NavigationProp<ParamListBase> navigation?: NavigationProp<ParamListBase>
translator?: Translator translator?: Translator
onLangSelected? : (lang : language_matrix_entry) => any onLangSelected?: (lang: language_matrix_entry) => any
}) { }) {
const [languages, setLanguages] = useState<language_matrix | undefined>(); const [languages, setLanguages] = useState<language_matrix | undefined>();
const [languagesLoaded, setLanguagesLoaded] = useState<boolean>(false); const [languagesLoaded, setLanguagesLoaded] = useState<boolean>(false);
const [translator, setTranslator] = useState<Translator | undefined>();
const translator = props.translator || new CachedTranslator("en") const nav = useNavigation();
const languageServer = new LanguageServer(LIBRETRANSLATE_BASE_URL);
function onLangSelected(language: language_matrix_entry) { function onLangSelected(language: language_matrix_entry) {
props.onLangSelected && props.onLangSelected(language) props.onLangSelected && props.onLangSelected(language)
@ -25,44 +30,53 @@ export function LanguageSelection(props: {
useEffect(() => { useEffect(() => {
const fetchData = async () => { (async () => {
await migrateDb();
try { try {
// Replace with your actual async data fetching logic // Replace with your actual async data fetching logic
const languages = await translator.fetchLanguages(); setTranslator(await CachedTranslator.getDefault());
const languageServer = await LanguageServer.getDefault();
const languages = await languageServer.fetchLanguages(10000);
setLanguages(languages); setLanguages(languages);
setLanguagesLoaded(true); setLanguagesLoaded(true);
} catch (error) { } catch (error) {
error = error as Response; console.error('Error fetching languages from %s: %s', languageServer.baseUrl, error);
console.error('Error fetching data (%d %s): %s', (error as Response).status, (error as Response).statusText, (error as Response).body);
} }
}; })();
fetchData();
}, []); }, []);
return ( return (
<ScrollView > <View>
<SafeAreaProvider > <Pressable onPress={() => nav.navigate('Settings')}>
<SafeAreaView> <Text>Settings</Text>
{(languages && languagesLoaded) ? Object.entries(languages).filter((l) => (LANG_FLAGS as any)[l[0]] !== undefined).map( </Pressable>
([lang, lang_entry]) => { <ScrollView >
return ( <SafeAreaProvider>
<ISpeakButton language={lang_entry} key={lang_entry.code} onLangSelected={onLangSelected} /> <SafeAreaView style={styles.table}>
); {(languages && languagesLoaded) ? Object.entries(languages).filter((l) => (LANG_FLAGS as any)[l[0]] !== undefined).map(
([lang, lang_entry]) => {
return (
<ISpeakButton language={lang_entry} key={lang_entry.code} onLangSelected={onLangSelected} translator={translator} />
);
}
) : <Text>Waiting...</Text>
} }
) : <Text>Waiting...</Text> </SafeAreaView>
} </SafeAreaProvider>
</SafeAreaView> </ScrollView>
</SafeAreaProvider> </View>
</ScrollView>
) )
} }
const DEBUG_BORDER = {
borderWidth: 3,
borderStyle: "dotted",
borderColor: "blue",
}
const styles = StyleSheet.create({ const styles = StyleSheet.create({
column: { table: {
flex: 1, flexDirection: "row",
flexDirection: 'row', flexWrap: "wrap",
flexWrap: 'wrap',
padding: 8,
}, },
}) })

View File

@ -1,89 +1,155 @@
import React, { useEffect, useState } from "react"; import React, { useState, useEffect } from "react";
import { StyleSheet, View } from "react-native"; import { View, Text, TextInput, StyleSheet } from "react-native";
import { NavigationContainer } from "@react-navigation/native"; import { Settings } from "@/app/lib/settings";
import { Picker } from "@react-native-picker/picker";
import { import {
default as ReactNativeSettings, LanguageServer,
SettingsElement, language_matrix,
} from "@mmomtchev/react-native-settings"; } from "@/app/i18n/api";
import { longLang } from "@/app/i18n/lang";
import { Translator, language_matrix } from "@/app/i18n/api";
// We will store the config here const LIBRETRANSLATE_BASE_URL = "https://translate.argosopentech.com/translate";
const configData: Record<string, string> = {};
const SettingsComponent = () => {
const [hostLanguage, setHostLanguage] = useState<string | null>(null);
const [libretranslateBaseUrl, setLibretranslateBaseUrl] = useState<
string | null
>(null);
const [languageOptions, setLanguageOptions] = useState<
language_matrix | undefined
>();
const [langServerConn, setLangServerConn] = useState<{
success: boolean;
error?: string;
} | null>(null);
useEffect(() => {
(async function () {
const settings = await Settings.getDefault();
setHostLanguage((await settings.getHostLanguage()) || "en");
setLibretranslateBaseUrl(
(await settings.getLibretranslateBaseUrl()) || LIBRETRANSLATE_BASE_URL
);
})();
});
const handleHostLanguageChange = async (lang: string) => {
const settings = await Settings.getDefault();
setHostLanguage(lang);
await settings.setHostLanguage(lang);
};
const handleLibretranslateBaseUrlChange = async (url: string) => {
const settings = await Settings.getDefault();
setLibretranslateBaseUrl(url);
await settings.setLibretranslateBaseUrl(url);
checkLangServerConnection(url);
};
const checkLangServerConnection = async (baseUrl: string) => {
try {
// Replace with actual connection check logic
const testResult = await fetch(baseUrl, {
method: "HEAD",
});
if (testResult.status !== 200) {
setLangServerConn({ success: true, error: testResult.statusText });
}
} catch (error) {
setLangServerConn({ success: false, error: `${error}` });
}
};
return hostLanguage && libretranslateBaseUrl ? (
<View style={styles.container}>
<Text style={styles.label}>Host Language:</Text>
{
<Picker
selectedValue={hostLanguage}
style={{ height: 50, width: "100%" }}
onValueChange={handleHostLanguageChange}
accessibilityHint="host language"
>
{languageOptions &&
Object.entries(languageOptions).map(([key, value]) => {
return <Picker.Item label={value.name} value={value.code} />;
})}
</Picker>
}
<Text style={styles.label}>LibreTranslate Base URL:</Text>
<TextInput
style={styles.input}
value={libretranslateBaseUrl || LIBRETRANSLATE_BASE_URL}
onChangeText={handleLibretranslateBaseUrlChange}
accessibilityHint="libretranslate base url"
/>
{langServerConn &&
(langServerConn.success ? (
<Text>Success connecting to {libretranslateBaseUrl}</Text>
) : (
<Text>
Error connecting to {libretranslateBaseUrl}: {langServerConn.error}
</Text>
))}
</View>
) : (
<View>
<Text>Loading ...</Text>
</View>
);
};
// Create styles for the component
const styles = StyleSheet.create({ const styles = StyleSheet.create({
downloadButtonWrapper: {
flexDirection: "row",
},
downloadButton: {
backgroundColor: "#236b9f",
padding: 20,
margin: 10,
flex: 1,
flexDirection: "column",
alignItems: "center",
},
deleteButton: {
backgroundColor: "darkred",
flex: 1,
flexDirection: "column",
padding: 10,
margin: 10,
height: 50,
},
pauseDownloadButton: {
backgroundColor: "#444444",
padding: 10,
margin: 10,
height: 50,
},
buttonText: {
color: "#fff",
// flex: 1,
// fontSize: 16,
// alignSelf: "center",
// textAlign: "center",
// textAlignVertical: "top",
},
container: { container: {
flex: 1, flex: 1,
backgroundColor: "#fff", padding: 20,
justifyContent: "center", },
padding: "1.5%", label: {
fontSize: 16,
marginBottom: 8,
},
input: {
height: 40,
borderColor: "gray",
borderWidth: 1,
marginBottom: 20,
paddingHorizontal: 8,
}, },
}); });
// Retrieve a conf item or return the default export default SettingsComponent;
const confGet = (key: string, def: string): string => configData[key] || def;
// Store a conf item
const confSet = (key: string, value: string): void => {
configData[key] = value;
};
// Choose from a list item
const intelligence: Record<string, string> = {
L: "Low",
M: "Medium",
H: "High",
};
export default function Settings() {
// Simply pass the schema here
// It integrates in your existing `NavigationContainer` or `Screen`
const [translator, setTranslator] = useState<Translator>(new Translator("en"))
const [languages, setLanguages] = useState<language_matrix | undefined>();
const [languagesLoaded, setLanguagesLoaded] = useState<boolean>(false);
// This is the configuration schema
const settings: SettingsElement[] = [
{
label: "LibreTranslate server",
type: "string",
get: confGet.bind(null, "@ltServer", "http://localhost:5000"),
set: confSet.bind(null, "@ltServer"),
},
{
label: "Host Language",
type: "enum",
// You can override the way the value is displayed
values: ["en", "es", "fr"],
display: (v : string) => {
return longLang(v);
},
get: confGet.bind(null, "@hostLanguage", ""),
set: confSet.bind(null, "@hostLanguage"),
},
];
useEffect(() => {
const fetchData = async () => {
try {
// Replace with your actual async data fetching logic
const languages = await translator.fetchLanguages();
setLanguages(languages);
setLanguagesLoaded(true);
} catch (error) {
console.error("Error fetching data:", error);
}
};
});
return (
<NavigationContainer>
<View style={styles.container}>
<ReactNativeSettings settings={settings} />
</View>
</NavigationContainer>
);
}

42
components/TTNavStack.tsx Normal file
View File

@ -0,0 +1,42 @@
import * as React from "react";
import SettingsComponent from "@/components/Settings";
import { LanguageSelection } from "@/components/LanguageSelection";
import {
createNativeStackNavigator,
NativeStackNavigationProp,
} from "@react-navigation/native-stack";
import { useNavigation } from "@react-navigation/native";
import ConversationThread from "@/components/ConversationThread";
import { language_matrix_entry, Translator } from "@/app/i18n/api";
import { Conversation } from "@/app/lib/conversation";
import { Settings } from "@/app/lib/settings";
import { RootStackParamList } from "@/navigation.types";
const Stack = createNativeStackNavigator();
export default function TTNavStack() {
const nav = useNavigation<NativeStackNavigationProp<RootStackParamList, "Conversation">>()
async function onLangSelected(lang: language_matrix_entry) {
const settings = await Settings.getDefault();
const hostLanguage = await settings.getHostLanguage();
const conversation = new Conversation(
await Translator.getDefault(lang.code),
{ id: "host", language: hostLanguage },
{ id: "guest", language: lang.code }
);
nav.navigate("ConversationThread", { conversation });
}
return (
<Stack.Navigator initialRouteName="LanguageSelection">
<Stack.Screen name="LanguageSelection">
{(props) => (
<LanguageSelection {...props} onLangSelected={onLangSelected} />
)}
</Stack.Screen>
<Stack.Screen name="ConversationThread" component={ConversationThread} />
<Stack.Screen name="Settings" component={SettingsComponent} />
</Stack.Navigator>
);
}

View File

@ -0,0 +1,70 @@
jest.mock("@/app/i18n/api", () => require("../../__mocks__/api.ts"));
import { renderRouter } from "expo-router/testing-library";
import React from "react";
import {
act,
fireEvent,
render,
screen,
waitFor,
} from "@testing-library/react-native";
import {
NavigationContainer,
createNavigationContainerRef,
} from "@react-navigation/native";
import TTNavStack from "../TTNavStack";
import { migrateDb } from "@/app/lib/db";
describe("Navigation", () => {
beforeEach(async () => {
await migrateDb("development", "up");
// Reset the navigation state before each test
jest.useFakeTimers();
});
afterEach(async () => {
await migrateDb("development", "down");
jest.clearAllMocks();
jest.useRealTimers();
});
it("Navigates to ConversationThread on language selection", async () => {
const MockComponent = jest.fn(() => <TTNavStack />);
renderRouter(
{
index: MockComponent,
},
{
initialUrl: "/",
}
);
const languageSelectionText = await waitFor(() =>
screen.getByText(/.*I Speak French.*/i)
);
act(() => {
fireEvent.press(languageSelectionText);
});
expect(await screen.findByText("Conversation Thread")).toBeOnTheScreen();
});
it("Navigates to Settings on settings selection", async () => {
const MockComponent = jest.fn(() => <TTNavStack />);
renderRouter(
{
index: MockComponent,
},
{
initialUrl: "/",
}
);
const settingsButton = await waitFor(() =>
screen.getByText(/.*Settings.*/i)
);
fireEvent.press(settingsButton);
expect(
await waitFor(() => screen.getByText(/Settings/i))
).toBeOnTheScreen();
// expect(waitFor(() => screen.getByText(/Settings/i))).toBeTruthy()
expect(screen.getByText("Settings")).toBeOnTheScreen();
});
});

View File

@ -1,121 +1,143 @@
// import AsyncStorage from '@react-native-async-storage/async-storage'; // import AsyncStorage from '@react-native-async-storage/async-storage';
import { CachedTranslator, Translator, language_matrix_entry } from "@/app/i18n/api" import {
import { longLang } from "@/app/i18n/lang" CachedTranslator,
import React, { useEffect, useRef, useState } from "react" Translator,
import { Button, Image, ImageBackground, Pressable, StyleSheet, TouchableOpacity, View } from "react-native" language_matrix_entry,
import { Text } from 'react-native'; } from "@/app/i18n/api";
import { longLang } from "@/app/i18n/lang";
import React, { useEffect, useRef, useState } from "react";
import {
Button,
Image,
ImageBackground,
Pressable,
StyleSheet,
TouchableOpacity,
View,
} from "react-native";
import { Text } from "react-native";
import CountryFlag from "react-native-country-flag"; import CountryFlag from "react-native-country-flag";
import { chooseCountry } from '@/app/i18n/countries'; import { chooseCountry } from "@/app/i18n/countries";
type ISpeakButtonProps = { type ISpeakButtonProps = {
language: language_matrix_entry, language: language_matrix_entry;
translator?: Translator, translator?: Translator;
onLangSelected?: (lang : language_matrix_entry) => any | Promise<any>, onLangSelected?: (lang: language_matrix_entry) => any | Promise<any>;
};
function iSpeak(language: language_matrix_entry) {
return `I speak ${language.name}.`;
} }
function iSpeak(language : language_matrix_entry) { async function iSpeakTr(
return `I speak ${language.name}.` translator: CachedTranslator,
} targetLang: language_matrix_entry
) {
async function iSpeakTr(translator : CachedTranslator, targetLang : language_matrix_entry) { const sourceStr = iSpeak(targetLang);
const sourceStr = iSpeak(targetLang) return await translator.translate(sourceStr, targetLang.code);
return await translator.translate(sourceStr, targetLang.code);
} }
const DEFAULT_FLAGS = { const DEFAULT_FLAGS = {
"en": ["us", "gb"], en: ["us", "gb"],
// "sq": ["al"], // "sq": ["al"],
"ar": ["ae"], ar: ["ae"],
"es": ["es"], es: ["es"],
"pt": ["pt"], pt: ["pt"],
"ru": ["ru"], ru: ["ru"],
"it": ["it"], it: ["it"],
"ir": ["ie"], ir: ["ie"],
"sk": ["sk"], sk: ["sk"],
"ro": ["ro"], ro: ["ro"],
"ja": ["jp"], ja: ["jp"],
"ko": ["kp", "kr"], ko: ["kp", "kr"],
"el": ["gr"], el: ["gr"],
"fr": ["fr"], fr: ["fr"],
"de": ["de"], de: ["de"],
"nl": ["nl"], nl: ["nl"],
"cz": ["cz"], cz: ["cz"],
"uk": ["ua"], uk: ["ua"],
"he": ["il"], he: ["il"],
"hi": ["in"], hi: ["in"],
"gl": ["es"], gl: ["es"],
"fa": ["ir"], fa: ["ir"],
"ur": ["pk"], ur: ["pk"],
"ga": ["ie"], ga: ["ie"],
"eo": ["es"] eo: ["es"],
} };
const ISpeakButton = (props : ISpeakButtonProps) => { const ISpeakButton = (props: ISpeakButtonProps) => {
const [title, setTitle] = useState<string | undefined>();
const [titleLoaded, setTitleLoaded] = useState<boolean>(false);
const [translator, setTranslator] = useState<Translator | undefined>(
undefined
);
const [title, setTitle] = useState<string | undefined>(); useEffect(() => {
const [titleLoaded, setTitleLoaded] = useState<boolean>(false); (async function () {
const translator = props.translator || new CachedTranslator("en"); const tr = props.translator || (await CachedTranslator.getDefault());
if (!tr) {
console.error("Failed to construct cachedTranslator");
}
setTranslator(tr);
try {
// Replace with your actual async data fetching logic
const title2 = await iSpeakTr(tr, props.language);
setTitle(title2);
} catch (error) {
console.error("Error fetching data from %s: %s", tr.languageServer.baseUrl, error);
} finally {
setTitleLoaded(true);
}
})();
}, []);
useEffect(() => { const countries =
const fetchData = async () => { // @ts-ignore
try { DEFAULT_FLAGS[props.language.code] || chooseCountry(props.language.code);
// Replace with your actual async data fetching logic
const title = await iSpeakTr(translator, props.language);
setTitle(title);
} catch (error) {
console.error('Error fetching data:', error);
} finally {
setTitleLoaded(true);
}
};
fetchData(); return title ? (
}, []); <TouchableOpacity
style={styles.button}
const countries = DEFAULT_FLAGS[props.language.code] || chooseCountry(props.language.code); onPress={() =>
props.onLangSelected && props.onLangSelected(props.language)
return ( }
title ? ( >
<TouchableOpacity style={styles.button} onPress={() => props.onLangSelected && props.onLangSelected(props.language)}> <View>
<View> <View style={styles.flag}>
<View style={styles.flag}> {countries &&
{countries && countries.map((c) => {
countries.map( c => { return (
return <CountryFlag isoCode={c} size={25} key={c}/> } <CountryFlag isoCode={c} size={25} key={c} />
) );
} })}
</View> </View>
<View style={styles.iSpeak}> <View>
<Text style={styles.iSpeakText}>{ title }</Text> <Text style={styles.iSpeakText}>{title}</Text>
</View> </View>
</View> </View>
</TouchableOpacity> </TouchableOpacity>
) : ( ) : (
<Text>Loading...</Text> <Text>Loading...</Text>
) );
) };
}
const styles = StyleSheet.create({ const styles = StyleSheet.create({
button: { button: {
width: "20%", borderRadius: 10,
borderRadius: 10, borderColor: "white",
borderColor: "white", borderWidth: 1,
borderWidth: 1, borderStyle: "solid",
borderStyle: "solid", height: 110,
height: 110, width: 170,
alignSelf: "flex-start", margin: 10,
margin: 8, },
}, flag: {},
flag: { iSpeak: {
}, textAlign: "center",
iSpeak: { },
textAlign: "center", iSpeakText: {
}, textAlign: "center",
iSpeakText: { },
textAlign: "center" });
}
})
export default ISpeakButton; export default ISpeakButton;

View File

@ -9,58 +9,35 @@ type MessageProps = {
} }
const MessageBubble = (props: MessageProps) => { const MessageBubble = (props: MessageProps) => {
const [text, setText] = useState(props.message.text);
const [translatedText, setTranslatedText] = useState<string|undefined>();
const [isTranslating, setIsTranslating] = useState<boolean>(false);
useEffect(() => {
props.message.onTextUpdate = (message: Message) => {
setText(message.text);
}
props.message.onTextDone = async (message: Message) => {
setIsTranslating(true);
await props.message.translate()
}
props.message.onTranslationDone = (message: Message) => {
if (!message.translation) throw new Error("Missing translation");
setTranslatedText(message.translation);
setIsTranslating(false);
}
}, [props.message])
const spId = props.message.speaker.id
return ( return (
<SafeAreaView> <SafeAreaView>
{text && ( {props.message.text && (
<Text>{text}</Text> <Text>{props.message.text}</Text>
)} )}
{translatedText && {props.message.translation &&
<Text>{translatedText}</Text> <Text accessibilityHint="translation">{props.message.translation}</Text>
} }
</SafeAreaView> </SafeAreaView>
) )
} }
// const bubbleStyle = StyleSheet.create({ const bubbleStyle = StyleSheet.create({
// host: { host: {
// }, },
// guest: { guest: {
// }, },
// }) })
// const textStyles = StyleSheet.create({ const textStyles = StyleSheet.create({
// native: { native: {
// }, },
// translation: { translation: {
// }, },
// }); });
export default MessageBubble; export default MessageBubble;

View File

View File

@ -0,0 +1,33 @@
import { Settings } from "@/app/lib/settings"
import { WHISPER_MODELS } from "@/app/lib/whisper"
import { Picker } from "@react-native-picker/picker"
import { useEffect, useState } from "react"
import { Pressable, View } from "react-native"
const WhisperDownloader = () => {
const [whisperModel, setWhisperModel] = useState<string|undefined>();
useEffect(() => {
const settings = await Settings.getDefault();
setWhisperModel((await settings.getWhisperModel()) || "small");
}, [])
return (
<View>
<Picker
selectedValue={whisperModel || ""}
style={{ height: 50, width: "100%" }}
onValueChange={setWhisperModel}
accessibilityHint="whisper model"
>
{Object.entries(WHISPER_MODELS).map(([key, { label }]) => (
<Picker.Item key={key} label={label} value={key} />
))}
</Picker>
<WhisperDownloadButton whisperModel={whisperModel} />
<WhisperDownloadInfo whisperModel={whisperModel} />
</View>
}

View File

@ -1,12 +1,59 @@
import React, { act } from 'react'; import React, { act } from 'react';
import { render, screen } from '@testing-library/react-native' import { render, screen, waitFor } from '@testing-library/react-native'
import MessageBubble from '@/components/ui/MessageBubble'; import MessageBubble from '@/components/ui/MessageBubble';
import { Conversation, Speaker } from '@/app/lib/conversation'; import { Conversation, Speaker } from '@/app/lib/conversation';
import {Translator} from '@/app/i18n/api'; import {LanguageServer, Translator, language_matrix} from '@/app/i18n/api';
import { View } from 'react-native'; import { View } from 'react-native';
import { LIBRETRANSLATE_BASE_URL } from '@/constants/api';
jest.mock("@/app/i18n/api", () => {
class LanguageServer {
fetchLanguages = () => {
return {
"en": {
code: "en",
name: "English",
targets: [
"fr",
"es"
]
},
"fr": {
code: "fr",
name: "French",
targets: [
"en",
"es"
]
},
"es": {
code: "es",
name: "Spanish",
targets: [
"en",
"fr"
]
},
} as language_matrix
}
}
class Translator {
translate = jest.fn((text : string, target : string) => {
if (text.match(/Hello, how are you\?/i)) {
return "Hola, ¿cómo estás?"
}
return "??? Huh ???"
})
}
return {
LanguageServer,
Translator,
}
})
describe('Message Component', () => { describe('Message Component', () => {
const translator = new Translator('en', 'es'); const translator = new Translator('en', 'es', new LanguageServer(LIBRETRANSLATE_BASE_URL));
const host : Speaker = {id : "host", language : "en"} const host : Speaker = {id : "host", language : "en"}
const guest : Speaker = {id : "guest", language: "es"} const guest : Speaker = {id : "guest", language: "es"}
@ -21,8 +68,8 @@ describe('Message Component', () => {
it('renders the message text correctly', async () => { it('renders the message text correctly', async () => {
conversation.addMessage(host, "Hello, World!"); conversation.addMessage(host, "Hello, World!");
const message = conversation[0]; const message = conversation[0];
render(<View></View>); // render(<View></View>);
// render(<MessageBubble message={message} />); render(<MessageBubble message={message} />);
expect(await screen.findByText(message.text as string)).toBeOnTheScreen(); expect(await screen.findByText(message.text as string)).toBeOnTheScreen();
}); });
@ -32,7 +79,7 @@ describe('Message Component', () => {
await conversation.translateLast(); await conversation.translateLast();
render(<MessageBubble message={conversation[0]} />); render(<MessageBubble message={conversation[0]} />);
expect(await screen.findByText(translatedText)).toBeOnTheScreen(); expect(screen.getByAccessibilityHint("translation")).toBeOnTheScreen();
}); });
it('widget still renders pre-translation', async () => { it('widget still renders pre-translation', async () => {
@ -42,10 +89,8 @@ describe('Message Component', () => {
render(<MessageBubble message={conversation[0]} />); render(<MessageBubble message={conversation[0]} />);
expect(screen.getByText(text)).toBeOnTheScreen(); expect(screen.getByText(text)).toBeOnTheScreen();
// expect(screen.getByText(translatedText)).not.toBeOnTheScreen(); // expect(screen.getByText(translatedText)).not.toBeOnTheScreen();
await act(async () => { // await conversation.translateLast();
await conversation.translateLast(); // expect(await screen.findByText(text)).toBeOnTheScreen();
}); // expect(await screen.findByText(translatedText)).toBeOnTheScreen();
expect(await screen.findByText(text)).toBeOnTheScreen();
expect(await screen.findByText(translatedText)).toBeOnTheScreen();
}); });
}); });

View File

@ -0,0 +1,222 @@
import React, { Dispatch } from "react";
import { render, screen, fireEvent, act } from "@testing-library/react-native";
import SettingsComponent from "@/components/Settings";
import { language_matrix } from "@/app/i18n/api";
import { Settings } from "@/app/lib/settings";
import { getDb, migrateDb } from "@/app/lib/db";
import { Knex } from "knex";
import { WhisperFile } from "@/app/lib/whisper";
import { SQLiteDatabase } from "expo-sqlite";
const RENDER_TIME = 1000;
jest.mock("@/app/lib/whisper", () => {
const originalModule = jest.requireActual("@/app/lib/whisper");
return {
...originalModule,
WhisperFile: jest.fn().mockImplementation((tag, targetFileName, label, size) => ({
tag,
targetFileName,
label,
size,
doesTargetExist: jest.fn(),
getDownloadStatus: jest.fn(), // Mock other methods as needed
isDownloadComplete: jest.fn(() => false), // Initially assume download is not complete
createDownloadResumable: jest.fn().mockResolvedValue({
startAsync: jest.fn().mockResolvedValue({}),
}),
})),
};
});
jest.mock("expo-file-system", () => {
const originalModule = jest.requireActual("expo-file-system");
return {
...originalModule,
File: jest.fn().mockImplementation(() => ({
bytes: jest.fn(),
exists: jest.fn(),
})),
};
});
jest.mock("@/app/i18n/api", () => {
const LanguageServer = jest.fn();
const Translator = jest.fn();
// Mock the fetchLanguages method to return a predefined language matrix
LanguageServer.prototype.fetchLanguages = jest.fn(() => ({
en: {
code: "en",
name: "English",
targets: ["fr", "es"],
},
fr: {
code: "fr",
name: "French",
targets: ["en", "es"],
},
es: {
code: "es",
name: "Spanish",
targets: ["en", "fr"],
},
} as language_matrix));
// Mock the translate method
Translator.prototype.translate = jest.fn((text: string, target: string) => {
return "Hola, como estas?";
});
return {
LanguageServer,
Translator,
};
});
describe("SettingsComponent", () => {
let db: SQLiteDatabase;
let settings: Settings;
beforeEach(async () => {
db = await getDb("development");
await migrateDb("development");
settings = new Settings(db);
jest.spyOn(Settings, 'getDefault').mockResolvedValue(settings);
await settings.setHostLanguage("en");
await settings.setLibretranslateBaseUrl("https://example.com");
});
afterEach(async () => {
jest.restoreAllMocks();
await migrateDb("development", "down");
});
beforeAll(async () => {
jest.useFakeTimers();
});
afterAll(() => {
jest.useRealTimers();
});
test("renders correctly with initial settings", async () => {
render(<SettingsComponent />);
screen.debug();
// Wait for the component to fetch and display the initial settings
await screen.findByText(/Host Language:/i);
await screen.findByText(/LibreTranslate Base URL:/i);
// expect(screen.getByDisplayValue("English")).toBeTruthy();
expect(
screen.getByAccessibilityHint("libretranslate base url")
).toBeTruthy();
});
test("updates host language setting when input changes", async () => {
render(<SettingsComponent />);
// Wait for the component to fetch and display the initial settings
await screen.findByText(/Host Language:/i);
await screen.findByText(/LibreTranslate Base URL:/i);
// Change the host language input value
const picker = screen.getByAccessibilityHint("host language");
fireEvent(picker, "onvalueChange", "es");
expect(picker.props.selectedIndex).toStrictEqual(0);
});
test("updates LibreTranslate base URL setting when input changes", async () => {
render(<SettingsComponent />);
jest.advanceTimersByTime(RENDER_TIME);
screen.debug();
// Wait for the component to fetch and display the initial settings
await screen.findByText(/Host Language:/i);
await screen.findByText(/LibreTranslate Base URL:/i);
// Change the LibreTranslate base URL input value
fireEvent.changeText(
screen.getByAccessibilityHint("libretranslate base url"),
"http://new-example.com"
);
jest.advanceTimersByTime(RENDER_TIME);
expect(
screen.getByAccessibilityHint("libretranslate base url")
).toBeTruthy();
});
describe("Download Whisper Model", () => {
it("should trigger download when model is not present", async () => {
const whisperFile = new WhisperFile("small");
(whisperFile.doesTargetExist as jest.Mock).mockResolvedValue(false);
render(<SettingsComponent />);
await screen.findByText(/\s*Download Small\s*/i);
// Assuming there's a button or trigger to start download
act(() => {
fireEvent.press(screen.getByText(/\s*Download Small\s*/i));
})
expect(whisperFile.createDownloadResumable).toHaveBeenCalled();
});
it("should show progress when download is in progress", async () => {
const whisperFile = new WhisperFile("small");
(whisperFile.doesTargetExist as jest.Mock).mockResolvedValue(false);
(whisperFile.getDownloadStatus as jest.Mock).mockResolvedValue({
doesTargetExist: false,
isDownloadComplete: false,
hasDownloadStarted: true,
progress: {
current: 1024,
total: 2048,
remaining: 1024,
percentRemaining: 50,
},
});
render(<SettingsComponent />);
await screen.findByText(/Host Language:/i);
fireEvent.press(screen.getByText(/Download Model/i));
expect(await screen.findByText("50%")).toBeTruthy();
});
it("should indicate download is complete", async () => {
const whisperFile = new WhisperFile("small");
(whisperFile.doesTargetExist as jest.Mock).mockResolvedValue(false);
(whisperFile.getDownloadStatus as jest.Mock)
.mockResolvedValueOnce({
doesTargetExist: false,
isDownloadComplete: false,
hasDownloadStarted: true,
progress: {
current: 1024,
total: 2048,
remaining: 1024,
percentRemaining: 50,
},
})
.mockResolvedValueOnce({
doesTargetExist: true,
isDownloadComplete: true,
hasDownloadStarted: false,
progress: undefined,
});
render(<SettingsComponent />);
await screen.findByText(/Host Language:/i);
fireEvent.press(screen.getByText(/Download Model/i));
expect(await screen.findByText("Download Complete")).toBeTruthy();
});
});
});

15
file.ts Normal file
View File

@ -0,0 +1,15 @@
interface Settings {
host_language: string;
libretranslate_base_url: string;
ui_direction: number;
whisper_model: string;
}
interface WhisperModel {
model: string;
download_status: boolean;
expected_size: number;
last_hash: string;
bytes_done: string;
bytes_total: string;
}

View File

@ -1,24 +1,130 @@
// jestSetup.ts // jestSetup.ts
jest.mock('expo-sqlite', () => { // include this line for mocking react-native-gesture-handler
return { import 'react-native-gesture-handler/jestSetup';
openDatabaseAsync: async (name: string) => {
const {DatabaseSync} = require("node:sqlite")
const db = new DatabaseSync(':memory:');
return { jest.mock("expo-sqlite", () => {
closeAsync: jest.fn(() => db.close()), const { DatabaseSync } = require("node:sqlite");
executeSql: jest.fn((sql: string) => db.exec(sql)), const db = new DatabaseSync(":memory:");
runAsync: jest.fn(async (sql: string, params = []) => {
const stmt = db.prepare(sql); const { MIGRATE_UP } = jest.requireActual("./app/lib/migrations");
stmt.run(params)
}), const genericRun = (sql: string, ... params : string []) => {
getFirstAsync: jest.fn(async (sql : string, params = []) => { // console.log("Running %s with %s", sql, params);
const stmt = db.prepare(sql) try {
const result = stmt.run(params); const stmt = db.prepare(sql);
return stmt.all(params)[0] stmt.run(...params);
}) } catch (e) {
}; throw new Error(
}, `running ${sql} with params ${JSON.stringify(params)}: ${e}`
);
}
}
const genericGetFirst = (sql: string, params = []) => {
const stmt = db.prepare(sql);
// const result = stmt.run(...params);
return stmt.get(params);
};
const openDatabaseAsync = async (name: string) => {
return {
closeAsync: jest.fn(() => db.close()),
executeSql: jest.fn((sql: string) => db.exec(sql)),
runAsync: jest.fn(genericRun),
runSync: jest.fn(genericRun),
getFirstAsync: jest.fn(genericGetFirst),
getFirstSync: jest.fn(genericGetFirst),
}; };
};
return {
migrateDb: async (direction: "up" | "down" = "up") => {
const db = await openDatabaseAsync("translation_terrace_development");
for (let m of Object.values(MIGRATE_UP)) {
for (let stmt of m) {
await db.executeSql(stmt);
}
}
},
openDatabaseAsync,
};
}); });
// include this section and the NativeAnimatedHelper section for mocking react-native-reanimated
jest.mock('react-native-reanimated', () => {
const Reanimated = require('react-native-reanimated/mock');
// The mock for `call` immediately calls the callback which is incorrect
// So we override it with a no-op
Reanimated.default.call = () => {};
return Reanimated;
});
// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
// jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
// Mock implementation of the Settings class for Jest
// Mock implementation of the Settings class
jest.mock('@/app/lib/settings', () => {
const originalModule = jest.requireActual('@/app/lib/settings');
class MockSettings extends originalModule.Settings {
constructor(db: any) {
super(db);
}
private getValue(key: string) {
// Return mock values for testing
switch (key) {
case "host_language":
return "en";
case "libretranslate_base_url":
return "http://mock.libretranslate.com";
case 'ui_direction':
return "ltr";
case "whisper_model":
return "base";
default:
throw new Error(`Invalid setting: '${key}'`);
}
}
private setValue(key: string, value: any) {
// Mock setting values
console.log(`Mock set ${key} to ${value}`);
}
static getDefault() {
const mockDb = { // Mock database object
select: jest.fn().mockReturnThis(),
limit: jest.fn().mockReturnThis(),
first: jest.fn().mockResolvedValue({ host_language: "en" }),
update: jest.fn().mockResolvedValue(1),
insert: jest.fn().mockResolvedValue([1])
};
return new MockSettings(mockDb);
}
}
return {
__esModule: true,
...originalModule,
default: MockSettings
};
});
jest.mock('expo-file-system', () => ({
// ... other methods ...
createDownloadResumable: jest.fn(() => ({
downloadAsync: jest.fn(() => Promise.resolve({ uri: 'mocked-uri' })),
pauseAsync: jest.fn(() => Promise.resolve()),
resumeAsync: jest.fn(() => Promise.resolve()),
cancelAsync: jest.fn(() => Promise.resolve()),
})),
getInfoAsync: jest.fn(() => ({
exists: () => false,
}))
// ... other methods ...
}));

37
knexfile.ts Normal file
View File

@ -0,0 +1,37 @@
// import type { Knex } from "knex";
import ExpoSQLiteDialect from "@expo/knex-expo-sqlite-dialect";
import {Knex} from "knex"
const EXPO_CONFIG = {
client: ExpoSQLiteDialect,
connection: {
filename: "translation_terrace.db",
},
};
// Update with your config settings.
export default {
development: {
...EXPO_CONFIG,
client: "sqlite3"
},
staging: {
...EXPO_CONFIG,
migrations: {
tableName: "knex_migrations",
},
},
production: {
...EXPO_CONFIG,
migrations: {
tableName: "knex_migrations",
},
},
} as {
development: Knex.Config,
staging: Knex.Config,
production: Knex.Config,
};

Submodule langs-flags-list deleted from f888fb8e1b

View File

@ -0,0 +1,27 @@
import type { Knex } from "knex";
export async function up(knex: Knex): Promise<void> {
await knex.schema.createTable("settings", (table) => {
table.string("host_language");
table.string("libretranslate_base_url");
table.integer("ui_direction");
table.string("whisper_model");
});
await knex.schema.createTable("whisper_models", (table) => {
table.string("model");
table.boolean("download_status");
table.integer("expected_size");
table.text("last_hash"),
table.string("bytes_done");
table.string("bytes_total");
});
}
export async function down(knex: Knex): Promise<void> {
await knex.schema.dropTable("whisper_models");
await knex.schema.dropTable("settings");
}

11
navigation.types.ts Normal file
View File

@ -0,0 +1,11 @@
// navigation.types.ts
import { ParamListBase } from '@react-navigation/native';
import { Conversation } from '@/app/lib/conversation';
export type RootStackParamList = {
LanguageSelection: undefined;
ConversationThread: undefined;
Settings: undefined;
Conversation: { conversation?: Conversation };
};

2784
package-lock.json generated
View File

@ -9,29 +9,37 @@
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.26.7", "@babel/runtime": "^7.26.7",
"@expo/knex-expo-sqlite-dialect": "^0.0.1",
"@expo/vector-icons": "^14.0.4", "@expo/vector-icons": "^14.0.4",
"@mmomtchev/react-native-settings": "^1.1.0", "@mmomtchev/react-native-settings": "^1.1.0",
"@react-native-async-storage/async-storage": "^2.1.0", "@react-native-async-storage/async-storage": "^2.1.0",
"@react-native-picker/picker": "^2.11.0",
"@react-navigation/bottom-tabs": "^7.2.0", "@react-navigation/bottom-tabs": "^7.2.0",
"@react-navigation/native": "^7.0.14",
"@react-navigation/native-stack": "^7.2.0", "@react-navigation/native-stack": "^7.2.0",
"expo": "~52.0.28", "expo": "~52.0.28",
"expo-audio": "~0.3.4",
"expo-background-fetch": "~13.0.5",
"expo-blur": "~14.0.3", "expo-blur": "~14.0.3",
"expo-constants": "~17.0.5", "expo-constants": "~17.0.6",
"expo-crypto": "~14.0.2",
"expo-device": "~7.0.2",
"expo-file-system": "^18.0.10",
"expo-font": "~13.0.3", "expo-font": "~13.0.3",
"expo-haptics": "~14.0.1", "expo-haptics": "~14.0.1",
"expo-linking": "~7.0.5", "expo-linking": "~7.0.5",
"expo-notifications": "~0.29.13",
"expo-router": "~4.0.17", "expo-router": "~4.0.17",
"expo-screen-orientation": "~8.0.4", "expo-screen-orientation": "~8.0.4",
"expo-sharing": "^13.0.1",
"expo-splash-screen": "~0.29.21", "expo-splash-screen": "~0.29.21",
"expo-sqlite": "~15.1.2", "expo-sqlite": "^15.1.2",
"expo-status-bar": "~2.0.1", "expo-status-bar": "~2.0.1",
"expo-symbols": "~0.2.2", "expo-symbols": "~0.2.2",
"expo-system-ui": "~4.0.7", "expo-system-ui": "~4.0.7",
"expo-web-browser": "~14.0.2", "expo-web-browser": "~14.0.2",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-native": "0.76.6", "react-native": "^0.76.7",
"react-native-cache": "^2.0.3", "react-native-cache": "^2.0.3",
"react-native-country-flag": "^2.0.2", "react-native-country-flag": "^2.0.2",
"react-native-gesture-handler": "~2.20.2", "react-native-gesture-handler": "~2.20.2",
@ -42,23 +50,31 @@
"react-native-sqlite-storage": "^6.0.1", "react-native-sqlite-storage": "^6.0.1",
"react-native-web": "~0.19.13", "react-native-web": "~0.19.13",
"react-native-webview": "13.12.5", "react-native-webview": "13.12.5",
"readable-stream": "^4.7.0",
"sqlite": "^5.1.1",
"sqlite3": "^5.1.7",
"whisper.rn": "^0.3.9" "whisper.rn": "^0.3.9"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.26.7", "@babel/core": "^7.26.7",
"@babel/preset-typescript": "^7.26.0", "@babel/preset-typescript": "^7.26.0",
"@jest/globals": "^29.7.0", "@jest/globals": "^29.7.0",
"@react-navigation/native": "^7.0.14",
"@react-navigation/stack": "^7.1.1",
"@testing-library/react-native": "^13.0.1", "@testing-library/react-native": "^13.0.1",
"@types/jest": "^29.5.14", "@types/jest": "^29.5.14",
"@types/react": "~18.3.18", "@types/react": "~18.3.18",
"@types/react-native-sqlite-storage": "^6.0.5", "@types/react-native-sqlite-storage": "^6.0.5",
"@types/react-navigation": "^3.0.8",
"@types/react-test-renderer": "^18.3.1", "@types/react-test-renderer": "^18.3.1",
"@types/readable-stream": "^4.0.18",
"babel-jest": "^29.7.0", "babel-jest": "^29.7.0",
"babel-plugin-module-resolver": "^5.0.2", "babel-plugin-module-resolver": "^5.0.2",
"expo": "~52.0.28", "expo": "~52.0.28",
"expo-sqlite-mock": "^2.0.1", "expo-sqlite-mock": "^2.0.1",
"jest": "^29.7.0", "jest": "^29.7.0",
"jest-expo": "~52.0.3", "jest-expo": "~52.0.3",
"knex": "^3.1.0",
"metro-react-native-babel-preset": "^0.77.0", "metro-react-native-babel-preset": "^0.77.0",
"react-test-renderer": "18.3.1", "react-test-renderer": "18.3.1",
"ts-jest": "^29.2.5", "ts-jest": "^29.2.5",
@ -147,13 +163,13 @@
} }
}, },
"node_modules/@babel/generator": { "node_modules/@babel/generator": {
"version": "7.26.8", "version": "7.26.9",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.8.tgz", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz",
"integrity": "sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA==", "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/parser": "^7.26.8", "@babel/parser": "^7.26.9",
"@babel/types": "^7.26.8", "@babel/types": "^7.26.9",
"@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25", "@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^3.0.2" "jsesc": "^3.0.2"
@ -509,12 +525,12 @@
} }
}, },
"node_modules/@babel/parser": { "node_modules/@babel/parser": {
"version": "7.26.8", "version": "7.26.9",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.8.tgz", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz",
"integrity": "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==", "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/types": "^7.26.8" "@babel/types": "^7.26.9"
}, },
"bin": { "bin": {
"parser": "bin/babel-parser.js" "parser": "bin/babel-parser.js"
@ -2274,14 +2290,14 @@
} }
}, },
"node_modules/@babel/template": { "node_modules/@babel/template": {
"version": "7.26.8", "version": "7.26.9",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.8.tgz", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz",
"integrity": "sha512-iNKaX3ZebKIsCvJ+0jd6embf+Aulaa3vNBqZ41kM7iTWjx5qzWKXGHiJUW3+nTpQ18SG11hdF8OAzKrpXkb96Q==", "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/code-frame": "^7.26.2", "@babel/code-frame": "^7.26.2",
"@babel/parser": "^7.26.8", "@babel/parser": "^7.26.9",
"@babel/types": "^7.26.8" "@babel/types": "^7.26.9"
}, },
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
@ -2307,16 +2323,16 @@
}, },
"node_modules/@babel/traverse--for-generate-function-map": { "node_modules/@babel/traverse--for-generate-function-map": {
"name": "@babel/traverse", "name": "@babel/traverse",
"version": "7.26.8", "version": "7.26.9",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.8.tgz", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz",
"integrity": "sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA==", "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/code-frame": "^7.26.2", "@babel/code-frame": "^7.26.2",
"@babel/generator": "^7.26.8", "@babel/generator": "^7.26.9",
"@babel/parser": "^7.26.8", "@babel/parser": "^7.26.9",
"@babel/template": "^7.26.8", "@babel/template": "^7.26.9",
"@babel/types": "^7.26.8", "@babel/types": "^7.26.9",
"debug": "^4.3.1", "debug": "^4.3.1",
"globals": "^11.1.0" "globals": "^11.1.0"
}, },
@ -2325,9 +2341,9 @@
} }
}, },
"node_modules/@babel/types": { "node_modules/@babel/types": {
"version": "7.26.8", "version": "7.26.9",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.8.tgz", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz",
"integrity": "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==", "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/helper-string-parser": "^7.25.9", "@babel/helper-string-parser": "^7.25.9",
@ -2518,15 +2534,15 @@
} }
}, },
"node_modules/@expo/config": { "node_modules/@expo/config": {
"version": "10.0.8", "version": "10.0.10",
"resolved": "https://registry.npmjs.org/@expo/config/-/config-10.0.8.tgz", "resolved": "https://registry.npmjs.org/@expo/config/-/config-10.0.10.tgz",
"integrity": "sha512-RaKwi8e6PbkMilRexdsxObLMdQwxhY6mlgel+l/eW+IfIw8HEydSU0ERlzYUjlGJxHLHUXe4rC2vw8FEvaowyQ==", "integrity": "sha512-wI9/iam3Irk99ADGM/FyD7YrrEibIZXR4huSZiU5zt9o3dASOKhqepiNJex4YPiktLfKhYrpSEJtwno1g0SrgA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/code-frame": "~7.10.4", "@babel/code-frame": "~7.10.4",
"@expo/config-plugins": "~9.0.14", "@expo/config-plugins": "~9.0.15",
"@expo/config-types": "^52.0.3", "@expo/config-types": "^52.0.4",
"@expo/json-file": "^9.0.1", "@expo/json-file": "^9.0.2",
"deepmerge": "^4.3.1", "deepmerge": "^4.3.1",
"getenv": "^1.0.0", "getenv": "^1.0.0",
"glob": "^10.4.2", "glob": "^10.4.2",
@ -2928,9 +2944,9 @@
} }
}, },
"node_modules/@expo/json-file": { "node_modules/@expo/json-file": {
"version": "9.0.1", "version": "9.0.2",
"resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-9.0.1.tgz", "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-9.0.2.tgz",
"integrity": "sha512-ZVPhbbEBEwafPCJ0+kI25O2Iivt3XKHEKAADCml1q2cmOIbQnKgLyn8DpOJXqWEyRQr/VWS+hflBh8DU2YFSqg==", "integrity": "sha512-yAznIUrybOIWp3Uax7yRflB0xsEpvIwIEqIjao9SGi2Gaa+N0OamWfe0fnXBSWF+2zzF4VvqwT4W5zwelchfgw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/code-frame": "~7.10.4", "@babel/code-frame": "~7.10.4",
@ -2958,6 +2974,26 @@
"signal-exit": "^3.0.2" "signal-exit": "^3.0.2"
} }
}, },
"node_modules/@expo/knex-expo-sqlite-dialect": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/@expo/knex-expo-sqlite-dialect/-/knex-expo-sqlite-dialect-0.0.1.tgz",
"integrity": "sha512-nCSBIW3uZqQiK/HyoXTJnuxUGxcM5ayYxppwMECGCQ90ouiTkboGFoS6nRzIIqwhvb41vsdikE0m6C9IWdcTig==",
"license": "MIT",
"dependencies": {
"assert": "^2.1.0",
"babel-plugin-module-resolver": "^5.0.0",
"crypto-browserify": "^3.12.0",
"events": "^3.3.0",
"node-libs-browser": "^2.2.1",
"stream-browserify": "^3.0.0",
"timers-browserify": "^2.0.12",
"tty-browserify": "^0.0.1"
},
"peerDependencies": {
"expo-sqlite": "*",
"knex": "*"
}
},
"node_modules/@expo/metro-config": { "node_modules/@expo/metro-config": {
"version": "0.19.9", "version": "0.19.9",
"resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.19.9.tgz", "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.19.9.tgz",
@ -3387,6 +3423,19 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/@gar/promisify": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
"integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
"license": "MIT",
"optional": true
},
"node_modules/@ide/backoff": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@ide/backoff/-/backoff-1.0.0.tgz",
"integrity": "sha512-F0YfUDjvT+Mtt/R4xdl2X0EYCHMMiJqNLdxHD++jDT5ydEFIyqbCHh51Qx2E211dgZprPKhV7sHmnXKpLuvc5g==",
"license": "MIT"
},
"node_modules/@isaacs/cliui": { "node_modules/@isaacs/cliui": {
"version": "8.0.2", "version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@ -3998,6 +4047,34 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/@npmcli/move-file": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
"integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
"deprecated": "This functionality has been moved to @npmcli/fs",
"license": "MIT",
"optional": true,
"dependencies": {
"mkdirp": "^1.0.4",
"rimraf": "^3.0.2"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@npmcli/move-file/node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"license": "MIT",
"optional": true,
"bin": {
"mkdirp": "bin/cmd.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@pkgjs/parseargs": { "node_modules/@pkgjs/parseargs": {
"version": "0.11.0", "version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@ -4045,10 +4122,23 @@
"react-native": "^0.0.0-0 || >=0.65 <1.0" "react-native": "^0.0.0-0 || >=0.65 <1.0"
} }
}, },
"node_modules/@react-native-picker/picker": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@react-native-picker/picker/-/picker-2.11.0.tgz",
"integrity": "sha512-QuZU6gbxmOID5zZgd/H90NgBnbJ3VV6qVzp6c7/dDrmWdX8S0X5YFYgDcQFjE3dRen9wB9FWnj2VVdPU64adSg==",
"license": "MIT",
"workspaces": [
"example"
],
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/@react-native/assets-registry": { "node_modules/@react-native/assets-registry": {
"version": "0.76.6", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.76.6.tgz", "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.76.7.tgz",
"integrity": "sha512-YI8HoReYiIwdFQs+k9Q9qpFTnsyYikZxgs/UVtVbhKixXDQF6F9LLvj2naOx4cfV+RGybNKxwmDl1vUok/dRFQ==", "integrity": "sha512-o79whsqL5fbPTUQO9w1FptRd4cw1TaeOrXtQSLQeDrMVAenw/wmsjyPK10VKtvqxa1KNMtWEyfgxcM8CVZVFmg==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=18" "node": ">=18"
@ -4169,13 +4259,13 @@
} }
}, },
"node_modules/@react-native/community-cli-plugin": { "node_modules/@react-native/community-cli-plugin": {
"version": "0.76.6", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.76.6.tgz", "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.76.7.tgz",
"integrity": "sha512-nETlc/+U5cESVluzzgN0OcVfcoMijGBaDWzOaJhoYUodcuqnqtu75XsSEc7yzlYjwNQG+vF83mu9CQGezruNMA==", "integrity": "sha512-lrcsY2WPLCEWU1pjdNV9+Ccj8vCEwCCURZiPa5aqi7lKB4C++1hPrxA8/CWWnTNcQp76DsBKGYqTFj7Ud4aupw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@react-native/dev-middleware": "0.76.6", "@react-native/dev-middleware": "0.76.7",
"@react-native/metro-babel-transformer": "0.76.6", "@react-native/metro-babel-transformer": "0.76.7",
"chalk": "^4.0.0", "chalk": "^4.0.0",
"execa": "^5.1.1", "execa": "^5.1.1",
"invariant": "^2.2.4", "invariant": "^2.2.4",
@ -4198,46 +4288,6 @@
} }
} }
}, },
"node_modules/@react-native/community-cli-plugin/node_modules/@react-native/debugger-frontend": {
"version": "0.76.6",
"resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.76.6.tgz",
"integrity": "sha512-kP97xMQjiANi5/lmf8MakS7d8FTJl+BqYHQMqyvNiY+eeWyKnhqW2GL2v3eEUBAuyPBgJGivuuO4RvjZujduJg==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=18"
}
},
"node_modules/@react-native/community-cli-plugin/node_modules/@react-native/dev-middleware": {
"version": "0.76.6",
"resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.76.6.tgz",
"integrity": "sha512-1bAyd2/X48Nzb45s5l2omM75vy764odx/UnDs4sJfFCuK+cupU4nRPgl0XWIqgdM/2+fbQ3E4QsVS/WIKTFxvQ==",
"license": "MIT",
"dependencies": {
"@isaacs/ttlcache": "^1.4.1",
"@react-native/debugger-frontend": "0.76.6",
"chrome-launcher": "^0.15.2",
"chromium-edge-launcher": "^0.2.0",
"connect": "^3.6.5",
"debug": "^2.2.0",
"nullthrows": "^1.1.1",
"open": "^7.0.3",
"selfsigned": "^2.4.1",
"serve-static": "^1.13.1",
"ws": "^6.2.3"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@react-native/community-cli-plugin/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/@react-native/community-cli-plugin/node_modules/execa": { "node_modules/@react-native/community-cli-plugin/node_modules/execa": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
@ -4294,12 +4344,6 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/@react-native/community-cli-plugin/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT"
},
"node_modules/@react-native/community-cli-plugin/node_modules/npm-run-path": { "node_modules/@react-native/community-cli-plugin/node_modules/npm-run-path": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
@ -4339,15 +4383,6 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/@react-native/community-cli-plugin/node_modules/ws": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
"integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
"license": "MIT",
"dependencies": {
"async-limiter": "~1.0.0"
}
},
"node_modules/@react-native/debugger-frontend": { "node_modules/@react-native/debugger-frontend": {
"version": "0.76.7", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.76.7.tgz", "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.76.7.tgz",
@ -4405,31 +4440,31 @@
} }
}, },
"node_modules/@react-native/gradle-plugin": { "node_modules/@react-native/gradle-plugin": {
"version": "0.76.6", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.76.6.tgz", "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.76.7.tgz",
"integrity": "sha512-sDzpf4eiynryoS6bpYCweGoxSmWgCSx9lzBoxIIW+S6siyGiTaffzZHWCm8mIn9UZsSPlEO37q62ggnR9Zu/OA==", "integrity": "sha512-gQI6RcrJbigU8xk7F960C5xQIgvbBj20TUvGecD+N2PHfbLpqR+92cj7hz3UcbrCONmTP40WHnbMMJ8P+kLsrA==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=18" "node": ">=18"
} }
}, },
"node_modules/@react-native/js-polyfills": { "node_modules/@react-native/js-polyfills": {
"version": "0.76.6", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.76.6.tgz", "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.76.7.tgz",
"integrity": "sha512-cDD7FynxWYxHkErZzAJtzPGhJ13JdOgL+R0riTh0hCovOfIUz9ItffdLQv2nx48lnvMTQ+HZXMnGOZnsFCNzQw==", "integrity": "sha512-+iEikj6c6Zvrg1c3cYMeiPB+5nS8EaIC3jCtP6Muk3qc7c386IymEPM2xycIlfg04DPZvO3D4P2/vaO9/TCnUg==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=18" "node": ">=18"
} }
}, },
"node_modules/@react-native/metro-babel-transformer": { "node_modules/@react-native/metro-babel-transformer": {
"version": "0.76.6", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.76.6.tgz", "resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.76.7.tgz",
"integrity": "sha512-xSBi9jPliThu5HRSJvluqUlDOLLEmf34zY/U7RDDjEbZqC0ufPcPS7c5XsSg0GDPiXc7lgjBVesPZsKFkoIBgA==", "integrity": "sha512-jDS1wR7q46xY5ah+jF714Mvss9l7+lmwW/tplahZgLKozkYDC8Td5o9TOCgKlv18acw9H1V7zv8ivuRSj8ICPg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.25.2",
"@react-native/babel-preset": "0.76.6", "@react-native/babel-preset": "0.76.7",
"hermes-parser": "0.23.1", "hermes-parser": "0.23.1",
"nullthrows": "^1.1.1" "nullthrows": "^1.1.1"
}, },
@ -4440,120 +4475,6 @@
"@babel/core": "*" "@babel/core": "*"
} }
}, },
"node_modules/@react-native/metro-babel-transformer/node_modules/@react-native/babel-plugin-codegen": {
"version": "0.76.6",
"resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.76.6.tgz",
"integrity": "sha512-yFC9I/aDBOBz3ZMlqKn2NY/mDUtCksUNZ7AQmBiTAeVTUP0ujEjE0hTOx5Qd+kok7A7hwZEX87HdSgjiJZfr5g==",
"license": "MIT",
"dependencies": {
"@react-native/codegen": "0.76.6"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@react-native/metro-babel-transformer/node_modules/@react-native/babel-preset": {
"version": "0.76.6",
"resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.76.6.tgz",
"integrity": "sha512-ojlVWY6S/VE/nb9hIRetPMTsW9ZmGb2R3dnToEXAtQQDz41eHMHXbkw/k2h0THp6qhas25ruNvn3N5n2o+lBzg==",
"license": "MIT",
"dependencies": {
"@babel/core": "^7.25.2",
"@babel/plugin-proposal-export-default-from": "^7.24.7",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-export-default-from": "^7.24.7",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
"@babel/plugin-syntax-optional-chaining": "^7.8.3",
"@babel/plugin-transform-arrow-functions": "^7.24.7",
"@babel/plugin-transform-async-generator-functions": "^7.25.4",
"@babel/plugin-transform-async-to-generator": "^7.24.7",
"@babel/plugin-transform-block-scoping": "^7.25.0",
"@babel/plugin-transform-class-properties": "^7.25.4",
"@babel/plugin-transform-classes": "^7.25.4",
"@babel/plugin-transform-computed-properties": "^7.24.7",
"@babel/plugin-transform-destructuring": "^7.24.8",
"@babel/plugin-transform-flow-strip-types": "^7.25.2",
"@babel/plugin-transform-for-of": "^7.24.7",
"@babel/plugin-transform-function-name": "^7.25.1",
"@babel/plugin-transform-literals": "^7.25.2",
"@babel/plugin-transform-logical-assignment-operators": "^7.24.7",
"@babel/plugin-transform-modules-commonjs": "^7.24.8",
"@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7",
"@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7",
"@babel/plugin-transform-numeric-separator": "^7.24.7",
"@babel/plugin-transform-object-rest-spread": "^7.24.7",
"@babel/plugin-transform-optional-catch-binding": "^7.24.7",
"@babel/plugin-transform-optional-chaining": "^7.24.8",
"@babel/plugin-transform-parameters": "^7.24.7",
"@babel/plugin-transform-private-methods": "^7.24.7",
"@babel/plugin-transform-private-property-in-object": "^7.24.7",
"@babel/plugin-transform-react-display-name": "^7.24.7",
"@babel/plugin-transform-react-jsx": "^7.25.2",
"@babel/plugin-transform-react-jsx-self": "^7.24.7",
"@babel/plugin-transform-react-jsx-source": "^7.24.7",
"@babel/plugin-transform-regenerator": "^7.24.7",
"@babel/plugin-transform-runtime": "^7.24.7",
"@babel/plugin-transform-shorthand-properties": "^7.24.7",
"@babel/plugin-transform-spread": "^7.24.7",
"@babel/plugin-transform-sticky-regex": "^7.24.7",
"@babel/plugin-transform-typescript": "^7.25.2",
"@babel/plugin-transform-unicode-regex": "^7.24.7",
"@babel/template": "^7.25.0",
"@react-native/babel-plugin-codegen": "0.76.6",
"babel-plugin-syntax-hermes-parser": "^0.25.1",
"babel-plugin-transform-flow-enums": "^0.0.2",
"react-refresh": "^0.14.0"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@babel/core": "*"
}
},
"node_modules/@react-native/metro-babel-transformer/node_modules/@react-native/codegen": {
"version": "0.76.6",
"resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.76.6.tgz",
"integrity": "sha512-BABb3e5G/+hyQYEYi0AODWh2km2d8ERoASZr6Hv90pVXdUHRYR+yxCatX7vSd9rnDUYndqRTzD0hZWAucPNAKg==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.25.3",
"glob": "^7.1.1",
"hermes-parser": "0.23.1",
"invariant": "^2.2.4",
"jscodeshift": "^0.14.0",
"mkdirp": "^0.5.1",
"nullthrows": "^1.1.1",
"yargs": "^17.6.2"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@babel/preset-env": "^7.1.6"
}
},
"node_modules/@react-native/metro-babel-transformer/node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@react-native/normalize-colors": { "node_modules/@react-native/normalize-colors": {
"version": "0.76.7", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.76.7.tgz", "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.76.7.tgz",
@ -4561,9 +4482,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@react-native/virtualized-lists": { "node_modules/@react-native/virtualized-lists": {
"version": "0.76.6", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.76.6.tgz", "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.76.7.tgz",
"integrity": "sha512-0HUWVwJbRq1BWFOu11eOWGTSmK9nMHhoMPyoI27wyWcl/nqUx7HOxMbRVq0DsTCyATSMPeF+vZ6o1REapcNWKw==", "integrity": "sha512-pRUf1jUO8H9Ft04CaWv76t34QI9wY0sydoYlIwEtqXjjMJgmgDoOCAWBjArgn2mk8/rK+u/uicI67ZCYCp1pJw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"invariant": "^2.2.4", "invariant": "^2.2.4",
@ -4682,6 +4603,25 @@
"nanoid": "3.3.8" "nanoid": "3.3.8"
} }
}, },
"node_modules/@react-navigation/stack": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-7.1.1.tgz",
"integrity": "sha512-CBTKQlIkELp05zRiTAv5Pa7OMuCpKyBXcdB3PGMN2Mm55/5MkDsA1IaZorp/6TsVCdllITD6aTbGX/HA/88A6w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@react-navigation/elements": "^2.2.5",
"color": "^4.2.3"
},
"peerDependencies": {
"@react-navigation/native": "^7.0.14",
"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/@remix-run/node": { "node_modules/@remix-run/node": {
"version": "2.15.3", "version": "2.15.3",
"resolved": "https://registry.npmjs.org/@remix-run/node/-/node-2.15.3.tgz", "resolved": "https://registry.npmjs.org/@remix-run/node/-/node-2.15.3.tgz",
@ -5056,6 +4996,17 @@
"csstype": "^3.0.2" "csstype": "^3.0.2"
} }
}, },
"node_modules/@types/react-native": {
"version": "0.72.8",
"resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.72.8.tgz",
"integrity": "sha512-St6xA7+EoHN5mEYfdWnfYt0e8u6k2FR0P9s2arYgakQGFgU1f9FlPrIEcj0X24pLCF5c5i3WVuLCUdiCYHmOoA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@react-native/virtualized-lists": "^0.72.4",
"@types/react": "*"
}
},
"node_modules/@types/react-native-sqlite-storage": { "node_modules/@types/react-native-sqlite-storage": {
"version": "6.0.5", "version": "6.0.5",
"resolved": "https://registry.npmjs.org/@types/react-native-sqlite-storage/-/react-native-sqlite-storage-6.0.5.tgz", "resolved": "https://registry.npmjs.org/@types/react-native-sqlite-storage/-/react-native-sqlite-storage-6.0.5.tgz",
@ -5063,6 +5014,31 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/react-native/node_modules/@react-native/virtualized-lists": {
"version": "0.72.8",
"resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.72.8.tgz",
"integrity": "sha512-J3Q4Bkuo99k7mu+jPS9gSUSgq+lLRSI/+ahXNwV92XgJ/8UgOTxu2LPwhJnBk/sQKxq7E8WkZBnBiozukQMqrw==",
"dev": true,
"license": "MIT",
"dependencies": {
"invariant": "^2.2.4",
"nullthrows": "^1.1.1"
},
"peerDependencies": {
"react-native": "*"
}
},
"node_modules/@types/react-navigation": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/@types/react-navigation/-/react-navigation-3.0.8.tgz",
"integrity": "sha512-r8UQvBmOz7XjPE8AHTHh0SThGqModhQtSsntkmob7rczhueJIqDwBOgsEn54SJa25XzD/KBlelAWeVZ7+Ggm8A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/react": "*",
"@types/react-native": "*"
}
},
"node_modules/@types/react-test-renderer": { "node_modules/@types/react-test-renderer": {
"version": "18.3.1", "version": "18.3.1",
"resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.3.1.tgz", "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.3.1.tgz",
@ -5073,6 +5049,24 @@
"@types/react": "^18" "@types/react": "^18"
} }
}, },
"node_modules/@types/readable-stream": {
"version": "4.0.18",
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.18.tgz",
"integrity": "sha512-21jK/1j+Wg+7jVw1xnSwy/2Q1VgVjWuFssbYGTREPUBeZ+rqVFl2udq0IkxzPC0ZhOzVceUbyIACFZKLqKEBlA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*",
"safe-buffer": "~5.1.1"
}
},
"node_modules/@types/readable-stream/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/stack-utils": { "node_modules/@types/stack-utils": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
@ -5347,6 +5341,13 @@
"dev": true, "dev": true,
"license": "BSD-3-Clause" "license": "BSD-3-Clause"
}, },
"node_modules/abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"license": "ISC",
"optional": true
},
"node_modules/abort-controller": { "node_modules/abort-controller": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
@ -5425,7 +5426,7 @@
"version": "6.0.2", "version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"dev": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"debug": "4" "debug": "4"
@ -5434,6 +5435,19 @@
"node": ">= 6.0.0" "node": ">= 6.0.0"
} }
}, },
"node_modules/agentkeepalive": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
"integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"humanize-ms": "^1.2.1"
},
"engines": {
"node": ">= 8.0.0"
}
},
"node_modules/aggregate-error": { "node_modules/aggregate-error": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
@ -5574,6 +5588,43 @@
"integrity": "sha512-zy9cHePtMP0YhwG+CfHm0bgwdnga2X3gZexpdCwEj//dpb+TKajtiC8REEUJUSq6Ab4f9cgNy2l8ObXzCXFkEw==", "integrity": "sha512-zy9cHePtMP0YhwG+CfHm0bgwdnga2X3gZexpdCwEj//dpb+TKajtiC8REEUJUSq6Ab4f9cgNy2l8ObXzCXFkEw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/aproba": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
"license": "ISC",
"optional": true
},
"node_modules/are-we-there-yet": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
"integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
"deprecated": "This package is no longer supported.",
"license": "ISC",
"optional": true,
"dependencies": {
"delegates": "^1.0.0",
"readable-stream": "^3.6.0"
},
"engines": {
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
"node_modules/are-we-there-yet/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
"optional": true,
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/arg": { "node_modules/arg": {
"version": "5.0.2", "version": "5.0.2",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
@ -5604,6 +5655,36 @@
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/asn1.js": {
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
"integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
"license": "MIT",
"dependencies": {
"bn.js": "^4.0.0",
"inherits": "^2.0.1",
"minimalistic-assert": "^1.0.0"
}
},
"node_modules/asn1.js/node_modules/bn.js": {
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
"license": "MIT"
},
"node_modules/assert": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz",
"integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==",
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.2",
"is-nan": "^1.3.2",
"object-is": "^1.1.5",
"object.assign": "^4.1.4",
"util": "^0.12.5"
}
},
"node_modules/ast-types": { "node_modules/ast-types": {
"version": "0.15.2", "version": "0.15.2",
"resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.15.2.tgz", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.15.2.tgz",
@ -5724,7 +5805,6 @@
"version": "5.0.2", "version": "5.0.2",
"resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.2.tgz", "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.2.tgz",
"integrity": "sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg==", "integrity": "sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"find-babel-config": "^2.1.1", "find-babel-config": "^2.1.1",
@ -5883,6 +5963,12 @@
"@babel/core": "^7.0.0" "@babel/core": "^7.0.0"
} }
}, },
"node_modules/badgin": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/badgin/-/badgin-1.2.3.tgz",
"integrity": "sha512-NQGA7LcfCpSzIbGRbkgjgdWkjy7HI+Th5VLxTJfW5EeaAf3fnS+xWQaQOCYiny+q6QSvxqoSO04vCx+4u++EJw==",
"license": "MIT"
},
"node_modules/balanced-match": { "node_modules/balanced-match": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -5964,9 +6050,7 @@
"version": "1.5.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"file-uri-to-path": "1.0.0" "file-uri-to-path": "1.0.0"
} }
@ -5975,15 +6059,33 @@
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"buffer": "^5.5.0", "buffer": "^5.5.0",
"inherits": "^2.0.4", "inherits": "^2.0.4",
"readable-stream": "^3.4.0" "readable-stream": "^3.4.0"
} }
}, },
"node_modules/bl/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/bn.js": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
"integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==",
"license": "MIT"
},
"node_modules/bplist-creator": { "node_modules/bplist-creator": {
"version": "0.0.7", "version": "0.0.7",
"resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz", "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz",
@ -6027,6 +6129,129 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/brorand": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
"integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==",
"license": "MIT"
},
"node_modules/browserify-aes": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
"license": "MIT",
"dependencies": {
"buffer-xor": "^1.0.3",
"cipher-base": "^1.0.0",
"create-hash": "^1.1.0",
"evp_bytestokey": "^1.0.3",
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
}
},
"node_modules/browserify-cipher": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
"integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
"license": "MIT",
"dependencies": {
"browserify-aes": "^1.0.4",
"browserify-des": "^1.0.0",
"evp_bytestokey": "^1.0.0"
}
},
"node_modules/browserify-des": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
"integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
"license": "MIT",
"dependencies": {
"cipher-base": "^1.0.1",
"des.js": "^1.0.0",
"inherits": "^2.0.1",
"safe-buffer": "^5.1.2"
}
},
"node_modules/browserify-rsa": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz",
"integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==",
"license": "MIT",
"dependencies": {
"bn.js": "^5.2.1",
"randombytes": "^2.1.0",
"safe-buffer": "^5.2.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/browserify-sign": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz",
"integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==",
"license": "ISC",
"dependencies": {
"bn.js": "^5.2.1",
"browserify-rsa": "^4.1.0",
"create-hash": "^1.2.0",
"create-hmac": "^1.1.7",
"elliptic": "^6.5.5",
"hash-base": "~3.0",
"inherits": "^2.0.4",
"parse-asn1": "^5.1.7",
"readable-stream": "^2.3.8",
"safe-buffer": "^5.2.1"
},
"engines": {
"node": ">= 0.12"
}
},
"node_modules/browserify-sign/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/browserify-sign/node_modules/readable-stream/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/browserify-sign/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/browserify-sign/node_modules/string_decoder/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/browserify-zlib": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
"integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
"license": "MIT",
"dependencies": {
"pako": "~1.0.5"
}
},
"node_modules/browserslist": { "node_modules/browserslist": {
"version": "4.24.4", "version": "4.24.4",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
@ -6133,6 +6358,18 @@
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/buffer-xor": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
"integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==",
"license": "MIT"
},
"node_modules/builtin-status-codes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
"integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==",
"license": "MIT"
},
"node_modules/bytes": { "node_modules/bytes": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@ -6448,6 +6685,19 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/cipher-base": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz",
"integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.4",
"safe-buffer": "^5.2.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/cjs-module-lexer": { "node_modules/cjs-module-lexer": {
"version": "1.4.3", "version": "1.4.3",
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz",
@ -6590,6 +6840,22 @@
"simple-swizzle": "^0.2.2" "simple-swizzle": "^0.2.2"
} }
}, },
"node_modules/color-support": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
"license": "ISC",
"optional": true,
"bin": {
"color-support": "bin.js"
}
},
"node_modules/colorette": {
"version": "2.0.19",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz",
"integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==",
"license": "MIT"
},
"node_modules/combined-stream": { "node_modules/combined-stream": {
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@ -6722,6 +6988,24 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/console-browserify": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
"integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA=="
},
"node_modules/console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
"license": "ISC",
"optional": true
},
"node_modules/constants-browserify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
"integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==",
"license": "MIT"
},
"node_modules/convert-source-map": { "node_modules/convert-source-map": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@ -6759,6 +7043,12 @@
"url": "https://opencollective.com/core-js" "url": "https://opencollective.com/core-js"
} }
}, },
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
"license": "MIT"
},
"node_modules/cosmiconfig": { "node_modules/cosmiconfig": {
"version": "5.2.1", "version": "5.2.1",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
@ -6787,6 +7077,49 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/create-ecdh": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
"integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
"license": "MIT",
"dependencies": {
"bn.js": "^4.1.0",
"elliptic": "^6.5.3"
}
},
"node_modules/create-ecdh/node_modules/bn.js": {
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
"license": "MIT"
},
"node_modules/create-hash": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"license": "MIT",
"dependencies": {
"cipher-base": "^1.0.1",
"inherits": "^2.0.1",
"md5.js": "^1.3.4",
"ripemd160": "^2.0.1",
"sha.js": "^2.4.0"
}
},
"node_modules/create-hmac": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"license": "MIT",
"dependencies": {
"cipher-base": "^1.0.3",
"create-hash": "^1.1.0",
"inherits": "^2.0.1",
"ripemd160": "^2.0.0",
"safe-buffer": "^5.0.1",
"sha.js": "^2.4.8"
}
},
"node_modules/create-jest": { "node_modules/create-jest": {
"version": "29.7.0", "version": "29.7.0",
"resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz",
@ -6841,6 +7174,32 @@
"node": "*" "node": "*"
} }
}, },
"node_modules/crypto-browserify": {
"version": "3.12.1",
"resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.1.tgz",
"integrity": "sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==",
"license": "MIT",
"dependencies": {
"browserify-cipher": "^1.0.1",
"browserify-sign": "^4.2.3",
"create-ecdh": "^4.0.4",
"create-hash": "^1.2.0",
"create-hmac": "^1.1.7",
"diffie-hellman": "^5.0.3",
"hash-base": "~3.0.4",
"inherits": "^2.0.4",
"pbkdf2": "^3.1.2",
"public-encrypt": "^4.0.3",
"randombytes": "^2.1.0",
"randomfill": "^1.0.4"
},
"engines": {
"node": ">= 0.10"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/crypto-random-string": { "node_modules/crypto-random-string": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
@ -6953,9 +7312,7 @@
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"mimic-response": "^3.1.0" "mimic-response": "^3.1.0"
}, },
@ -7050,6 +7407,23 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/define-properties": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"license": "MIT",
"dependencies": {
"define-data-property": "^1.0.1",
"has-property-descriptors": "^1.0.0",
"object-keys": "^1.1.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/del": { "node_modules/del": {
"version": "6.1.1", "version": "6.1.1",
"resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz",
@ -7081,6 +7455,13 @@
"node": ">=0.4.0" "node": ">=0.4.0"
} }
}, },
"node_modules/delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
"license": "MIT",
"optional": true
},
"node_modules/depd": { "node_modules/depd": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@ -7090,6 +7471,16 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/des.js": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz",
"integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.1",
"minimalistic-assert": "^1.0.0"
}
},
"node_modules/destroy": { "node_modules/destroy": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
@ -7132,6 +7523,23 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0" "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
} }
}, },
"node_modules/diffie-hellman": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
"integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
"license": "MIT",
"dependencies": {
"bn.js": "^4.1.0",
"miller-rabin": "^4.0.0",
"randombytes": "^2.0.0"
}
},
"node_modules/diffie-hellman/node_modules/bn.js": {
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
"license": "MIT"
},
"node_modules/dir-glob": { "node_modules/dir-glob": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@ -7144,6 +7552,16 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/domain-browser": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
"integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
"license": "MIT",
"engines": {
"node": ">=0.4",
"npm": ">=1.2"
}
},
"node_modules/domexception": { "node_modules/domexception": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
@ -7233,6 +7651,27 @@
"integrity": "sha512-8AJUW6dh75Fm/ny8+kZKJzI1pgoE8bKLZlzDU2W1ENd+DXKJrx7I7l9hb8UWR4ojlnb5OlixMt00QWiYJoVw1w==", "integrity": "sha512-8AJUW6dh75Fm/ny8+kZKJzI1pgoE8bKLZlzDU2W1ENd+DXKJrx7I7l9hb8UWR4ojlnb5OlixMt00QWiYJoVw1w==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/elliptic": {
"version": "6.6.1",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz",
"integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==",
"license": "MIT",
"dependencies": {
"bn.js": "^4.11.9",
"brorand": "^1.1.0",
"hash.js": "^1.0.0",
"hmac-drbg": "^1.0.1",
"inherits": "^2.0.4",
"minimalistic-assert": "^1.0.1",
"minimalistic-crypto-utils": "^1.0.1"
}
},
"node_modules/elliptic/node_modules/bn.js": {
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
"license": "MIT"
},
"node_modules/emittery": { "node_modules/emittery": {
"version": "0.13.1", "version": "0.13.1",
"resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
@ -7267,7 +7706,6 @@
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"peer": true,
"dependencies": { "dependencies": {
"iconv-lite": "^0.6.2" "iconv-lite": "^0.6.2"
} }
@ -7318,12 +7756,29 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/env-paths": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=6"
}
},
"node_modules/eol": { "node_modules/eol": {
"version": "0.9.1", "version": "0.9.1",
"resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz", "resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz",
"integrity": "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==", "integrity": "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/err-code": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
"integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
"license": "MIT",
"optional": true
},
"node_modules/error-ex": { "node_modules/error-ex": {
"version": "1.3.2", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@ -7466,6 +7921,15 @@
"node": ">=4.0" "node": ">=4.0"
} }
}, },
"node_modules/esm": {
"version": "3.2.25",
"resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
"integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/esprima": { "node_modules/esprima": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
@ -7534,13 +7998,21 @@
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=0.8.x" "node": ">=0.8.x"
} }
}, },
"node_modules/evp_bytestokey": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
"integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
"license": "MIT",
"dependencies": {
"md5.js": "^1.3.4",
"safe-buffer": "^5.1.1"
}
},
"node_modules/exec-async": { "node_modules/exec-async": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/exec-async/-/exec-async-2.2.0.tgz", "resolved": "https://registry.npmjs.org/exec-async/-/exec-async-2.2.0.tgz",
@ -7645,9 +8117,7 @@
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
"dev": true,
"license": "(MIT OR WTFPL)", "license": "(MIT OR WTFPL)",
"peer": true,
"engines": { "engines": {
"node": ">=6" "node": ">=6"
} }
@ -7716,6 +8186,15 @@
} }
} }
}, },
"node_modules/expo-application": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/expo-application/-/expo-application-6.0.2.tgz",
"integrity": "sha512-qcj6kGq3mc7x5yIb5KxESurFTJCoEKwNEL34RdPEvTB/xhl7SeVZlu05sZBqxB1V4Ryzq/LsCb7NHNfBbb3L7A==",
"license": "MIT",
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-asset": { "node_modules/expo-asset": {
"version": "11.0.3", "version": "11.0.3",
"resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-11.0.3.tgz", "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-11.0.3.tgz",
@ -7733,6 +8212,29 @@
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/expo-audio": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/expo-audio/-/expo-audio-0.3.5.tgz",
"integrity": "sha512-gzpDH3vZI1FDL1Q8pXryACtNIW+idZ/zIZ8WqdTRzJuzxucazrG2gLXUS2ngcXQBn09Jyz4RUnU10Tu2N7/Hgg==",
"license": "MIT",
"peerDependencies": {
"expo": "*",
"react": "*",
"react-native": "*"
}
},
"node_modules/expo-background-fetch": {
"version": "13.0.5",
"resolved": "https://registry.npmjs.org/expo-background-fetch/-/expo-background-fetch-13.0.5.tgz",
"integrity": "sha512-rLRM+rYDRT0fA0Oaet5ibJK3nKVRkfdjXjISHxjUvIE4ktD9pE+UjAPPdjTXZ5CkNb3JyNNhQGJEGpdJC2HLKw==",
"license": "MIT",
"dependencies": {
"expo-task-manager": "~12.0.5"
},
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-blur": { "node_modules/expo-blur": {
"version": "14.0.3", "version": "14.0.3",
"resolved": "https://registry.npmjs.org/expo-blur/-/expo-blur-14.0.3.tgz", "resolved": "https://registry.npmjs.org/expo-blur/-/expo-blur-14.0.3.tgz",
@ -7745,12 +8247,12 @@
} }
}, },
"node_modules/expo-constants": { "node_modules/expo-constants": {
"version": "17.0.5", "version": "17.0.6",
"resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-17.0.5.tgz", "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-17.0.6.tgz",
"integrity": "sha512-6SHXh32jCB+vrp2TRDNkoGoM421eOBPZIXX9ixI0hKKz71tIjD+LMr/P+rGUd/ks312MP3WK3j5vcYYPkCD8tQ==", "integrity": "sha512-rl3/hBIIkh4XDkCEMzGpmY6kWj2G1TA4Mq2joeyzoFBepJuGjqnGl7phf/71sTTgamQ1hmhKCLRNXMpRqzzqxw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@expo/config": "~10.0.8", "@expo/config": "~10.0.9",
"@expo/env": "~0.4.1" "@expo/env": "~0.4.1"
}, },
"peerDependencies": { "peerDependencies": {
@ -7758,6 +8260,56 @@
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/expo-crypto": {
"version": "14.0.2",
"resolved": "https://registry.npmjs.org/expo-crypto/-/expo-crypto-14.0.2.tgz",
"integrity": "sha512-WRc9PBpJraJN29VD5Ef7nCecxJmZNyRKcGkNiDQC1nhY5agppzwhqh7zEzNFarE/GqDgSiaDHS8yd5EgFhP9AQ==",
"license": "MIT",
"dependencies": {
"base64-js": "^1.3.0"
},
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-device": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/expo-device/-/expo-device-7.0.2.tgz",
"integrity": "sha512-0PkTixE4Qi8VQBjixnj4aw2f6vE4tUZH7GK8zHROGKlBypZKcWmsA+W/Vp3RC5AyREjX71pO/hjKTSo/vF0E2w==",
"license": "MIT",
"dependencies": {
"ua-parser-js": "^0.7.33"
},
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-device/node_modules/ua-parser-js": {
"version": "0.7.40",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.40.tgz",
"integrity": "sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/ua-parser-js"
},
{
"type": "paypal",
"url": "https://paypal.me/faisalman"
},
{
"type": "github",
"url": "https://github.com/sponsors/faisalman"
}
],
"license": "MIT",
"bin": {
"ua-parser-js": "script/cli.js"
},
"engines": {
"node": "*"
}
},
"node_modules/expo-file-system": { "node_modules/expo-file-system": {
"version": "18.0.10", "version": "18.0.10",
"resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-18.0.10.tgz", "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-18.0.10.tgz",
@ -7927,6 +8479,26 @@
"invariant": "^2.2.4" "invariant": "^2.2.4"
} }
}, },
"node_modules/expo-notifications": {
"version": "0.29.13",
"resolved": "https://registry.npmjs.org/expo-notifications/-/expo-notifications-0.29.13.tgz",
"integrity": "sha512-GHye6XeI1uEeVttJO/hGwUyA5cgQsxR3mi5q37yOE7cZN3cMj36pIfEEmjXEr0nWIWSzoJ0w8c2QxNj5xfP1pA==",
"license": "MIT",
"dependencies": {
"@expo/image-utils": "^0.6.4",
"@ide/backoff": "^1.0.0",
"abort-controller": "^3.0.0",
"assert": "^2.0.0",
"badgin": "^1.1.5",
"expo-application": "~6.0.2",
"expo-constants": "~17.0.5"
},
"peerDependencies": {
"expo": "*",
"react": "*",
"react-native": "*"
}
},
"node_modules/expo-router": { "node_modules/expo-router": {
"version": "4.0.17", "version": "4.0.17",
"resolved": "https://registry.npmjs.org/expo-router/-/expo-router-4.0.17.tgz", "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-4.0.17.tgz",
@ -7990,6 +8562,15 @@
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/expo-sharing": {
"version": "13.0.1",
"resolved": "https://registry.npmjs.org/expo-sharing/-/expo-sharing-13.0.1.tgz",
"integrity": "sha512-qych3Nw65wlFcnzE/gRrsdtvmdV0uF4U4qVMZBJYPG90vYyWh2QM9rp1gVu0KWOBc7N8CC2dSVYn4/BXqJy6Xw==",
"license": "MIT",
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-splash-screen": { "node_modules/expo-splash-screen": {
"version": "0.29.21", "version": "0.29.21",
"resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-0.29.21.tgz", "resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-0.29.21.tgz",
@ -8068,6 +8649,19 @@
} }
} }
}, },
"node_modules/expo-task-manager": {
"version": "12.0.5",
"resolved": "https://registry.npmjs.org/expo-task-manager/-/expo-task-manager-12.0.5.tgz",
"integrity": "sha512-tDHOBYORA6wuO32NWwz/Egrvn+N6aANHAa0DFs+01VK/IJZfU9D05ZN6M5XYIlZv5ll4GSX1wJZyTCY0HZGapw==",
"license": "MIT",
"dependencies": {
"unimodules-app-loader": "~5.0.1"
},
"peerDependencies": {
"expo": "*",
"react-native": "*"
}
},
"node_modules/expo-web-browser": { "node_modules/expo-web-browser": {
"version": "14.0.2", "version": "14.0.2",
"resolved": "https://registry.npmjs.org/expo-web-browser/-/expo-web-browser-14.0.2.tgz", "resolved": "https://registry.npmjs.org/expo-web-browser/-/expo-web-browser-14.0.2.tgz",
@ -8192,9 +8786,7 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"dev": true, "license": "MIT"
"license": "MIT",
"peer": true
}, },
"node_modules/filelist": { "node_modules/filelist": {
"version": "1.0.4", "version": "1.0.4",
@ -8287,7 +8879,6 @@
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-2.1.2.tgz", "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-2.1.2.tgz",
"integrity": "sha512-ZfZp1rQyp4gyuxqt1ZqjFGVeVBvmpURMqdIWXbPRfB97Bf6BzdK/xSIbylEINzQ0kB5tlDQfn9HkNXXWsqTqLg==", "integrity": "sha512-ZfZp1rQyp4gyuxqt1ZqjFGVeVBvmpURMqdIWXbPRfB97Bf6BzdK/xSIbylEINzQ0kB5tlDQfn9HkNXXWsqTqLg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"json5": "^2.2.3" "json5": "^2.2.3"
@ -8515,9 +9106,7 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
"dev": true, "license": "MIT"
"license": "MIT",
"peer": true
}, },
"node_modules/fs-extra": { "node_modules/fs-extra": {
"version": "8.1.0", "version": "8.1.0",
@ -8574,6 +9163,27 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/gauge": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
"integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
"deprecated": "This package is no longer supported.",
"license": "ISC",
"optional": true,
"dependencies": {
"aproba": "^1.0.3 || ^2.0.0",
"color-support": "^1.1.3",
"console-control-strings": "^1.1.0",
"has-unicode": "^2.0.1",
"signal-exit": "^3.0.7",
"string-width": "^4.2.3",
"strip-ansi": "^6.0.1",
"wide-align": "^1.1.5"
},
"engines": {
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
"node_modules/gensync": { "node_modules/gensync": {
"version": "1.0.0-beta.2", "version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@ -8668,19 +9278,22 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/getopts": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz",
"integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==",
"license": "MIT"
},
"node_modules/github-from-package": { "node_modules/github-from-package": {
"version": "0.0.0", "version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
"dev": true, "license": "MIT"
"license": "MIT",
"peer": true
}, },
"node_modules/glob": { "node_modules/glob": {
"version": "9.3.5", "version": "9.3.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz",
"integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==",
"dev": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"fs.realpath": "^1.0.0", "fs.realpath": "^1.0.0",
@ -8719,7 +9332,6 @@
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"balanced-match": "^1.0.0" "balanced-match": "^1.0.0"
@ -8729,7 +9341,6 @@
"version": "8.0.4", "version": "8.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz",
"integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==",
"dev": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"brace-expansion": "^2.0.1" "brace-expansion": "^2.0.1"
@ -8745,7 +9356,6 @@
"version": "4.2.8", "version": "4.2.8",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
"integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
"dev": true,
"license": "ISC", "license": "ISC",
"engines": { "engines": {
"node": ">=8" "node": ">=8"
@ -8846,6 +9456,36 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
"license": "ISC",
"optional": true
},
"node_modules/hash-base": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.5.tgz",
"integrity": "sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.4",
"safe-buffer": "^5.2.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/hash.js": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
"integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.3",
"minimalistic-assert": "^1.0.1"
}
},
"node_modules/hasown": { "node_modules/hasown": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
@ -8873,6 +9513,17 @@
"hermes-estree": "0.23.1" "hermes-estree": "0.23.1"
} }
}, },
"node_modules/hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
"integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==",
"license": "MIT",
"dependencies": {
"hash.js": "^1.0.3",
"minimalistic-assert": "^1.0.0",
"minimalistic-crypto-utils": "^1.0.1"
}
},
"node_modules/hoist-non-react-statics": { "node_modules/hoist-non-react-statics": {
"version": "3.3.2", "version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@ -8926,6 +9577,13 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/http-cache-semantics": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
"integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
"license": "BSD-2-Clause",
"optional": true
},
"node_modules/http-errors": { "node_modules/http-errors": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@ -8966,11 +9624,17 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/https-browserify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
"integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==",
"license": "MIT"
},
"node_modules/https-proxy-agent": { "node_modules/https-proxy-agent": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
"dev": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"agent-base": "6", "agent-base": "6",
@ -8989,6 +9653,16 @@
"node": ">=10.17.0" "node": ">=10.17.0"
} }
}, },
"node_modules/humanize-ms": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
"integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"ms": "^2.0.0"
}
},
"node_modules/hyphenate-style-name": { "node_modules/hyphenate-style-name": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz",
@ -9112,6 +9786,13 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/infer-owner": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
"integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
"license": "ISC",
"optional": true
},
"node_modules/inflight": { "node_modules/inflight": {
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@ -9158,6 +9839,15 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/interpret": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz",
"integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==",
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/invariant": { "node_modules/invariant": {
"version": "2.2.4", "version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
@ -9167,6 +9857,27 @@
"loose-envify": "^1.0.0" "loose-envify": "^1.0.0"
} }
}, },
"node_modules/ip-address": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
"integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
"license": "MIT",
"optional": true,
"dependencies": {
"jsbn": "1.1.0",
"sprintf-js": "^1.1.3"
},
"engines": {
"node": ">= 12"
}
},
"node_modules/ip-address/node_modules/sprintf-js": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
"license": "BSD-3-Clause",
"optional": true
},
"node_modules/ip-regex": { "node_modules/ip-regex": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
@ -9322,6 +10033,29 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/is-lambda": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
"integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
"license": "MIT",
"optional": true
},
"node_modules/is-nan": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz",
"integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==",
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.0",
"define-properties": "^1.1.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-number": { "node_modules/is-number": {
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@ -9431,6 +10165,12 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
"license": "MIT"
},
"node_modules/isexe": { "node_modules/isexe": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@ -10633,6 +11373,13 @@
"js-yaml": "bin/js-yaml.js" "js-yaml": "bin/js-yaml.js"
} }
}, },
"node_modules/jsbn": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
"integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==",
"license": "MIT",
"optional": true
},
"node_modules/jsc-android": { "node_modules/jsc-android": {
"version": "250231.0.0", "version": "250231.0.0",
"resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250231.0.0.tgz", "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250231.0.0.tgz",
@ -10820,6 +11567,89 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/knex": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/knex/-/knex-3.1.0.tgz",
"integrity": "sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw==",
"license": "MIT",
"dependencies": {
"colorette": "2.0.19",
"commander": "^10.0.0",
"debug": "4.3.4",
"escalade": "^3.1.1",
"esm": "^3.2.25",
"get-package-type": "^0.1.0",
"getopts": "2.3.0",
"interpret": "^2.2.0",
"lodash": "^4.17.21",
"pg-connection-string": "2.6.2",
"rechoir": "^0.8.0",
"resolve-from": "^5.0.0",
"tarn": "^3.0.2",
"tildify": "2.0.0"
},
"bin": {
"knex": "bin/cli.js"
},
"engines": {
"node": ">=16"
},
"peerDependenciesMeta": {
"better-sqlite3": {
"optional": true
},
"mysql": {
"optional": true
},
"mysql2": {
"optional": true
},
"pg": {
"optional": true
},
"pg-native": {
"optional": true
},
"sqlite3": {
"optional": true
},
"tedious": {
"optional": true
}
}
},
"node_modules/knex/node_modules/commander": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"license": "MIT",
"engines": {
"node": ">=14"
}
},
"node_modules/knex/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/knex/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"license": "MIT"
},
"node_modules/leven": { "node_modules/leven": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@ -11276,6 +12106,240 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/make-fetch-happen": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
"integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
"license": "ISC",
"optional": true,
"dependencies": {
"agentkeepalive": "^4.1.3",
"cacache": "^15.2.0",
"http-cache-semantics": "^4.1.0",
"http-proxy-agent": "^4.0.1",
"https-proxy-agent": "^5.0.0",
"is-lambda": "^1.0.1",
"lru-cache": "^6.0.0",
"minipass": "^3.1.3",
"minipass-collect": "^1.0.2",
"minipass-fetch": "^1.3.2",
"minipass-flush": "^1.0.5",
"minipass-pipeline": "^1.2.4",
"negotiator": "^0.6.2",
"promise-retry": "^2.0.1",
"socks-proxy-agent": "^6.0.0",
"ssri": "^8.0.0"
},
"engines": {
"node": ">= 10"
}
},
"node_modules/make-fetch-happen/node_modules/@npmcli/fs": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
"integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
"license": "ISC",
"optional": true,
"dependencies": {
"@gar/promisify": "^1.0.1",
"semver": "^7.3.5"
}
},
"node_modules/make-fetch-happen/node_modules/@tootallnate/once": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
"integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 6"
}
},
"node_modules/make-fetch-happen/node_modules/cacache": {
"version": "15.3.0",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
"integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
"license": "ISC",
"optional": true,
"dependencies": {
"@npmcli/fs": "^1.0.0",
"@npmcli/move-file": "^1.0.1",
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"glob": "^7.1.4",
"infer-owner": "^1.0.4",
"lru-cache": "^6.0.0",
"minipass": "^3.1.1",
"minipass-collect": "^1.0.2",
"minipass-flush": "^1.0.5",
"minipass-pipeline": "^1.2.2",
"mkdirp": "^1.0.3",
"p-map": "^4.0.0",
"promise-inflight": "^1.0.1",
"rimraf": "^3.0.2",
"ssri": "^8.0.1",
"tar": "^6.0.2",
"unique-filename": "^1.1.1"
},
"engines": {
"node": ">= 10"
}
},
"node_modules/make-fetch-happen/node_modules/fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"license": "ISC",
"optional": true,
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/make-fetch-happen/node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"license": "ISC",
"optional": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/make-fetch-happen/node_modules/http-proxy-agent": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
"integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
"license": "MIT",
"optional": true,
"dependencies": {
"@tootallnate/once": "1",
"agent-base": "6",
"debug": "4"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/make-fetch-happen/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"license": "ISC",
"optional": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/make-fetch-happen/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"license": "ISC",
"optional": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/make-fetch-happen/node_modules/minipass-collect": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
"integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
"license": "ISC",
"optional": true,
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/make-fetch-happen/node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"license": "MIT",
"optional": true,
"bin": {
"mkdirp": "bin/cmd.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/make-fetch-happen/node_modules/semver": {
"version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
"license": "ISC",
"optional": true,
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/make-fetch-happen/node_modules/ssri": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
"integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
"license": "ISC",
"optional": true,
"dependencies": {
"minipass": "^3.1.1"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/make-fetch-happen/node_modules/unique-filename": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
"integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
"license": "ISC",
"optional": true,
"dependencies": {
"unique-slug": "^2.0.0"
}
},
"node_modules/make-fetch-happen/node_modules/unique-slug": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
"integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
"license": "ISC",
"optional": true,
"dependencies": {
"imurmurhash": "^0.1.4"
}
},
"node_modules/make-fetch-happen/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"license": "ISC",
"optional": true
},
"node_modules/makeerror": { "node_modules/makeerror": {
"version": "1.0.12", "version": "1.0.12",
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
@ -11326,6 +12390,17 @@
"node": ">=0.10" "node": ">=0.10"
} }
}, },
"node_modules/md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
"integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
"license": "MIT",
"dependencies": {
"hash-base": "^3.0.0",
"inherits": "^2.0.1",
"safe-buffer": "^5.1.2"
}
},
"node_modules/memoize-one": { "node_modules/memoize-one": {
"version": "5.2.1", "version": "5.2.1",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
@ -11360,9 +12435,9 @@
} }
}, },
"node_modules/metro": { "node_modules/metro": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro/-/metro-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro/-/metro-0.81.3.tgz",
"integrity": "sha512-fqRu4fg8ONW7VfqWFMGgKAcOuMzyoQah2azv9Y3VyFXAmG+AoTU6YIFWqAADESCGVWuWEIvxTJhMf3jxU6jwjA==", "integrity": "sha512-upilFs7z1uLKvdzFYHiVKrGT/uC7h7d53R0g/FaJoQvLfA8jQG2V69jeOcGi4wCsFYvl1zBSZvKxpQb0nA3giQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/code-frame": "^7.24.7", "@babel/code-frame": "^7.24.7",
@ -11383,21 +12458,21 @@
"hermes-parser": "0.25.1", "hermes-parser": "0.25.1",
"image-size": "^1.0.2", "image-size": "^1.0.2",
"invariant": "^2.2.4", "invariant": "^2.2.4",
"jest-worker": "^29.6.3", "jest-worker": "^29.7.0",
"jsc-safe-url": "^0.2.2", "jsc-safe-url": "^0.2.2",
"lodash.throttle": "^4.1.1", "lodash.throttle": "^4.1.1",
"metro-babel-transformer": "0.81.1", "metro-babel-transformer": "0.81.3",
"metro-cache": "0.81.1", "metro-cache": "0.81.3",
"metro-cache-key": "0.81.1", "metro-cache-key": "0.81.3",
"metro-config": "0.81.1", "metro-config": "0.81.3",
"metro-core": "0.81.1", "metro-core": "0.81.3",
"metro-file-map": "0.81.1", "metro-file-map": "0.81.3",
"metro-resolver": "0.81.1", "metro-resolver": "0.81.3",
"metro-runtime": "0.81.1", "metro-runtime": "0.81.3",
"metro-source-map": "0.81.1", "metro-source-map": "0.81.3",
"metro-symbolicate": "0.81.1", "metro-symbolicate": "0.81.3",
"metro-transform-plugins": "0.81.1", "metro-transform-plugins": "0.81.3",
"metro-transform-worker": "0.81.1", "metro-transform-worker": "0.81.3",
"mime-types": "^2.1.27", "mime-types": "^2.1.27",
"nullthrows": "^1.1.1", "nullthrows": "^1.1.1",
"serialize-error": "^2.1.0", "serialize-error": "^2.1.0",
@ -11414,9 +12489,9 @@
} }
}, },
"node_modules/metro-babel-transformer": { "node_modules/metro-babel-transformer": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.81.3.tgz",
"integrity": "sha512-JECKDrQaUnDmj0x/Q/c8c5YwsatVx38Lu+BfCwX9fR8bWipAzkvJocBpq5rOAJRDXRgDcPv2VO4Q4nFYrpYNQg==", "integrity": "sha512-ENqtnPy2mQZFOuKrbqHRcAwZuaYe43X+30xIF0xlkLuMyCvc0CsFzrrSK9EqrQwexhVlqaRALb0GQbBMcE/y8g==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.25.2",
@ -11444,23 +12519,23 @@
} }
}, },
"node_modules/metro-cache": { "node_modules/metro-cache": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.81.3.tgz",
"integrity": "sha512-Uqcmn6sZ+Y0VJHM88VrG5xCvSeU7RnuvmjPmSOpEcyJJBe02QkfHL05MX2ZyGDTyZdbKCzaX0IijrTe4hN3F0Q==", "integrity": "sha512-6UelMQYjlto/79tTXu0vsTxAX4e+Bkf0tgtDL1BNx3wd68pBg8qKIYpJPaUlOIaNUzFXTBDjYwUverkEW0KAtA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"exponential-backoff": "^3.1.1", "exponential-backoff": "^3.1.1",
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
"metro-core": "0.81.1" "metro-core": "0.81.3"
}, },
"engines": { "engines": {
"node": ">=18.18" "node": ">=18.18"
} }
}, },
"node_modules/metro-cache-key": { "node_modules/metro-cache-key": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.81.3.tgz",
"integrity": "sha512-5fDaHR1yTvpaQuwMAeEoZGsVyvjrkw9IFAS7WixSPvaNY5YfleqoJICPc6hbXFJjvwCCpwmIYFkjqzR/qJ6yqA==", "integrity": "sha512-KPsPSRUd6uRva7k7k/DqiiD8td7URQWx0RkX/Cj5+bed5zSXEg/XoQA+b+DmMxS5C7TqP61Fh3XvHx6TQRW82A==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"flow-enums-runtime": "^0.0.6" "flow-enums-runtime": "^0.0.6"
@ -11470,42 +12545,42 @@
} }
}, },
"node_modules/metro-config": { "node_modules/metro-config": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.81.3.tgz",
"integrity": "sha512-VAAJmxsKIZ+Fz5/z1LVgxa32gE6+2TvrDSSx45g85WoX4EtLmdBGP3DSlpQW3DqFUfNHJCGwMLGXpJnxifd08g==", "integrity": "sha512-WpTaT0iQr5juVY50Y/cyacG2ggZqF38VshEQepT+ovPK8E/xUVxlbO5yxLSXUxxUXX3Hka9r6g64+y2WC6c/xQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"connect": "^3.6.5", "connect": "^3.6.5",
"cosmiconfig": "^5.0.5", "cosmiconfig": "^5.0.5",
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
"jest-validate": "^29.6.3", "jest-validate": "^29.7.0",
"metro": "0.81.1", "metro": "0.81.3",
"metro-cache": "0.81.1", "metro-cache": "0.81.3",
"metro-core": "0.81.1", "metro-core": "0.81.3",
"metro-runtime": "0.81.1" "metro-runtime": "0.81.3"
}, },
"engines": { "engines": {
"node": ">=18.18" "node": ">=18.18"
} }
}, },
"node_modules/metro-core": { "node_modules/metro-core": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.81.3.tgz",
"integrity": "sha512-4d2/+02IYqOwJs4dmM0dC8hIZqTzgnx2nzN4GTCaXb3Dhtmi/SJ3v6744zZRnithhN4lxf8TTJSHnQV75M7SSA==", "integrity": "sha512-WZ+qohnpvvSWdPj1VJPUrZz+2ik29M+UUpMU6YrmzQUfDyZ6JYHhzlw5WVBtwpt/+2xTsIyrZ2C1fByT/DsLQA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
"lodash.throttle": "^4.1.1", "lodash.throttle": "^4.1.1",
"metro-resolver": "0.81.1" "metro-resolver": "0.81.3"
}, },
"engines": { "engines": {
"node": ">=18.18" "node": ">=18.18"
} }
}, },
"node_modules/metro-file-map": { "node_modules/metro-file-map": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.81.3.tgz",
"integrity": "sha512-aY72H2ujmRfFxcsbyh83JgqFF+uQ4HFN1VhV2FmcfQG4s1bGKf2Vbkk+vtZ1+EswcBwDZFbkpvAjN49oqwGzAA==", "integrity": "sha512-F+t4lnVRoauJxtr9xmI4pWIOE77/vl0IrHDGeJSI9cW6LmuqxkpOlZHTKpbs/hMAo6+KhG2JMJACQDvXDLd/GA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"debug": "^2.2.0", "debug": "^2.2.0",
@ -11513,7 +12588,7 @@
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
"graceful-fs": "^4.2.4", "graceful-fs": "^4.2.4",
"invariant": "^2.2.4", "invariant": "^2.2.4",
"jest-worker": "^29.6.3", "jest-worker": "^29.7.0",
"micromatch": "^4.0.4", "micromatch": "^4.0.4",
"nullthrows": "^1.1.1", "nullthrows": "^1.1.1",
"walker": "^1.0.7" "walker": "^1.0.7"
@ -11538,9 +12613,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/metro-minify-terser": { "node_modules/metro-minify-terser": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.81.3.tgz",
"integrity": "sha512-p/Qz3NNh1nebSqMlxlUALAnESo6heQrnvgHtAuxufRPtKvghnVDq9hGGex8H7z7YYLsqe42PWdt4JxTA3mgkvg==", "integrity": "sha512-912AYv3OmwcbUwzCdWbdQRk+RV6kXXluHKlhBdYFD3kr4Ece691rzlofU/Mlt9qZrhHtctD5Q8cFqOEf9Z69bQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
@ -11615,9 +12690,9 @@
} }
}, },
"node_modules/metro-resolver": { "node_modules/metro-resolver": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.81.3.tgz",
"integrity": "sha512-E61t6fxRoYRkl6Zo3iUfCKW4DYfum/bLjcejXBMt1y3I7LFkK84TCR/Rs9OAwsMCY/7GOPB4+CREYZOtCC7CNA==", "integrity": "sha512-XnjENY1c6jcsEfFVIjN/8McUIInCVgGxv5eva+9ZWeCTyiAE/L5HPj2ai/Myb349+6QuSMR0dscTkKCnOwWXdw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"flow-enums-runtime": "^0.0.6" "flow-enums-runtime": "^0.0.6"
@ -11627,9 +12702,9 @@
} }
}, },
"node_modules/metro-runtime": { "node_modules/metro-runtime": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.81.3.tgz",
"integrity": "sha512-pqu5j5d01rjF85V/K8SDDJ0NR3dRp6bE3z5bKVVb5O2Rx0nbR9KreUxYALQCRCcQHaYySqCg5fYbGKBHC295YQ==", "integrity": "sha512-neuGRMC2pgGKIFPbmbrxW41/SmvL7OX4i1LN+saUY2t1cZfxf9haQHUMCGhO3498uEL2N+ulKRSlQrHt6XwGaw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.25.0", "@babel/runtime": "^7.25.0",
@ -11640,9 +12715,9 @@
} }
}, },
"node_modules/metro-source-map": { "node_modules/metro-source-map": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.81.3.tgz",
"integrity": "sha512-1i8ROpNNiga43F0ZixAXoFE/SS3RqcRDCCslpynb+ytym0VI7pkTH1woAN2HI9pczYtPrp3Nq0AjRpsuY35ieA==", "integrity": "sha512-BHJJurmDQRn3hCbBawh/UHzPz3duMpwpE3ofImO2DoWHYzn6nSg/D4wfCN4y14d9fFLE4e0I+BAOX1HWNP4jsw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/traverse": "^7.25.3", "@babel/traverse": "^7.25.3",
@ -11650,9 +12725,9 @@
"@babel/types": "^7.25.2", "@babel/types": "^7.25.2",
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
"invariant": "^2.2.4", "invariant": "^2.2.4",
"metro-symbolicate": "0.81.1", "metro-symbolicate": "0.81.3",
"nullthrows": "^1.1.1", "nullthrows": "^1.1.1",
"ob1": "0.81.1", "ob1": "0.81.3",
"source-map": "^0.5.6", "source-map": "^0.5.6",
"vlq": "^1.0.0" "vlq": "^1.0.0"
}, },
@ -11670,14 +12745,14 @@
} }
}, },
"node_modules/metro-symbolicate": { "node_modules/metro-symbolicate": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.81.3.tgz",
"integrity": "sha512-Lgk0qjEigtFtsM7C0miXITbcV47E1ZYIfB+m/hCraihiwRWkNUQEPCWvqZmwXKSwVE5mXA0EzQtghAvQSjZDxw==", "integrity": "sha512-LQLT6WopQmIz2SDSVh3Lw7nLzF58HpsrPYqRB7RpRXBYhYmPFIjiGaP8qqtKHXczM/5YAOJzpgt8t/OGZgh6Eg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
"invariant": "^2.2.4", "invariant": "^2.2.4",
"metro-source-map": "0.81.1", "metro-source-map": "0.81.3",
"nullthrows": "^1.1.1", "nullthrows": "^1.1.1",
"source-map": "^0.5.6", "source-map": "^0.5.6",
"vlq": "^1.0.0" "vlq": "^1.0.0"
@ -11699,9 +12774,9 @@
} }
}, },
"node_modules/metro-transform-plugins": { "node_modules/metro-transform-plugins": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.81.3.tgz",
"integrity": "sha512-7L1lI44/CyjIoBaORhY9fVkoNe8hrzgxjSCQ/lQlcfrV31cZb7u0RGOQrKmUX7Bw4FpejrB70ArQ7Mse9mk7+Q==", "integrity": "sha512-4JMUXhBB5y4h3dyA272k7T7+U3+J4fSBcct0Y8Yur9ziZB/dK8fieEQg5ZPfEGsgOGI+54zTzOUqga6AgmZSNg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.25.2",
@ -11716,9 +12791,9 @@
} }
}, },
"node_modules/metro-transform-worker": { "node_modules/metro-transform-worker": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.81.1.tgz", "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.81.3.tgz",
"integrity": "sha512-M+2hVT3rEy5K7PBmGDgQNq3Zx53TjScOcO/CieyLnCRFtBGWZiSJ2+bLAXXOKyKa/y3bI3i0owxtyxuPGDwbZg==", "integrity": "sha512-KZqm9sVyBKRygUxRm+yP4DguE9R1EEv28KJhIxghNp5dcdVXBYUPe1xHoc3QVdzD9c3tf8JFzA2FBlKTlwMwNg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.25.2",
@ -11726,13 +12801,13 @@
"@babel/parser": "^7.25.3", "@babel/parser": "^7.25.3",
"@babel/types": "^7.25.2", "@babel/types": "^7.25.2",
"flow-enums-runtime": "^0.0.6", "flow-enums-runtime": "^0.0.6",
"metro": "0.81.1", "metro": "0.81.3",
"metro-babel-transformer": "0.81.1", "metro-babel-transformer": "0.81.3",
"metro-cache": "0.81.1", "metro-cache": "0.81.3",
"metro-cache-key": "0.81.1", "metro-cache-key": "0.81.3",
"metro-minify-terser": "0.81.1", "metro-minify-terser": "0.81.3",
"metro-source-map": "0.81.1", "metro-source-map": "0.81.3",
"metro-transform-plugins": "0.81.1", "metro-transform-plugins": "0.81.3",
"nullthrows": "^1.1.1" "nullthrows": "^1.1.1"
}, },
"engines": { "engines": {
@ -11830,6 +12905,25 @@
"url": "https://github.com/sponsors/jonschlinkert" "url": "https://github.com/sponsors/jonschlinkert"
} }
}, },
"node_modules/miller-rabin": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
"integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
"license": "MIT",
"dependencies": {
"bn.js": "^4.0.0",
"brorand": "^1.0.1"
},
"bin": {
"miller-rabin": "bin/miller-rabin"
}
},
"node_modules/miller-rabin/node_modules/bn.js": {
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
"license": "MIT"
},
"node_modules/mime": { "node_modules/mime": {
"version": "1.6.0", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
@ -11885,9 +12979,7 @@
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=10" "node": ">=10"
}, },
@ -11905,6 +12997,18 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
"integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
"license": "ISC"
},
"node_modules/minimalistic-crypto-utils": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
"integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==",
"license": "MIT"
},
"node_modules/minimatch": { "node_modules/minimatch": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@ -11947,6 +13051,44 @@
"node": ">=16 || 14 >=14.17" "node": ">=16 || 14 >=14.17"
} }
}, },
"node_modules/minipass-fetch": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
"integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
"license": "MIT",
"optional": true,
"dependencies": {
"minipass": "^3.1.0",
"minipass-sized": "^1.0.3",
"minizlib": "^2.0.0"
},
"engines": {
"node": ">=8"
},
"optionalDependencies": {
"encoding": "^0.1.12"
}
},
"node_modules/minipass-fetch/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"license": "ISC",
"optional": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minipass-fetch/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"license": "ISC",
"optional": true
},
"node_modules/minipass-flush": { "node_modules/minipass-flush": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
@ -12007,6 +13149,39 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/minipass-sized": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
"integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
"license": "ISC",
"optional": true,
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minipass-sized/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"license": "ISC",
"optional": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minipass-sized/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"license": "ISC",
"optional": true
},
"node_modules/minizlib": { "node_modules/minizlib": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
@ -12054,9 +13229,7 @@
"version": "0.5.3", "version": "0.5.3",
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
"dev": true, "license": "MIT"
"license": "MIT",
"peer": true
}, },
"node_modules/mrmime": { "node_modules/mrmime": {
"version": "1.0.1", "version": "1.0.1",
@ -12106,9 +13279,7 @@
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
"integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
"dev": true, "license": "MIT"
"license": "MIT",
"peer": true
}, },
"node_modules/natural-compare": { "node_modules/natural-compare": {
"version": "1.4.0", "version": "1.4.0",
@ -12148,9 +13319,7 @@
"version": "3.74.0", "version": "3.74.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz",
"integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==", "integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"semver": "^7.3.5" "semver": "^7.3.5"
}, },
@ -12162,9 +13331,7 @@
"version": "7.7.1", "version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
"dev": true,
"license": "ISC", "license": "ISC",
"peer": true,
"bin": { "bin": {
"semver": "bin/semver.js" "semver": "bin/semver.js"
}, },
@ -12172,6 +13339,12 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/node-addon-api": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
"license": "MIT"
},
"node_modules/node-dir": { "node_modules/node-dir": {
"version": "0.1.17", "version": "0.1.17",
"resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz",
@ -12235,18 +13408,222 @@
"node": ">= 6.13.0" "node": ">= 6.13.0"
} }
}, },
"node_modules/node-gyp": {
"version": "8.4.1",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz",
"integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==",
"license": "MIT",
"optional": true,
"dependencies": {
"env-paths": "^2.2.0",
"glob": "^7.1.4",
"graceful-fs": "^4.2.6",
"make-fetch-happen": "^9.1.0",
"nopt": "^5.0.0",
"npmlog": "^6.0.0",
"rimraf": "^3.0.2",
"semver": "^7.3.5",
"tar": "^6.1.2",
"which": "^2.0.2"
},
"bin": {
"node-gyp": "bin/node-gyp.js"
},
"engines": {
"node": ">= 10.12.0"
}
},
"node_modules/node-gyp/node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"license": "ISC",
"optional": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/node-gyp/node_modules/semver": {
"version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
"license": "ISC",
"optional": true,
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/node-int64": { "node_modules/node-int64": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
"integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/node-libs-browser": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
"integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
"license": "MIT",
"dependencies": {
"assert": "^1.1.1",
"browserify-zlib": "^0.2.0",
"buffer": "^4.3.0",
"console-browserify": "^1.1.0",
"constants-browserify": "^1.0.0",
"crypto-browserify": "^3.11.0",
"domain-browser": "^1.1.1",
"events": "^3.0.0",
"https-browserify": "^1.0.0",
"os-browserify": "^0.3.0",
"path-browserify": "0.0.1",
"process": "^0.11.10",
"punycode": "^1.2.4",
"querystring-es3": "^0.2.0",
"readable-stream": "^2.3.3",
"stream-browserify": "^2.0.1",
"stream-http": "^2.7.2",
"string_decoder": "^1.0.0",
"timers-browserify": "^2.0.4",
"tty-browserify": "0.0.0",
"url": "^0.11.0",
"util": "^0.11.0",
"vm-browserify": "^1.0.1"
}
},
"node_modules/node-libs-browser/node_modules/assert": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/assert/-/assert-1.5.1.tgz",
"integrity": "sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==",
"license": "MIT",
"dependencies": {
"object.assign": "^4.1.4",
"util": "^0.10.4"
}
},
"node_modules/node-libs-browser/node_modules/assert/node_modules/util": {
"version": "0.10.4",
"resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
"integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
"license": "MIT",
"dependencies": {
"inherits": "2.0.3"
}
},
"node_modules/node-libs-browser/node_modules/buffer": {
"version": "4.9.2",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
"integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
"license": "MIT",
"dependencies": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4",
"isarray": "^1.0.0"
}
},
"node_modules/node-libs-browser/node_modules/inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
"license": "ISC"
},
"node_modules/node-libs-browser/node_modules/punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
"license": "MIT"
},
"node_modules/node-libs-browser/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/node-libs-browser/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/node-libs-browser/node_modules/stream-browserify": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
"integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
"license": "MIT",
"dependencies": {
"inherits": "~2.0.1",
"readable-stream": "^2.0.2"
}
},
"node_modules/node-libs-browser/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/node-libs-browser/node_modules/tty-browserify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
"integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==",
"license": "MIT"
},
"node_modules/node-libs-browser/node_modules/util": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
"integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==",
"license": "MIT",
"dependencies": {
"inherits": "2.0.3"
}
},
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.19", "version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/nopt": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
"license": "ISC",
"optional": true,
"dependencies": {
"abbrev": "1"
},
"bin": {
"nopt": "bin/nopt.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/normalize-path": { "node_modules/normalize-path": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@ -12304,6 +13681,23 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/npmlog": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
"integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
"deprecated": "This package is no longer supported.",
"license": "ISC",
"optional": true,
"dependencies": {
"are-we-there-yet": "^3.0.0",
"console-control-strings": "^1.1.0",
"gauge": "^4.0.3",
"set-blocking": "^2.0.0"
},
"engines": {
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
"node_modules/nullthrows": { "node_modules/nullthrows": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
@ -12318,9 +13712,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/ob1": { "node_modules/ob1": {
"version": "0.81.1", "version": "0.81.3",
"resolved": "https://registry.npmjs.org/ob1/-/ob1-0.81.1.tgz", "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.81.3.tgz",
"integrity": "sha512-1PEbvI+AFvOcgdNcO79FtDI1TUO8S3lhiKOyAiyWQF3sFDDKS+aw2/BZvGlArFnSmqckwOOB9chQuIX0/OahoQ==", "integrity": "sha512-wd8zdH0DWsn2iDVn2zT/QURihcqoc73K8FhNCmQ16qkJaoYJLNb/N+huOwdCgsbNP8Lk/s1+dPnDETx+RzsrWA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"flow-enums-runtime": "^0.0.6" "flow-enums-runtime": "^0.0.6"
@ -12338,6 +13732,63 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/object-inspect": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object-is": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
"integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/object.assign": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
"integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.3",
"define-properties": "^1.2.1",
"es-object-atoms": "^1.0.0",
"has-symbols": "^1.1.0",
"object-keys": "^1.1.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/on-finished": { "node_modules/on-finished": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
@ -12505,6 +13956,12 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/os-browserify": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
"integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==",
"license": "MIT"
},
"node_modules/os-tmpdir": { "node_modules/os-tmpdir": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
@ -12595,6 +14052,29 @@
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
"license": "BlueOak-1.0.0" "license": "BlueOak-1.0.0"
}, },
"node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
"license": "(MIT AND Zlib)"
},
"node_modules/parse-asn1": {
"version": "5.1.7",
"resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz",
"integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==",
"license": "ISC",
"dependencies": {
"asn1.js": "^4.10.1",
"browserify-aes": "^1.2.0",
"evp_bytestokey": "^1.0.3",
"hash-base": "~3.0",
"pbkdf2": "^3.1.2",
"safe-buffer": "^5.2.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/parse-json": { "node_modules/parse-json": {
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
@ -12658,6 +14138,12 @@
"cross-spawn": "^7.0.3" "cross-spawn": "^7.0.3"
} }
}, },
"node_modules/path-browserify": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
"integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
"license": "MIT"
},
"node_modules/path-exists": { "node_modules/path-exists": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@ -12722,6 +14208,28 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/pbkdf2": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
"integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
"license": "MIT",
"dependencies": {
"create-hash": "^1.1.2",
"create-hmac": "^1.1.4",
"ripemd160": "^2.0.1",
"safe-buffer": "^5.0.1",
"sha.js": "^2.4.8"
},
"engines": {
"node": ">=0.12"
}
},
"node_modules/pg-connection-string": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz",
"integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==",
"license": "MIT"
},
"node_modules/picocolors": { "node_modules/picocolors": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@ -12775,7 +14283,6 @@
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz",
"integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"find-up": "^3.0.0" "find-up": "^3.0.0"
@ -12788,7 +14295,6 @@
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"locate-path": "^3.0.0" "locate-path": "^3.0.0"
@ -12801,7 +14307,6 @@
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"p-locate": "^3.0.0", "p-locate": "^3.0.0",
@ -12815,7 +14320,6 @@
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"p-try": "^2.0.0" "p-try": "^2.0.0"
@ -12831,7 +14335,6 @@
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"p-limit": "^2.0.0" "p-limit": "^2.0.0"
@ -12844,7 +14347,6 @@
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
"integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=4" "node": ">=4"
@ -12938,9 +14440,7 @@
"version": "7.1.3", "version": "7.1.3",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
"integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"detect-libc": "^2.0.0", "detect-libc": "^2.0.0",
"expand-template": "^2.0.3", "expand-template": "^2.0.3",
@ -12966,9 +14466,7 @@
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
"integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
"dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
@ -13020,6 +14518,21 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0" "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
} }
}, },
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"license": "MIT",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"license": "MIT"
},
"node_modules/progress": { "node_modules/progress": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
@ -13038,6 +14551,27 @@
"asap": "~2.0.3" "asap": "~2.0.3"
} }
}, },
"node_modules/promise-inflight": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
"integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
"license": "ISC",
"optional": true
},
"node_modules/promise-retry": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
"integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
"license": "MIT",
"optional": true,
"dependencies": {
"err-code": "^2.0.2",
"retry": "^0.12.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/prompts": { "node_modules/prompts": {
"version": "2.4.2", "version": "2.4.2",
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
@ -13081,6 +14615,26 @@
"url": "https://github.com/sponsors/lupomontero" "url": "https://github.com/sponsors/lupomontero"
} }
}, },
"node_modules/public-encrypt": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
"integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
"license": "MIT",
"dependencies": {
"bn.js": "^4.1.0",
"browserify-rsa": "^4.0.0",
"create-hash": "^1.1.0",
"parse-asn1": "^5.0.0",
"randombytes": "^2.0.1",
"safe-buffer": "^5.1.2"
}
},
"node_modules/public-encrypt/node_modules/bn.js": {
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
"integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
"license": "MIT"
},
"node_modules/pump": { "node_modules/pump": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
@ -13125,6 +14679,21 @@
"qrcode-terminal": "bin/qrcode-terminal.js" "qrcode-terminal": "bin/qrcode-terminal.js"
} }
}, },
"node_modules/qs": {
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.1.0"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/query-string": { "node_modules/query-string": {
"version": "7.1.3", "version": "7.1.3",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz",
@ -13143,6 +14712,14 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/querystring-es3": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
"integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==",
"engines": {
"node": ">=0.4.x"
}
},
"node_modules/querystringify": { "node_modules/querystringify": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
@ -13183,13 +14760,21 @@
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"safe-buffer": "^5.1.0" "safe-buffer": "^5.1.0"
} }
}, },
"node_modules/randomfill": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
"integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
"license": "MIT",
"dependencies": {
"randombytes": "^2.0.5",
"safe-buffer": "^5.1.0"
}
},
"node_modules/range-parser": { "node_modules/range-parser": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@ -13321,19 +14906,19 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/react-native": { "node_modules/react-native": {
"version": "0.76.6", "version": "0.76.7",
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.76.6.tgz", "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.76.7.tgz",
"integrity": "sha512-AsRi+ud6v6ADH7ZtSOY42kRB4nbM0KtSu450pGO4pDudl4AEK/AF96ai88snb2/VJJSGGa/49QyJVFXxz/qoFg==", "integrity": "sha512-GPJcQeO3qUi1MvuhsC2DC6tH8gJQ4uc4JWPORrdeuCGFWE3QLsN8/hiChTEvJREHLfQSV61YPI8gIOtAQ8c37g==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@jest/create-cache-key-function": "^29.6.3", "@jest/create-cache-key-function": "^29.6.3",
"@react-native/assets-registry": "0.76.6", "@react-native/assets-registry": "0.76.7",
"@react-native/codegen": "0.76.6", "@react-native/codegen": "0.76.7",
"@react-native/community-cli-plugin": "0.76.6", "@react-native/community-cli-plugin": "0.76.7",
"@react-native/gradle-plugin": "0.76.6", "@react-native/gradle-plugin": "0.76.7",
"@react-native/js-polyfills": "0.76.6", "@react-native/js-polyfills": "0.76.7",
"@react-native/normalize-colors": "0.76.6", "@react-native/normalize-colors": "0.76.7",
"@react-native/virtualized-lists": "0.76.6", "@react-native/virtualized-lists": "0.76.7",
"abort-controller": "^3.0.0", "abort-controller": "^3.0.0",
"anser": "^1.4.9", "anser": "^1.4.9",
"ansi-regex": "^5.0.0", "ansi-regex": "^5.0.0",
@ -13557,34 +15142,6 @@
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/react-native/node_modules/@react-native/codegen": {
"version": "0.76.6",
"resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.76.6.tgz",
"integrity": "sha512-BABb3e5G/+hyQYEYi0AODWh2km2d8ERoASZr6Hv90pVXdUHRYR+yxCatX7vSd9rnDUYndqRTzD0hZWAucPNAKg==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.25.3",
"glob": "^7.1.1",
"hermes-parser": "0.23.1",
"invariant": "^2.2.4",
"jscodeshift": "^0.14.0",
"mkdirp": "^0.5.1",
"nullthrows": "^1.1.1",
"yargs": "^17.6.2"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@babel/preset-env": "^7.1.6"
}
},
"node_modules/react-native/node_modules/@react-native/normalize-colors": {
"version": "0.76.6",
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.76.6.tgz",
"integrity": "sha512-1n4udXH2Cla31iA/8eLRdhFHpYUYK1NKWCn4m1Sr9L4SarWKAYuRFliK1fcLvPPALCFoFlWvn8I0ekdUOHMzDQ==",
"license": "MIT"
},
"node_modules/react-native/node_modules/babel-plugin-syntax-hermes-parser": { "node_modules/react-native/node_modules/babel-plugin-syntax-hermes-parser": {
"version": "0.23.1", "version": "0.23.1",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.23.1.tgz", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.23.1.tgz",
@ -13708,19 +15265,43 @@
} }
}, },
"node_modules/readable-stream": { "node_modules/readable-stream": {
"version": "3.6.2", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"inherits": "^2.0.3", "abort-controller": "^3.0.0",
"string_decoder": "^1.1.1", "buffer": "^6.0.3",
"util-deprecate": "^1.0.1" "events": "^3.3.0",
"process": "^0.11.10",
"string_decoder": "^1.3.0"
}, },
"engines": { "engines": {
"node": ">= 6" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/readable-stream/node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
} }
}, },
"node_modules/readline": { "node_modules/readline": {
@ -13753,6 +15334,18 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/rechoir": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
"integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
"license": "MIT",
"dependencies": {
"resolve": "^1.20.0"
},
"engines": {
"node": ">= 10.13.0"
}
},
"node_modules/redent": { "node_modules/redent": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
@ -13904,7 +15497,6 @@
"version": "4.1.8", "version": "4.1.8",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz",
"integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==", "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/resolve": { "node_modules/resolve": {
@ -13977,6 +15569,16 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
"integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/reusify": { "node_modules/reusify": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@ -14024,6 +15626,16 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/ripemd160": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
"integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
"license": "MIT",
"dependencies": {
"hash-base": "^3.0.0",
"inherits": "^2.0.1"
}
},
"node_modules/run-parallel": { "node_modules/run-parallel": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@ -14348,6 +15960,13 @@
"integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==", "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
"license": "ISC",
"optional": true
},
"node_modules/set-cookie-parser": { "node_modules/set-cookie-parser": {
"version": "2.7.1", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
@ -14392,6 +16011,19 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/sha.js": {
"version": "2.4.11",
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"license": "(MIT AND BSD-3-Clause)",
"dependencies": {
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
},
"bin": {
"sha.js": "bin.js"
}
},
"node_modules/shallow-clone": { "node_modules/shallow-clone": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
@ -14443,6 +16075,78 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3",
"side-channel-list": "^1.0.0",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-list": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-map": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3",
"side-channel-map": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/signal-exit": { "node_modules/signal-exit": {
"version": "3.0.7", "version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
@ -14453,7 +16157,6 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
"dev": true,
"funding": [ "funding": [
{ {
"type": "github", "type": "github",
@ -14468,14 +16171,12 @@
"url": "https://feross.org/support" "url": "https://feross.org/support"
} }
], ],
"license": "MIT", "license": "MIT"
"peer": true
}, },
"node_modules/simple-get": { "node_modules/simple-get": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
"dev": true,
"funding": [ "funding": [
{ {
"type": "github", "type": "github",
@ -14491,7 +16192,6 @@
} }
], ],
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"decompress-response": "^6.0.0", "decompress-response": "^6.0.0",
"once": "^1.3.1", "once": "^1.3.1",
@ -14569,6 +16269,47 @@
"node": ">=8.0.0" "node": ">=8.0.0"
} }
}, },
"node_modules/smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/socks": {
"version": "2.8.4",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz",
"integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"ip-address": "^9.0.5",
"smart-buffer": "^4.2.0"
},
"engines": {
"node": ">= 10.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/socks-proxy-agent": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
"integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"agent-base": "^6.0.2",
"debug": "^4.3.3",
"socks": "^2.6.2"
},
"engines": {
"node": ">= 10"
}
},
"node_modules/source-map": { "node_modules/source-map": {
"version": "0.7.4", "version": "0.7.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
@ -14633,6 +16374,36 @@
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
"license": "BSD-3-Clause" "license": "BSD-3-Clause"
}, },
"node_modules/sqlite": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/sqlite/-/sqlite-5.1.1.tgz",
"integrity": "sha512-oBkezXa2hnkfuJwUo44Hl9hS3er+YFtueifoajrgidvqsJRQFpc5fKoAkAor1O5ZnLoa28GBScfHXs8j0K358Q==",
"license": "MIT"
},
"node_modules/sqlite3": {
"version": "5.1.7",
"resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz",
"integrity": "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==",
"hasInstallScript": true,
"license": "BSD-3-Clause",
"dependencies": {
"bindings": "^1.5.0",
"node-addon-api": "^7.0.0",
"prebuild-install": "^7.1.1",
"tar": "^6.1.11"
},
"optionalDependencies": {
"node-gyp": "8.x"
},
"peerDependencies": {
"node-gyp": "8.x"
},
"peerDependenciesMeta": {
"node-gyp": {
"optional": true
}
}
},
"node_modules/ssri": { "node_modules/ssri": {
"version": "10.0.6", "version": "10.0.6",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz",
@ -14745,6 +16516,30 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/stream-browserify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz",
"integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==",
"license": "MIT",
"dependencies": {
"inherits": "~2.0.4",
"readable-stream": "^3.5.0"
}
},
"node_modules/stream-browserify/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/stream-buffers": { "node_modules/stream-buffers": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz",
@ -14754,6 +16549,49 @@
"node": ">= 0.10.0" "node": ">= 0.10.0"
} }
}, },
"node_modules/stream-http": {
"version": "2.8.3",
"resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
"integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
"license": "MIT",
"dependencies": {
"builtin-status-codes": "^3.0.0",
"inherits": "^2.0.1",
"readable-stream": "^2.3.6",
"to-arraybuffer": "^1.0.0",
"xtend": "^4.0.0"
}
},
"node_modules/stream-http/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/stream-http/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/stream-http/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/stream-slice": { "node_modules/stream-slice": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/stream-slice/-/stream-slice-0.1.2.tgz", "resolved": "https://registry.npmjs.org/stream-slice/-/stream-slice-0.1.2.tgz",
@ -14773,9 +16611,7 @@
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"safe-buffer": "~5.2.0" "safe-buffer": "~5.2.0"
} }
@ -15072,9 +16908,7 @@
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz",
"integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"chownr": "^1.1.1", "chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2", "mkdirp-classic": "^0.5.2",
@ -15086,17 +16920,13 @@
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
"dev": true, "license": "ISC"
"license": "ISC",
"peer": true
}, },
"node_modules/tar-stream": { "node_modules/tar-stream": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"bl": "^4.0.3", "bl": "^4.0.3",
"end-of-stream": "^1.4.1", "end-of-stream": "^1.4.1",
@ -15108,6 +16938,20 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/tar-stream/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/tar/node_modules/fs-minipass": { "node_modules/tar/node_modules/fs-minipass": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
@ -15159,6 +17003,15 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/tarn": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz",
"integrity": "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==",
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/temp": { "node_modules/temp": {
"version": "0.8.4", "version": "0.8.4",
"resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz",
@ -15434,6 +17287,27 @@
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/tildify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz",
"integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/timers-browserify": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
"integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==",
"license": "MIT",
"dependencies": {
"setimmediate": "^1.0.4"
},
"engines": {
"node": ">=0.6.0"
}
},
"node_modules/tmp": { "node_modules/tmp": {
"version": "0.0.33", "version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@ -15452,6 +17326,12 @@
"integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
"license": "BSD-3-Clause" "license": "BSD-3-Clause"
}, },
"node_modules/to-arraybuffer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
"integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==",
"license": "MIT"
},
"node_modules/to-regex-range": { "node_modules/to-regex-range": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@ -15586,13 +17466,17 @@
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD" "license": "0BSD"
}, },
"node_modules/tty-browserify": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz",
"integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==",
"license": "MIT"
},
"node_modules/tunnel-agent": { "node_modules/tunnel-agent": {
"version": "0.6.0", "version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
"dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"dependencies": { "dependencies": {
"safe-buffer": "^5.0.1" "safe-buffer": "^5.0.1"
}, },
@ -15722,6 +17606,12 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/unimodules-app-loader": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/unimodules-app-loader/-/unimodules-app-loader-5.0.1.tgz",
"integrity": "sha512-JI4dUMOovvLrZ1U/mrQrR73cxGH26H7NpfBxwE0hk59CBOyHO4YYpliI3hPSGgZzt+YEy2VZR6nrspSUXY8jyw==",
"license": "MIT"
},
"node_modules/unique-filename": { "node_modules/unique-filename": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz",
@ -15817,6 +17707,19 @@
"punycode": "^2.1.0" "punycode": "^2.1.0"
} }
}, },
"node_modules/url": {
"version": "0.11.4",
"resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz",
"integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==",
"license": "MIT",
"dependencies": {
"punycode": "^1.4.1",
"qs": "^6.12.3"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/url-parse": { "node_modules/url-parse": {
"version": "1.5.10", "version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
@ -15828,6 +17731,12 @@
"requires-port": "^1.0.0" "requires-port": "^1.0.0"
} }
}, },
"node_modules/url/node_modules/punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
"license": "MIT"
},
"node_modules/use-latest-callback": { "node_modules/use-latest-callback": {
"version": "0.2.3", "version": "0.2.3",
"resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.2.3.tgz", "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.2.3.tgz",
@ -15863,9 +17772,7 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true, "license": "MIT"
"license": "MIT",
"peer": true
}, },
"node_modules/utils-merge": { "node_modules/utils-merge": {
"version": "1.0.1", "version": "1.0.1",
@ -15924,6 +17831,12 @@
"integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==", "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/vm-browserify": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
"license": "MIT"
},
"node_modules/w3c-xmlserializer": { "node_modules/w3c-xmlserializer": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
@ -16237,6 +18150,16 @@
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/wide-align": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
"license": "ISC",
"optional": true,
"dependencies": {
"string-width": "^1.0.2 || 2 || 3 || 4"
}
},
"node_modules/wonka": { "node_modules/wonka": {
"version": "6.3.4", "version": "6.3.4",
"resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.4.tgz", "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.4.tgz",
@ -16388,6 +18311,15 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"license": "MIT",
"engines": {
"node": ">=0.4"
}
},
"node_modules/y18n": { "node_modules/y18n": {
"version": "5.0.8", "version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",

View File

@ -4,41 +4,50 @@
"version": "1.0.0", "version": "1.0.0",
"scripts": { "scripts": {
"test": "jest --watch --coverage=false --changedSince=origin/main", "test": "jest --watch --coverage=false --changedSince=origin/main",
"testDebug": "jest -o --watch --coverage=false", "testDebug": "jest -o --watch --bail --coverage=false",
"testFinal": "jest", "testFinal": "jest",
"updateSnapshots": "jest -u --coverage=false", "updateSnapshots": "jest -u --coverage=false",
"start": "expo start", "start": "expo start",
"reset-project": "node ./scripts/reset-project.js", "reset-project": "node ./scripts/reset-project.js",
"android": "expo prebuild --npm -p android", "prebuild:android": "expo prebuild --npm -p android",
"android": "expo run:android",
"ios": "expo prebuild --npm -p android --offline", "ios": "expo prebuild --npm -p android --offline",
"web": "expo start --offline --web", "web": "expo start --offline --web",
"lint": "expo lint" "lint": "expo lint"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.26.7", "@babel/runtime": "^7.26.7",
"@expo/knex-expo-sqlite-dialect": "^0.0.1",
"@expo/vector-icons": "^14.0.4", "@expo/vector-icons": "^14.0.4",
"@mmomtchev/react-native-settings": "^1.1.0", "@mmomtchev/react-native-settings": "^1.1.0",
"@react-native-async-storage/async-storage": "^2.1.0", "@react-native-async-storage/async-storage": "^2.1.0",
"@react-native-picker/picker": "^2.11.0",
"@react-navigation/bottom-tabs": "^7.2.0", "@react-navigation/bottom-tabs": "^7.2.0",
"@react-navigation/native": "^7.0.14",
"@react-navigation/native-stack": "^7.2.0", "@react-navigation/native-stack": "^7.2.0",
"expo": "~52.0.28", "expo": "~52.0.28",
"expo-audio": "~0.3.4",
"expo-background-fetch": "~13.0.5",
"expo-blur": "~14.0.3", "expo-blur": "~14.0.3",
"expo-constants": "~17.0.5", "expo-constants": "~17.0.6",
"expo-crypto": "~14.0.2",
"expo-device": "~7.0.2",
"expo-file-system": "^18.0.10",
"expo-font": "~13.0.3", "expo-font": "~13.0.3",
"expo-haptics": "~14.0.1", "expo-haptics": "~14.0.1",
"expo-linking": "~7.0.5", "expo-linking": "~7.0.5",
"expo-notifications": "~0.29.13",
"expo-router": "~4.0.17", "expo-router": "~4.0.17",
"expo-screen-orientation": "~8.0.4", "expo-screen-orientation": "~8.0.4",
"expo-sharing": "^13.0.1",
"expo-splash-screen": "~0.29.21", "expo-splash-screen": "~0.29.21",
"expo-sqlite": "~15.1.2", "expo-sqlite": "^15.1.2",
"expo-status-bar": "~2.0.1", "expo-status-bar": "~2.0.1",
"expo-symbols": "~0.2.2", "expo-symbols": "~0.2.2",
"expo-system-ui": "~4.0.7", "expo-system-ui": "~4.0.7",
"expo-web-browser": "~14.0.2", "expo-web-browser": "~14.0.2",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-native": "0.76.6", "react-native": "^0.76.7",
"react-native-cache": "^2.0.3", "react-native-cache": "^2.0.3",
"react-native-country-flag": "^2.0.2", "react-native-country-flag": "^2.0.2",
"react-native-gesture-handler": "~2.20.2", "react-native-gesture-handler": "~2.20.2",
@ -49,43 +58,44 @@
"react-native-sqlite-storage": "^6.0.1", "react-native-sqlite-storage": "^6.0.1",
"react-native-web": "~0.19.13", "react-native-web": "~0.19.13",
"react-native-webview": "13.12.5", "react-native-webview": "13.12.5",
"readable-stream": "^4.7.0",
"sqlite": "^5.1.1",
"sqlite3": "^5.1.7",
"whisper.rn": "^0.3.9" "whisper.rn": "^0.3.9"
}, },
"jest": { "jest": {
"preset": "jest-expo", "preset": "jest-expo",
"testPathIgnorePatterns": [
".ollama"
],
"transformIgnorePatterns": [ "transformIgnorePatterns": [
"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg)" "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg)"
], ],
"collectCoverage": true,
"collectCoverageFrom": [
"**/*.{ts,tsx,js,jsx}",
"!**/coverage/**",
"!**/node_modules/**",
"!**/babel.config.js",
"!**/expo-env.d.ts",
"!**/.expo/**"
],
"automock": false, "automock": false,
"setupFilesAfterEnv": [ "setupFilesAfterEnv": [
"<rootDir>/jestSetup.ts" "<rootDir>/jestSetup.ts"
], ]
"testTimeout": 10000
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.26.7", "@babel/core": "^7.26.7",
"@babel/preset-typescript": "^7.26.0", "@babel/preset-typescript": "^7.26.0",
"@jest/globals": "^29.7.0", "@jest/globals": "^29.7.0",
"@react-navigation/native": "^7.0.14",
"@react-navigation/stack": "^7.1.1",
"@testing-library/react-native": "^13.0.1", "@testing-library/react-native": "^13.0.1",
"@types/jest": "^29.5.14", "@types/jest": "^29.5.14",
"@types/react": "~18.3.18", "@types/react": "~18.3.18",
"@types/react-native-sqlite-storage": "^6.0.5", "@types/react-native-sqlite-storage": "^6.0.5",
"@types/react-navigation": "^3.0.8",
"@types/react-test-renderer": "^18.3.1", "@types/react-test-renderer": "^18.3.1",
"@types/readable-stream": "^4.0.18",
"babel-jest": "^29.7.0", "babel-jest": "^29.7.0",
"babel-plugin-module-resolver": "^5.0.2", "babel-plugin-module-resolver": "^5.0.2",
"expo": "~52.0.28", "expo": "~52.0.28",
"expo-sqlite-mock": "^2.0.1", "expo-sqlite-mock": "^2.0.1",
"jest": "^29.7.0", "jest": "^29.7.0",
"jest-expo": "~52.0.3", "jest-expo": "~52.0.3",
"knex": "^3.1.0",
"metro-react-native-babel-preset": "^0.77.0", "metro-react-native-babel-preset": "^0.77.0",
"react-test-renderer": "18.3.1", "react-test-renderer": "18.3.1",
"ts-jest": "^29.2.5", "ts-jest": "^29.2.5",

BIN
translation_terrace.db Normal file

Binary file not shown.