diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 0d82694..ce3779c 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1 +1 @@
-{"lib":"2.0.4","packages/google-signin":"1.1.1"}
\ No newline at end of file
+{"lib":"2.0.4","packages/google-signin":"1.1.1","packages/apple-signin":"1.0.0"}
\ No newline at end of file
diff --git a/packages/apple-signin/README.md b/packages/apple-signin/README.md
new file mode 100644
index 0000000..7882ada
--- /dev/null
+++ b/packages/apple-signin/README.md
@@ -0,0 +1,224 @@
+# @forward-software/react-auth-apple
+
+Apple Sign-In adapter for [`@forward-software/react-auth`](https://github.com/forwardsoftware/react-auth) with support for **Web** and **React Native** (Expo).
+
+## Installation
+
+```bash
+npm install @forward-software/react-auth-apple @forward-software/react-auth
+# or
+pnpm add @forward-software/react-auth-apple @forward-software/react-auth
+```
+
+### React Native (Expo)
+
+This package includes an Expo native module. You need a **development build** (not Expo Go):
+
+```bash
+npx expo prebuild
+npx expo run:ios
+```
+
+No additional CocoaPods are required -- Apple Sign-In uses the system `AuthenticationServices` framework.
+
+## Quick Start
+
+### Web
+
+```tsx
+import { createAuth } from '@forward-software/react-auth';
+import { AppleAuthClient, AppleSignInButton } from '@forward-software/react-auth-apple';
+
+const appleClient = new AppleAuthClient({
+ clientId: 'com.example.service', // Your Apple Services ID
+ redirectURI: 'https://example.com/auth/apple/callback',
+});
+
+const { AuthProvider, useAuthClient } = createAuth(appleClient);
+
+function App() {
+ return (
+
+
+
+ );
+}
+
+function LoginScreen() {
+ const auth = useAuthClient();
+
+ return (
+ auth.login(credentials)}
+ onError={(error) => console.error(error)}
+ />
+ );
+}
+```
+
+### React Native
+
+```tsx
+import { createAuth } from '@forward-software/react-auth';
+import { AppleAuthClient, AppleSignInButton } from '@forward-software/react-auth-apple';
+import { MMKV } from 'react-native-mmkv';
+
+const mmkv = new MMKV();
+const storage = {
+ getItem: (key: string) => mmkv.getString(key) ?? null,
+ setItem: (key: string, value: string) => mmkv.set(key, value),
+ removeItem: (key: string) => mmkv.delete(key),
+};
+
+const appleClient = new AppleAuthClient({
+ clientId: 'com.example.app',
+ storage,
+});
+
+const { AuthProvider, useAuthClient } = createAuth(appleClient);
+
+function LoginScreen() {
+ const auth = useAuthClient();
+
+ return (
+ auth.login(credentials)}
+ onError={(error) => console.error(error)}
+ />
+ );
+}
+```
+
+## Web Setup
+
+1. Register a **Services ID** in the [Apple Developer Console](https://developer.apple.com/account/resources/identifiers/list/serviceId)
+2. Configure the **Sign in with Apple** capability with your domain and redirect URL
+3. Pass the Services ID as `clientId` and your registered redirect URL as `redirectURI`
+
+## React Native Setup
+
+### iOS
+
+No additional setup is needed beyond enabling the **Sign in with Apple** capability in your Xcode project:
+
+1. Open your project in Xcode
+2. Go to **Signing & Capabilities**
+3. Click **+ Capability** and add **Sign in with Apple**
+
+### Android
+
+Apple Sign-In on Android uses a web-based OAuth flow via Chrome Custom Tabs. This requires a **backend intermediary** because Apple uses `response_mode=form_post`:
+
+1. Your backend receives the POST from Apple at your `androidRedirectUri`
+2. It extracts the `id_token` and `code` from the POST body
+3. It redirects back to your app via a deep link with these parameters
+
+```tsx
+ auth.login(credentials)}
+/>
+```
+
+## Button Props
+
+### Web (`AppleSignInButton`)
+
+| Prop | Type | Default | Description |
+|------|------|---------|-------------|
+| `config` | `AppleWebAuthConfig` | required | Apple Sign-In configuration |
+| `onCredential` | `(credentials) => void` | required | Called with credentials on success |
+| `onError` | `(error) => void` | - | Called on error |
+| `color` | `'black' \| 'white' \| 'white-outline'` | `'black'` | Button color scheme |
+| `type` | `'sign-in' \| 'continue' \| 'sign-up'` | `'sign-in'` | Button label type |
+| `label` | `string` | Based on `type` | Custom label for localization |
+| `width` | `number` | auto | Button width in pixels |
+| `height` | `number` | `44` | Button height in pixels |
+
+### React Native (`AppleSignInButton`)
+
+| Prop | Type | Default | Description |
+|------|------|---------|-------------|
+| `config` | `AppleNativeAuthConfig` | required | Apple Sign-In configuration |
+| `onCredential` | `(credentials) => void` | required | Called with credentials on success |
+| `onError` | `(error) => void` | - | Called on error |
+| `style` | `StyleProp` | - | Additional button styles |
+| `disabled` | `boolean` | `false` | Disable the button |
+| `color` | `'black' \| 'white'` | `'black'` | Button color scheme |
+| `label` | `string` | `'Sign in with Apple'` | Custom label for localization |
+
+## Manual Integration
+
+You can use the SDK wrapper directly for custom flows:
+
+```ts
+// Web
+import { loadAppleIdScript, initializeAppleAuth, signInWithApple } from '@forward-software/react-auth-apple/web/appleid';
+
+await loadAppleIdScript();
+initializeAppleAuth({
+ clientId: 'com.example.service',
+ scope: 'name email',
+ redirectURI: 'https://example.com/callback',
+ usePopup: true,
+});
+const response = await signInWithApple();
+```
+
+```ts
+// React Native
+import { AppleSignInModule } from '@forward-software/react-auth-apple';
+
+AppleSignInModule.configure({ scopes: ['name', 'email'] });
+const credentials = await AppleSignInModule.signIn();
+const state = await AppleSignInModule.getCredentialState(credentials.user);
+```
+
+## Token Behavior
+
+- **Identity Token**: Apple issues a JWT `identityToken` (similar to Google's `idToken`). The `exp` claim is extracted automatically for expiration tracking.
+- **First Authorization Only**: Apple provides user info (email, name) only on the **first** authorization. Subsequent sign-ins return only the `identityToken` and `user` ID. Store user info on your backend after the first login.
+- **Credential State**: On iOS, you can check if the user's Apple ID is still authorized via `getCredentialState()`. This is used during token refresh instead of silent re-authentication.
+- **No Client-Side Refresh**: Apple does not support client-side token refresh. When the identity token expires, the user must re-authenticate.
+
+## API Reference
+
+### Types
+
+- `AppleAuthTokens` - Token object stored after sign-in
+- `AppleAuthCredentials` - Credentials passed to `login()`
+- `AppleFullName` - Structured name (givenName, familyName, etc.)
+- `AppleWebAuthConfig` - Web configuration
+- `AppleNativeAuthConfig` - Native configuration
+- `AppleScope` - `'name' | 'email'`
+- `TokenStorage` - Storage interface for persistence
+
+### Classes
+
+- `AppleAuthClient` - Implements `AuthClient`
+
+### Functions (Web SDK)
+
+- `loadAppleIdScript()` - Load the Apple JS SDK
+- `initializeAppleAuth(config)` - Initialize the SDK
+- `signInWithApple()` - Trigger sign-in flow
+
+### Functions (Native Module)
+
+- `AppleSignInModule.configure(config)` - Configure the native module
+- `AppleSignInModule.signIn()` - Trigger native sign-in
+- `AppleSignInModule.getCredentialState(userID)` - Check credential state (iOS only)
+- `AppleSignInModule.signOut()` - Sign out (no-op, clears JS-side storage)
+
+## License
+
+MIT
diff --git a/packages/apple-signin/android/build.gradle b/packages/apple-signin/android/build.gradle
new file mode 100644
index 0000000..fbe7dc2
--- /dev/null
+++ b/packages/apple-signin/android/build.gradle
@@ -0,0 +1,35 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+
+group = 'expo.modules.applesignin'
+version = '1.0.0'
+
+android {
+ namespace "expo.modules.applesignin"
+ compileSdkVersion safeExtGet("compileSdkVersion", 34)
+
+ defaultConfig {
+ minSdkVersion safeExtGet("minSdkVersion", 23)
+ targetSdkVersion safeExtGet("targetSdkVersion", 34)
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
+ }
+
+ kotlinOptions {
+ jvmTarget = "17"
+ }
+}
+
+dependencies {
+ implementation project(':expo-modules-core')
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${safeExtGet('kotlinVersion', '1.9.24')}"
+
+ implementation 'androidx.browser:browser:1.8.0'
+}
+
+def safeExtGet(prop, fallback) {
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
+}
diff --git a/packages/apple-signin/android/src/main/java/expo/modules/applesignin/AppleSignInModule.kt b/packages/apple-signin/android/src/main/java/expo/modules/applesignin/AppleSignInModule.kt
new file mode 100644
index 0000000..8c8a16a
--- /dev/null
+++ b/packages/apple-signin/android/src/main/java/expo/modules/applesignin/AppleSignInModule.kt
@@ -0,0 +1,123 @@
+package expo.modules.applesignin
+
+import android.net.Uri
+import androidx.browser.customtabs.CustomTabsIntent
+import expo.modules.kotlin.Promise
+import expo.modules.kotlin.exception.CodedException
+import expo.modules.kotlin.modules.Module
+import expo.modules.kotlin.modules.ModuleDefinition
+
+/**
+ * Apple Sign-In on Android uses web-based OAuth via Custom Tabs.
+ *
+ * Apple's authorization endpoint uses response_mode=form_post, which means
+ * the response is POSTed to your redirectUri. A backend intermediary is required
+ * to convert this POST into a deep link redirect back to your app with the
+ * id_token and authorization code as query parameters.
+ */
+class AppleSignInModule : Module() {
+ private var clientId: String? = null
+ private var redirectUri: String? = null
+ private var scopes: List = listOf("name", "email")
+ private var nonce: String? = null
+ private var state: String? = null
+ private var pendingPromise: Promise? = null
+
+ override fun definition() = ModuleDefinition {
+ Name("AppleSignIn")
+
+ Function("configure") { config: Map ->
+ clientId = config["clientId"] as? String
+ redirectUri = config["redirectUri"] as? String
+ scopes = (config["scopes"] as? List<*>)?.filterIsInstance() ?: listOf("name", "email")
+ nonce = config["nonce"] as? String
+ state = config["state"] as? String
+ }
+
+ AsyncFunction("signIn") { promise: Promise ->
+ val cid = clientId
+ if (cid == null) {
+ promise.reject(CodedException("NOT_CONFIGURED", "AppleSignIn has not been configured with a clientId. Call configure() first.", null))
+ return@AsyncFunction
+ }
+
+ val redirect = redirectUri
+ if (redirect == null) {
+ promise.reject(CodedException("MISSING_REDIRECT_URI", "androidRedirectUri is required for Apple Sign-In on Android.", null))
+ return@AsyncFunction
+ }
+
+ val activity = appContext.currentActivity
+ if (activity == null) {
+ promise.reject(CodedException("NO_ACTIVITY", "No current activity available", null))
+ return@AsyncFunction
+ }
+
+ val scopeString = scopes.joinToString(" ")
+ val uriBuilder = Uri.parse("https://appleid.apple.com/auth/authorize").buildUpon()
+ .appendQueryParameter("client_id", cid)
+ .appendQueryParameter("redirect_uri", redirect)
+ .appendQueryParameter("response_type", "code id_token")
+ .appendQueryParameter("response_mode", "form_post")
+ .appendQueryParameter("scope", scopeString)
+
+ nonce?.let { uriBuilder.appendQueryParameter("nonce", it) }
+ state?.let { uriBuilder.appendQueryParameter("state", it) }
+
+ pendingPromise = promise
+
+ try {
+ val customTabsIntent = CustomTabsIntent.Builder().build()
+ customTabsIntent.launchUrl(activity, uriBuilder.build())
+ } catch (e: Exception) {
+ pendingPromise = null
+ promise.reject(CodedException("SIGN_IN_FAILED", "Failed to launch Apple Sign-In: ${e.message}", e))
+ }
+ }
+
+ /**
+ * Called from your app's deep link handler after the backend redirects
+ * with the Apple Sign-In response parameters.
+ */
+ Function("handleCallback") { params: Map ->
+ val promise = pendingPromise
+ if (promise == null) {
+ throw CodedException("NO_PENDING_SIGN_IN", "No pending sign-in to handle", null)
+ }
+
+ pendingPromise = null
+
+ val identityToken = params["id_token"] as? String
+ if (identityToken == null) {
+ promise.reject(CodedException("MISSING_TOKEN", "No identity token in callback", null))
+ return@Function
+ }
+
+ val response = mutableMapOf(
+ "identityToken" to identityToken,
+ )
+
+ val code = params["code"] as? String
+ if (code != null) {
+ response["authorizationCode"] = code
+ }
+
+ val user = params["user"] as? String
+ if (user != null) {
+ response["user"] = user
+ }
+
+ promise.resolve(response)
+ }
+
+ AsyncFunction("getCredentialState") { _: String, promise: Promise ->
+ // Apple credential state is not available on Android
+ promise.reject(CodedException("UNSUPPORTED", "getCredentialState is not supported on Android", null))
+ }
+
+ AsyncFunction("signOut") { promise: Promise ->
+ // Apple has no sign-out API; clearing is handled on the JS side
+ promise.resolve(null)
+ }
+ }
+}
diff --git a/packages/apple-signin/expo-module.config.json b/packages/apple-signin/expo-module.config.json
new file mode 100644
index 0000000..c645847
--- /dev/null
+++ b/packages/apple-signin/expo-module.config.json
@@ -0,0 +1,9 @@
+{
+ "platforms": ["apple", "android"],
+ "apple": {
+ "modules": ["AppleSignInModule"]
+ },
+ "android": {
+ "modules": ["expo.modules.applesignin.AppleSignInModule"]
+ }
+}
diff --git a/packages/apple-signin/ios/AppleSignInModule.swift b/packages/apple-signin/ios/AppleSignInModule.swift
new file mode 100644
index 0000000..c30db4c
--- /dev/null
+++ b/packages/apple-signin/ios/AppleSignInModule.swift
@@ -0,0 +1,201 @@
+import ExpoModulesCore
+import AuthenticationServices
+import CryptoKit
+
+public class AppleSignInModule: Module {
+ private var scopes: [ASAuthorization.Scope] = []
+ private var rawNonce: String?
+
+ public func definition() -> ModuleDefinition {
+ Name("AppleSignIn")
+
+ Function("configure") { (config: [String: Any]) in
+ self.scopes = []
+
+ if let scopeStrings = config["scopes"] as? [String] {
+ for scope in scopeStrings {
+ switch scope {
+ case "name":
+ self.scopes.append(.fullName)
+ case "email":
+ self.scopes.append(.email)
+ default:
+ break
+ }
+ }
+ }
+
+ self.rawNonce = config["nonce"] as? String
+ }
+
+ AsyncFunction("signIn") { (promise: Promise) in
+ guard let presentingViewController = self.getPresentingViewController() else {
+ promise.reject(AppleSignInError.noPresentingViewController)
+ return
+ }
+
+ let provider = ASAuthorizationAppleIDProvider()
+ let request = provider.createRequest()
+ request.requestedScopes = self.scopes
+
+ if let nonce = self.rawNonce {
+ request.nonce = self.sha256(nonce)
+ }
+
+ let delegate = SignInDelegate(promise: promise, rawNonce: self.rawNonce)
+ let controller = ASAuthorizationController(authorizationRequests: [request])
+ controller.delegate = delegate
+ controller.presentationContextProvider = PresentationContextProvider(window: presentingViewController.view.window)
+
+ // Prevent delegate from being deallocated during async flow
+ objc_setAssociatedObject(controller, "delegate", delegate, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+
+ controller.performRequests()
+ }
+
+ AsyncFunction("getCredentialState") { (userID: String, promise: Promise) in
+ let provider = ASAuthorizationAppleIDProvider()
+ provider.getCredentialState(forUserID: userID) { state, error in
+ if let error = error {
+ promise.reject(AppleSignInError.credentialStateFailed(error.localizedDescription))
+ return
+ }
+
+ switch state {
+ case .authorized:
+ promise.resolve("authorized")
+ case .revoked:
+ promise.resolve("revoked")
+ case .notFound:
+ promise.resolve("notFound")
+ case .transferred:
+ promise.resolve("transferred")
+ @unknown default:
+ promise.resolve("notFound")
+ }
+ }
+ }
+
+ AsyncFunction("signOut") { (promise: Promise) in
+ // Apple has no sign-out API; clearing is handled on the JS side
+ promise.resolve(nil)
+ }
+ }
+
+ private func getPresentingViewController() -> UIViewController? {
+ guard let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
+ let window = scene.windows.first(where: { $0.isKeyWindow }),
+ let rootViewController = window.rootViewController else {
+ return nil
+ }
+
+ var topController = rootViewController
+ while let presented = topController.presentedViewController {
+ topController = presented
+ }
+
+ return topController
+ }
+
+ private func sha256(_ input: String) -> String {
+ let inputData = Data(input.utf8)
+ let hashed = SHA256.hash(data: inputData)
+ return hashed.compactMap { String(format: "%02x", $0) }.joined()
+ }
+}
+
+private class SignInDelegate: NSObject, ASAuthorizationControllerDelegate {
+ private let promise: Promise
+ private let rawNonce: String?
+
+ init(promise: Promise, rawNonce: String?) {
+ self.promise = promise
+ self.rawNonce = rawNonce
+ super.init()
+ }
+
+ func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
+ guard let credential = authorization.credential as? ASAuthorizationAppleIDCredential else {
+ promise.reject(AppleSignInError.signInFailed("Unexpected credential type"))
+ return
+ }
+
+ var response: [String: Any] = [:]
+
+ if let identityTokenData = credential.identityToken,
+ let identityToken = String(data: identityTokenData, encoding: .utf8) {
+ response["identityToken"] = identityToken
+ } else {
+ promise.reject(AppleSignInError.signInFailed("No identity token returned"))
+ return
+ }
+
+ if let authCodeData = credential.authorizationCode,
+ let authorizationCode = String(data: authCodeData, encoding: .utf8) {
+ response["authorizationCode"] = authorizationCode
+ }
+
+ response["user"] = credential.user
+
+ if let email = credential.email {
+ response["email"] = email
+ }
+
+ if let fullName = credential.fullName {
+ var nameDict: [String: String] = [:]
+ if let givenName = fullName.givenName { nameDict["givenName"] = givenName }
+ if let familyName = fullName.familyName { nameDict["familyName"] = familyName }
+ if let middleName = fullName.middleName { nameDict["middleName"] = middleName }
+ if let namePrefix = fullName.namePrefix { nameDict["namePrefix"] = namePrefix }
+ if let nameSuffix = fullName.nameSuffix { nameDict["nameSuffix"] = nameSuffix }
+ if let nickname = fullName.nickname { nameDict["nickname"] = nickname }
+ if !nameDict.isEmpty {
+ response["fullName"] = nameDict
+ }
+ }
+
+ promise.resolve(response)
+ }
+
+ func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
+ let authError = error as? ASAuthorizationError
+ if authError?.code == .canceled {
+ promise.reject(AppleSignInError.cancelled)
+ } else {
+ promise.reject(AppleSignInError.signInFailed(error.localizedDescription))
+ }
+ }
+}
+
+private class PresentationContextProvider: NSObject, ASAuthorizationControllerPresentationContextProviding {
+ private let window: UIWindow?
+
+ init(window: UIWindow?) {
+ self.window = window
+ super.init()
+ }
+
+ func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
+ return window ?? ASPresentationAnchor()
+ }
+}
+
+enum AppleSignInError: Error, CustomStringConvertible {
+ case noPresentingViewController
+ case signInFailed(String)
+ case cancelled
+ case credentialStateFailed(String)
+
+ var description: String {
+ switch self {
+ case .noPresentingViewController:
+ return "Could not find a presenting view controller"
+ case .signInFailed(let message):
+ return "Sign-in failed: \(message)"
+ case .cancelled:
+ return "Sign-in was cancelled by the user"
+ case .credentialStateFailed(let message):
+ return "Credential state check failed: \(message)"
+ }
+ }
+}
diff --git a/packages/apple-signin/ios/react-auth-apple.podspec b/packages/apple-signin/ios/react-auth-apple.podspec
new file mode 100644
index 0000000..4be7bc0
--- /dev/null
+++ b/packages/apple-signin/ios/react-auth-apple.podspec
@@ -0,0 +1,20 @@
+require 'json'
+
+package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
+
+Pod::Spec.new do |s|
+ s.name = 'react-auth-apple'
+ s.version = package['version']
+ s.summary = package['description'] || 'Apple Sign-In for react-auth'
+ s.homepage = 'https://github.com/forwardsoftware/react-auth'
+ s.license = package['license']
+ s.author = 'ForWarD Software'
+ s.source = { :git => 'https://github.com/forwardsoftware/react-auth.git', :tag => s.version.to_s }
+
+ s.platform = :ios, '15.1'
+ s.swift_version = '5.0'
+ s.source_files = '**/*.{swift,h,m}'
+ s.frameworks = 'AuthenticationServices', 'CryptoKit'
+
+ s.dependency 'ExpoModulesCore'
+end
diff --git a/packages/apple-signin/package.json b/packages/apple-signin/package.json
new file mode 100644
index 0000000..b05cbfb
--- /dev/null
+++ b/packages/apple-signin/package.json
@@ -0,0 +1,87 @@
+{
+ "name": "@forward-software/react-auth-apple",
+ "description": "Apple Sign-In adapter for @forward-software/react-auth - Web and React Native/Expo",
+ "version": "1.0.0",
+ "author": "ForWarD Software (https://forwardsoftware.solutions/)",
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/forwardsoftware/react-auth.git",
+ "directory": "packages/apple-signin"
+ },
+ "homepage": "https://github.com/forwardsoftware/react-auth/tree/main/packages/apple-signin#readme",
+ "keywords": [
+ "react",
+ "react-native",
+ "auth",
+ "authentication",
+ "apple",
+ "apple-sign-in",
+ "sign-in-with-apple",
+ "expo",
+ "expo-modules-core"
+ ],
+ "main": "dist/index.js",
+ "types": "dist/index.d.ts",
+ "react-native": "dist/index.native.js",
+ "source": "src/index.ts",
+ "exports": {
+ ".": {
+ "react-native": "./dist/index.native.js",
+ "default": "./dist/index.js"
+ },
+ "./web/appleid": {
+ "types": "./dist/web/appleid.d.ts",
+ "default": "./dist/web/appleid.js"
+ }
+ },
+ "files": [
+ "dist",
+ "src",
+ "ios",
+ "android",
+ "expo-module.config.json",
+ "react-auth-apple.podspec"
+ ],
+ "scripts": {
+ "build:code": "tsc --removeComments",
+ "build:types": "tsc --declaration --emitDeclarationOnly",
+ "build": "npm-run-all clean build:*",
+ "lint": "eslint src",
+ "test": "vitest",
+ "test:watch": "vitest watch",
+ "clean": "rimraf dist"
+ },
+ "devDependencies": {
+ "@forward-software/react-auth": "^2.0.0",
+ "@testing-library/dom": "^10.4.1",
+ "@testing-library/jest-dom": "^6.9.1",
+ "@testing-library/react": "^16.3.2",
+ "@types/node": "^25.2.3",
+ "@types/react": "catalog:",
+ "@vitejs/plugin-react": "catalog:",
+ "expo-modules-core": "^55.0.17",
+ "jsdom": "catalog:",
+ "react": "catalog:",
+ "react-dom": "catalog:",
+ "react-native": "^0.84.1",
+ "rimraf": "catalog:",
+ "typescript": "catalog:",
+ "vite": "catalog:",
+ "vitest": "catalog:"
+ },
+ "peerDependencies": {
+ "@forward-software/react-auth": ">=2.0.0",
+ "expo-modules-core": ">=2.0.0",
+ "react": ">=16.8",
+ "react-native": ">=0.73.0"
+ },
+ "peerDependenciesMeta": {
+ "expo-modules-core": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+}
diff --git a/packages/apple-signin/react-auth-apple.podspec b/packages/apple-signin/react-auth-apple.podspec
new file mode 100644
index 0000000..1db91b8
--- /dev/null
+++ b/packages/apple-signin/react-auth-apple.podspec
@@ -0,0 +1,20 @@
+require 'json'
+
+package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
+
+Pod::Spec.new do |s|
+ s.name = 'react-auth-apple'
+ s.version = package['version']
+ s.summary = package['description'] || 'Apple Sign-In for react-auth'
+ s.homepage = 'https://github.com/forwardsoftware/react-auth'
+ s.license = package['license']
+ s.author = 'ForWarD Software'
+ s.source = { :git => 'https://github.com/forwardsoftware/react-auth.git', :tag => s.version.to_s }
+
+ s.platform = :ios, '15.1'
+ s.swift_version = '5.0'
+ s.source_files = 'ios/**/*.{swift,h,m}'
+ s.frameworks = 'AuthenticationServices', 'CryptoKit'
+
+ s.dependency 'ExpoModulesCore'
+end
diff --git a/packages/apple-signin/src/index.native.ts b/packages/apple-signin/src/index.native.ts
new file mode 100644
index 0000000..4b747da
--- /dev/null
+++ b/packages/apple-signin/src/index.native.ts
@@ -0,0 +1,4 @@
+export { AppleAuthClient } from './native';
+export { AppleSignInButton } from './native';
+export { AppleSignInModule } from './native';
+export * from './types';
diff --git a/packages/apple-signin/src/index.ts b/packages/apple-signin/src/index.ts
new file mode 100644
index 0000000..fb35506
--- /dev/null
+++ b/packages/apple-signin/src/index.ts
@@ -0,0 +1,3 @@
+export { AppleAuthClient } from './web';
+export { AppleSignInButton } from './web';
+export * from './types';
diff --git a/packages/apple-signin/src/native/AppleAuthClient.ts b/packages/apple-signin/src/native/AppleAuthClient.ts
new file mode 100644
index 0000000..d4da24e
--- /dev/null
+++ b/packages/apple-signin/src/native/AppleAuthClient.ts
@@ -0,0 +1,158 @@
+import type { AuthClient } from '@forward-software/react-auth';
+import type {
+ AppleAuthCredentials,
+ AppleAuthTokens,
+ AppleNativeAuthConfig,
+ TokenStorage,
+} from '../types';
+import { DEFAULT_SCOPES, DEFAULT_STORAGE_KEY } from '../types';
+import * as AppleSignInModule from './AppleSignInModule';
+
+export class AppleAuthClient implements AuthClient {
+ private config: AppleNativeAuthConfig;
+ private storage: TokenStorage;
+ private storageKey: string;
+ private configured = false;
+
+ constructor(config: AppleNativeAuthConfig) {
+ this.config = {
+ scopes: DEFAULT_SCOPES,
+ persistTokens: true,
+ ...config,
+ };
+ this.storage = config.storage;
+ this.storageKey = config.storageKey ?? DEFAULT_STORAGE_KEY;
+ }
+
+ async onInit(): Promise {
+ if (!this.configured) {
+ AppleSignInModule.configure(this.config);
+ this.configured = true;
+ }
+
+ if (!this.config.persistTokens) {
+ return null;
+ }
+
+ const raw = await this.storage.getItem(this.storageKey);
+ if (!raw) {
+ return null;
+ }
+
+ try {
+ const tokens: AppleAuthTokens = JSON.parse(raw);
+
+ // Check credential state if we have a user ID
+ if (tokens.user) {
+ try {
+ const state = await AppleSignInModule.getCredentialState(tokens.user);
+ if (state !== 'authorized') {
+ await this.storage.removeItem(this.storageKey);
+ return null;
+ }
+ } catch {
+ // If credential state check fails, fall back to expiry check
+ }
+ }
+
+ if (tokens.expiresAt && Date.now() >= tokens.expiresAt) {
+ await this.storage.removeItem(this.storageKey);
+ return null;
+ }
+
+ return tokens;
+ } catch {
+ await this.storage.removeItem(this.storageKey);
+ return null;
+ }
+ }
+
+ async onLogin(credentials?: AppleAuthCredentials): Promise {
+ if (!this.configured) {
+ AppleSignInModule.configure(this.config);
+ this.configured = true;
+ }
+
+ if (!credentials?.identityToken) {
+ throw new Error(
+ 'AppleAuthClient: credentials with identityToken are required. ' +
+ 'Trigger Apple Sign-In via AppleSignInButton or AppleSignInModule.signIn() and pass the result to login().'
+ );
+ }
+
+ const tokens = this.mapToTokens(credentials);
+ await this.persistTokens(tokens);
+ return tokens;
+ }
+
+ async onRefresh(currentTokens: AppleAuthTokens): Promise {
+ if (!this.configured) {
+ AppleSignInModule.configure(this.config);
+ this.configured = true;
+ }
+
+ // Check credential state if user ID is available
+ if (currentTokens.user) {
+ const state = await AppleSignInModule.getCredentialState(currentTokens.user);
+ if (state === 'authorized') {
+ return currentTokens;
+ }
+ throw new Error(
+ `Apple credential state is '${state}'. User must re-authenticate.`
+ );
+ }
+
+ // Without a user ID, check token expiry
+ if (currentTokens.expiresAt && Date.now() < currentTokens.expiresAt) {
+ return currentTokens;
+ }
+
+ throw new Error(
+ 'Apple identity token has expired and no user ID is available to check credential state. User must re-authenticate.'
+ );
+ }
+
+ async onLogout(): Promise {
+ await AppleSignInModule.signOut();
+ await this.storage.removeItem(this.storageKey);
+ }
+
+ private mapToTokens(credentials: AppleAuthCredentials): AppleAuthTokens {
+ return {
+ identityToken: credentials.identityToken,
+ authorizationCode: credentials.authorizationCode,
+ email: credentials.email,
+ fullName: credentials.fullName,
+ user: credentials.user,
+ expiresAt: this.extractExpiration(credentials.identityToken),
+ };
+ }
+
+ private async persistTokens(tokens: AppleAuthTokens): Promise {
+ if (this.config.persistTokens) {
+ await this.storage.setItem(this.storageKey, JSON.stringify(tokens));
+ }
+ }
+
+ private base64UrlDecode(input: string): string {
+ const base64 = input.replace(/-/g, '+').replace(/_/g, '/');
+ const padded = base64.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), '=');
+ return atob(padded);
+ }
+
+ private extractExpiration(identityToken: string): number | undefined {
+ try {
+ const payload = identityToken.split('.')[1];
+ if (!payload) return undefined;
+
+ const decodedJson = this.base64UrlDecode(payload);
+ const decoded = JSON.parse(decodedJson);
+ if (typeof decoded.exp === 'number') {
+ return decoded.exp * 1000;
+ }
+ return undefined;
+ } catch {
+ return undefined;
+ }
+ }
+}
diff --git a/packages/apple-signin/src/native/AppleSignInButton.tsx b/packages/apple-signin/src/native/AppleSignInButton.tsx
new file mode 100644
index 0000000..893e54b
--- /dev/null
+++ b/packages/apple-signin/src/native/AppleSignInButton.tsx
@@ -0,0 +1,107 @@
+import React, { useState, useCallback } from 'react';
+import type { StyleProp, ViewStyle } from 'react-native';
+import type { AppleAuthCredentials, AppleNativeAuthConfig } from '../types';
+import * as AppleSignInModule from './AppleSignInModule';
+
+type AppleSignInButtonColor = 'black' | 'white';
+
+type AppleSignInButtonProps = {
+ config: AppleNativeAuthConfig;
+ onCredential: (credentials: AppleAuthCredentials) => void;
+ onError?: (error: Error) => void;
+ style?: StyleProp;
+ disabled?: boolean;
+ color?: AppleSignInButtonColor;
+ /** Button label text. Defaults to "Sign in with Apple". Pass a custom string for localization. */
+ label?: string;
+};
+
+export function AppleSignInButton({
+ config,
+ onCredential,
+ onError,
+ style,
+ disabled = false,
+ color = 'black',
+ label = 'Sign in with Apple',
+}: AppleSignInButtonProps) {
+ const [isLoading, setIsLoading] = useState(false);
+
+ const isBlack = color === 'black';
+
+ const handlePress = useCallback(async () => {
+ if (isLoading || disabled) return;
+
+ setIsLoading(true);
+ try {
+ AppleSignInModule.configure(config);
+ const credentials = await AppleSignInModule.signIn();
+ onCredential(credentials);
+ } catch (err) {
+ onError?.(
+ err instanceof Error ? err : new Error('Apple Sign-In failed')
+ );
+ } finally {
+ setIsLoading(false);
+ }
+ }, [config, onCredential, onError, isLoading, disabled]);
+
+ const { View, Text, Pressable, ActivityIndicator } = require('react-native');
+
+ return (
+
+ {isLoading ? (
+
+ ) : (
+
+
+
+ {label}
+
+
+ )}
+
+ );
+}
+
+function AppleLogo({ color }: { color: string }) {
+ const { Text } = require('react-native');
+
+ return (
+
+ {'\uF8FF'}
+
+ );
+}
diff --git a/packages/apple-signin/src/native/AppleSignInModule.ts b/packages/apple-signin/src/native/AppleSignInModule.ts
new file mode 100644
index 0000000..32204b9
--- /dev/null
+++ b/packages/apple-signin/src/native/AppleSignInModule.ts
@@ -0,0 +1,44 @@
+import { requireNativeModule } from 'expo-modules-core';
+import { Platform } from 'react-native';
+import type { AppleAuthCredentials, AppleNativeAuthConfig, AppleScope } from '../types';
+
+type AppleCredentialState = 'authorized' | 'revoked' | 'notFound' | 'transferred';
+
+type NativeAppleSignInModule = {
+ configure(config: {
+ scopes?: string[];
+ nonce?: string;
+ }): void;
+
+ signIn(): Promise;
+ getCredentialState(userID: string): Promise;
+ signOut(): Promise;
+};
+
+const NativeModule = requireNativeModule('AppleSignIn');
+
+export function configure(config: AppleNativeAuthConfig): void {
+ const nativeConfig: { scopes?: string[]; nonce?: string; clientId?: string; redirectUri?: string } = {
+ scopes: config.scopes,
+ nonce: config.nonce,
+ };
+
+ if (Platform.OS === 'android') {
+ nativeConfig.clientId = config.clientId;
+ nativeConfig.redirectUri = config.androidRedirectUri;
+ }
+
+ NativeModule.configure(nativeConfig);
+}
+
+export function signIn(): Promise {
+ return NativeModule.signIn();
+}
+
+export function getCredentialState(userID: string): Promise {
+ return NativeModule.getCredentialState(userID);
+}
+
+export function signOut(): Promise {
+ return NativeModule.signOut();
+}
diff --git a/packages/apple-signin/src/native/index.ts b/packages/apple-signin/src/native/index.ts
new file mode 100644
index 0000000..bb4a59e
--- /dev/null
+++ b/packages/apple-signin/src/native/index.ts
@@ -0,0 +1,3 @@
+export { AppleAuthClient } from './AppleAuthClient';
+export { AppleSignInButton } from './AppleSignInButton';
+export * as AppleSignInModule from './AppleSignInModule';
diff --git a/packages/apple-signin/src/types.ts b/packages/apple-signin/src/types.ts
new file mode 100644
index 0000000..d4c7f73
--- /dev/null
+++ b/packages/apple-signin/src/types.ts
@@ -0,0 +1,95 @@
+/**
+ * Structured name returned by Apple Sign-In.
+ * Apple only provides this on the first authorization.
+ */
+export type AppleFullName = {
+ givenName?: string;
+ familyName?: string;
+ middleName?: string;
+ namePrefix?: string;
+ nameSuffix?: string;
+ nickname?: string;
+};
+
+/**
+ * Tokens returned by Apple Sign-In
+ */
+export type AppleAuthTokens = {
+ identityToken: string;
+ authorizationCode?: string;
+ email?: string;
+ fullName?: AppleFullName;
+ /** Stable user identifier. Consistent across sessions for the same Apple ID + app. */
+ user?: string;
+ expiresAt?: number;
+};
+
+/**
+ * Credentials passed to authClient.login() after an Apple Sign-In flow
+ */
+export type AppleAuthCredentials = {
+ identityToken: string;
+ authorizationCode?: string;
+ email?: string;
+ fullName?: AppleFullName;
+ user?: string;
+};
+
+/**
+ * Platform-agnostic storage interface for token persistence.
+ * Compatible with localStorage (web), MMKV, and AsyncStorage (React Native).
+ */
+export interface TokenStorage {
+ getItem(key: string): string | null | Promise;
+ setItem(key: string, value: string): void | Promise;
+ removeItem(key: string): void | Promise;
+}
+
+/**
+ * Scopes supported by Apple Sign-In.
+ * Apple only supports 'name' and 'email'.
+ */
+export type AppleScope = 'name' | 'email';
+
+/**
+ * Base configuration shared by web and native adapters
+ */
+export type AppleAuthConfig = {
+ /** Apple Services ID (web) or App Bundle ID context */
+ clientId: string;
+ scopes?: AppleScope[];
+ persistTokens?: boolean;
+ storage?: TokenStorage;
+ storageKey?: string;
+ /** Nonce to bind the identity token to a session and prevent replay attacks. */
+ nonce?: string;
+};
+
+/**
+ * Web-specific configuration (Sign in with Apple JS options)
+ */
+export type AppleWebAuthConfig = AppleAuthConfig & {
+ /** Required redirect URI registered in Apple Developer Console */
+ redirectURI: string;
+ /** Use popup flow instead of redirect (default: false) */
+ usePopup?: boolean;
+ /** Opaque state value for CSRF protection */
+ state?: string;
+};
+
+/**
+ * React Native-specific configuration
+ */
+export type AppleNativeAuthConfig = Omit & {
+ /** Storage adapter is required on native (e.g., MMKV or AsyncStorage wrapper). */
+ storage: TokenStorage;
+ /**
+ * Redirect URI for Android web-based Apple OAuth.
+ * Apple uses response_mode=form_post, so a backend intermediary is needed
+ * to convert the POST into a deep link redirect back to your app.
+ */
+ androidRedirectUri?: string;
+};
+
+export const DEFAULT_SCOPES: AppleScope[] = ['name', 'email'];
+export const DEFAULT_STORAGE_KEY = '@react-auth/apple-tokens';
diff --git a/packages/apple-signin/src/web/AppleAuthClient.ts b/packages/apple-signin/src/web/AppleAuthClient.ts
new file mode 100644
index 0000000..f40535b
--- /dev/null
+++ b/packages/apple-signin/src/web/AppleAuthClient.ts
@@ -0,0 +1,107 @@
+import type { AuthClient } from '@forward-software/react-auth';
+import type {
+ AppleAuthCredentials,
+ AppleAuthTokens,
+ AppleWebAuthConfig,
+ TokenStorage,
+} from '../types';
+import { DEFAULT_SCOPES, DEFAULT_STORAGE_KEY } from '../types';
+
+const defaultWebStorage: TokenStorage = {
+ getItem: (key) => localStorage.getItem(key),
+ setItem: (key, value) => localStorage.setItem(key, value),
+ removeItem: (key) => localStorage.removeItem(key),
+};
+
+export class AppleAuthClient implements AuthClient {
+ private config: AppleWebAuthConfig;
+ private storage: TokenStorage;
+ private storageKey: string;
+
+ constructor(config: AppleWebAuthConfig) {
+ this.config = {
+ scopes: DEFAULT_SCOPES,
+ persistTokens: true,
+ ...config,
+ };
+ this.storage = config.storage ?? defaultWebStorage;
+ this.storageKey = config.storageKey ?? DEFAULT_STORAGE_KEY;
+ }
+
+ async onInit(): Promise {
+ if (!this.config.persistTokens) {
+ return null;
+ }
+
+ const raw = await this.storage.getItem(this.storageKey);
+ if (!raw) {
+ return null;
+ }
+
+ try {
+ const tokens: AppleAuthTokens = JSON.parse(raw);
+
+ if (tokens.expiresAt && Date.now() >= tokens.expiresAt) {
+ await this.storage.removeItem(this.storageKey);
+ return null;
+ }
+
+ return tokens;
+ } catch {
+ await this.storage.removeItem(this.storageKey);
+ return null;
+ }
+ }
+
+ async onLogin(credentials?: AppleAuthCredentials): Promise {
+ if (!credentials?.identityToken) {
+ throw new Error(
+ 'AppleAuthClient: credentials with identityToken are required. ' +
+ 'Trigger Apple Sign-In via AppleSignInButton or the Apple JS API and pass the result to login().'
+ );
+ }
+
+ const expiresAt = this.extractExpiration(credentials.identityToken);
+
+ const tokens: AppleAuthTokens = {
+ identityToken: credentials.identityToken,
+ authorizationCode: credentials.authorizationCode,
+ email: credentials.email,
+ fullName: credentials.fullName,
+ user: credentials.user,
+ expiresAt,
+ };
+
+ if (this.config.persistTokens) {
+ await this.storage.setItem(this.storageKey, JSON.stringify(tokens));
+ }
+
+ return tokens;
+ }
+
+ async onLogout(): Promise {
+ await this.storage.removeItem(this.storageKey);
+ }
+
+ private base64UrlDecode(input: string): string {
+ const base64 = input.replace(/-/g, '+').replace(/_/g, '/');
+ const padded = base64.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), '=');
+ return atob(padded);
+ }
+
+ private extractExpiration(identityToken: string): number | undefined {
+ try {
+ const payload = identityToken.split('.')[1];
+ if (!payload) return undefined;
+
+ const decodedJson = this.base64UrlDecode(payload);
+ const decoded = JSON.parse(decodedJson);
+ if (typeof decoded.exp === 'number') {
+ return decoded.exp * 1000;
+ }
+ return undefined;
+ } catch {
+ return undefined;
+ }
+ }
+}
diff --git a/packages/apple-signin/src/web/AppleSignInButton.tsx b/packages/apple-signin/src/web/AppleSignInButton.tsx
new file mode 100644
index 0000000..401cdaf
--- /dev/null
+++ b/packages/apple-signin/src/web/AppleSignInButton.tsx
@@ -0,0 +1,144 @@
+import React, { useEffect, useRef, useCallback, useState } from 'react';
+import type { AppleAuthCredentials, AppleWebAuthConfig } from '../types';
+import { DEFAULT_SCOPES } from '../types';
+import { loadAppleIdScript, initializeAppleAuth, signInWithApple } from './appleid';
+
+type AppleSignInButtonColor = 'black' | 'white' | 'white-outline';
+type AppleSignInButtonType = 'sign-in' | 'continue' | 'sign-up';
+
+type AppleSignInButtonProps = {
+ config: AppleWebAuthConfig;
+ onCredential: (credentials: AppleAuthCredentials) => void;
+ onError?: (error: Error) => void;
+ color?: AppleSignInButtonColor;
+ type?: AppleSignInButtonType;
+ /** Button label text. Defaults based on `type` prop. Pass a custom string for localization. */
+ label?: string;
+ width?: number;
+ height?: number;
+};
+
+const DEFAULT_LABELS: Record = {
+ 'sign-in': 'Sign in with Apple',
+ 'continue': 'Continue with Apple',
+ 'sign-up': 'Sign up with Apple',
+};
+
+const BUTTON_STYLES: Record = {
+ 'black': { bg: '#000000', text: '#ffffff', border: '#000000' },
+ 'white': { bg: '#ffffff', text: '#000000', border: '#ffffff' },
+ 'white-outline': { bg: '#ffffff', text: '#000000', border: '#000000' },
+};
+
+const APPLE_LOGO_SVG = `data:image/svg+xml;base64,${btoa('')}`;
+
+export function AppleSignInButton({
+ config,
+ onCredential,
+ onError,
+ color = 'black',
+ type = 'sign-in',
+ label,
+ width,
+ height = 44,
+}: AppleSignInButtonProps) {
+ const [isLoading, setIsLoading] = useState(false);
+ const onCredentialRef = useRef(onCredential);
+ const onErrorRef = useRef(onError);
+
+ onCredentialRef.current = onCredential;
+ onErrorRef.current = onError;
+
+ const displayLabel = label ?? DEFAULT_LABELS[type];
+ const style = BUTTON_STYLES[color];
+
+ const initialize = useCallback(async () => {
+ try {
+ await loadAppleIdScript();
+
+ const scopes = (config.scopes ?? DEFAULT_SCOPES).join(' ');
+ initializeAppleAuth({
+ clientId: config.clientId,
+ scope: scopes,
+ redirectURI: config.redirectURI,
+ state: config.state,
+ nonce: config.nonce,
+ usePopup: config.usePopup,
+ });
+ } catch (err) {
+ onErrorRef.current?.(
+ err instanceof Error ? err : new Error('Failed to initialize Apple Sign-In')
+ );
+ }
+ }, [config.clientId, config.scopes, config.redirectURI, config.state, config.nonce, config.usePopup]);
+
+ useEffect(() => {
+ initialize();
+ }, [initialize]);
+
+ const handleClick = useCallback(async () => {
+ if (isLoading) return;
+
+ setIsLoading(true);
+ try {
+ const response = await signInWithApple();
+
+ const credentials: AppleAuthCredentials = {
+ identityToken: response.authorization.id_token,
+ authorizationCode: response.authorization.code,
+ email: response.user?.email,
+ fullName: response.user?.name
+ ? {
+ givenName: response.user.name.firstName,
+ familyName: response.user.name.lastName,
+ }
+ : undefined,
+ };
+
+ onCredentialRef.current(credentials);
+ } catch (err) {
+ onErrorRef.current?.(
+ err instanceof Error ? err : new Error('Apple Sign-In failed')
+ );
+ } finally {
+ setIsLoading(false);
+ }
+ }, [isLoading]);
+
+ return (
+
+ );
+}
diff --git a/packages/apple-signin/src/web/appleid.ts b/packages/apple-signin/src/web/appleid.ts
new file mode 100644
index 0000000..478d139
--- /dev/null
+++ b/packages/apple-signin/src/web/appleid.ts
@@ -0,0 +1,163 @@
+/**
+ * Thin wrapper around the Sign in with Apple JavaScript API.
+ * Dynamically loads the Apple ID script and provides typed access to its functionality.
+ */
+
+const APPLE_SCRIPT_SRC = 'https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js';
+const APPLE_SCRIPT_ID = '__apple-signin-script';
+const APPLE_SCRIPT_TIMEOUT_MS = 10_000;
+
+export type AppleSignInResponse = {
+ authorization: {
+ code: string;
+ id_token: string;
+ state?: string;
+ };
+ user?: {
+ email?: string;
+ name?: {
+ firstName?: string;
+ lastName?: string;
+ };
+ };
+};
+
+export type AppleSignInError = {
+ error: string;
+};
+
+export type AppleAuthInitConfig = {
+ clientId: string;
+ scope: string;
+ redirectURI: string;
+ state?: string;
+ nonce?: string;
+ usePopup?: boolean;
+};
+
+interface AppleIDAuth {
+ init(config: AppleAuthInitConfig): void;
+ signIn(): Promise;
+}
+
+declare global {
+ interface Window {
+ AppleID?: {
+ auth: AppleIDAuth;
+ };
+ }
+}
+
+let scriptLoadPromise: Promise | null = null;
+
+/**
+ * Loads the Sign in with Apple JS script if not already loaded.
+ * Returns a promise that resolves when the script is ready.
+ */
+export function loadAppleIdScript(): Promise {
+ if (scriptLoadPromise) {
+ return scriptLoadPromise;
+ }
+
+ if (typeof window === 'undefined') {
+ return Promise.reject(new Error('Apple Sign-In script can only be loaded in a browser environment'));
+ }
+
+ if (window.AppleID?.auth) {
+ scriptLoadPromise = Promise.resolve();
+ return scriptLoadPromise;
+ }
+
+ scriptLoadPromise = new Promise((resolve, reject) => {
+ const existingScript = document.getElementById(APPLE_SCRIPT_ID);
+ if (existingScript) {
+ if (window.AppleID?.auth) {
+ resolve();
+ return;
+ }
+
+ let settled = false;
+ const timeoutId = setTimeout(() => {
+ if (!settled) {
+ settled = true;
+ scriptLoadPromise = null;
+ reject(new Error('Sign in with Apple script load timed out'));
+ }
+ }, APPLE_SCRIPT_TIMEOUT_MS);
+
+ existingScript.addEventListener('load', () => {
+ if (!settled) {
+ settled = true;
+ clearTimeout(timeoutId);
+ resolve();
+ }
+ });
+ existingScript.addEventListener('error', () => {
+ if (!settled) {
+ settled = true;
+ clearTimeout(timeoutId);
+ scriptLoadPromise = null;
+ reject(new Error('Failed to load Sign in with Apple script'));
+ }
+ });
+ return;
+ }
+
+ let settled = false;
+ const timeoutId = setTimeout(() => {
+ if (!settled) {
+ settled = true;
+ scriptLoadPromise = null;
+ reject(new Error('Sign in with Apple script load timed out'));
+ }
+ }, APPLE_SCRIPT_TIMEOUT_MS);
+
+ const script = document.createElement('script');
+ script.id = APPLE_SCRIPT_ID;
+ script.src = APPLE_SCRIPT_SRC;
+ script.async = true;
+ script.defer = true;
+ script.onload = () => {
+ if (!settled) {
+ settled = true;
+ clearTimeout(timeoutId);
+ resolve();
+ }
+ };
+ script.onerror = () => {
+ if (!settled) {
+ settled = true;
+ clearTimeout(timeoutId);
+ scriptLoadPromise = null;
+ reject(new Error('Failed to load Sign in with Apple script'));
+ }
+ };
+ document.head.appendChild(script);
+ });
+
+ return scriptLoadPromise;
+}
+
+/**
+ * Returns the AppleID.auth API, throwing if the script is not loaded.
+ */
+function getAppleAuth(): AppleIDAuth {
+ if (!window.AppleID?.auth) {
+ throw new Error('Sign in with Apple script is not loaded. Call loadAppleIdScript() first.');
+ }
+ return window.AppleID.auth;
+}
+
+/**
+ * Initializes the Apple Sign-In client with the given configuration.
+ */
+export function initializeAppleAuth(config: AppleAuthInitConfig): void {
+ getAppleAuth().init(config);
+}
+
+/**
+ * Triggers the Apple Sign-In flow and returns the response.
+ */
+export function signInWithApple(): Promise {
+ return getAppleAuth().signIn();
+}
diff --git a/packages/apple-signin/src/web/index.ts b/packages/apple-signin/src/web/index.ts
new file mode 100644
index 0000000..d25435f
--- /dev/null
+++ b/packages/apple-signin/src/web/index.ts
@@ -0,0 +1,2 @@
+export { AppleAuthClient } from './AppleAuthClient';
+export { AppleSignInButton } from './AppleSignInButton';
diff --git a/packages/apple-signin/test/AppleAuthClient.native.spec.ts b/packages/apple-signin/test/AppleAuthClient.native.spec.ts
new file mode 100644
index 0000000..e6aae02
--- /dev/null
+++ b/packages/apple-signin/test/AppleAuthClient.native.spec.ts
@@ -0,0 +1,176 @@
+import { describe, it, expect, beforeEach, vi } from 'vitest';
+import { MockTokenStorage, createMockAppleIdToken, createExpiredMockAppleIdToken } from './test-utils';
+import { DEFAULT_STORAGE_KEY } from '../src/types';
+
+// Mock react-native Platform
+vi.mock('react-native', () => ({
+ Platform: { OS: 'ios' },
+}));
+
+// Mock the native module
+vi.mock('expo-modules-core', () => ({
+ requireNativeModule: () => ({
+ configure: vi.fn(),
+ signIn: vi.fn(),
+ getCredentialState: vi.fn(),
+ signOut: vi.fn(),
+ }),
+}));
+
+// Import after mocking
+import { AppleAuthClient } from '../src/native/AppleAuthClient';
+import * as AppleSignInModule from '../src/native/AppleSignInModule';
+
+describe('AppleAuthClient (Native)', () => {
+ let storage: MockTokenStorage;
+ let client: AppleAuthClient;
+
+ beforeEach(() => {
+ vi.clearAllMocks();
+ storage = new MockTokenStorage();
+ client = new AppleAuthClient({
+ clientId: 'com.example.app',
+ storage,
+ });
+ });
+
+ describe('onInit', () => {
+ it('should configure the native module and return null when no tokens are stored', async () => {
+ const configureSpy = vi.spyOn(AppleSignInModule, 'configure');
+
+ const result = await client.onInit();
+
+ expect(configureSpy).toHaveBeenCalledWith(
+ expect.objectContaining({ clientId: 'com.example.app' })
+ );
+ expect(result).toBeNull();
+ });
+
+ it('should return stored tokens when they are valid', async () => {
+ const identityToken = createMockAppleIdToken();
+ const tokens = {
+ identityToken,
+ user: '001234.abcdef1234567890.1234',
+ expiresAt: Date.now() + 3600000,
+ };
+ storage.setItem(DEFAULT_STORAGE_KEY, JSON.stringify(tokens));
+
+ vi.spyOn(AppleSignInModule, 'getCredentialState').mockResolvedValueOnce('authorized');
+
+ const result = await client.onInit();
+ expect(result).not.toBeNull();
+ expect(result!.identityToken).toBe(identityToken);
+ });
+
+ it('should return null when credential state is revoked', async () => {
+ const tokens = {
+ identityToken: createMockAppleIdToken(),
+ user: '001234.abcdef1234567890.1234',
+ expiresAt: Date.now() + 3600000,
+ };
+ storage.setItem(DEFAULT_STORAGE_KEY, JSON.stringify(tokens));
+
+ vi.spyOn(AppleSignInModule, 'getCredentialState').mockResolvedValueOnce('revoked');
+
+ const result = await client.onInit();
+ expect(result).toBeNull();
+ expect(storage.has(DEFAULT_STORAGE_KEY)).toBe(false);
+ });
+
+ it('should return null when tokens are expired and no user ID', async () => {
+ const expiredTokens = {
+ identityToken: createExpiredMockAppleIdToken(),
+ expiresAt: Date.now() - 3600000,
+ };
+ storage.setItem(DEFAULT_STORAGE_KEY, JSON.stringify(expiredTokens));
+
+ const result = await client.onInit();
+ expect(result).toBeNull();
+ expect(storage.has(DEFAULT_STORAGE_KEY)).toBe(false);
+ });
+ });
+
+ describe('onLogin', () => {
+ it('should store and return tokens when valid credentials are provided', async () => {
+ const identityToken = createMockAppleIdToken();
+ const credentials = {
+ identityToken,
+ user: '001234.abcdef1234567890.1234',
+ };
+
+ const result = await client.onLogin(credentials);
+
+ expect(result.identityToken).toBe(identityToken);
+ expect(result.user).toBe('001234.abcdef1234567890.1234');
+ expect(storage.has(DEFAULT_STORAGE_KEY)).toBe(true);
+ });
+
+ it('should throw when no credentials are provided', async () => {
+ await expect(client.onLogin()).rejects.toThrow('credentials with identityToken are required');
+ });
+ });
+
+ describe('onRefresh', () => {
+ it('should return current tokens if credential state is authorized', async () => {
+ const identityToken = createMockAppleIdToken();
+ const currentTokens = {
+ identityToken,
+ user: '001234.abcdef1234567890.1234',
+ expiresAt: Date.now() + 3600000,
+ };
+
+ vi.spyOn(AppleSignInModule, 'getCredentialState').mockResolvedValueOnce('authorized');
+
+ const result = await client.onRefresh(currentTokens);
+ expect(result).toBe(currentTokens);
+ });
+
+ it('should throw when credential state is revoked', async () => {
+ const currentTokens = {
+ identityToken: createMockAppleIdToken(),
+ user: '001234.abcdef1234567890.1234',
+ expiresAt: Date.now() + 3600000,
+ };
+
+ vi.spyOn(AppleSignInModule, 'getCredentialState').mockResolvedValueOnce('revoked');
+
+ await expect(client.onRefresh(currentTokens)).rejects.toThrow(
+ "Apple credential state is 'revoked'"
+ );
+ });
+
+ it('should return current tokens if no user ID but not expired', async () => {
+ const identityToken = createMockAppleIdToken();
+ const currentTokens = {
+ identityToken,
+ expiresAt: Date.now() + 3600000,
+ };
+
+ const result = await client.onRefresh(currentTokens);
+ expect(result).toBe(currentTokens);
+ });
+
+ it('should throw if no user ID and token is expired', async () => {
+ const currentTokens = {
+ identityToken: createExpiredMockAppleIdToken(),
+ expiresAt: Date.now() - 3600000,
+ };
+
+ await expect(client.onRefresh(currentTokens)).rejects.toThrow(
+ 'Apple identity token has expired'
+ );
+ });
+ });
+
+ describe('onLogout', () => {
+ it('should call signOut and clear storage', async () => {
+ const signOutSpy = vi.spyOn(AppleSignInModule, 'signOut').mockResolvedValueOnce();
+ storage.setItem(DEFAULT_STORAGE_KEY, JSON.stringify({ identityToken: 'test' }));
+
+ await client.onLogout();
+
+ expect(signOutSpy).toHaveBeenCalled();
+ expect(storage.has(DEFAULT_STORAGE_KEY)).toBe(false);
+ });
+ });
+});
diff --git a/packages/apple-signin/test/AppleAuthClient.web.spec.ts b/packages/apple-signin/test/AppleAuthClient.web.spec.ts
new file mode 100644
index 0000000..760a75a
--- /dev/null
+++ b/packages/apple-signin/test/AppleAuthClient.web.spec.ts
@@ -0,0 +1,184 @@
+import { describe, it, expect, beforeEach } from 'vitest';
+import { AppleAuthClient } from '../src/web/AppleAuthClient';
+import {
+ MockTokenStorage,
+ createMockAppleIdToken,
+ createExpiredMockAppleIdToken,
+} from './test-utils';
+import { DEFAULT_STORAGE_KEY } from '../src/types';
+
+describe('AppleAuthClient (Web)', () => {
+ let storage: MockTokenStorage;
+ let client: AppleAuthClient;
+
+ beforeEach(() => {
+ storage = new MockTokenStorage();
+ client = new AppleAuthClient({
+ clientId: 'com.example.app',
+ redirectURI: 'https://example.com/callback',
+ storage,
+ });
+ });
+
+ describe('onInit', () => {
+ it('should return null when no tokens are stored', async () => {
+ const result = await client.onInit();
+ expect(result).toBeNull();
+ });
+
+ it('should return stored tokens when they are valid', async () => {
+ const identityToken = createMockAppleIdToken();
+ const tokens = {
+ identityToken,
+ expiresAt: Date.now() + 3600000,
+ };
+ storage.setItem(DEFAULT_STORAGE_KEY, JSON.stringify(tokens));
+
+ const result = await client.onInit();
+ expect(result).not.toBeNull();
+ expect(result!.identityToken).toBe(identityToken);
+ });
+
+ it('should return null and clear storage when tokens are expired', async () => {
+ const tokens = {
+ identityToken: createExpiredMockAppleIdToken(),
+ expiresAt: Date.now() - 3600000,
+ };
+ storage.setItem(DEFAULT_STORAGE_KEY, JSON.stringify(tokens));
+
+ const result = await client.onInit();
+ expect(result).toBeNull();
+ expect(storage.has(DEFAULT_STORAGE_KEY)).toBe(false);
+ });
+
+ it('should return null and clear storage when stored data is corrupted', async () => {
+ storage.setItem(DEFAULT_STORAGE_KEY, 'not-valid-json');
+
+ const result = await client.onInit();
+ expect(result).toBeNull();
+ expect(storage.has(DEFAULT_STORAGE_KEY)).toBe(false);
+ });
+
+ it('should return null when persistTokens is false', async () => {
+ const clientNoPersist = new AppleAuthClient({
+ clientId: 'com.example.app',
+ redirectURI: 'https://example.com/callback',
+ storage,
+ persistTokens: false,
+ });
+
+ const tokens = {
+ identityToken: createMockAppleIdToken(),
+ expiresAt: Date.now() + 3600000,
+ };
+ storage.setItem(DEFAULT_STORAGE_KEY, JSON.stringify(tokens));
+
+ const result = await clientNoPersist.onInit();
+ expect(result).toBeNull();
+ });
+ });
+
+ describe('onLogin', () => {
+ it('should store and return tokens when valid credentials are provided', async () => {
+ const identityToken = createMockAppleIdToken();
+ const credentials = { identityToken };
+
+ const result = await client.onLogin(credentials);
+
+ expect(result.identityToken).toBe(identityToken);
+ expect(result.expiresAt).toBeDefined();
+ expect(storage.has(DEFAULT_STORAGE_KEY)).toBe(true);
+ });
+
+ it('should include optional fields when provided', async () => {
+ const identityToken = createMockAppleIdToken();
+ const credentials = {
+ identityToken,
+ authorizationCode: 'test-auth-code',
+ email: 'test@example.com',
+ fullName: { givenName: 'Test', familyName: 'User' },
+ user: '001234.abcdef1234567890.1234',
+ };
+
+ const result = await client.onLogin(credentials);
+
+ expect(result.authorizationCode).toBe('test-auth-code');
+ expect(result.email).toBe('test@example.com');
+ expect(result.fullName?.givenName).toBe('Test');
+ expect(result.user).toBe('001234.abcdef1234567890.1234');
+ });
+
+ it('should throw when no credentials are provided', async () => {
+ await expect(client.onLogin()).rejects.toThrow(
+ 'credentials with identityToken are required',
+ );
+ });
+
+ it('should throw when credentials have no identityToken', async () => {
+ await expect(client.onLogin({ identityToken: '' })).rejects.toThrow(
+ 'credentials with identityToken are required',
+ );
+ });
+
+ it('should not persist when persistTokens is false', async () => {
+ const clientNoPersist = new AppleAuthClient({
+ clientId: 'com.example.app',
+ redirectURI: 'https://example.com/callback',
+ storage,
+ persistTokens: false,
+ });
+
+ const identityToken = createMockAppleIdToken();
+ await clientNoPersist.onLogin({ identityToken });
+
+ expect(storage.has(DEFAULT_STORAGE_KEY)).toBe(false);
+ });
+
+ it('should use custom storage key when provided', async () => {
+ const customKey = 'my-custom-key';
+ const customClient = new AppleAuthClient({
+ clientId: 'com.example.app',
+ redirectURI: 'https://example.com/callback',
+ storage,
+ storageKey: customKey,
+ });
+
+ const identityToken = createMockAppleIdToken();
+ await customClient.onLogin({ identityToken });
+
+ expect(storage.has(customKey)).toBe(true);
+ expect(storage.has(DEFAULT_STORAGE_KEY)).toBe(false);
+ });
+ });
+
+ describe('onLogout', () => {
+ it('should clear stored tokens', async () => {
+ storage.setItem(DEFAULT_STORAGE_KEY, JSON.stringify({ identityToken: 'test' }));
+
+ await client.onLogout();
+
+ expect(storage.has(DEFAULT_STORAGE_KEY)).toBe(false);
+ });
+ });
+
+ describe('token expiration extraction', () => {
+ it('should extract expiration from a valid JWT', async () => {
+ const exp = Math.floor(Date.now() / 1000) + 7200;
+ const identityToken = createMockAppleIdToken({ exp });
+
+ const result = await client.onLogin({ identityToken });
+
+ expect(result.expiresAt).toBe(exp * 1000);
+ });
+
+ it('should handle tokens without exp claim', async () => {
+ const header = btoa(JSON.stringify({ alg: 'none' }));
+ const payload = btoa(JSON.stringify({ sub: '123' }));
+ const identityToken = `${header}.${payload}.sig`;
+
+ const result = await client.onLogin({ identityToken });
+
+ expect(result.expiresAt).toBeUndefined();
+ });
+ });
+});
diff --git a/packages/apple-signin/test/test-utils.ts b/packages/apple-signin/test/test-utils.ts
new file mode 100644
index 0000000..876170d
--- /dev/null
+++ b/packages/apple-signin/test/test-utils.ts
@@ -0,0 +1,49 @@
+import type { TokenStorage } from '../src/types';
+
+export class MockTokenStorage implements TokenStorage {
+ private store: Map = new Map();
+
+ getItem(key: string): string | null {
+ return this.store.get(key) ?? null;
+ }
+
+ setItem(key: string, value: string): void {
+ this.store.set(key, value);
+ }
+
+ removeItem(key: string): void {
+ this.store.delete(key);
+ }
+
+ clear(): void {
+ this.store.clear();
+ }
+
+ has(key: string): boolean {
+ return this.store.has(key);
+ }
+}
+
+export function createMockAppleIdToken(claims: Record = {}): string {
+ const header = btoa(JSON.stringify({ alg: 'RS256', typ: 'JWT' }));
+ const payload = btoa(
+ JSON.stringify({
+ iss: 'https://appleid.apple.com',
+ sub: '001234.abcdef1234567890.1234',
+ aud: 'com.example.app',
+ email: 'test@privaterelay.appleid.com',
+ email_verified: true,
+ iat: Math.floor(Date.now() / 1000),
+ exp: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
+ ...claims,
+ })
+ );
+ const signature = btoa('mock-signature');
+ return `${header}.${payload}.${signature}`;
+}
+
+export function createExpiredMockAppleIdToken(): string {
+ return createMockAppleIdToken({
+ exp: Math.floor(Date.now() / 1000) - 3600, // 1 hour ago
+ });
+}
diff --git a/packages/apple-signin/tsconfig.json b/packages/apple-signin/tsconfig.json
new file mode 100644
index 0000000..16b16a5
--- /dev/null
+++ b/packages/apple-signin/tsconfig.json
@@ -0,0 +1,24 @@
+{
+ "compilerOptions": {
+ "declaration": false,
+ "target": "ES6",
+ "moduleResolution": "node",
+ "strict": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "allowSyntheticDefaultImports": true,
+ "forceConsistentCasingInFileNames": true,
+ "removeComments": false,
+ "outDir": "./dist",
+ "rootDir": "./src",
+ "jsx": "react-jsx"
+ },
+ "include": [
+ "src/**/*"
+ ],
+ "exclude": [
+ "node_modules",
+ "**/*.test.ts",
+ "**/*.spec.ts"
+ ]
+}
diff --git a/packages/apple-signin/vitest.config.ts b/packages/apple-signin/vitest.config.ts
new file mode 100644
index 0000000..585aba6
--- /dev/null
+++ b/packages/apple-signin/vitest.config.ts
@@ -0,0 +1,16 @@
+import { defineConfig } from "vitest/config";
+import react from "@vitejs/plugin-react";
+
+export default defineConfig({
+ plugins: [react()],
+ test: {
+ environment: "jsdom",
+ globals: true,
+ include: ["**/*.{test,spec}.{js,jsx,ts,tsx}"],
+ coverage: {
+ reporter: ["clover", "lcov", "html"],
+ include: ["src/**/*.{js,jsx,ts,tsx}"],
+ exclude: ["**/*.d.ts"],
+ },
+ },
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 18087c3..0b18e32 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -83,7 +83,7 @@ importers:
version: 1.5.0
'@vitejs/plugin-react':
specifier: 'catalog:'
- version: 6.0.1(vite@8.0.0(@types/node@25.5.0))
+ version: 6.0.1(vite@8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2))
jsdom:
specifier: 'catalog:'
version: 29.0.0
@@ -95,10 +95,61 @@ importers:
version: 19.2.4(react@19.2.4)
vite:
specifier: 'catalog:'
- version: 8.0.0(@types/node@25.5.0)
+ version: 8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2)
vitest:
specifier: 'catalog:'
- version: 4.1.0(@types/node@25.5.0)(jsdom@29.0.0)(vite@8.0.0(@types/node@25.5.0))
+ version: 4.1.0(@types/node@25.5.0)(jsdom@29.0.0)(vite@8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2))
+
+ packages/apple-signin:
+ devDependencies:
+ '@forward-software/react-auth':
+ specifier: ^2.0.0
+ version: 2.0.3(react@19.2.4)
+ '@testing-library/dom':
+ specifier: ^10.4.1
+ version: 10.4.1
+ '@testing-library/jest-dom':
+ specifier: ^6.9.1
+ version: 6.9.1
+ '@testing-library/react':
+ specifier: ^16.3.2
+ version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
+ '@types/node':
+ specifier: ^25.2.3
+ version: 25.5.0
+ '@types/react':
+ specifier: 'catalog:'
+ version: 19.2.14
+ '@vitejs/plugin-react':
+ specifier: 'catalog:'
+ version: 6.0.1(vite@8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2))
+ expo-modules-core:
+ specifier: ^55.0.17
+ version: 55.0.17(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
+ jsdom:
+ specifier: 'catalog:'
+ version: 29.0.0
+ react:
+ specifier: 'catalog:'
+ version: 19.2.4
+ react-dom:
+ specifier: 'catalog:'
+ version: 19.2.4(react@19.2.4)
+ react-native:
+ specifier: ^0.84.1
+ version: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
+ rimraf:
+ specifier: 'catalog:'
+ version: 6.1.3
+ typescript:
+ specifier: 'catalog:'
+ version: 5.9.3
+ vite:
+ specifier: 'catalog:'
+ version: 8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2)
+ vitest:
+ specifier: 'catalog:'
+ version: 4.1.0(@types/node@25.5.0)(jsdom@29.0.0)(vite@8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2))
packages/google-signin:
devDependencies:
@@ -122,7 +173,7 @@ importers:
version: 19.2.14
'@vitejs/plugin-react':
specifier: 'catalog:'
- version: 6.0.1(vite@8.0.0(@types/node@25.5.0))
+ version: 6.0.1(vite@8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2))
jsdom:
specifier: 'catalog:'
version: 29.0.0
@@ -140,10 +191,10 @@ importers:
version: 5.9.3
vite:
specifier: 'catalog:'
- version: 8.0.0(@types/node@25.5.0)
+ version: 8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2)
vitest:
specifier: 'catalog:'
- version: 4.1.0(@types/node@25.5.0)(jsdom@29.0.0)(vite@8.0.0(@types/node@25.5.0))
+ version: 4.1.0(@types/node@25.5.0)(jsdom@29.0.0)(vite@8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2))
packages:
@@ -165,14 +216,156 @@ packages:
resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
engines: {node: '>=6.9.0'}
+ '@babel/compat-data@7.29.0':
+ resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/core@7.29.0':
+ resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/generator@7.29.1':
+ resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-compilation-targets@7.28.6':
+ resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-globals@7.28.0':
+ resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-imports@7.28.6':
+ resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-transforms@7.28.6':
+ resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+
+ '@babel/helper-plugin-utils@7.28.6':
+ resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-string-parser@7.27.1':
+ resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
+ engines: {node: '>=6.9.0'}
+
'@babel/helper-validator-identifier@7.28.5':
resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
engines: {node: '>=6.9.0'}
+ '@babel/helper-validator-option@7.27.1':
+ resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helpers@7.29.2':
+ resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.29.2':
+ resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/plugin-syntax-async-generators@7.8.4':
+ resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-syntax-bigint@7.8.3':
+ resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-syntax-class-properties@7.12.13':
+ resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-syntax-class-static-block@7.14.5':
+ resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-syntax-import-attributes@7.28.6':
+ resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-syntax-import-meta@7.10.4':
+ resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-syntax-json-strings@7.8.3':
+ resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-syntax-logical-assignment-operators@7.10.4':
+ resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3':
+ resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-syntax-numeric-separator@7.10.4':
+ resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-syntax-object-rest-spread@7.8.3':
+ resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-syntax-optional-catch-binding@7.8.3':
+ resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-syntax-optional-chaining@7.8.3':
+ resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-syntax-private-property-in-object@7.14.5':
+ resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-syntax-top-level-await@7.14.5':
+ resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
'@babel/runtime@7.29.2':
resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==}
engines: {node: '>=6.9.0'}
+ '@babel/template@7.28.6':
+ resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/traverse@7.29.0':
+ resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/types@7.29.0':
+ resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
+ engines: {node: '>=6.9.0'}
+
'@bramus/specificity@2.4.2':
resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==}
hasBin: true
@@ -236,9 +429,61 @@ packages:
peerDependencies:
react: '>=16.8'
+ '@isaacs/ttlcache@1.4.1':
+ resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==}
+ engines: {node: '>=12'}
+
+ '@istanbuljs/load-nyc-config@1.1.0':
+ resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==}
+ engines: {node: '>=8'}
+
+ '@istanbuljs/schema@0.1.3':
+ resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==}
+ engines: {node: '>=8'}
+
+ '@jest/create-cache-key-function@29.7.0':
+ resolution: {integrity: sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ '@jest/environment@29.7.0':
+ resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ '@jest/fake-timers@29.7.0':
+ resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ '@jest/schemas@29.6.3':
+ resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ '@jest/transform@29.7.0':
+ resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ '@jest/types@29.6.3':
+ resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ '@jridgewell/gen-mapping@0.3.13':
+ resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
+
+ '@jridgewell/remapping@2.3.5':
+ resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/source-map@0.3.11':
+ resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==}
+
'@jridgewell/sourcemap-codec@1.5.5':
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+ '@jridgewell/trace-mapping@0.3.31':
+ resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+
'@napi-rs/wasm-runtime@1.1.1':
resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==}
@@ -249,6 +494,60 @@ packages:
'@oxc-project/types@0.115.0':
resolution: {integrity: sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw==}
+ '@react-native/assets-registry@0.84.1':
+ resolution: {integrity: sha512-lAJ6PDZv95FdT9s9uhc9ivhikW1Zwh4j9XdXM7J2l4oUA3t37qfoBmTSDLuPyE3Bi+Xtwa11hJm0BUTT2sc/gg==}
+ engines: {node: '>= 20.19.4'}
+
+ '@react-native/codegen@0.84.1':
+ resolution: {integrity: sha512-n1RIU0QAavgCg1uC5+s53arL7/mpM+16IBhJ3nCFSd/iK5tUmCwxQDcIDC703fuXfpub/ZygeSjVN8bcOWn0gA==}
+ engines: {node: '>= 20.19.4'}
+
+ '@react-native/community-cli-plugin@0.84.1':
+ resolution: {integrity: sha512-f6a+mJEJ6Joxlt/050TqYUr7uRRbeKnz8lnpL7JajhpsgZLEbkJRjH8HY5QiLcRdUwWFtizml4V+vcO3P4RxoQ==}
+ engines: {node: '>= 20.19.4'}
+ peerDependencies:
+ '@react-native-community/cli': '*'
+ '@react-native/metro-config': '*'
+ peerDependenciesMeta:
+ '@react-native-community/cli':
+ optional: true
+ '@react-native/metro-config':
+ optional: true
+
+ '@react-native/debugger-frontend@0.84.1':
+ resolution: {integrity: sha512-rUU/Pyh3R5zT0WkVgB+yA6VwOp7HM5Hz4NYE97ajFS07OUIcv8JzBL3MXVdSSjLfldfqOuPEuKUaZcAOwPgabw==}
+ engines: {node: '>= 20.19.4'}
+
+ '@react-native/debugger-shell@0.84.1':
+ resolution: {integrity: sha512-LIGhh4q4ette3yW5OzmukNMYwmINYrRGDZqKyTYc/VZyNpblZPw72coXVHXdfpPT6+YlxHqXzn3UjFZpNODGCQ==}
+ engines: {node: '>= 20.19.4'}
+
+ '@react-native/dev-middleware@0.84.1':
+ resolution: {integrity: sha512-Z83ra+Gk6ElAhH3XRrv3vwbwCPTb04sPPlNpotxcFZb5LtRQZwT91ZQEXw3GOJCVIFp9EQ/gj8AQbVvtHKOUlQ==}
+ engines: {node: '>= 20.19.4'}
+
+ '@react-native/gradle-plugin@0.84.1':
+ resolution: {integrity: sha512-7uVlPBE3uluRNRX4MW7PUJIO1LDBTpAqStKHU7LHH+GRrdZbHsWtOEAX8PiY4GFfBEvG8hEjiuTOqAxMjV+hDg==}
+ engines: {node: '>= 20.19.4'}
+
+ '@react-native/js-polyfills@0.84.1':
+ resolution: {integrity: sha512-UsTe2AbUugsfyI7XIHMQq4E7xeC8a6GrYwuK+NohMMMJMxmyM3JkzIk+GB9e2il6ScEQNMJNaj+q+i5za8itxQ==}
+ engines: {node: '>= 20.19.4'}
+
+ '@react-native/normalize-colors@0.84.1':
+ resolution: {integrity: sha512-/UPaQ4jl95soXnLDEJ6Cs6lnRXhwbxtT4KbZz+AFDees7prMV2NOLcHfCnzmTabf5Y3oxENMVBL666n4GMLcTA==}
+
+ '@react-native/virtualized-lists@0.84.1':
+ resolution: {integrity: sha512-sJoDunzhci8ZsqxlUiKoLut4xQeQcmbIgvDHGQKeBz6uEq9HgU+hCWOijMRr6sLP0slQVfBAza34Rq7IbXZZOA==}
+ engines: {node: '>= 20.19.4'}
+ peerDependencies:
+ '@types/react': ^19.2.0
+ react: '*'
+ react-native: '*'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
'@rolldown/binding-android-arm64@1.0.0-rc.9':
resolution: {integrity: sha512-lcJL0bN5hpgJfSIz/8PIf02irmyL43P+j1pTCfbD1DbLkmGRuFIA4DD3B3ZOvGqG0XiVvRznbKtN0COQVaKUTg==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -350,6 +649,15 @@ packages:
'@rolldown/pluginutils@1.0.0-rc.9':
resolution: {integrity: sha512-w6oiRWgEBl04QkFZgmW+jnU1EC9b57Oihi2ot3HNWIQRqgHp5PnYDia5iZ5FF7rpa4EQdiqMDXjlqKGXBhsoXw==}
+ '@sinclair/typebox@0.27.10':
+ resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==}
+
+ '@sinonjs/commons@3.0.1':
+ resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==}
+
+ '@sinonjs/fake-timers@10.3.0':
+ resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==}
+
'@standard-schema/spec@1.1.0':
resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
@@ -382,6 +690,18 @@ packages:
'@types/aria-query@5.0.4':
resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
+ '@types/babel__core@7.20.5':
+ resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
+
+ '@types/babel__generator@7.27.0':
+ resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==}
+
+ '@types/babel__template@7.4.4':
+ resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
+
+ '@types/babel__traverse@7.28.0':
+ resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==}
+
'@types/chai@5.2.3':
resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
@@ -391,6 +711,18 @@ packages:
'@types/estree@1.0.8':
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
+ '@types/graceful-fs@4.1.9':
+ resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==}
+
+ '@types/istanbul-lib-coverage@2.0.6':
+ resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==}
+
+ '@types/istanbul-lib-report@3.0.3':
+ resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==}
+
+ '@types/istanbul-reports@3.0.4':
+ resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==}
+
'@types/node@25.5.0':
resolution: {integrity: sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==}
@@ -402,9 +734,18 @@ packages:
'@types/react@19.2.14':
resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==}
+ '@types/stack-utils@2.0.3':
+ resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==}
+
'@types/use-sync-external-store@1.5.0':
resolution: {integrity: sha512-5dyB8nLC/qogMrlCizZnYWQTA4lnb/v+It+sqNl5YnSRAPMlIqY/X0Xn+gZw8vOL+TgTTr28VEbn3uf8fUtAkw==}
+ '@types/yargs-parser@21.0.3':
+ resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==}
+
+ '@types/yargs@17.0.35':
+ resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==}
+
'@vitejs/plugin-react@6.0.1':
resolution: {integrity: sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -447,10 +788,34 @@ packages:
'@vitest/utils@4.1.0':
resolution: {integrity: sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==}
+ abort-controller@3.0.0:
+ resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
+ engines: {node: '>=6.5'}
+
+ accepts@2.0.0:
+ resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
+ engines: {node: '>= 0.6'}
+
+ acorn@8.16.0:
+ resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ agent-base@7.1.4:
+ resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
+ engines: {node: '>= 14'}
+
+ anser@1.4.10:
+ resolution: {integrity: sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==}
+
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
ansi-styles@5.2.0:
resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
engines: {node: '>=10'}
@@ -459,6 +824,13 @@ packages:
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
engines: {node: '>=12'}
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
+ argparse@1.0.10:
+ resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
+
aria-query@5.3.0:
resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==}
@@ -466,25 +838,140 @@ packages:
resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
engines: {node: '>= 0.4'}
+ asap@2.0.6:
+ resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==}
+
assertion-error@2.0.1:
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
engines: {node: '>=12'}
+ babel-jest@29.7.0:
+ resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ peerDependencies:
+ '@babel/core': ^7.8.0
+
+ babel-plugin-istanbul@6.1.1:
+ resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==}
+ engines: {node: '>=8'}
+
+ babel-plugin-jest-hoist@29.6.3:
+ resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ babel-plugin-syntax-hermes-parser@0.32.0:
+ resolution: {integrity: sha512-m5HthL++AbyeEA2FcdwOLfVFvWYECOBObLHNqdR8ceY4TsEdn4LdX2oTvbB2QJSSElE2AWA/b2MXZ/PF/CqLZg==}
+
+ babel-preset-current-node-syntax@1.2.0:
+ resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==}
+ peerDependencies:
+ '@babel/core': ^7.0.0 || ^8.0.0-0
+
+ babel-preset-jest@29.6.3:
+ resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
balanced-match@4.0.4:
resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
engines: {node: 18 || 20 || >=22}
+ base64-js@1.5.1:
+ resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
+
+ baseline-browser-mapping@2.10.9:
+ resolution: {integrity: sha512-OZd0e2mU11ClX8+IdXe3r0dbqMEznRiT4TfbhYIbcRPZkqJ7Qwer8ij3GZAmLsRKa+II9V1v5czCkvmHH3XZBg==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
bidi-js@1.0.3:
resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==}
+ brace-expansion@1.1.12:
+ resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
+
brace-expansion@5.0.4:
resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==}
engines: {node: 18 || 20 || >=22}
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ browserslist@4.28.1:
+ resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
+ bser@2.1.1:
+ resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==}
+
+ buffer-from@1.1.2:
+ resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+
+ camelcase@5.3.1:
+ resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
+ engines: {node: '>=6'}
+
+ camelcase@6.3.0:
+ resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
+ engines: {node: '>=10'}
+
+ caniuse-lite@1.0.30001780:
+ resolution: {integrity: sha512-llngX0E7nQci5BPJDqoZSbuZ5Bcs9F5db7EtgfwBerX9XGtkkiO4NwfDDIRzHTTwcYC8vC7bmeUEPGrKlR/TkQ==}
+
chai@6.2.2:
resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==}
engines: {node: '>=18'}
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+
+ chrome-launcher@0.15.2:
+ resolution: {integrity: sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==}
+ engines: {node: '>=12.13.0'}
+ hasBin: true
+
+ chromium-edge-launcher@0.2.0:
+ resolution: {integrity: sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg==}
+
+ ci-info@2.0.0:
+ resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==}
+
+ ci-info@3.9.0:
+ resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==}
+ engines: {node: '>=8'}
+
+ cliui@8.0.1:
+ resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
+ engines: {node: '>=12'}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ commander@12.1.0:
+ resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
+ engines: {node: '>=18'}
+
+ commander@2.20.3:
+ resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
+
+ concat-map@0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+
+ connect@3.7.0:
+ resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==}
+ engines: {node: '>= 0.10.0'}
+
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
@@ -506,13 +993,38 @@ packages:
resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+ debug@2.6.9:
+ resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
decimal.js@10.6.0:
resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==}
+ depd@2.0.0:
+ resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
+ engines: {node: '>= 0.8'}
+
dequal@2.0.3:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
engines: {node: '>=6'}
+ destroy@1.2.0:
+ resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
+ engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
+
detect-libc@2.1.2:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'}
@@ -523,20 +1035,88 @@ packages:
dom-accessibility-api@0.6.3:
resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==}
+ ee-first@1.1.1:
+ resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
+
+ electron-to-chromium@1.5.321:
+ resolution: {integrity: sha512-L2C7Q279W2D/J4PLZLk7sebOILDSWos7bMsMNN06rK482umHUrh/3lM8G7IlHFOYip2oAg5nha1rCMxr/rs6ZQ==}
+
+ emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
+ encodeurl@1.0.2:
+ resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
+ engines: {node: '>= 0.8'}
+
+ encodeurl@2.0.0:
+ resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
+ engines: {node: '>= 0.8'}
+
entities@6.0.1:
resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
engines: {node: '>=0.12'}
+ error-stack-parser@2.1.4:
+ resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==}
+
es-module-lexer@2.0.0:
resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==}
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
+ escape-html@1.0.3:
+ resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
+
+ escape-string-regexp@2.0.0:
+ resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
+ engines: {node: '>=8'}
+
+ escape-string-regexp@4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+
+ esprima@4.0.1:
+ resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
+ engines: {node: '>=4'}
+ hasBin: true
+
estree-walker@3.0.3:
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+ etag@1.8.1:
+ resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
+ engines: {node: '>= 0.6'}
+
+ event-target-shim@5.0.1:
+ resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
+ engines: {node: '>=6'}
+
expect-type@1.3.0:
resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==}
engines: {node: '>=12.0.0'}
+ expo-modules-core@55.0.17:
+ resolution: {integrity: sha512-pw3cZiaSlBrqRJUD/pHuMnKGsRTW6XJ255FrjDd3HC4QrqErCnfSQPmz+Sv4Qkelcvd9UGdAewyTqZdFwjLwOw==}
+ peerDependencies:
+ react: '*'
+ react-native: '*'
+
+ exponential-backoff@3.1.3:
+ resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==}
+
+ fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
+ fb-dotslash@0.5.8:
+ resolution: {integrity: sha512-XHYLKk9J4BupDxi9bSEhkfss0m+Vr9ChTrjhf9l2iw3jB5C7BnY4GVPoMcqbrTutsKJso6yj2nAB6BI/F2oZaA==}
+ engines: {node: '>=20'}
+ hasBin: true
+
+ fb-watchman@2.0.2:
+ resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==}
+
fdir@6.5.0:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'}
@@ -546,26 +1126,130 @@ packages:
picomatch:
optional: true
- fsevents@2.3.3:
- resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
- engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
- os: [darwin]
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
- glob@13.0.6:
- resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==}
+ finalhandler@1.1.2:
+ resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==}
+ engines: {node: '>= 0.8'}
+
+ find-up@4.1.0:
+ resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
+ engines: {node: '>=8'}
+
+ flow-enums-runtime@0.0.6:
+ resolution: {integrity: sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==}
+
+ fresh@0.5.2:
+ resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
+ engines: {node: '>= 0.6'}
+
+ fs.realpath@1.0.0:
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ gensync@1.0.0-beta.2:
+ resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
+ engines: {node: '>=6.9.0'}
+
+ get-caller-file@2.0.5:
+ resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
+ engines: {node: 6.* || 8.* || >= 10.*}
+
+ get-package-type@0.1.0:
+ resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==}
+ engines: {node: '>=8.0.0'}
+
+ glob@13.0.6:
+ resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==}
engines: {node: 18 || 20 || >=22}
+ glob@7.2.3:
+ resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ hermes-compiler@250829098.0.9:
+ resolution: {integrity: sha512-hZ5O7PDz1vQ99TS7HD3FJ9zVynfU1y+VWId6U1Pldvd8hmAYrNec/XLPYJKD3dLOW6NXak6aAQAuMuSo3ji0tQ==}
+
+ hermes-estree@0.32.0:
+ resolution: {integrity: sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ==}
+
+ hermes-estree@0.33.3:
+ resolution: {integrity: sha512-6kzYZHCk8Fy1Uc+t3HGYyJn3OL4aeqKLTyina4UFtWl8I0kSL7OmKThaiX+Uh2f8nGw3mo4Ifxg0M5Zk3/Oeqg==}
+
+ hermes-parser@0.32.0:
+ resolution: {integrity: sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw==}
+
+ hermes-parser@0.33.3:
+ resolution: {integrity: sha512-Yg3HgaG4CqgyowtYjX/FsnPAuZdHOqSMtnbpylbptsQ9nwwSKsy6uRWcGO5RK0EqiX12q8HvDWKgeAVajRO5DA==}
+
html-encoding-sniffer@6.0.0:
resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+ http-errors@2.0.1:
+ resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==}
+ engines: {node: '>= 0.8'}
+
+ https-proxy-agent@7.0.6:
+ resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
+ engines: {node: '>= 14'}
+
+ image-size@1.2.1:
+ resolution: {integrity: sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==}
+ engines: {node: '>=16.x'}
+ hasBin: true
+
+ imurmurhash@0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+
indent-string@4.0.0:
resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
engines: {node: '>=8'}
+ inflight@1.0.6:
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+ deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
+
+ inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ invariant@2.2.4:
+ resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
+
+ is-docker@2.2.1:
+ resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
+ engines: {node: '>=8'}
+ hasBin: true
+
+ is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
is-potential-custom-element-name@1.0.1:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
+ is-wsl@2.2.0:
+ resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
+ engines: {node: '>=8'}
+
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
@@ -573,9 +1257,60 @@ packages:
resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==}
engines: {node: '>=18'}
+ istanbul-lib-coverage@3.2.2:
+ resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
+ engines: {node: '>=8'}
+
+ istanbul-lib-instrument@5.2.1:
+ resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==}
+ engines: {node: '>=8'}
+
+ jest-environment-node@29.7.0:
+ resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-get-type@29.6.3:
+ resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-haste-map@29.7.0:
+ resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-message-util@29.7.0:
+ resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-mock@29.7.0:
+ resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-regex-util@29.6.3:
+ resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-util@29.7.0:
+ resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-validate@29.7.0:
+ resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-worker@29.7.0:
+ resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+ js-yaml@3.14.2:
+ resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==}
+ hasBin: true
+
+ jsc-safe-url@0.2.4:
+ resolution: {integrity: sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==}
+
jsdom@29.0.0:
resolution: {integrity: sha512-9FshNB6OepopZ08unmmGpsF7/qCjxGPbo3NbgfJAnPeHXnsODE9WWffXZtRFRFe0ntzaAOcSKNJFz8wiyvF1jQ==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0}
@@ -585,10 +1320,27 @@ packages:
canvas:
optional: true
+ jsesc@3.1.0:
+ resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
+ engines: {node: '>=6'}
+ hasBin: true
+
json-parse-even-better-errors@4.0.0:
resolution: {integrity: sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==}
engines: {node: ^18.17.0 || >=20.5.0}
+ json5@2.2.3:
+ resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ leven@3.1.0:
+ resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
+ engines: {node: '>=6'}
+
+ lighthouse-logger@1.4.2:
+ resolution: {integrity: sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==}
+
lightningcss-android-arm64@1.32.0:
resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
engines: {node: '>= 12.0.0'}
@@ -663,10 +1415,24 @@ packages:
resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
engines: {node: '>= 12.0.0'}
+ locate-path@5.0.0:
+ resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
+ engines: {node: '>=8'}
+
+ lodash.throttle@4.1.1:
+ resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==}
+
+ loose-envify@1.4.0:
+ resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
+ hasBin: true
+
lru-cache@11.2.7:
resolution: {integrity: sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==}
engines: {node: 20 || >=22}
+ lru-cache@5.1.1:
+ resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+
lz-string@1.5.0:
resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
hasBin: true
@@ -674,13 +1440,100 @@ packages:
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+ makeerror@1.0.12:
+ resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
+
+ marky@1.3.0:
+ resolution: {integrity: sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==}
+
mdn-data@2.27.1:
resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==}
+ memoize-one@5.2.1:
+ resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==}
+
memorystream@0.3.1:
resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==}
engines: {node: '>= 0.10.0'}
+ merge-stream@2.0.0:
+ resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
+
+ metro-babel-transformer@0.83.5:
+ resolution: {integrity: sha512-d9FfmgUEVejTiSb7bkQeLRGl6aeno2UpuPm3bo3rCYwxewj03ymvOn8s8vnS4fBqAPQ+cE9iQM40wh7nGXR+eA==}
+ engines: {node: '>=20.19.4'}
+
+ metro-cache-key@0.83.5:
+ resolution: {integrity: sha512-Ycl8PBajB7bhbAI7Rt0xEyiF8oJ0RWX8EKkolV1KfCUlC++V/GStMSGpPLwnnBZXZWkCC5edBPzv1Hz1Yi0Euw==}
+ engines: {node: '>=20.19.4'}
+
+ metro-cache@0.83.5:
+ resolution: {integrity: sha512-oH+s4U+IfZyg8J42bne2Skc90rcuESIYf86dYittcdWQtPfcaFXWpByPyTuWk3rR1Zz3Eh5HOrcVImfEhhJLng==}
+ engines: {node: '>=20.19.4'}
+
+ metro-config@0.83.5:
+ resolution: {integrity: sha512-JQ/PAASXH7yczgV6OCUSRhZYME+NU8NYjI2RcaG5ga4QfQ3T/XdiLzpSb3awWZYlDCcQb36l4Vl7i0Zw7/Tf9w==}
+ engines: {node: '>=20.19.4'}
+
+ metro-core@0.83.5:
+ resolution: {integrity: sha512-YcVcLCrf0ed4mdLa82Qob0VxYqfhmlRxUS8+TO4gosZo/gLwSvtdeOjc/Vt0pe/lvMNrBap9LlmvZM8FIsMgJQ==}
+ engines: {node: '>=20.19.4'}
+
+ metro-file-map@0.83.5:
+ resolution: {integrity: sha512-ZEt8s3a1cnYbn40nyCD+CsZdYSlwtFh2kFym4lo+uvfM+UMMH+r/BsrC6rbNClSrt+B7rU9T+Te/sh/NL8ZZKQ==}
+ engines: {node: '>=20.19.4'}
+
+ metro-minify-terser@0.83.5:
+ resolution: {integrity: sha512-Toe4Md1wS1PBqbvB0cFxBzKEVyyuYTUb0sgifAZh/mSvLH84qA1NAWik9sISWatzvfWf3rOGoUoO5E3f193a3Q==}
+ engines: {node: '>=20.19.4'}
+
+ metro-resolver@0.83.5:
+ resolution: {integrity: sha512-7p3GtzVUpbAweJeCcUJihJeOQl1bDuimO5ueo1K0BUpUtR41q5EilbQ3klt16UTPPMpA+tISWBtsrqU556mY1A==}
+ engines: {node: '>=20.19.4'}
+
+ metro-runtime@0.83.5:
+ resolution: {integrity: sha512-f+b3ue9AWTVlZe2Xrki6TAoFtKIqw30jwfk7GQ1rDUBQaE0ZQ+NkiMEtb9uwH7uAjJ87U7Tdx1Jg1OJqUfEVlA==}
+ engines: {node: '>=20.19.4'}
+
+ metro-source-map@0.83.5:
+ resolution: {integrity: sha512-VT9bb2KO2/4tWY9Z2yeZqTUao7CicKAOps9LUg2aQzsz+04QyuXL3qgf1cLUVRjA/D6G5u1RJAlN1w9VNHtODQ==}
+ engines: {node: '>=20.19.4'}
+
+ metro-symbolicate@0.83.5:
+ resolution: {integrity: sha512-EMIkrjNRz/hF+p0RDdxoE60+dkaTLPN3vaaGkFmX5lvFdO6HPfHA/Ywznzkev+za0VhPQ5KSdz49/MALBRteHA==}
+ engines: {node: '>=20.19.4'}
+ hasBin: true
+
+ metro-transform-plugins@0.83.5:
+ resolution: {integrity: sha512-KxYKzZL+lt3Os5H2nx7YkbkWVduLZL5kPrE/Yq+Prm/DE1VLhpfnO6HtPs8vimYFKOa58ncl60GpoX0h7Wm0Vw==}
+ engines: {node: '>=20.19.4'}
+
+ metro-transform-worker@0.83.5:
+ resolution: {integrity: sha512-8N4pjkNXc6ytlP9oAM6MwqkvUepNSW39LKYl9NjUMpRDazBQ7oBpQDc8Sz4aI8jnH6AGhF7s1m/ayxkN1t04yA==}
+ engines: {node: '>=20.19.4'}
+
+ metro@0.83.5:
+ resolution: {integrity: sha512-BgsXevY1MBac/3ZYv/RfNFf/4iuW9X7f4H8ZNkiH+r667HD9sVujxcmu4jvEzGCAm4/WyKdZCuyhAcyhTHOucQ==}
+ engines: {node: '>=20.19.4'}
+ hasBin: true
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
+ mime-db@1.54.0:
+ resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@3.0.2:
+ resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==}
+ engines: {node: '>=18'}
+
+ mime@1.6.0:
+ resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
min-indent@1.0.1:
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
engines: {node: '>=4'}
@@ -689,15 +1542,43 @@ packages:
resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==}
engines: {node: 18 || 20 || >=22}
+ minimatch@3.1.5:
+ resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
+
minipass@7.1.3:
resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
engines: {node: '>=16 || 14 >=14.17'}
+ mkdirp@1.0.4:
+ resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ ms@2.0.0:
+ resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
nanoid@3.3.11:
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
+ negotiator@1.0.0:
+ resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
+ engines: {node: '>= 0.6'}
+
+ node-int64@0.4.0:
+ resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
+
+ node-releases@2.0.36:
+ resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==}
+
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
npm-normalize-package-bin@4.0.0:
resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==}
engines: {node: ^18.17.0 || >=20.5.0}
@@ -707,15 +1588,61 @@ packages:
engines: {node: ^20.5.0 || >=22.0.0, npm: '>= 10'}
hasBin: true
+ nullthrows@1.1.1:
+ resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==}
+
+ ob1@0.83.5:
+ resolution: {integrity: sha512-vNKPYC8L5ycVANANpF/S+WZHpfnRWKx/F3AYP4QMn6ZJTh+l2HOrId0clNkEmua58NB9vmI9Qh7YOoV/4folYg==}
+ engines: {node: '>=20.19.4'}
+
obug@2.1.1:
resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==}
+ on-finished@2.3.0:
+ resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
+ engines: {node: '>= 0.8'}
+
+ on-finished@2.4.1:
+ resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
+ engines: {node: '>= 0.8'}
+
+ once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+
+ open@7.4.2:
+ resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==}
+ engines: {node: '>=8'}
+
+ p-limit@2.3.0:
+ resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
+ engines: {node: '>=6'}
+
+ p-locate@4.1.0:
+ resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
+ engines: {node: '>=8'}
+
+ p-try@2.2.0:
+ resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
+ engines: {node: '>=6'}
+
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
parse5@8.0.0:
resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==}
+ parseurl@1.3.3:
+ resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
+ engines: {node: '>= 0.8'}
+
+ path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+
+ path-is-absolute@1.0.1:
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
+ engines: {node: '>=0.10.0'}
+
path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
@@ -730,6 +1657,10 @@ packages:
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+ picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
picomatch@4.0.3:
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
engines: {node: '>=12'}
@@ -739,6 +1670,10 @@ packages:
engines: {node: '>=0.10'}
hasBin: true
+ pirates@4.0.7:
+ resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
+ engines: {node: '>= 6'}
+
postcss@8.5.8:
resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==}
engines: {node: ^10 || ^12 || >=14}
@@ -747,10 +1682,27 @@ packages:
resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+ pretty-format@29.7.0:
+ resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ promise@8.3.0:
+ resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==}
+
punycode@2.3.1:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
+ queue@6.0.2:
+ resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==}
+
+ range-parser@1.2.1:
+ resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
+ engines: {node: '>= 0.6'}
+
+ react-devtools-core@6.1.5:
+ resolution: {integrity: sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==}
+
react-dom@19.2.4:
resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==}
peerDependencies:
@@ -759,6 +1711,24 @@ packages:
react-is@17.0.2:
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
+ react-is@18.3.1:
+ resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
+
+ react-native@0.84.1:
+ resolution: {integrity: sha512-0PjxOyXRu3tZ8EobabxSukvhKje2HJbsZikR0U+pvS0pYZza2hXKjcSBiBdFN4h9D0S3v6a8kkrDK6WTRKMwzg==}
+ engines: {node: '>= 20.19.4'}
+ hasBin: true
+ peerDependencies:
+ '@types/react': ^19.1.1
+ react: ^19.2.3
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-refresh@0.14.2:
+ resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
+ engines: {node: '>=0.10.0'}
+
react@19.2.4:
resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==}
engines: {node: '>=0.10.0'}
@@ -771,10 +1741,26 @@ packages:
resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
engines: {node: '>=8'}
+ regenerator-runtime@0.13.11:
+ resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
+
+ require-directory@2.1.1:
+ resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
+ engines: {node: '>=0.10.0'}
+
require-from-string@2.0.2:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'}
+ resolve-from@5.0.0:
+ resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
+ engines: {node: '>=8'}
+
+ rimraf@3.0.2:
+ resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
+ deprecated: Rimraf versions prior to v4 are no longer supported
+ hasBin: true
+
rimraf@6.1.3:
resolution: {integrity: sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==}
engines: {node: 20 || >=22}
@@ -792,6 +1778,30 @@ packages:
scheduler@0.27.0:
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
+ semver@6.3.1:
+ resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+ hasBin: true
+
+ semver@7.7.4:
+ resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ send@0.19.2:
+ resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==}
+ engines: {node: '>= 0.8.0'}
+
+ serialize-error@2.1.0:
+ resolution: {integrity: sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==}
+ engines: {node: '>=0.10.0'}
+
+ serve-static@1.16.3:
+ resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==}
+ engines: {node: '>= 0.8.0'}
+
+ setprototypeof@1.2.0:
+ resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
+
shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
@@ -807,23 +1817,91 @@ packages:
siginfo@2.0.0:
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+ signal-exit@3.0.7:
+ resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
+
+ slash@3.0.0:
+ resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
+ engines: {node: '>=8'}
+
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
+ source-map-support@0.5.21:
+ resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
+
+ source-map@0.5.7:
+ resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==}
+ engines: {node: '>=0.10.0'}
+
+ source-map@0.6.1:
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+ engines: {node: '>=0.10.0'}
+
+ sprintf-js@1.0.3:
+ resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
+
+ stack-utils@2.0.6:
+ resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
+ engines: {node: '>=10'}
+
stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+ stackframe@1.3.4:
+ resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==}
+
+ stacktrace-parser@0.1.11:
+ resolution: {integrity: sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==}
+ engines: {node: '>=6'}
+
+ statuses@1.5.0:
+ resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==}
+ engines: {node: '>= 0.6'}
+
+ statuses@2.0.2:
+ resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
+ engines: {node: '>= 0.8'}
+
std-env@4.0.0:
resolution: {integrity: sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==}
+ string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
strip-indent@3.0.0:
resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
engines: {node: '>=8'}
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ supports-color@8.1.1:
+ resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
+ engines: {node: '>=10'}
+
symbol-tree@3.2.4:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
+ terser@5.46.1:
+ resolution: {integrity: sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ test-exclude@6.0.0:
+ resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==}
+ engines: {node: '>=8'}
+
+ throat@5.0.0:
+ resolution: {integrity: sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==}
+
tinybench@2.9.0:
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
@@ -846,6 +1924,17 @@ packages:
resolution: {integrity: sha512-WiGwQjr0qYdNNG8KpMKlSvpxz652lqa3Rd+/hSaDcY4Uo6SKWZq2LAF+hsAhUewTtYhXlorBKgNF3Kk8hnjGoQ==}
hasBin: true
+ tmpl@1.0.5:
+ resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==}
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ toidentifier@1.0.1:
+ resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
+ engines: {node: '>=0.6'}
+
tough-cookie@6.0.1:
resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==}
engines: {node: '>=16'}
@@ -857,6 +1946,14 @@ packages:
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+ type-detect@4.0.8:
+ resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==}
+ engines: {node: '>=4'}
+
+ type-fest@0.7.1:
+ resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==}
+ engines: {node: '>=8'}
+
typescript@5.9.3:
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
engines: {node: '>=14.17'}
@@ -869,11 +1966,25 @@ packages:
resolution: {integrity: sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==}
engines: {node: '>=20.18.1'}
+ unpipe@1.0.0:
+ resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
+ engines: {node: '>= 0.8'}
+
+ update-browserslist-db@1.2.3:
+ resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
use-sync-external-store@1.6.0:
resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ utils-merge@1.0.1:
+ resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
+ engines: {node: '>= 0.4.0'}
+
vite@8.0.0:
resolution: {integrity: sha512-fPGaRNj9Zytaf8LEiBhY7Z6ijnFKdzU/+mL8EFBaKr7Vw1/FWcTBAMW0wLPJAGMPX38ZPVCVgLceWiEqeoqL2Q==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -952,14 +2063,23 @@ packages:
jsdom:
optional: true
+ vlq@1.0.1:
+ resolution: {integrity: sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==}
+
w3c-xmlserializer@5.0.0:
resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
engines: {node: '>=18'}
+ walker@1.0.8:
+ resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==}
+
webidl-conversions@8.0.1:
resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==}
engines: {node: '>=20'}
+ whatwg-fetch@3.6.20:
+ resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==}
+
whatwg-mimetype@5.0.0:
resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==}
engines: {node: '>=20'}
@@ -983,6 +2103,29 @@ packages:
engines: {node: '>=8'}
hasBin: true
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
+ write-file-atomic@4.0.2:
+ resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==}
+ engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
+
+ ws@7.5.10:
+ resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==}
+ engines: {node: '>=8.3.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: ^5.0.2
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+
xml-name-validator@5.0.0:
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
engines: {node: '>=18'}
@@ -990,6 +2133,26 @@ packages:
xmlchars@2.2.0:
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
+ y18n@5.0.8:
+ resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
+ engines: {node: '>=10'}
+
+ yallist@3.1.1:
+ resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+
+ yaml@2.8.2:
+ resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==}
+ engines: {node: '>= 14.6'}
+ hasBin: true
+
+ yargs-parser@21.1.1:
+ resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
+ engines: {node: '>=12'}
+
+ yargs@17.7.2:
+ resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
+ engines: {node: '>=12'}
+
snapshots:
'@adobe/css-tools@4.4.4': {}
@@ -1018,41 +2181,210 @@ snapshots:
js-tokens: 4.0.0
picocolors: 1.1.1
- '@babel/helper-validator-identifier@7.28.5': {}
-
- '@babel/runtime@7.29.2': {}
+ '@babel/compat-data@7.29.0': {}
- '@bramus/specificity@2.4.2':
+ '@babel/core@7.29.0':
dependencies:
- css-tree: 3.2.1
+ '@babel/code-frame': 7.29.0
+ '@babel/generator': 7.29.1
+ '@babel/helper-compilation-targets': 7.28.6
+ '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0)
+ '@babel/helpers': 7.29.2
+ '@babel/parser': 7.29.2
+ '@babel/template': 7.28.6
+ '@babel/traverse': 7.29.0
+ '@babel/types': 7.29.0
+ '@jridgewell/remapping': 2.3.5
+ convert-source-map: 2.0.0
+ debug: 4.4.3
+ gensync: 1.0.0-beta.2
+ json5: 2.2.3
+ semver: 6.3.1
+ transitivePeerDependencies:
+ - supports-color
- '@csstools/color-helpers@6.0.2': {}
+ '@babel/generator@7.29.1':
+ dependencies:
+ '@babel/parser': 7.29.2
+ '@babel/types': 7.29.0
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+ jsesc: 3.1.0
- '@csstools/css-calc@3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
+ '@babel/helper-compilation-targets@7.28.6':
dependencies:
- '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
- '@csstools/css-tokenizer': 4.0.0
+ '@babel/compat-data': 7.29.0
+ '@babel/helper-validator-option': 7.27.1
+ browserslist: 4.28.1
+ lru-cache: 5.1.1
+ semver: 6.3.1
- '@csstools/css-color-parser@4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
+ '@babel/helper-globals@7.28.0': {}
+
+ '@babel/helper-module-imports@7.28.6':
dependencies:
- '@csstools/color-helpers': 6.0.2
- '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
- '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
- '@csstools/css-tokenizer': 4.0.0
+ '@babel/traverse': 7.29.0
+ '@babel/types': 7.29.0
+ transitivePeerDependencies:
+ - supports-color
- '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)':
+ '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)':
dependencies:
- '@csstools/css-tokenizer': 4.0.0
+ '@babel/core': 7.29.0
+ '@babel/helper-module-imports': 7.28.6
+ '@babel/helper-validator-identifier': 7.28.5
+ '@babel/traverse': 7.29.0
+ transitivePeerDependencies:
+ - supports-color
- '@csstools/css-syntax-patches-for-csstree@1.1.1(css-tree@3.2.1)':
- optionalDependencies:
- css-tree: 3.2.1
+ '@babel/helper-plugin-utils@7.28.6': {}
- '@csstools/css-tokenizer@4.0.0': {}
+ '@babel/helper-string-parser@7.27.1': {}
- '@emnapi/core@1.9.0':
- dependencies:
- '@emnapi/wasi-threads': 1.2.0
+ '@babel/helper-validator-identifier@7.28.5': {}
+
+ '@babel/helper-validator-option@7.27.1': {}
+
+ '@babel/helpers@7.29.2':
+ dependencies:
+ '@babel/template': 7.28.6
+ '@babel/types': 7.29.0
+
+ '@babel/parser@7.29.2':
+ dependencies:
+ '@babel/types': 7.29.0
+
+ '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/helper-plugin-utils': 7.28.6
+
+ '@babel/runtime@7.29.2': {}
+
+ '@babel/template@7.28.6':
+ dependencies:
+ '@babel/code-frame': 7.29.0
+ '@babel/parser': 7.29.2
+ '@babel/types': 7.29.0
+
+ '@babel/traverse@7.29.0':
+ dependencies:
+ '@babel/code-frame': 7.29.0
+ '@babel/generator': 7.29.1
+ '@babel/helper-globals': 7.28.0
+ '@babel/parser': 7.29.2
+ '@babel/template': 7.28.6
+ '@babel/types': 7.29.0
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/types@7.29.0':
+ dependencies:
+ '@babel/helper-string-parser': 7.27.1
+ '@babel/helper-validator-identifier': 7.28.5
+
+ '@bramus/specificity@2.4.2':
+ dependencies:
+ css-tree: 3.2.1
+
+ '@csstools/color-helpers@6.0.2': {}
+
+ '@csstools/css-calc@3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
+ dependencies:
+ '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
+ '@csstools/css-tokenizer': 4.0.0
+
+ '@csstools/css-color-parser@4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
+ dependencies:
+ '@csstools/color-helpers': 6.0.2
+ '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
+ '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
+ '@csstools/css-tokenizer': 4.0.0
+
+ '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)':
+ dependencies:
+ '@csstools/css-tokenizer': 4.0.0
+
+ '@csstools/css-syntax-patches-for-csstree@1.1.1(css-tree@3.2.1)':
+ optionalDependencies:
+ css-tree: 3.2.1
+
+ '@csstools/css-tokenizer@4.0.0': {}
+
+ '@emnapi/core@1.9.0':
+ dependencies:
+ '@emnapi/wasi-threads': 1.2.0
tslib: 2.8.1
optional: true
@@ -1073,8 +2405,95 @@ snapshots:
react: 19.2.4
use-sync-external-store: 1.6.0(react@19.2.4)
+ '@isaacs/ttlcache@1.4.1': {}
+
+ '@istanbuljs/load-nyc-config@1.1.0':
+ dependencies:
+ camelcase: 5.3.1
+ find-up: 4.1.0
+ get-package-type: 0.1.0
+ js-yaml: 3.14.2
+ resolve-from: 5.0.0
+
+ '@istanbuljs/schema@0.1.3': {}
+
+ '@jest/create-cache-key-function@29.7.0':
+ dependencies:
+ '@jest/types': 29.6.3
+
+ '@jest/environment@29.7.0':
+ dependencies:
+ '@jest/fake-timers': 29.7.0
+ '@jest/types': 29.6.3
+ '@types/node': 25.5.0
+ jest-mock: 29.7.0
+
+ '@jest/fake-timers@29.7.0':
+ dependencies:
+ '@jest/types': 29.6.3
+ '@sinonjs/fake-timers': 10.3.0
+ '@types/node': 25.5.0
+ jest-message-util: 29.7.0
+ jest-mock: 29.7.0
+ jest-util: 29.7.0
+
+ '@jest/schemas@29.6.3':
+ dependencies:
+ '@sinclair/typebox': 0.27.10
+
+ '@jest/transform@29.7.0':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@jest/types': 29.6.3
+ '@jridgewell/trace-mapping': 0.3.31
+ babel-plugin-istanbul: 6.1.1
+ chalk: 4.1.2
+ convert-source-map: 2.0.0
+ fast-json-stable-stringify: 2.1.0
+ graceful-fs: 4.2.11
+ jest-haste-map: 29.7.0
+ jest-regex-util: 29.6.3
+ jest-util: 29.7.0
+ micromatch: 4.0.8
+ pirates: 4.0.7
+ slash: 3.0.0
+ write-file-atomic: 4.0.2
+ transitivePeerDependencies:
+ - supports-color
+
+ '@jest/types@29.6.3':
+ dependencies:
+ '@jest/schemas': 29.6.3
+ '@types/istanbul-lib-coverage': 2.0.6
+ '@types/istanbul-reports': 3.0.4
+ '@types/node': 25.5.0
+ '@types/yargs': 17.0.35
+ chalk: 4.1.2
+
+ '@jridgewell/gen-mapping@0.3.13':
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/remapping@2.3.5':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/source-map@0.3.11':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+
'@jridgewell/sourcemap-codec@1.5.5': {}
+ '@jridgewell/trace-mapping@0.3.31':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.5
+
'@napi-rs/wasm-runtime@1.1.1':
dependencies:
'@emnapi/core': 1.9.0
@@ -1086,6 +2505,78 @@ snapshots:
'@oxc-project/types@0.115.0': {}
+ '@react-native/assets-registry@0.84.1': {}
+
+ '@react-native/codegen@0.84.1':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/parser': 7.29.2
+ hermes-parser: 0.32.0
+ invariant: 2.2.4
+ nullthrows: 1.1.1
+ tinyglobby: 0.2.15
+ yargs: 17.7.2
+ transitivePeerDependencies:
+ - supports-color
+
+ '@react-native/community-cli-plugin@0.84.1':
+ dependencies:
+ '@react-native/dev-middleware': 0.84.1
+ debug: 4.4.3
+ invariant: 2.2.4
+ metro: 0.83.5
+ metro-config: 0.83.5
+ metro-core: 0.83.5
+ semver: 7.7.4
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ '@react-native/debugger-frontend@0.84.1': {}
+
+ '@react-native/debugger-shell@0.84.1':
+ dependencies:
+ cross-spawn: 7.0.6
+ debug: 4.4.3
+ fb-dotslash: 0.5.8
+ transitivePeerDependencies:
+ - supports-color
+
+ '@react-native/dev-middleware@0.84.1':
+ dependencies:
+ '@isaacs/ttlcache': 1.4.1
+ '@react-native/debugger-frontend': 0.84.1
+ '@react-native/debugger-shell': 0.84.1
+ chrome-launcher: 0.15.2
+ chromium-edge-launcher: 0.2.0
+ connect: 3.7.0
+ debug: 4.4.3
+ invariant: 2.2.4
+ nullthrows: 1.1.1
+ open: 7.4.2
+ serve-static: 1.16.3
+ ws: 7.5.10
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ '@react-native/gradle-plugin@0.84.1': {}
+
+ '@react-native/js-polyfills@0.84.1': {}
+
+ '@react-native/normalize-colors@0.84.1': {}
+
+ '@react-native/virtualized-lists@0.84.1(@types/react@19.2.14)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)':
+ dependencies:
+ invariant: 2.2.4
+ nullthrows: 1.1.1
+ react: 19.2.4
+ react-native: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
+ optionalDependencies:
+ '@types/react': 19.2.14
+
'@rolldown/binding-android-arm64@1.0.0-rc.9':
optional: true
@@ -1137,6 +2628,16 @@ snapshots:
'@rolldown/pluginutils@1.0.0-rc.9': {}
+ '@sinclair/typebox@0.27.10': {}
+
+ '@sinonjs/commons@3.0.1':
+ dependencies:
+ type-detect: 4.0.8
+
+ '@sinonjs/fake-timers@10.3.0':
+ dependencies:
+ '@sinonjs/commons': 3.0.1
+
'@standard-schema/spec@1.1.0': {}
'@testing-library/dom@10.4.1':
@@ -1176,6 +2677,27 @@ snapshots:
'@types/aria-query@5.0.4': {}
+ '@types/babel__core@7.20.5':
+ dependencies:
+ '@babel/parser': 7.29.2
+ '@babel/types': 7.29.0
+ '@types/babel__generator': 7.27.0
+ '@types/babel__template': 7.4.4
+ '@types/babel__traverse': 7.28.0
+
+ '@types/babel__generator@7.27.0':
+ dependencies:
+ '@babel/types': 7.29.0
+
+ '@types/babel__template@7.4.4':
+ dependencies:
+ '@babel/parser': 7.29.2
+ '@babel/types': 7.29.0
+
+ '@types/babel__traverse@7.28.0':
+ dependencies:
+ '@babel/types': 7.29.0
+
'@types/chai@5.2.3':
dependencies:
'@types/deep-eql': 4.0.2
@@ -1185,6 +2707,20 @@ snapshots:
'@types/estree@1.0.8': {}
+ '@types/graceful-fs@4.1.9':
+ dependencies:
+ '@types/node': 25.5.0
+
+ '@types/istanbul-lib-coverage@2.0.6': {}
+
+ '@types/istanbul-lib-report@3.0.3':
+ dependencies:
+ '@types/istanbul-lib-coverage': 2.0.6
+
+ '@types/istanbul-reports@3.0.4':
+ dependencies:
+ '@types/istanbul-lib-report': 3.0.3
+
'@types/node@25.5.0':
dependencies:
undici-types: 7.18.2
@@ -1197,12 +2733,20 @@ snapshots:
dependencies:
csstype: 3.2.3
+ '@types/stack-utils@2.0.3': {}
+
'@types/use-sync-external-store@1.5.0': {}
- '@vitejs/plugin-react@6.0.1(vite@8.0.0(@types/node@25.5.0))':
+ '@types/yargs-parser@21.0.3': {}
+
+ '@types/yargs@17.0.35':
+ dependencies:
+ '@types/yargs-parser': 21.0.3
+
+ '@vitejs/plugin-react@6.0.1(vite@8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2))':
dependencies:
'@rolldown/pluginutils': 1.0.0-rc.7
- vite: 8.0.0(@types/node@25.5.0)
+ vite: 8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2)
'@vitest/expect@4.1.0':
dependencies:
@@ -1213,13 +2757,13 @@ snapshots:
chai: 6.2.2
tinyrainbow: 3.1.0
- '@vitest/mocker@4.1.0(vite@8.0.0(@types/node@25.5.0))':
+ '@vitest/mocker@4.1.0(vite@8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2))':
dependencies:
'@vitest/spy': 4.1.0
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
- vite: 8.0.0(@types/node@25.5.0)
+ vite: 8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2)
'@vitest/pretty-format@4.1.0':
dependencies:
@@ -1245,32 +2789,212 @@ snapshots:
convert-source-map: 2.0.0
tinyrainbow: 3.1.0
+ abort-controller@3.0.0:
+ dependencies:
+ event-target-shim: 5.0.1
+
+ accepts@2.0.0:
+ dependencies:
+ mime-types: 3.0.2
+ negotiator: 1.0.0
+
+ acorn@8.16.0: {}
+
+ agent-base@7.1.4: {}
+
+ anser@1.4.10: {}
+
ansi-regex@5.0.1: {}
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
ansi-styles@5.2.0: {}
ansi-styles@6.2.3: {}
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+
+ argparse@1.0.10:
+ dependencies:
+ sprintf-js: 1.0.3
+
aria-query@5.3.0:
dependencies:
dequal: 2.0.3
aria-query@5.3.2: {}
+ asap@2.0.6: {}
+
assertion-error@2.0.1: {}
+ babel-jest@29.7.0(@babel/core@7.29.0):
+ dependencies:
+ '@babel/core': 7.29.0
+ '@jest/transform': 29.7.0
+ '@types/babel__core': 7.20.5
+ babel-plugin-istanbul: 6.1.1
+ babel-preset-jest: 29.6.3(@babel/core@7.29.0)
+ chalk: 4.1.2
+ graceful-fs: 4.2.11
+ slash: 3.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ babel-plugin-istanbul@6.1.1:
+ dependencies:
+ '@babel/helper-plugin-utils': 7.28.6
+ '@istanbuljs/load-nyc-config': 1.1.0
+ '@istanbuljs/schema': 0.1.3
+ istanbul-lib-instrument: 5.2.1
+ test-exclude: 6.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ babel-plugin-jest-hoist@29.6.3:
+ dependencies:
+ '@babel/template': 7.28.6
+ '@babel/types': 7.29.0
+ '@types/babel__core': 7.20.5
+ '@types/babel__traverse': 7.28.0
+
+ babel-plugin-syntax-hermes-parser@0.32.0:
+ dependencies:
+ hermes-parser: 0.32.0
+
+ babel-preset-current-node-syntax@1.2.0(@babel/core@7.29.0):
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.29.0)
+ '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.29.0)
+ '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.29.0)
+ '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.29.0)
+ '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0)
+ '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.29.0)
+ '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.29.0)
+ '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.29.0)
+ '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.29.0)
+ '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.29.0)
+ '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.29.0)
+ '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.29.0)
+ '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.29.0)
+ '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0)
+ '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.29.0)
+
+ babel-preset-jest@29.6.3(@babel/core@7.29.0):
+ dependencies:
+ '@babel/core': 7.29.0
+ babel-plugin-jest-hoist: 29.6.3
+ babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0)
+
+ balanced-match@1.0.2: {}
+
balanced-match@4.0.4: {}
+ base64-js@1.5.1: {}
+
+ baseline-browser-mapping@2.10.9: {}
+
bidi-js@1.0.3:
dependencies:
require-from-string: 2.0.2
+ brace-expansion@1.1.12:
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+
brace-expansion@5.0.4:
dependencies:
balanced-match: 4.0.4
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
+ browserslist@4.28.1:
+ dependencies:
+ baseline-browser-mapping: 2.10.9
+ caniuse-lite: 1.0.30001780
+ electron-to-chromium: 1.5.321
+ node-releases: 2.0.36
+ update-browserslist-db: 1.2.3(browserslist@4.28.1)
+
+ bser@2.1.1:
+ dependencies:
+ node-int64: 0.4.0
+
+ buffer-from@1.1.2: {}
+
+ camelcase@5.3.1: {}
+
+ camelcase@6.3.0: {}
+
+ caniuse-lite@1.0.30001780: {}
+
chai@6.2.2: {}
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ chrome-launcher@0.15.2:
+ dependencies:
+ '@types/node': 25.5.0
+ escape-string-regexp: 4.0.0
+ is-wsl: 2.2.0
+ lighthouse-logger: 1.4.2
+ transitivePeerDependencies:
+ - supports-color
+
+ chromium-edge-launcher@0.2.0:
+ dependencies:
+ '@types/node': 25.5.0
+ escape-string-regexp: 4.0.0
+ is-wsl: 2.2.0
+ lighthouse-logger: 1.4.2
+ mkdirp: 1.0.4
+ rimraf: 3.0.2
+ transitivePeerDependencies:
+ - supports-color
+
+ ci-info@2.0.0: {}
+
+ ci-info@3.9.0: {}
+
+ cliui@8.0.1:
+ dependencies:
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ wrap-ansi: 7.0.0
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+
+ color-name@1.1.4: {}
+
+ commander@12.1.0: {}
+
+ commander@2.20.3: {}
+
+ concat-map@0.0.1: {}
+
+ connect@3.7.0:
+ dependencies:
+ debug: 2.6.9
+ finalhandler: 1.1.2
+ parseurl: 1.3.3
+ utils-merge: 1.0.1
+ transitivePeerDependencies:
+ - supports-color
+
convert-source-map@2.0.0: {}
cross-spawn@7.0.6:
@@ -1295,55 +3019,304 @@ snapshots:
transitivePeerDependencies:
- '@noble/hashes'
+ debug@2.6.9:
+ dependencies:
+ ms: 2.0.0
+
+ debug@4.4.3:
+ dependencies:
+ ms: 2.1.3
+
decimal.js@10.6.0: {}
+ depd@2.0.0: {}
+
dequal@2.0.3: {}
+ destroy@1.2.0: {}
+
detect-libc@2.1.2: {}
dom-accessibility-api@0.5.16: {}
dom-accessibility-api@0.6.3: {}
+ ee-first@1.1.1: {}
+
+ electron-to-chromium@1.5.321: {}
+
+ emoji-regex@8.0.0: {}
+
+ encodeurl@1.0.2: {}
+
+ encodeurl@2.0.0: {}
+
entities@6.0.1: {}
+ error-stack-parser@2.1.4:
+ dependencies:
+ stackframe: 1.3.4
+
es-module-lexer@2.0.0: {}
+ escalade@3.2.0: {}
+
+ escape-html@1.0.3: {}
+
+ escape-string-regexp@2.0.0: {}
+
+ escape-string-regexp@4.0.0: {}
+
+ esprima@4.0.1: {}
+
estree-walker@3.0.3:
dependencies:
'@types/estree': 1.0.8
+ etag@1.8.1: {}
+
+ event-target-shim@5.0.1: {}
+
expect-type@1.3.0: {}
+ expo-modules-core@55.0.17(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4):
+ dependencies:
+ invariant: 2.2.4
+ react: 19.2.4
+ react-native: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
+
+ exponential-backoff@3.1.3: {}
+
+ fast-json-stable-stringify@2.1.0: {}
+
+ fb-dotslash@0.5.8: {}
+
+ fb-watchman@2.0.2:
+ dependencies:
+ bser: 2.1.1
+
fdir@6.5.0(picomatch@4.0.3):
optionalDependencies:
picomatch: 4.0.3
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
+ finalhandler@1.1.2:
+ dependencies:
+ debug: 2.6.9
+ encodeurl: 1.0.2
+ escape-html: 1.0.3
+ on-finished: 2.3.0
+ parseurl: 1.3.3
+ statuses: 1.5.0
+ unpipe: 1.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ find-up@4.1.0:
+ dependencies:
+ locate-path: 5.0.0
+ path-exists: 4.0.0
+
+ flow-enums-runtime@0.0.6: {}
+
+ fresh@0.5.2: {}
+
+ fs.realpath@1.0.0: {}
+
fsevents@2.3.3:
optional: true
+ gensync@1.0.0-beta.2: {}
+
+ get-caller-file@2.0.5: {}
+
+ get-package-type@0.1.0: {}
+
glob@13.0.6:
dependencies:
minimatch: 10.2.4
minipass: 7.1.3
path-scurry: 2.0.2
+ glob@7.2.3:
+ dependencies:
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 3.1.5
+ once: 1.4.0
+ path-is-absolute: 1.0.1
+
+ graceful-fs@4.2.11: {}
+
+ has-flag@4.0.0: {}
+
+ hermes-compiler@250829098.0.9: {}
+
+ hermes-estree@0.32.0: {}
+
+ hermes-estree@0.33.3: {}
+
+ hermes-parser@0.32.0:
+ dependencies:
+ hermes-estree: 0.32.0
+
+ hermes-parser@0.33.3:
+ dependencies:
+ hermes-estree: 0.33.3
+
html-encoding-sniffer@6.0.0:
dependencies:
'@exodus/bytes': 1.15.0
transitivePeerDependencies:
- '@noble/hashes'
+ http-errors@2.0.1:
+ dependencies:
+ depd: 2.0.0
+ inherits: 2.0.4
+ setprototypeof: 1.2.0
+ statuses: 2.0.2
+ toidentifier: 1.0.1
+
+ https-proxy-agent@7.0.6:
+ dependencies:
+ agent-base: 7.1.4
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ image-size@1.2.1:
+ dependencies:
+ queue: 6.0.2
+
+ imurmurhash@0.1.4: {}
+
indent-string@4.0.0: {}
+ inflight@1.0.6:
+ dependencies:
+ once: 1.4.0
+ wrappy: 1.0.2
+
+ inherits@2.0.4: {}
+
+ invariant@2.2.4:
+ dependencies:
+ loose-envify: 1.4.0
+
+ is-docker@2.2.1: {}
+
+ is-fullwidth-code-point@3.0.0: {}
+
+ is-number@7.0.0: {}
+
is-potential-custom-element-name@1.0.1: {}
+ is-wsl@2.2.0:
+ dependencies:
+ is-docker: 2.2.1
+
isexe@2.0.0: {}
isexe@3.1.5: {}
+ istanbul-lib-coverage@3.2.2: {}
+
+ istanbul-lib-instrument@5.2.1:
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/parser': 7.29.2
+ '@istanbuljs/schema': 0.1.3
+ istanbul-lib-coverage: 3.2.2
+ semver: 6.3.1
+ transitivePeerDependencies:
+ - supports-color
+
+ jest-environment-node@29.7.0:
+ dependencies:
+ '@jest/environment': 29.7.0
+ '@jest/fake-timers': 29.7.0
+ '@jest/types': 29.6.3
+ '@types/node': 25.5.0
+ jest-mock: 29.7.0
+ jest-util: 29.7.0
+
+ jest-get-type@29.6.3: {}
+
+ jest-haste-map@29.7.0:
+ dependencies:
+ '@jest/types': 29.6.3
+ '@types/graceful-fs': 4.1.9
+ '@types/node': 25.5.0
+ anymatch: 3.1.3
+ fb-watchman: 2.0.2
+ graceful-fs: 4.2.11
+ jest-regex-util: 29.6.3
+ jest-util: 29.7.0
+ jest-worker: 29.7.0
+ micromatch: 4.0.8
+ walker: 1.0.8
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ jest-message-util@29.7.0:
+ dependencies:
+ '@babel/code-frame': 7.29.0
+ '@jest/types': 29.6.3
+ '@types/stack-utils': 2.0.3
+ chalk: 4.1.2
+ graceful-fs: 4.2.11
+ micromatch: 4.0.8
+ pretty-format: 29.7.0
+ slash: 3.0.0
+ stack-utils: 2.0.6
+
+ jest-mock@29.7.0:
+ dependencies:
+ '@jest/types': 29.6.3
+ '@types/node': 25.5.0
+ jest-util: 29.7.0
+
+ jest-regex-util@29.6.3: {}
+
+ jest-util@29.7.0:
+ dependencies:
+ '@jest/types': 29.6.3
+ '@types/node': 25.5.0
+ chalk: 4.1.2
+ ci-info: 3.9.0
+ graceful-fs: 4.2.11
+ picomatch: 2.3.1
+
+ jest-validate@29.7.0:
+ dependencies:
+ '@jest/types': 29.6.3
+ camelcase: 6.3.0
+ chalk: 4.1.2
+ jest-get-type: 29.6.3
+ leven: 3.1.0
+ pretty-format: 29.7.0
+
+ jest-worker@29.7.0:
+ dependencies:
+ '@types/node': 25.5.0
+ jest-util: 29.7.0
+ merge-stream: 2.0.0
+ supports-color: 8.1.1
+
js-tokens@4.0.0: {}
+ js-yaml@3.14.2:
+ dependencies:
+ argparse: 1.0.10
+ esprima: 4.0.1
+
+ jsc-safe-url@0.2.4: {}
+
jsdom@29.0.0:
dependencies:
'@asamuzakjp/css-color': 5.0.1
@@ -1370,8 +3343,21 @@ snapshots:
transitivePeerDependencies:
- '@noble/hashes'
+ jsesc@3.1.0: {}
+
json-parse-even-better-errors@4.0.0: {}
+ json5@2.2.3: {}
+
+ leven@3.1.0: {}
+
+ lighthouse-logger@1.4.2:
+ dependencies:
+ debug: 2.6.9
+ marky: 1.3.0
+ transitivePeerDependencies:
+ - supports-color
+
lightningcss-android-arm64@1.32.0:
optional: true
@@ -1421,28 +3407,257 @@ snapshots:
lightningcss-win32-arm64-msvc: 1.32.0
lightningcss-win32-x64-msvc: 1.32.0
+ locate-path@5.0.0:
+ dependencies:
+ p-locate: 4.1.0
+
+ lodash.throttle@4.1.1: {}
+
+ loose-envify@1.4.0:
+ dependencies:
+ js-tokens: 4.0.0
+
lru-cache@11.2.7: {}
+ lru-cache@5.1.1:
+ dependencies:
+ yallist: 3.1.1
+
lz-string@1.5.0: {}
magic-string@0.30.21:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
+ makeerror@1.0.12:
+ dependencies:
+ tmpl: 1.0.5
+
+ marky@1.3.0: {}
+
mdn-data@2.27.1: {}
+ memoize-one@5.2.1: {}
+
memorystream@0.3.1: {}
+ merge-stream@2.0.0: {}
+
+ metro-babel-transformer@0.83.5:
+ dependencies:
+ '@babel/core': 7.29.0
+ flow-enums-runtime: 0.0.6
+ hermes-parser: 0.33.3
+ nullthrows: 1.1.1
+ transitivePeerDependencies:
+ - supports-color
+
+ metro-cache-key@0.83.5:
+ dependencies:
+ flow-enums-runtime: 0.0.6
+
+ metro-cache@0.83.5:
+ dependencies:
+ exponential-backoff: 3.1.3
+ flow-enums-runtime: 0.0.6
+ https-proxy-agent: 7.0.6
+ metro-core: 0.83.5
+ transitivePeerDependencies:
+ - supports-color
+
+ metro-config@0.83.5:
+ dependencies:
+ connect: 3.7.0
+ flow-enums-runtime: 0.0.6
+ jest-validate: 29.7.0
+ metro: 0.83.5
+ metro-cache: 0.83.5
+ metro-core: 0.83.5
+ metro-runtime: 0.83.5
+ yaml: 2.8.2
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ metro-core@0.83.5:
+ dependencies:
+ flow-enums-runtime: 0.0.6
+ lodash.throttle: 4.1.1
+ metro-resolver: 0.83.5
+
+ metro-file-map@0.83.5:
+ dependencies:
+ debug: 4.4.3
+ fb-watchman: 2.0.2
+ flow-enums-runtime: 0.0.6
+ graceful-fs: 4.2.11
+ invariant: 2.2.4
+ jest-worker: 29.7.0
+ micromatch: 4.0.8
+ nullthrows: 1.1.1
+ walker: 1.0.8
+ transitivePeerDependencies:
+ - supports-color
+
+ metro-minify-terser@0.83.5:
+ dependencies:
+ flow-enums-runtime: 0.0.6
+ terser: 5.46.1
+
+ metro-resolver@0.83.5:
+ dependencies:
+ flow-enums-runtime: 0.0.6
+
+ metro-runtime@0.83.5:
+ dependencies:
+ '@babel/runtime': 7.29.2
+ flow-enums-runtime: 0.0.6
+
+ metro-source-map@0.83.5:
+ dependencies:
+ '@babel/traverse': 7.29.0
+ '@babel/types': 7.29.0
+ flow-enums-runtime: 0.0.6
+ invariant: 2.2.4
+ metro-symbolicate: 0.83.5
+ nullthrows: 1.1.1
+ ob1: 0.83.5
+ source-map: 0.5.7
+ vlq: 1.0.1
+ transitivePeerDependencies:
+ - supports-color
+
+ metro-symbolicate@0.83.5:
+ dependencies:
+ flow-enums-runtime: 0.0.6
+ invariant: 2.2.4
+ metro-source-map: 0.83.5
+ nullthrows: 1.1.1
+ source-map: 0.5.7
+ vlq: 1.0.1
+ transitivePeerDependencies:
+ - supports-color
+
+ metro-transform-plugins@0.83.5:
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/generator': 7.29.1
+ '@babel/template': 7.28.6
+ '@babel/traverse': 7.29.0
+ flow-enums-runtime: 0.0.6
+ nullthrows: 1.1.1
+ transitivePeerDependencies:
+ - supports-color
+
+ metro-transform-worker@0.83.5:
+ dependencies:
+ '@babel/core': 7.29.0
+ '@babel/generator': 7.29.1
+ '@babel/parser': 7.29.2
+ '@babel/types': 7.29.0
+ flow-enums-runtime: 0.0.6
+ metro: 0.83.5
+ metro-babel-transformer: 0.83.5
+ metro-cache: 0.83.5
+ metro-cache-key: 0.83.5
+ metro-minify-terser: 0.83.5
+ metro-source-map: 0.83.5
+ metro-transform-plugins: 0.83.5
+ nullthrows: 1.1.1
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ metro@0.83.5:
+ dependencies:
+ '@babel/code-frame': 7.29.0
+ '@babel/core': 7.29.0
+ '@babel/generator': 7.29.1
+ '@babel/parser': 7.29.2
+ '@babel/template': 7.28.6
+ '@babel/traverse': 7.29.0
+ '@babel/types': 7.29.0
+ accepts: 2.0.0
+ chalk: 4.1.2
+ ci-info: 2.0.0
+ connect: 3.7.0
+ debug: 4.4.3
+ error-stack-parser: 2.1.4
+ flow-enums-runtime: 0.0.6
+ graceful-fs: 4.2.11
+ hermes-parser: 0.33.3
+ image-size: 1.2.1
+ invariant: 2.2.4
+ jest-worker: 29.7.0
+ jsc-safe-url: 0.2.4
+ lodash.throttle: 4.1.1
+ metro-babel-transformer: 0.83.5
+ metro-cache: 0.83.5
+ metro-cache-key: 0.83.5
+ metro-config: 0.83.5
+ metro-core: 0.83.5
+ metro-file-map: 0.83.5
+ metro-resolver: 0.83.5
+ metro-runtime: 0.83.5
+ metro-source-map: 0.83.5
+ metro-symbolicate: 0.83.5
+ metro-transform-plugins: 0.83.5
+ metro-transform-worker: 0.83.5
+ mime-types: 3.0.2
+ nullthrows: 1.1.1
+ serialize-error: 2.1.0
+ source-map: 0.5.7
+ throat: 5.0.0
+ ws: 7.5.10
+ yargs: 17.7.2
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.1
+
+ mime-db@1.54.0: {}
+
+ mime-types@3.0.2:
+ dependencies:
+ mime-db: 1.54.0
+
+ mime@1.6.0: {}
+
min-indent@1.0.1: {}
minimatch@10.2.4:
dependencies:
brace-expansion: 5.0.4
+ minimatch@3.1.5:
+ dependencies:
+ brace-expansion: 1.1.12
+
minipass@7.1.3: {}
+ mkdirp@1.0.4: {}
+
+ ms@2.0.0: {}
+
+ ms@2.1.3: {}
+
nanoid@3.3.11: {}
+ negotiator@1.0.0: {}
+
+ node-int64@0.4.0: {}
+
+ node-releases@2.0.36: {}
+
+ normalize-path@3.0.0: {}
+
npm-normalize-package-bin@4.0.0: {}
npm-run-all2@8.0.4:
@@ -1456,14 +3671,53 @@ snapshots:
shell-quote: 1.8.3
which: 5.0.0
+ nullthrows@1.1.1: {}
+
+ ob1@0.83.5:
+ dependencies:
+ flow-enums-runtime: 0.0.6
+
obug@2.1.1: {}
+ on-finished@2.3.0:
+ dependencies:
+ ee-first: 1.1.1
+
+ on-finished@2.4.1:
+ dependencies:
+ ee-first: 1.1.1
+
+ once@1.4.0:
+ dependencies:
+ wrappy: 1.0.2
+
+ open@7.4.2:
+ dependencies:
+ is-docker: 2.2.1
+ is-wsl: 2.2.0
+
+ p-limit@2.3.0:
+ dependencies:
+ p-try: 2.2.0
+
+ p-locate@4.1.0:
+ dependencies:
+ p-limit: 2.3.0
+
+ p-try@2.2.0: {}
+
package-json-from-dist@1.0.1: {}
parse5@8.0.0:
dependencies:
entities: 6.0.1
+ parseurl@1.3.3: {}
+
+ path-exists@4.0.0: {}
+
+ path-is-absolute@1.0.1: {}
+
path-key@3.1.1: {}
path-scurry@2.0.2:
@@ -1475,10 +3729,14 @@ snapshots:
picocolors@1.1.1: {}
+ picomatch@2.3.1: {}
+
picomatch@4.0.3: {}
pidtree@0.6.0: {}
+ pirates@4.0.7: {}
+
postcss@8.5.8:
dependencies:
nanoid: 3.3.11
@@ -1491,8 +3749,32 @@ snapshots:
ansi-styles: 5.2.0
react-is: 17.0.2
+ pretty-format@29.7.0:
+ dependencies:
+ '@jest/schemas': 29.6.3
+ ansi-styles: 5.2.0
+ react-is: 18.3.1
+
+ promise@8.3.0:
+ dependencies:
+ asap: 2.0.6
+
punycode@2.3.1: {}
+ queue@6.0.2:
+ dependencies:
+ inherits: 2.0.4
+
+ range-parser@1.2.1: {}
+
+ react-devtools-core@6.1.5:
+ dependencies:
+ shell-quote: 1.8.3
+ ws: 7.5.10
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+
react-dom@19.2.4(react@19.2.4):
dependencies:
react: 19.2.4
@@ -1500,6 +3782,58 @@ snapshots:
react-is@17.0.2: {}
+ react-is@18.3.1: {}
+
+ react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4):
+ dependencies:
+ '@jest/create-cache-key-function': 29.7.0
+ '@react-native/assets-registry': 0.84.1
+ '@react-native/codegen': 0.84.1
+ '@react-native/community-cli-plugin': 0.84.1
+ '@react-native/gradle-plugin': 0.84.1
+ '@react-native/js-polyfills': 0.84.1
+ '@react-native/normalize-colors': 0.84.1
+ '@react-native/virtualized-lists': 0.84.1(@types/react@19.2.14)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
+ abort-controller: 3.0.0
+ anser: 1.4.10
+ ansi-regex: 5.0.1
+ babel-jest: 29.7.0(@babel/core@7.29.0)
+ babel-plugin-syntax-hermes-parser: 0.32.0
+ base64-js: 1.5.1
+ commander: 12.1.0
+ flow-enums-runtime: 0.0.6
+ hermes-compiler: 250829098.0.9
+ invariant: 2.2.4
+ jest-environment-node: 29.7.0
+ memoize-one: 5.2.1
+ metro-runtime: 0.83.5
+ metro-source-map: 0.83.5
+ nullthrows: 1.1.1
+ pretty-format: 29.7.0
+ promise: 8.3.0
+ react: 19.2.4
+ react-devtools-core: 6.1.5
+ react-refresh: 0.14.2
+ regenerator-runtime: 0.13.11
+ scheduler: 0.27.0
+ semver: 7.7.4
+ stacktrace-parser: 0.1.11
+ tinyglobby: 0.2.15
+ whatwg-fetch: 3.6.20
+ ws: 7.5.10
+ yargs: 17.7.2
+ optionalDependencies:
+ '@types/react': 19.2.14
+ transitivePeerDependencies:
+ - '@babel/core'
+ - '@react-native-community/cli'
+ - '@react-native/metro-config'
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ react-refresh@0.14.2: {}
+
react@19.2.4: {}
read-package-json-fast@4.0.0:
@@ -1512,8 +3846,18 @@ snapshots:
indent-string: 4.0.0
strip-indent: 3.0.0
+ regenerator-runtime@0.13.11: {}
+
+ require-directory@2.1.1: {}
+
require-from-string@2.0.2: {}
+ resolve-from@5.0.0: {}
+
+ rimraf@3.0.2:
+ dependencies:
+ glob: 7.2.3
+
rimraf@6.1.3:
dependencies:
glob: 13.0.6
@@ -1546,6 +3890,41 @@ snapshots:
scheduler@0.27.0: {}
+ semver@6.3.1: {}
+
+ semver@7.7.4: {}
+
+ send@0.19.2:
+ dependencies:
+ debug: 2.6.9
+ depd: 2.0.0
+ destroy: 1.2.0
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ etag: 1.8.1
+ fresh: 0.5.2
+ http-errors: 2.0.1
+ mime: 1.6.0
+ ms: 2.1.3
+ on-finished: 2.4.1
+ range-parser: 1.2.1
+ statuses: 2.0.2
+ transitivePeerDependencies:
+ - supports-color
+
+ serialize-error@2.1.0: {}
+
+ serve-static@1.16.3:
+ dependencies:
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ parseurl: 1.3.3
+ send: 0.19.2
+ transitivePeerDependencies:
+ - supports-color
+
+ setprototypeof@1.2.0: {}
+
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
@@ -1556,18 +3935,80 @@ snapshots:
siginfo@2.0.0: {}
+ signal-exit@3.0.7: {}
+
+ slash@3.0.0: {}
+
source-map-js@1.2.1: {}
+ source-map-support@0.5.21:
+ dependencies:
+ buffer-from: 1.1.2
+ source-map: 0.6.1
+
+ source-map@0.5.7: {}
+
+ source-map@0.6.1: {}
+
+ sprintf-js@1.0.3: {}
+
+ stack-utils@2.0.6:
+ dependencies:
+ escape-string-regexp: 2.0.0
+
stackback@0.0.2: {}
+ stackframe@1.3.4: {}
+
+ stacktrace-parser@0.1.11:
+ dependencies:
+ type-fest: 0.7.1
+
+ statuses@1.5.0: {}
+
+ statuses@2.0.2: {}
+
std-env@4.0.0: {}
+ string-width@4.2.3:
+ dependencies:
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
+
+ strip-ansi@6.0.1:
+ dependencies:
+ ansi-regex: 5.0.1
+
strip-indent@3.0.0:
dependencies:
min-indent: 1.0.1
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ supports-color@8.1.1:
+ dependencies:
+ has-flag: 4.0.0
+
symbol-tree@3.2.4: {}
+ terser@5.46.1:
+ dependencies:
+ '@jridgewell/source-map': 0.3.11
+ acorn: 8.16.0
+ commander: 2.20.3
+ source-map-support: 0.5.21
+
+ test-exclude@6.0.0:
+ dependencies:
+ '@istanbuljs/schema': 0.1.3
+ glob: 7.2.3
+ minimatch: 3.1.5
+
+ throat@5.0.0: {}
+
tinybench@2.9.0: {}
tinyexec@1.0.4: {}
@@ -1585,6 +4026,14 @@ snapshots:
dependencies:
tldts-core: 7.0.26
+ tmpl@1.0.5: {}
+
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
+ toidentifier@1.0.1: {}
+
tough-cookie@6.0.1:
dependencies:
tldts: 7.0.26
@@ -1595,17 +4044,31 @@ snapshots:
tslib@2.8.1: {}
+ type-detect@4.0.8: {}
+
+ type-fest@0.7.1: {}
+
typescript@5.9.3: {}
undici-types@7.18.2: {}
undici@7.24.4: {}
+ unpipe@1.0.0: {}
+
+ update-browserslist-db@1.2.3(browserslist@4.28.1):
+ dependencies:
+ browserslist: 4.28.1
+ escalade: 3.2.0
+ picocolors: 1.1.1
+
use-sync-external-store@1.6.0(react@19.2.4):
dependencies:
react: 19.2.4
- vite@8.0.0(@types/node@25.5.0):
+ utils-merge@1.0.1: {}
+
+ vite@8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2):
dependencies:
'@oxc-project/runtime': 0.115.0
lightningcss: 1.32.0
@@ -1616,11 +4079,13 @@ snapshots:
optionalDependencies:
'@types/node': 25.5.0
fsevents: 2.3.3
+ terser: 5.46.1
+ yaml: 2.8.2
- vitest@4.1.0(@types/node@25.5.0)(jsdom@29.0.0)(vite@8.0.0(@types/node@25.5.0)):
+ vitest@4.1.0(@types/node@25.5.0)(jsdom@29.0.0)(vite@8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2)):
dependencies:
'@vitest/expect': 4.1.0
- '@vitest/mocker': 4.1.0(vite@8.0.0(@types/node@25.5.0))
+ '@vitest/mocker': 4.1.0(vite@8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2))
'@vitest/pretty-format': 4.1.0
'@vitest/runner': 4.1.0
'@vitest/snapshot': 4.1.0
@@ -1637,7 +4102,7 @@ snapshots:
tinyexec: 1.0.4
tinyglobby: 0.2.15
tinyrainbow: 3.1.0
- vite: 8.0.0(@types/node@25.5.0)
+ vite: 8.0.0(@types/node@25.5.0)(terser@5.46.1)(yaml@2.8.2)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 25.5.0
@@ -1645,12 +4110,20 @@ snapshots:
transitivePeerDependencies:
- msw
+ vlq@1.0.1: {}
+
w3c-xmlserializer@5.0.0:
dependencies:
xml-name-validator: 5.0.0
+ walker@1.0.8:
+ dependencies:
+ makeerror: 1.0.12
+
webidl-conversions@8.0.1: {}
+ whatwg-fetch@3.6.20: {}
+
whatwg-mimetype@5.0.0: {}
whatwg-url@16.0.1:
@@ -1674,6 +4147,39 @@ snapshots:
siginfo: 2.0.0
stackback: 0.0.2
+ wrap-ansi@7.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ wrappy@1.0.2: {}
+
+ write-file-atomic@4.0.2:
+ dependencies:
+ imurmurhash: 0.1.4
+ signal-exit: 3.0.7
+
+ ws@7.5.10: {}
+
xml-name-validator@5.0.0: {}
xmlchars@2.2.0: {}
+
+ y18n@5.0.8: {}
+
+ yallist@3.1.1: {}
+
+ yaml@2.8.2: {}
+
+ yargs-parser@21.1.1: {}
+
+ yargs@17.7.2:
+ dependencies:
+ cliui: 8.0.1
+ escalade: 3.2.0
+ get-caller-file: 2.0.5
+ require-directory: 2.1.1
+ string-width: 4.2.3
+ y18n: 5.0.8
+ yargs-parser: 21.1.1
diff --git a/release-please-config.json b/release-please-config.json
index cdc6272..197f944 100644
--- a/release-please-config.json
+++ b/release-please-config.json
@@ -9,6 +9,9 @@
},
"packages/google-signin": {
"include-component-in-tag": true
+ },
+ "packages/apple-signin": {
+ "include-component-in-tag": true
}
}
}
\ No newline at end of file