diff --git a/apps/mobile/app.config.ts b/apps/mobile/app.config.ts index 52eae6db97777ac4cc9d60079e34735859dada30..6a992e6c5264ac8e1a9a96775f27a24d587b649c 100644 --- a/apps/mobile/app.config.ts +++ b/apps/mobile/app.config.ts @@ -401,6 +401,9 @@ const config: ExpoConfig = { android: { // Keep the supported floor explicit and covered by native notification tests. minSdkVersion: 24, + // kotlinx-io uses Kotlin 2.3's return-value checker annotation, while + // SDK 58 builds with Kotlin 2.2. It has no runtime behavior. + extraProguardRules: "-dontwarn kotlin.MustUseReturnValues", }, ios: { deploymentTarget: "18.0", @@ -419,7 +422,6 @@ const config: ExpoConfig = { // would delete the asset catalog) and its xcodeproj mod creates the widget // target (which must exist before the compile phase can be attached). ...(!isIosPersonalTeamBuild ? ["./plugins/withWidgetLogoAsset.cjs", widgetsPlugin] : []), - "./plugins/withIosSceneLifecycle.cjs", "./plugins/withAndroidCleartextTraffic.cjs", "./plugins/withAndroidGradleHeap.cjs", "./plugins/withAndroidInputBackground.cjs", diff --git a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownText.mm b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownText.mm index 533c13108865432523317f6541783ca7e36ff17c..8fa5abfe2a8ec543d6f7830be6d20e2060036715 100644 --- a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownText.mm +++ b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownText.mm @@ -10,7 +10,7 @@ #import #import #import -#import "RCTFabricComponentsPlugins.h" +#import using namespace facebook::react; diff --git a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextManager.mm b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextManager.mm index 3ca2b1eee5b9f39e4bacac750456a3e8b379d3b4..93f1b2e4ba2a4b81806f5658c17a9b9329e15b4c 100644 --- a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextManager.mm +++ b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextManager.mm @@ -1,6 +1,5 @@ #import #import -#import "RCTBridge.h" #import "Utils.h" @interface T3MarkdownTextManager : RCTViewManager diff --git a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRun.mm b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRun.mm index d2de6884396f2e1a291203a1d2692d78cb48de6e..2cd9444f6d2274469aa4016c5ecb271a9036e267 100644 --- a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRun.mm +++ b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRun.mm @@ -4,7 +4,7 @@ #import #import #import -#import "RCTFabricComponentsPlugins.h" +#import #import "Utils.h" using namespace facebook::react; diff --git a/apps/mobile/modules/t3-markdown-text/src/MarkdownTextPrimitive.tsx b/apps/mobile/modules/t3-markdown-text/src/MarkdownTextPrimitive.tsx index 1e9394bd6eca83d3f03ad623855ddf2eea4c2f62..2e8026f328288fc48069754f14e679231255b26b 100644 --- a/apps/mobile/modules/t3-markdown-text/src/MarkdownTextPrimitive.tsx +++ b/apps/mobile/modules/t3-markdown-text/src/MarkdownTextPrimitive.tsx @@ -6,6 +6,7 @@ import { StyleSheet, Text as RNText, type ColorValue, + type TextInstance, type TextProps, type ViewStyle, } from "react-native"; @@ -43,7 +44,7 @@ export type ContextMenuActionEvent = { * while the React Native Text fallback reports measured `TextLayoutLine`s. */ export type MarkdownTextPrimitiveProps = Omit & { - nativeTextRef?: Ref; + nativeTextRef?: Ref; selectionHandleColor?: ColorValue; uiTextView?: boolean; contextMenuConfig?: string; @@ -134,13 +135,17 @@ function AndroidMarkdownText({ contextClipboardConfig: _contextClipboardConfig, ...props }: MarkdownTextPrimitiveProps) { - const textRef = React.useRef(null); - React.useImperativeHandle(nativeTextRef, () => textRef.current, []); + const textRef = React.useRef(null); + React.useImperativeHandle( + nativeTextRef, + () => textRef.current, + [], + ); const color = processColor(selectionHandleColor); const applyHandleColor = React.useCallback(() => { if (!textRef.current || typeof color !== "number") return; const reactTag = findNodeHandle(textRef.current); - if (reactTag !== null) setMarkdownSelectionHandleColor(reactTag, color); + if (reactTag != null) setMarkdownSelectionHandleColor(reactTag, color); }, [color]); // RN's selectionColor only sets the highlight. Retint mounted handles when diff --git a/apps/mobile/modules/t3-markdown-text/src/NativeMarkdownSelectableText.tsx b/apps/mobile/modules/t3-markdown-text/src/NativeMarkdownSelectableText.tsx index 1d9c2b93ede8419889732ae431e5692cbd19ab05..5a01dd436bbc73e0227210add31f4281ffcbbb88 100644 --- a/apps/mobile/modules/t3-markdown-text/src/NativeMarkdownSelectableText.tsx +++ b/apps/mobile/modules/t3-markdown-text/src/NativeMarkdownSelectableText.tsx @@ -6,14 +6,14 @@ import { Linking, Platform, StyleSheet, - Text as RNText, + type TextInstance, type TextStyle, useColorScheme, View, } from "react-native"; import { MarkdownTextPrimitive } from "./MarkdownTextPrimitive"; -import { markdownFileIconSource } from "./markdownFileIcons"; +import { markdownFileIconSource, markdownIconAssetUri } from "./markdownFileIcons"; import { markdownLinkIconSource } from "./markdownLinkIcons"; import { resolveMarkdownFileIcon, resolveMarkdownLinkIcon } from "./markdownLinks"; import type { NativeMarkdownTextRun } from "./nativeMarkdownText"; @@ -236,11 +236,11 @@ export function NativeMarkdownSelectableText(props: { interactive: Boolean(run.href), iconUri: !contextReference && run.fileIcon - ? Image.resolveAssetSource(markdownFileIconSource(run.fileIcon)).uri + ? markdownIconAssetUri(markdownFileIconSource(run.fileIcon)) : contextRecord?.kind === "mention" && "path" in contextRecord - ? Image.resolveAssetSource( + ? markdownIconAssetUri( markdownFileIconSource(resolveMarkdownFileIcon(contextRecord.path)), - ).uri + ) : undefined, fontSize: props.textStyle.fontSize * 0.8, foreground: props.textStyle.color, @@ -297,10 +297,12 @@ export function NativeMarkdownSelectableText(props: { ? JSON.stringify({ fragment: contextClipboardFragment, ranges }) : ""; const attachAndroidText = useCallback( - (textView: RNText | null) => { + (textView: TextInstance | null) => { if (Platform.OS !== "android" || !containsInlineIcon || !textView) return; const reactTag = findNodeHandle(textView); - if (reactTag !== null) installMarkdownCopySanitizer(reactTag, contextClipboardConfig); + if (typeof reactTag === "number") { + installMarkdownCopySanitizer(reactTag, contextClipboardConfig); + } }, [containsInlineIcon, contextClipboardConfig], ); @@ -358,6 +360,12 @@ export function NativeMarkdownSelectableText(props: { else void Linking.openURL(href); } : undefined; + const fileIconUri = run.fileIcon + ? markdownIconAssetUri(markdownFileIconSource(run.fileIcon)) + : undefined; + const linkIconUri = linkIcon + ? markdownIconAssetUri(markdownLinkIconSource(linkIcon)) + : undefined; return ( ; - ellipsizeMode?: WithDefault; + numberOfLines?: CodegenTypes.Int32; + allowFontScaling?: CodegenTypes.WithDefault; + ellipsizeMode?: CodegenTypes.WithDefault; selectable?: boolean; - onTextLayout?: BubblingEventHandler; + onTextLayout?: CodegenTypes.BubblingEventHandler; /** * Callback fired when the text selection changes. * @@ -48,7 +42,7 @@ interface NativeProps extends ViewProps { * * ``` */ - onSelectionChange?: BubblingEventHandler; + onSelectionChange?: CodegenTypes.BubblingEventHandler; } export default codegenNativeComponent("T3MarkdownText", { diff --git a/apps/mobile/modules/t3-markdown-text/src/T3MarkdownTextRunNativeComponent.ts b/apps/mobile/modules/t3-markdown-text/src/T3MarkdownTextRunNativeComponent.ts index 040e44bc18b5f6bf35227dfb64a6a17ac361ce89..6c28742256c653c536adb7b0123daa6a56f13b07 100644 --- a/apps/mobile/modules/t3-markdown-text/src/T3MarkdownTextRunNativeComponent.ts +++ b/apps/mobile/modules/t3-markdown-text/src/T3MarkdownTextRunNativeComponent.ts @@ -1,14 +1,12 @@ -import type { ColorValue, ViewProps } from "react-native"; -import type { - BubblingEventHandler, - Float, - Int32, - WithDefault, -} from "react-native/Libraries/Types/CodegenTypes"; -import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNativeComponent"; +import { + codegenNativeComponent, + type CodegenTypes, + type ColorValue, + type ViewProps, +} from "react-native"; interface TargetedEvent { - target: Int32; + target: CodegenTypes.Int32; } interface ContextMenuActionEvent extends TargetedEvent { @@ -35,21 +33,21 @@ type TextAlign = "auto" | "left" | "right" | "center" | "justify"; interface NativeProps extends ViewProps { text: string; color?: ColorValue; - fontSize?: Float; - fontStyle?: WithDefault; - fontWeight?: WithDefault; + fontSize?: CodegenTypes.Float; + fontStyle?: CodegenTypes.WithDefault; + fontWeight?: CodegenTypes.WithDefault; fontFamily?: string; - letterSpacing?: Float; - lineHeight?: Float; - textDecorationLine?: WithDefault; - textDecorationStyle?: WithDefault; + letterSpacing?: CodegenTypes.Float; + lineHeight?: CodegenTypes.Float; + textDecorationLine?: CodegenTypes.WithDefault; + textDecorationStyle?: CodegenTypes.WithDefault; textDecorationColor?: ColorValue; - textAlign?: WithDefault; - shadowRadius?: WithDefault; + textAlign?: CodegenTypes.WithDefault; + shadowRadius?: CodegenTypes.WithDefault; contextMenuConfig?: string; - onPress?: BubblingEventHandler; - onLongPress?: BubblingEventHandler; - onContextMenuAction?: BubblingEventHandler; + onPress?: CodegenTypes.BubblingEventHandler; + onLongPress?: CodegenTypes.BubblingEventHandler; + onContextMenuAction?: CodegenTypes.BubblingEventHandler; } export default codegenNativeComponent("T3MarkdownTextRun", { diff --git a/apps/mobile/modules/t3-markdown-text/src/markdownFileIcons.ts b/apps/mobile/modules/t3-markdown-text/src/markdownFileIcons.ts index 94b08c1de7eec523ce14f938651911d543dd5778..99c902727dfe53bb3ca949dd0e64a70231871e8a 100644 --- a/apps/mobile/modules/t3-markdown-text/src/markdownFileIcons.ts +++ b/apps/mobile/modules/t3-markdown-text/src/markdownFileIcons.ts @@ -1,4 +1,4 @@ -import type { ImageSourcePropType } from "react-native"; +import { Image, type ImageSourcePropType } from "react-native"; import type { MarkdownFileIcon } from "./markdownLinks"; import { MARKDOWN_FILE_ICON_SOURCES } from "./markdownFileIcons.generated"; @@ -6,3 +6,12 @@ import { MARKDOWN_FILE_ICON_SOURCES } from "./markdownFileIcons.generated"; export function markdownFileIconSource(icon: MarkdownFileIcon): ImageSourcePropType { return MARKDOWN_FILE_ICON_SOURCES[icon]; } + +/** + * Bundled icon URI handed to native views that draw the icon themselves. The + * sources are static requires, so this only comes back undefined when the + * bundler dropped the asset; callers treat a missing icon as "no icon". + */ +export function markdownIconAssetUri(source: ImageSourcePropType): string | undefined { + return Image.resolveAssetSource(source)?.uri; +} diff --git a/apps/mobile/package.json b/apps/mobile/package.json index fb3eee190cd199acfeaae102b9ad260fc698914c..ae52098e59dd63929266b815ca70905971e314d5 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -49,7 +49,8 @@ "@clerk/expo": "catalog:", "@effect/atom-react": "catalog:", "@expo-google-fonts/dm-sans": "^0.4.2", - "@expo/ui": "~57.0.14", + "@expo/metro-runtime": "~58.0.9", + "@expo/ui": "~58.0.9", "@legendapp/list": "catalog:", "@material/material-color-utilities": "0.3.0", "@noble/curves": "catalog:", @@ -73,56 +74,56 @@ "clsx": "^2.1.1", "diff": "8.0.3", "effect": "catalog:", - "expo": "~57.0.18", - "expo-asset": "~57.0.15", - "expo-audio": "57.0.4", - "expo-auth-session": "~57.0.10", - "expo-blur": "~57.0.2", - "expo-build-properties": "~57.0.15", - "expo-camera": "~57.0.4", - "expo-clipboard": "~57.0.1", - "expo-constants": "~57.0.16", - "expo-crypto": "~57.0.2", - "expo-dev-client": "~57.0.16", - "expo-device": "~57.0.1", - "expo-document-picker": "~57.0.1", - "expo-file-system": "~57.0.6", - "expo-font": "~57.0.2", - "expo-glass-effect": "~57.0.1", - "expo-haptics": "~57.0.2", - "expo-image": "~57.0.3", - "expo-image-manipulator": "~57.0.17", - "expo-image-picker": "~57.0.14", - "expo-keep-awake": "~57.0.2", - "expo-linking": "~57.0.8", - "expo-network": "~57.0.1", - "expo-notifications": "57.0.15", + "expo": "58.0.0", + "expo-asset": "~58.0.9", + "expo-audio": "58.0.3", + "expo-auth-session": "~58.0.6", + "expo-blur": "58.0.2", + "expo-build-properties": "~58.0.9", + "expo-camera": "~58.0.5", + "expo-clipboard": "~58.0.2", + "expo-constants": "~58.0.9", + "expo-crypto": "~58.0.3", + "expo-dev-client": "~58.0.9", + "expo-device": "~58.0.3", + "expo-document-picker": "~58.0.3", + "expo-file-system": "~58.0.4", + "expo-font": "~58.0.4", + "expo-glass-effect": "58.0.3", + "expo-haptics": "~58.0.3", + "expo-image": "~58.0.8", + "expo-image-manipulator": "~58.0.10", + "expo-image-picker": "~58.0.9", + "expo-keep-awake": "~58.0.2", + "expo-linking": "~58.0.9", + "expo-network": "~58.0.2", + "expo-notifications": "~58.0.9", "expo-paste-input": "^0.1.15", "expo-quick-actions": "^6.0.2", - "expo-secure-store": "~57.0.2", - "expo-sharing": "57.0.17", - "expo-splash-screen": "~57.0.8", - "expo-sqlite": "~57.0.2", - "expo-symbols": "~57.0.2", - "expo-updates": "~57.0.19", - "expo-video": "~57.0.3", - "expo-web-browser": "~57.0.2", - "expo-widgets": "57.0.15", - "react": "19.2.3", - "react-dom": "19.2.3", - "react-native": "0.86.3", - "react-native-gesture-handler": "~2.32.0", + "expo-secure-store": "~58.0.1", + "expo-sharing": "58.0.12", + "expo-splash-screen": "~58.0.2", + "expo-sqlite": "~58.0.7", + "expo-symbols": "~58.0.3", + "expo-updates": "~58.0.11", + "expo-video": "~58.0.5", + "expo-web-browser": "~58.0.3", + "expo-widgets": "58.0.9", + "react": "19.3.0", + "react-dom": "19.3.0", + "react-native": "0.88.0-rc.3", + "react-native-gesture-handler": "~3.2.1", "react-native-image-viewing": "^0.2.2", - "react-native-keyboard-controller": "1.21.13", + "react-native-keyboard-controller": "1.22.4", "react-native-nitro-markdown": "^0.5.0", "react-native-nitro-modules": "0.35.9", - "react-native-reanimated": "4.5.5", - "react-native-safe-area-context": "~5.7.0", - "react-native-screens": "~4.26.0", + "react-native-reanimated": "4.7.0", + "react-native-safe-area-context": "~5.9.1", + "react-native-screens": "~4.28.0", "react-native-shiki-engine": "^0.3.12", - "react-native-svg": "15.15.4", - "react-native-webview": "^13.16.1", - "react-native-worklets": "0.11.4", + "react-native-svg": "15.15.5", + "react-native-webview": "14.0.1", + "react-native-worklets": "0.13.0", "shiki": "4.2.0", "tailwind-merge": "^3.5.0", "uniwind": "1.11.0" @@ -130,9 +131,9 @@ "devDependencies": { "@effect/vitest": "catalog:", "@pierre/trees": "1.0.0-beta.4", - "@types/react": "~19.2.0", + "@types/react": "~19.3.0", "@types/react-dom": "~19.2.3", - "babel-preset-expo": "~57.0.9", + "babel-preset-expo": "~58.0.6", "tailwindcss": "^4.0.0", "typescript": "catalog:" }, diff --git a/apps/mobile/plugins/withIosSceneLifecycle.cjs b/apps/mobile/plugins/withIosSceneLifecycle.cjs deleted file mode 100644 index c0d7f02ece3285e1221e3408c79533cd911fb53c..0000000000000000000000000000000000000000 --- a/apps/mobile/plugins/withIosSceneLifecycle.cjs +++ /dev/null @@ -1,123 +0,0 @@ -const { withAppDelegate, withInfoPlist } = require("expo/config-plugins"); - -const SCENE_DELEGATE = ` - -class SceneDelegate: UIResponder, UIWindowSceneDelegate { - var window: UIWindow? - - func scene( - _ scene: UIScene, - willConnectTo session: UISceneSession, - options connectionOptions: UIScene.ConnectionOptions - ) { - guard - let windowScene = scene as? UIWindowScene, - let appDelegate = UIApplication.shared.delegate as? AppDelegate - else { - return - } - - let appWindow: UIWindow - if let existingWindow = appDelegate.window { - appWindow = existingWindow - } else { - appWindow = UIWindow(windowScene: windowScene) - appDelegate.window = appWindow - appDelegate.reactNativeFactory?.startReactNative( - withModuleName: "main", - in: appWindow, - launchOptions: appDelegate.sceneLaunchOptions) - appDelegate.sceneLaunchOptions = nil - } - - window = appWindow - appWindow.windowScene = windowScene - appWindow.makeKeyAndVisible() - - if let url = connectionOptions.urlContexts.first?.url { - _ = appDelegate.application(UIApplication.shared, open: url, options: [:]) - } - - if let userActivity = connectionOptions.userActivities.first { - _ = appDelegate.application( - UIApplication.shared, - continue: userActivity, - restorationHandler: { _ in }) - } - } - - func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { - guard - let url = URLContexts.first?.url, - let appDelegate = UIApplication.shared.delegate as? AppDelegate - else { - return - } - - _ = appDelegate.application(UIApplication.shared, open: url, options: [:]) - } - - func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { - guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { - return - } - - _ = appDelegate.application( - UIApplication.shared, - continue: userActivity, - restorationHandler: { _ in }) - } -}`; - -module.exports = function withIosSceneLifecycle(config) { - config = withInfoPlist(config, (nextConfig) => { - nextConfig.modResults.UIApplicationSceneManifest = { - UIApplicationSupportsMultipleScenes: false, - UISceneConfigurations: { - UIWindowSceneSessionRoleApplication: [ - { - UISceneConfigurationName: "Default Configuration", - UISceneDelegateClassName: "$(PRODUCT_MODULE_NAME).SceneDelegate", - }, - ], - }, - }; - - return nextConfig; - }); - - return withAppDelegate(config, (nextConfig) => { - if (nextConfig.modResults.language !== "swift") { - throw new Error("The iOS scene lifecycle plugin requires a Swift AppDelegate."); - } - - // Creating the window before a scene exists leaves iOS share scenes with - // incorrect geometry, even if windowScene is assigned afterward. - const startup = - /window = UIWindow\(frame: UIScreen\.main\.bounds\)\s+factory\.startReactNative\(\s+withModuleName: "main",\s+in: window,\s+launchOptions: launchOptions\)/; - if (startup.test(nextConfig.modResults.contents)) { - nextConfig.modResults.contents = nextConfig.modResults.contents.replace( - startup, - "sceneLaunchOptions = launchOptions", - ); - } else if (!nextConfig.modResults.contents.includes("sceneLaunchOptions = launchOptions")) { - throw new Error("Could not move React Native startup into the iOS scene lifecycle."); - } - if (!nextConfig.modResults.contents.includes("var sceneLaunchOptions:")) { - nextConfig.modResults.contents = nextConfig.modResults.contents.replace( - "var window: UIWindow?", - "var window: UIWindow?\n var sceneLaunchOptions: [UIApplication.LaunchOptionsKey: Any]?", - ); - } - if (!nextConfig.modResults.contents.includes("class SceneDelegate:")) { - nextConfig.modResults.contents += SCENE_DELEGATE; - } else { - nextConfig.modResults.contents = nextConfig.modResults.contents.replace( - "in: appWindow,\n launchOptions: nil)", - "in: appWindow,\n launchOptions: appDelegate.sceneLaunchOptions)\n appDelegate.sceneLaunchOptions = nil", - ); - } - - return nextConfig; - }); -}; diff --git a/apps/mobile/plugins/withIosSceneLifecycle.test.mjs b/apps/mobile/plugins/withIosSceneLifecycle.test.mjs deleted file mode 100644 index 34af7ab27fa22c20a953c9dcfb21039b3658d410..0000000000000000000000000000000000000000 --- a/apps/mobile/plugins/withIosSceneLifecycle.test.mjs +++ /dev/null @@ -1,58 +0,0 @@ -import { describe, expect, it } from "vitest"; -import withIosSceneLifecycle from "./withIosSceneLifecycle.cjs"; - -const appDelegate = `class AppDelegate: ExpoAppDelegate { - var window: UIWindow? - func application() { - window = UIWindow(frame: UIScreen.main.bounds) - factory.startReactNative( - withModuleName: "main", - in: window, - launchOptions: launchOptions) - } -}`; - -async function transform(contents) { - const config = withIosSceneLifecycle({ name: "Test", slug: "test" }); - const result = await config.mods.ios.appDelegate({ - ...config, - modRequest: { platform: "ios", modName: "appDelegate", introspect: false }, - modResults: { language: "swift", contents }, - }); - return result.modResults.contents; -} - -describe("iOS scene lifecycle generation", () => { - it("creates the window in the scene before starting React Native and retains launch options", async () => { - const result = await transform(appDelegate); - const [startup, scene] = result.split("class SceneDelegate:"); - expect(startup).not.toContain("UIWindow(frame:"); - expect(startup).not.toContain("startReactNative("); - expect(startup).toContain("sceneLaunchOptions = launchOptions"); - expect(scene.indexOf("UIWindow(windowScene: windowScene)")).toBeLessThan( - scene.indexOf("startReactNative("), - ); - expect(scene).toContain("launchOptions: appDelegate.sceneLaunchOptions)"); - expect(scene).toContain("appDelegate.sceneLaunchOptions = nil"); - }); - - it("does not duplicate startup or scene code on subsequent prebuilds", async () => { - const generated = await transform(appDelegate); - expect(await transform(generated)).toBe(generated); - }); - - it("updates the previously generated scene delegate", async () => { - const generated = await transform(appDelegate); - const oldScene = generated - .slice(generated.indexOf("class SceneDelegate:")) - .replace("launchOptions: appDelegate.sceneLaunchOptions)", "launchOptions: nil)") - .replace(" appDelegate.sceneLaunchOptions = nil\n", ""); - expect(await transform(`${appDelegate}\n\n${oldScene}`)).toBe(generated); - }); - - it("fails visibly when the Expo startup template changes", async () => { - await expect(transform("class AppDelegate: ExpoAppDelegate {}")).rejects.toThrow( - "Could not move React Native startup", - ); - }); -}); diff --git a/apps/mobile/src/App.tsx b/apps/mobile/src/App.tsx index 34a742f8f11b70d4b795380f45eb599a5cdd29f9..001c9d597cc8418d9102cac4f981e00c1db9f681 100644 --- a/apps/mobile/src/App.tsx +++ b/apps/mobile/src/App.tsx @@ -76,10 +76,7 @@ function AppContent() { - + {/* The navigation theme drives the NATIVE header appearance: native-stack forwards `dark` as the nav bar's overrideUserInterfaceStyle. Without this, React Navigation defaults to its light theme and every native diff --git a/apps/mobile/src/Stack.tsx b/apps/mobile/src/Stack.tsx index 4baeadb94238d0b7362b1a1ddf3b877fa76f909d..417473ba20e8a3aa2bf1f17f46cb0921f37dd497 100644 --- a/apps/mobile/src/Stack.tsx +++ b/apps/mobile/src/Stack.tsx @@ -520,7 +520,12 @@ function RootStackLayout(props: { const navigation = useNavigation(); const { pendingShare } = useIncomingShare(); const sharePresentationRef = useRef(EMPTY_INCOMING_SHARE_PRESENTATION_STATE); - useAgentNotificationNavigation(); + // Keyboard commands follow the top route; notification suppression follows + // the thread beneath overlay sheets. + const path = getPathFromState(props.state, navigationPathConfig); + const pathname = path.startsWith("/") ? path : `/${path}`; + const workspaceLocation = workspaceLocationFromState(props.state); + useAgentNotificationNavigation(workspaceLocation.pathname); // Presents the T3 Connect onboarding sheet after an in-session sign-in. useConnectOnboardingNavigation(); // Launcher app shortcuts: routes shortcut taps and tracks opened threads. @@ -540,11 +545,6 @@ function RootStackLayout(props: { params: { incomingShareId: transition.shareIdToPresent }, }); }, [navigation, pendingShare, props.state]); - // Full pathname (sheets included) for keyboard-command scoping; the - // workspace layout only reacts to the underlying non-overlay route. - const path = getPathFromState(props.state, navigationPathConfig); - const pathname = path.startsWith("/") ? path : `/${path}`; - const workspaceLocation = workspaceLocationFromState(props.state); return ( diff --git a/apps/mobile/src/components/AndroidAnchoredMenu.tsx b/apps/mobile/src/components/AndroidAnchoredMenu.tsx index 4c465a9f9ef411e0a3d6b3a1537a623e6428b25d..5dccade1c9ae7be8be25032a17f497883f4328f9 100644 --- a/apps/mobile/src/components/AndroidAnchoredMenu.tsx +++ b/apps/mobile/src/components/AndroidAnchoredMenu.tsx @@ -1,7 +1,7 @@ import type { MenuAction, MenuComponentProps } from "@react-native-menu/menu"; import type { ReactNode } from "react"; import { useCallback, useEffect, useRef, useState } from "react"; -import type { StyleProp, ViewStyle } from "react-native"; +import type { StyleProp, ViewInstance, ViewStyle } from "react-native"; import { BackHandler, Pressable, ScrollView, View } from "react-native"; import { useKeyboardState } from "react-native-keyboard-controller"; import Animated, { FadeIn } from "react-native-reanimated"; @@ -73,8 +73,8 @@ export function AndroidAnchoredMenu(props: AndroidAnchoredMenuProps) { overlay === null ? desiredMenuWidth : Math.min(desiredMenuWidth, Math.max(0, overlay.width - 2 * SCREEN_MARGIN)); - const anchorRef = useRef(null); - const overlayRef = useRef(null); + const anchorRef = useRef(null); + const overlayRef = useRef(null); const keyboardVisible = useKeyboardState((state) => state.isVisible); const keyboardHeight = useKeyboardState((state) => state.height); diff --git a/apps/mobile/src/components/AppText.tsx b/apps/mobile/src/components/AppText.tsx index 6f96f42469538da139cdd151888130a6974b54bb..7423ff678549d507ed3b16581cf223e8cd4fda5b 100644 --- a/apps/mobile/src/components/AppText.tsx +++ b/apps/mobile/src/components/AppText.tsx @@ -2,6 +2,7 @@ import { Platform, Text as RNText, TextInput as RNTextInput, + type TextInputInstance, type TextInputProps as RNTextInputProps, type TextProps as RNTextProps, } from "react-native"; @@ -26,7 +27,7 @@ export function AppText({ className, ...props }: AppTextProps) { export type AppTextInputProps = Omit & { readonly className?: string; - readonly ref?: React.Ref; + readonly ref?: React.Ref; }; /** diff --git a/apps/mobile/src/components/ComposerAttachmentStrip.tsx b/apps/mobile/src/components/ComposerAttachmentStrip.tsx index 04382839c909e99fa66dfe7b5f1599164f4856ba..7e988f1075e34d4993b6ca56228e1c1e65aa585b 100644 --- a/apps/mobile/src/components/ComposerAttachmentStrip.tsx +++ b/apps/mobile/src/components/ComposerAttachmentStrip.tsx @@ -127,7 +127,7 @@ async function materializeDataUrlPreview(id: string, dataUrl: string): Promise; + readonly ref?: Ref; readonly children: ReactNode; readonly glassEffectStyle?: "clear" | "regular" | "none"; readonly tintColor?: ColorValue; diff --git a/apps/mobile/src/components/LoadingScreen.tsx b/apps/mobile/src/components/LoadingScreen.tsx index 456a347d365d778445871cf891c6d834d719ea7f..351f828d3be203a2820dd5508e2ea7ed6404ac0c 100644 --- a/apps/mobile/src/components/LoadingScreen.tsx +++ b/apps/mobile/src/components/LoadingScreen.tsx @@ -15,7 +15,7 @@ export function LoadingScreen(props: { return ( - + {messagePlacement === "above-spinner" ? ( diff --git a/apps/mobile/src/components/MaterialSearchField.tsx b/apps/mobile/src/components/MaterialSearchField.tsx index 3609430a6e1a3ed2328158d8fb41e9cd88fb77c0..639249313bfde0bb094f71080b4d0439b21e7d8a 100644 --- a/apps/mobile/src/components/MaterialSearchField.tsx +++ b/apps/mobile/src/components/MaterialSearchField.tsx @@ -1,5 +1,5 @@ import type { RefObject } from "react"; -import { Pressable, TextInput, View } from "react-native"; +import { Pressable, TextInput, type TextInputInstance, View } from "react-native"; import { SymbolView } from "./AppSymbol"; import { useAndroidControlSizing } from "./useAndroidControlSizing"; @@ -12,7 +12,7 @@ export function MaterialSearchField({ value, onChangeText, }: { - readonly inputRef: RefObject; + readonly inputRef: RefObject; readonly accessibilityLabel: string; readonly clearAccessibilityLabel: string; readonly placeholder: string; diff --git a/apps/mobile/src/components/ScreenHeader.android.tsx b/apps/mobile/src/components/ScreenHeader.android.tsx index 1d3232fd1641e5636c4e81df2cff03e57cdc852d..333afbce7cccbd712e7e02e87c20ce634f310aad 100644 --- a/apps/mobile/src/components/ScreenHeader.android.tsx +++ b/apps/mobile/src/components/ScreenHeader.android.tsx @@ -1,5 +1,12 @@ import { useCallback, useEffect, useRef, useState } from "react"; -import { BackHandler, Keyboard, Pressable, TextInput, View } from "react-native"; +import { + BackHandler, + Keyboard, + Pressable, + TextInput, + type TextInputInstance, + View, +} from "react-native"; import { useMaterialToolbarLayout } from "./useMaterialToolbarLayout"; import { NativeStackScreenOptions } from "../native/StackHeader"; import { AndroidWorkspaceSidebarButton } from "../features/layout/workspace-sidebar-toolbar"; @@ -18,7 +25,7 @@ export function ScreenHeader(props: ScreenHeaderProps) { const { paddingTop, paddingBottom } = useMaterialToolbarLayout(); const { scale, buttonSize, iconSize, smallIconSize } = useAndroidControlSizing(); const { themeVariables } = useAppearancePreferences(); - const inputRef = useRef(null); + const inputRef = useRef(null); const [searchOpen, setSearchOpen] = useState(false); const searching = search !== undefined && (searchOpen || search.value.length > 0); const onSearchChange = search?.onChangeText; diff --git a/apps/mobile/src/connection/background-activity.ts b/apps/mobile/src/connection/background-activity.ts index 3364eed3c2d1518d171dc1467ebf8cc0d8dd5129..6ecc8d81f4647e50a486051de686f32070fe8473 100644 --- a/apps/mobile/src/connection/background-activity.ts +++ b/apps/mobile/src/connection/background-activity.ts @@ -14,7 +14,7 @@ import * as Queue from "effect/Queue"; import * as Schedule from "effect/Schedule"; import * as Stream from "effect/Stream"; import * as SubscriptionRef from "effect/SubscriptionRef"; -import { AppState, type AppStateStatus } from "react-native"; +import { AppState } from "react-native"; import * as MobileStorage from "../persistence/mobile-storage"; import { @@ -27,8 +27,10 @@ const REPORT_INTERVAL_MS = 25_000; const LEASE_TTL_MS = 45_000; const BASELINE_SCOPES: ReadonlyArray = [{ type: "provider-status" }]; +// `AppState.currentState` is a loosely typed string that can be unset before +// the first change event; anything outside the known states reports as unknown. function normalizeAppState( - state: AppStateStatus, + state: string | null | undefined, ): NonNullable { if (state === "active" || state === "inactive" || state === "background") return state; return "unknown"; diff --git a/apps/mobile/src/features/agent-awareness/foregroundNotificationBehavior.test.ts b/apps/mobile/src/features/agent-awareness/foregroundNotificationBehavior.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..a763917322391bfe17ba9a42c2c60c768fd14a55 --- /dev/null +++ b/apps/mobile/src/features/agent-awareness/foregroundNotificationBehavior.test.ts @@ -0,0 +1,61 @@ +import type { Notification } from "expo-notifications"; +import { describe, expect, it } from "vite-plus/test"; + +import { foregroundNotificationBehavior } from "./foregroundNotificationBehavior"; +import { threadDeepLinkOnScreen } from "./notificationPayload"; + +function notificationWithData(data: Record): Notification { + return { + date: 0, + request: { identifier: "notification-1", content: { data }, trigger: null }, + } as unknown as Notification; +} + +describe("threadDeepLinkOnScreen", () => { + it("maps a thread route and its nested screens to the thread deep link", () => { + expect(threadDeepLinkOnScreen("/threads/env-1/thread-1")).toBe("/threads/env-1/thread-1"); + expect(threadDeepLinkOnScreen("/threads/env-1/thread-1/files/src")).toBe( + "/threads/env-1/thread-1", + ); + }); + + it("returns null outside a thread", () => { + expect(threadDeepLinkOnScreen("/")).toBeNull(); + expect(threadDeepLinkOnScreen("/settings")).toBeNull(); + expect(threadDeepLinkOnScreen("/threads/env-1")).toBeNull(); + }); +}); + +describe("foregroundNotificationBehavior", () => { + it("suppresses a notification for the thread already on screen", () => { + const behavior = foregroundNotificationBehavior( + notificationWithData({ environmentId: "env-1", threadId: "thread-1" }), + "/threads/env-1/thread-1", + ); + expect(behavior.shouldShowBanner).toBe(false); + expect(behavior.shouldShowList).toBe(false); + expect(behavior.shouldPlaySound).toBe(false); + }); + + it("shows a notification for another thread", () => { + const behavior = foregroundNotificationBehavior( + notificationWithData({ deepLink: "/threads/env-1/thread-2" }), + "/threads/env-1/thread-1", + ); + expect(behavior.shouldShowBanner).toBe(true); + expect(behavior.shouldShowList).toBe(true); + }); + + it("shows a notification when no thread is open or the payload has no target", () => { + expect( + foregroundNotificationBehavior( + notificationWithData({ environmentId: "env-1", threadId: "thread-1" }), + null, + ).shouldShowBanner, + ).toBe(true); + expect( + foregroundNotificationBehavior(notificationWithData({}), "/threads/env-1/thread-1") + .shouldShowBanner, + ).toBe(true); + }); +}); diff --git a/apps/mobile/src/features/agent-awareness/foregroundNotificationBehavior.ts b/apps/mobile/src/features/agent-awareness/foregroundNotificationBehavior.ts new file mode 100644 index 0000000000000000000000000000000000000000..9ea77169dfea73d7166e3aa46d98d61c362d381b --- /dev/null +++ b/apps/mobile/src/features/agent-awareness/foregroundNotificationBehavior.ts @@ -0,0 +1,35 @@ +import type { Notification, NotificationBehavior } from "expo-notifications"; + +import { extractAgentNotificationDeepLink } from "./notificationPayload"; + +const SHOW: NotificationBehavior = { + shouldShowBanner: true, + shouldShowList: true, + shouldPlaySound: true, + shouldSetBadge: false, +}; + +const SUPPRESS: NotificationBehavior = { + shouldShowBanner: false, + shouldShowList: false, + shouldPlaySound: false, + shouldSetBadge: false, +}; + +/** + * Decides how a notification that arrives while the app is open is presented. + * A notification for the thread already on screen is redundant with the live + * feed, so it stays silent; everything else banners like it would in the + * background. `deepLinkOnScreen` is the normalized `/threads/:env/:thread` + * path of the current route, or null when no thread is open. + */ +export function foregroundNotificationBehavior( + notification: Notification, + deepLinkOnScreen: string | null, +): NotificationBehavior { + const target = extractAgentNotificationDeepLink({ notification }); + if (target !== null && target === deepLinkOnScreen) { + return SUPPRESS; + } + return SHOW; +} diff --git a/apps/mobile/src/features/agent-awareness/notificationNavigation.ts b/apps/mobile/src/features/agent-awareness/notificationNavigation.ts index e9ca9246b9a9e7d7efb3dd4804504ef02be59f95..ff65371ba3b6c0538aecdafb4b937224c94418e6 100644 --- a/apps/mobile/src/features/agent-awareness/notificationNavigation.ts +++ b/apps/mobile/src/features/agent-awareness/notificationNavigation.ts @@ -2,12 +2,27 @@ import { useEffect, useRef } from "react"; import * as Notifications from "expo-notifications"; import { useLinkTo } from "@react-navigation/native"; -import { routeAgentNotificationResponseOnce } from "./notificationPayload"; +import { foregroundNotificationBehavior } from "./foregroundNotificationBehavior"; +import { routeAgentNotificationResponseOnce, threadDeepLinkOnScreen } from "./notificationPayload"; import { consumeLastAgentNotificationResponse } from "./notificationResponseConsumer"; -export function useAgentNotificationNavigation(): void { +export function useAgentNotificationNavigation(pathname: string): void { const linkTo = useLinkTo(); const handledResponseIds = useRef(new Set()); + // Read through a ref so the native handler registered once below sees the + // current route without re-registering on every navigation. + const deepLinkOnScreen = useRef(null); + deepLinkOnScreen.current = threadDeepLinkOnScreen(pathname); + + useEffect(() => { + Notifications.setNotificationHandler({ + handleNotification: (notification) => + Promise.resolve(foregroundNotificationBehavior(notification, deepLinkOnScreen.current)), + }); + return () => { + Notifications.setNotificationHandler(null); + }; + }, []); useEffect(() => { const handleResponse = (response: Notifications.NotificationResponse): void => { diff --git a/apps/mobile/src/features/agent-awareness/notificationPayload.ts b/apps/mobile/src/features/agent-awareness/notificationPayload.ts index dc72e3d1bd2700c605e24d47443abe299e76b49a..e568ca8b6cd432b93fc1c7850e5e78f20d57fafc 100644 --- a/apps/mobile/src/features/agent-awareness/notificationPayload.ts +++ b/apps/mobile/src/features/agent-awareness/notificationPayload.ts @@ -69,6 +69,19 @@ function normalizeThreadDeepLink(value: string): string | null { } } +/** + * The deep link a notification would have to carry to target the thread the + * given route is showing, including its nested screens such as the file + * inspector. Null when the route is not inside a thread. + */ +export function threadDeepLinkOnScreen(pathname: string): string | null { + const match = /^\/threads\/([^/]+)\/([^/]+)(?:\/|$)/.exec(pathname); + if (!match?.[1] || !match[2]) { + return null; + } + return `/threads/${match[1]}/${match[2]}`; +} + export function extractAgentNotificationDeepLink(response: unknown): string | null { const data = dataFromNotificationResponse(response); const deepLink = data?.deepLink; diff --git a/apps/mobile/src/features/archive/ArchivedThreadsScreen.tsx b/apps/mobile/src/features/archive/ArchivedThreadsScreen.tsx index b786f9f4066cfbb444369989ccac842d8ac5de49..374d17ac4762ff2356b0254a2021acc06ffc7176 100644 --- a/apps/mobile/src/features/archive/ArchivedThreadsScreen.tsx +++ b/apps/mobile/src/features/archive/ArchivedThreadsScreen.tsx @@ -20,7 +20,7 @@ import { useWindowDimensions, View, } from "react-native"; -import { Gesture, GestureDetector } from "react-native-gesture-handler"; +import { GestureDetector, useNativeGesture } from "react-native-gesture-handler"; import type { SwipeableMethods } from "react-native-gesture-handler/ReanimatedSwipeable"; import { AppText as Text } from "../../components/AppText"; @@ -185,9 +185,7 @@ function ArchivedThreadRow(props: { readonly onDelete: () => void; readonly onSwipeableClose: (methods: SwipeableMethods) => void; readonly onSwipeableWillOpen: (methods: SwipeableMethods) => void; - readonly simultaneousSwipeGesture?: ComponentProps< - typeof ThreadSwipeable - >["simultaneousWithExternalGesture"]; + readonly simultaneousSwipeGesture?: ComponentProps["simultaneousWith"]; readonly onUnarchive: () => void; readonly thread: EnvironmentThreadShell; }) { @@ -221,7 +219,7 @@ function ArchivedThreadRow(props: { label: "Unarchive", onPress: props.onUnarchive, }} - simultaneousWithExternalGesture={props.simultaneousSwipeGesture} + simultaneousWith={props.simultaneousSwipeGesture} threadTitle={props.thread.title} > {() => ( @@ -303,7 +301,7 @@ export function ArchivedThreadsScreen(props: { }) { const { onDeleteThread, onUnarchiveThread } = props; const openSwipeableRef = useRef(null); - const archiveScrollGesture = useMemo(() => Gesture.Native(), []); + const archiveScrollGesture = useNativeGesture(); const environmentLabelsById = useMemo( () => new Map( diff --git a/apps/mobile/src/features/connection/CloudEnvironmentRows.tsx b/apps/mobile/src/features/connection/CloudEnvironmentRows.tsx index d362b78a93602bbbba879f1e1c88267d7b4ad8d1..dd6364f23d4f2de033e8a844275118f031f940a0 100644 --- a/apps/mobile/src/features/connection/CloudEnvironmentRows.tsx +++ b/apps/mobile/src/features/connection/CloudEnvironmentRows.tsx @@ -13,13 +13,7 @@ import { } from "@t3tools/contracts"; import { useAtomValue } from "@effect/atom-react"; import { useCallback, useState } from "react"; -import { - ActivityIndicator, - Pressable, - type NativeSyntheticEvent, - type TextLayoutEventData, - View, -} from "react-native"; +import { ActivityIndicator, Pressable, type TextLayoutEvent, View } from "react-native"; import { AppText as Text } from "../../components/AppText"; import { EnvironmentMachineSymbol } from "../../components/EnvironmentMachineSymbol"; @@ -334,7 +328,7 @@ function CloudEnvironmentRowShell(props: { const isErrorExpanded = errorCanExpand && props.errorExpanded; const StatusContainer = errorCanExpand ? Pressable : View; const onMeasuredErrorTextLayout = useCallback( - (event: NativeSyntheticEvent) => { + (event: TextLayoutEvent) => { if (!props.connectionError) { return; } diff --git a/apps/mobile/src/features/devices/DeviceStreamWebView.tsx b/apps/mobile/src/features/devices/DeviceStreamWebView.tsx index 423fdb1c84a0fd550dd08fae2483ab78623c85fa..c8831c59520237b9cf9394f1984c3f209576f5dc 100644 --- a/apps/mobile/src/features/devices/DeviceStreamWebView.tsx +++ b/apps/mobile/src/features/devices/DeviceStreamWebView.tsx @@ -89,7 +89,7 @@ function DeviceStreamDocumentView({ readonly onStreaming: () => void; readonly onRecoverProcess: () => boolean; }) { - const webView = useRef(null); + const webView = useRef>(null); const active = useRef(true); const failed = useRef(false); const [status, setStatus] = useState("connecting"); @@ -148,7 +148,7 @@ function DeviceStreamDocumentView({ }; return ( - ref={webView} source={source} originWhitelist={["*"]} diff --git a/apps/mobile/src/features/files/MaterialFilesHeader.tsx b/apps/mobile/src/features/files/MaterialFilesHeader.tsx index c652ab67d377166a4567795e689e2ec383f70184..17bd76b6ce3b3d645c3a05603c3b36fef2389881 100644 --- a/apps/mobile/src/features/files/MaterialFilesHeader.tsx +++ b/apps/mobile/src/features/files/MaterialFilesHeader.tsx @@ -1,5 +1,5 @@ import { useCallback, useEffect, useRef, useState, type ReactNode } from "react"; -import { BackHandler, Keyboard, type TextInput, View } from "react-native"; +import { BackHandler, Keyboard, type TextInputInstance, View } from "react-native"; import { AndroidHeaderIconButton, AndroidScreenHeader } from "../../components/AndroidScreenHeader"; import { AndroidAnchoredMenu } from "../../components/AndroidAnchoredMenu"; @@ -16,7 +16,7 @@ export function MaterialFilesHeader(props: { readonly leading?: ReactNode; }) { const { paddingTop, paddingBottom } = useMaterialToolbarLayout(); - const searchRef = useRef(null); + const searchRef = useRef(null); const [searchOpen, setSearchOpen] = useState(false); const searching = searchOpen || props.searchQuery.length > 0; const { onSearchQueryChange } = props; diff --git a/apps/mobile/src/features/home/HomeScreen.tsx b/apps/mobile/src/features/home/HomeScreen.tsx index 75be079f0de88ad61b1f9fa47eb76caf1c744393..c54f1c12bf5878ff994d1116b3eb52e40160b513 100644 --- a/apps/mobile/src/features/home/HomeScreen.tsx +++ b/apps/mobile/src/features/home/HomeScreen.tsx @@ -309,8 +309,8 @@ export function HomeScreen(props: HomeScreenProps) { (event: GestureResponderEvent, started: boolean) => { const { changedTouches, touches } = event.nativeEvent; swipeRowActivation.trackTouches( - started ? changedTouches.map((touch) => touch.identifier) : [], - touches.map((touch) => touch.identifier), + started ? changedTouches.map((touch) => String(touch.identifier)) : [], + touches.map((touch) => String(touch.identifier)), ); }, [swipeRowActivation], @@ -945,7 +945,7 @@ export function HomeScreen(props: HomeScreenProps) { ); } - const listHeader = Platform.OS === "ios" ? null : ; + const listHeader = Platform.OS === "ios" ? undefined : ; // Project scoping lives in the header filter menu (no inline chip row on // mobile — the menu is the one filter surface). @@ -954,7 +954,7 @@ export function HomeScreen(props: HomeScreenProps) { // Use the v2 project scope for its empty state. Snoozed threads need no // special empty state: their shelf header is a list row even while collapsed. const v2ListEmpty = - hasSearchQuery && threadSearch.isPending ? null : hasSearchQuery ? ( + hasSearchQuery && threadSearch.isPending ? undefined : hasSearchQuery ? ( (null); + const searchRef = useRef(null); const [searchOpen, setSearchOpen] = useState(false); const searching = searchOpen || props.searchQuery.length > 0; const openSearch = useCallback(() => { diff --git a/apps/mobile/src/features/home/thread-swipe-actions.tsx b/apps/mobile/src/features/home/thread-swipe-actions.tsx index e62935c28861850daa4379e11c06f52112a2000e..1d61cd3a0af28a0394bf8b9d63c0bb17987eb970 100644 --- a/apps/mobile/src/features/home/thread-swipe-actions.tsx +++ b/apps/mobile/src/features/home/thread-swipe-actions.tsx @@ -266,9 +266,7 @@ interface ThreadSwipeableProps { readonly resetKey?: string; /** Paints the row without swipe machinery; see swipe-row-activation. */ readonly dormant?: boolean; - readonly simultaneousWithExternalGesture?: ComponentProps< - typeof ReanimatedSwipeable - >["simultaneousWithExternalGesture"]; + readonly simultaneousWith?: ComponentProps["simultaneousWith"]; readonly threadTitle: string; } @@ -433,7 +431,7 @@ function ThreadSwipeableRow(props: ThreadSwipeableProps) { animationOptions={THREAD_SWIPE_SPRING} childrenContainerStyle={{ backgroundColor: props.backgroundColor }} containerStyle={[{ backgroundColor: props.backgroundColor }, props.containerStyle]} - dragOffsetFromRightEdge={8} + dragOffsetFromRight={-8} enabled={!isDismissing && props.enabled !== false && gateEnabled} enableTrackpadTwoFingerGesture={props.enableTrackpadSwipe ?? true} // Fail the swipe once the pan is vertically dominant (patched-in RNGH @@ -497,7 +495,7 @@ function ThreadSwipeableRow(props: ThreadSwipeableProps) { )} rightThreshold={actionsWidth * 0.42} - simultaneousWithExternalGesture={props.simultaneousWithExternalGesture} + simultaneousWith={props.simultaneousWith} > {props.children(close)} diff --git a/apps/mobile/src/features/keyboard/CommandPalette.tsx b/apps/mobile/src/features/keyboard/CommandPalette.tsx index 32344ef3fdac2e335eb3bbe481515497561995a2..e7d7b695b1505b98a0d7f7998e6f7b6b92344968 100644 --- a/apps/mobile/src/features/keyboard/CommandPalette.tsx +++ b/apps/mobile/src/features/keyboard/CommandPalette.tsx @@ -12,6 +12,7 @@ import { TextInput, useWindowDimensions, View, + type TextInputInstance, } from "react-native"; import { GestureHandlerRootView } from "react-native-gesture-handler"; @@ -151,7 +152,7 @@ export function CommandPalette(props: { const [visible, setVisible] = useState(true); const pendingAction = useRef<(() => void) | null>(null); const closing = useRef(false); - const inputRef = useRef(null); + const inputRef = useRef(null); const listRef = useRef>(null); const { width, height } = useWindowDimensions(); const searchEnvironmentIds = useMemo( diff --git a/apps/mobile/src/features/sharing/incoming-share-storage.ts b/apps/mobile/src/features/sharing/incoming-share-storage.ts index ce6d5ed0c5cdecc123a920b8896f68fdae41c74c..763da41cba8ca5589597da1919e7f026c8ecda19 100644 --- a/apps/mobile/src/features/sharing/incoming-share-storage.ts +++ b/apps/mobile/src/features/sharing/incoming-share-storage.ts @@ -68,7 +68,7 @@ export async function writeIncomingShareDraft(draft: IncomingShareDraft): Promis if (!file.exists) { file.create({ intermediates: true, overwrite: true }); } - file.write(JSON.stringify(draft)); + await file.write(JSON.stringify(draft)); } catch (cause) { throw new IncomingShareStorageError({ operation: "write", shareId: draft.id, cause }); } diff --git a/apps/mobile/src/features/terminal/NativeTerminalSurface.tsx b/apps/mobile/src/features/terminal/NativeTerminalSurface.tsx index e7beb0de54f8c7a560b356091872128e2ba9b1b8..328617bb717295a79deee7588c32c53dc278e626 100644 --- a/apps/mobile/src/features/terminal/NativeTerminalSurface.tsx +++ b/apps/mobile/src/features/terminal/NativeTerminalSurface.tsx @@ -6,6 +6,7 @@ import { View, type LayoutChangeEvent, type NativeSyntheticEvent, + type TextInputInstance, type ViewProps, } from "react-native"; @@ -61,7 +62,7 @@ function estimateGridSize(input: { const FallbackTerminalSurface = memo(function FallbackTerminalSurface(props: TerminalSurfaceProps) { const fontSize = props.fontSize ?? MOBILE_TYPOGRAPHY.label.fontSize; - const inputRef = useRef(null); + const inputRef = useRef(null); const { themeAppearance, themeId } = useAppearancePreferences(); const theme = props.theme ?? getMobileTerminalTheme(themeId, themeAppearance); const statusLabel = props.isRunning diff --git a/apps/mobile/src/features/threads/CustomSnoozeSheet.ios.tsx b/apps/mobile/src/features/threads/CustomSnoozeSheet.ios.tsx index c8d9abbc5fa80b9e4298846dd62155dac1d29668..cf123a736559f400581895cd23f349a5cb7f93b9 100644 --- a/apps/mobile/src/features/threads/CustomSnoozeSheet.ios.tsx +++ b/apps/mobile/src/features/threads/CustomSnoozeSheet.ios.tsx @@ -139,7 +139,7 @@ export function CustomSnoozeSheet(props: { modifiers={[ datePickerStyle("wheel"), labelsHidden(), - frame({ maxWidth: Infinity, height: 180 }), + frame({ maxWidth: Infinity, minHeight: 180, maxHeight: 180 }), ]} /> ) : ( @@ -154,7 +154,7 @@ export function CustomSnoozeSheet(props: { modifiers={[ pickerStyle("wheel"), labelsHidden(), - frame({ minWidth: 0, maxWidth: Infinity, height: 180 }), + frame({ minWidth: 0, maxWidth: Infinity, minHeight: 180, maxHeight: 180 }), clipped(), ]} > @@ -177,7 +177,7 @@ export function CustomSnoozeSheet(props: { modifiers={[ pickerStyle("wheel"), labelsHidden(), - frame({ minWidth: 0, maxWidth: Infinity, height: 180 }), + frame({ minWidth: 0, maxWidth: Infinity, minHeight: 180, maxHeight: 180 }), clipped(), ]} > diff --git a/apps/mobile/src/features/threads/ThreadDetailScreen.tsx b/apps/mobile/src/features/threads/ThreadDetailScreen.tsx index 14beefd6d178d61845ccb863c1190c4ca04a693c..d04ad7bc776c2858732653319d190a70490828e2 100644 --- a/apps/mobile/src/features/threads/ThreadDetailScreen.tsx +++ b/apps/mobile/src/features/threads/ThreadDetailScreen.tsx @@ -47,6 +47,7 @@ import { useWindowDimensions, View, type GestureResponderEvent, + type ViewInstance, } from "react-native"; import { KeyboardController, @@ -321,7 +322,7 @@ export const ThreadDetailScreen = memo(function ThreadDetailScreen(props: Thread const composerEditorRef = useRef(null); const draftMessageRef = useRef(props.draftMessage); draftMessageRef.current = props.draftMessage; - const composerOverlayRef = useRef(null); + const composerOverlayRef = useRef(null); const listRef = useRef(null); const feedTouchStartRef = useRef<{ pageX: number; pageY: number } | null>(null); const selectedThreadKeyRef = useRef(selectedThreadKey); diff --git a/apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx b/apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx index d9e165bd01072ea7de7e1a42c6bdcde1bb7323eb..63f7b48a0bb0f2b2af8d63e36b1001874ee451e5 100644 --- a/apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx +++ b/apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx @@ -14,9 +14,9 @@ import type { MenuAction } from "@react-native-menu/menu"; import { useAtomValue } from "@effect/atom-react"; import { type EnvironmentId, resolveEnvironmentMachineKind } from "@t3tools/contracts"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; -import type { LayoutChangeEvent } from "react-native"; +import type { LayoutChangeEvent, TextInputInstance } from "react-native"; import { Platform, StyleSheet, TextInput, View } from "react-native"; -import { Gesture, GestureDetector } from "react-native-gesture-handler"; +import { GestureDetector, useNativeGesture } from "react-native-gesture-handler"; import type { SwipeableMethods } from "react-native-gesture-handler/ReanimatedSwipeable"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import type { SearchBarCommands } from "react-native-screens"; @@ -139,10 +139,10 @@ function ThreadNavigationSidebarPane( const threads = useThreadShells(); const { environments: workspaceEnvironments, state: catalogState } = useWorkspaceState(); const { savedConnectionsById } = useSavedRemoteConnections(); - const searchInputRef = useRef(null); + const searchInputRef = useRef(null); const searchBarRef = useRef(null); const openSwipeableRef = useRef(null); - const sidebarScrollGesture = useMemo(() => Gesture.Native(), []); + const sidebarScrollGesture = useNativeGesture(); const { archiveThread, confirmDeleteThread, diff --git a/apps/mobile/src/features/threads/thread-list-v2-items.tsx b/apps/mobile/src/features/threads/thread-list-v2-items.tsx index 09ffe404ee79862cdbb31ba17a853ca4224269c6..10b01fef0ec73ed386cdbd09de70b6302d6078d6 100644 --- a/apps/mobile/src/features/threads/thread-list-v2-items.tsx +++ b/apps/mobile/src/features/threads/thread-list-v2-items.tsx @@ -523,9 +523,7 @@ export const ThreadListV2Row = memo(function ThreadListV2Row(props: { readonly activationKey?: string; readonly searchMatch?: EnvironmentThreadSearchMatch; readonly searchQuery?: string; - readonly simultaneousSwipeGesture?: ComponentProps< - typeof ThreadSwipeable - >["simultaneousWithExternalGesture"]; + readonly simultaneousSwipeGesture?: ComponentProps["simultaneousWith"]; }) { const { width: windowWidth } = useWindowDimensions(); const { @@ -1198,7 +1196,7 @@ export const ThreadListV2Row = memo(function ThreadListV2Row(props: { primaryAction={primaryAction} secondaryAction={secondaryAction} resetKey={`${thread.environmentId}:${thread.id}:${variant}:${snoozedRow}:${thread.settledAt}:${thread.unsettledAt}:${thread.snoozedUntil}`} - simultaneousWithExternalGesture={props.simultaneousSwipeGesture} + simultaneousWith={props.simultaneousSwipeGesture} threadTitle={thread.title} > {(close) => ( diff --git a/apps/mobile/src/lib/atomic-file.ts b/apps/mobile/src/lib/atomic-file.ts index 77a695967ff02658df6217b20b814ac522e2caa8..97468f44f5dcc2f283e6937c9d0c762e390f75f3 100644 --- a/apps/mobile/src/lib/atomic-file.ts +++ b/apps/mobile/src/lib/atomic-file.ts @@ -14,6 +14,6 @@ export async function writeFileAtomically(file: File, contents: string): Promise tempFileSequence += 1; const temp = new FileConstructor(file.parentDirectory, `${file.name}.${tempFileSequence}.tmp`); temp.create({ intermediates: true, overwrite: true }); - temp.write(contents); + await temp.write(contents); temp.moveSync(file, { overwrite: true }); } diff --git a/apps/mobile/src/lib/attachmentUpload.ts b/apps/mobile/src/lib/attachmentUpload.ts index 1bce3e26774fd389cc37695593191d24c7264ebb..50b6cf1cee1eb419502f651a96be6fbe1088a907 100644 --- a/apps/mobile/src/lib/attachmentUpload.ts +++ b/apps/mobile/src/lib/attachmentUpload.ts @@ -276,7 +276,7 @@ async function uploadFileBytes( try { if (fileUri === undefined && inlineDataUrl !== undefined) { file.create(); - file.write(inlineDataUrl.slice(inlineDataUrl.indexOf(",") + 1), { + await file.write(inlineDataUrl.slice(inlineDataUrl.indexOf(",") + 1), { encoding: "base64", }); } diff --git a/apps/mobile/src/lib/composerImages.ts b/apps/mobile/src/lib/composerImages.ts index 391bf633e5572952b25aa24072fb461460904cc8..8fc821d2d26fe834d11b00893dfc091983d507d0 100644 --- a/apps/mobile/src/lib/composerImages.ts +++ b/apps/mobile/src/lib/composerImages.ts @@ -161,7 +161,7 @@ export async function persistComposerAttachmentFile( try { let copiedBytes = 0; while (true) { - const chunk = reader.readBytes( + const chunk = await reader.readBytes( Math.min(ATTACHMENT_COPY_CHUNK_BYTES, maxBytes - copiedBytes + 1), ); if (chunk.byteLength === 0) { @@ -171,7 +171,7 @@ export async function persistComposerAttachmentFile( if (copiedBytes > maxBytes) { throw new Error(fileAttachmentTooLargeMessage(name, maxBytes)); } - writer.writeBytes(chunk); + await writer.writeBytes(chunk); } } finally { writer.close(); diff --git a/apps/mobile/src/native/T3ComposerEditor.ios.tsx b/apps/mobile/src/native/T3ComposerEditor.ios.tsx index 5b1a28d5df1cc640c80201318fd11c8fbd20b564..6eb169a73f870ba9d5f4cafe3b3618fa2e5e3547 100644 --- a/apps/mobile/src/native/T3ComposerEditor.ios.tsx +++ b/apps/mobile/src/native/T3ComposerEditor.ios.tsx @@ -13,9 +13,12 @@ import { type Ref, } from "react"; import type { NativeSyntheticEvent, StyleProp, ViewProps, ViewStyle } from "react-native"; -import { Image, StyleSheet } from "react-native"; +import { StyleSheet } from "react-native"; -import { markdownFileIconSource } from "@t3tools/mobile-markdown-text/file-icons"; +import { + markdownFileIconSource, + markdownIconAssetUri, +} from "@t3tools/mobile-markdown-text/file-icons"; import { composerChipSizeSuffix, contextChipPresentation, @@ -109,8 +112,8 @@ function basename(path: string): string { return separator >= 0 ? path.slice(separator + 1) : path; } -function fileIconUri(path: string): string { - return Image.resolveAssetSource(markdownFileIconSource(resolveMarkdownFileIcon(path))).uri; +function fileIconUri(path: string): string | null { + return markdownIconAssetUri(markdownFileIconSource(resolveMarkdownFileIcon(path))) ?? null; } export function ComposerEditor({ diff --git a/apps/mobile/src/native/T3ComposerEditor.native.tsx b/apps/mobile/src/native/T3ComposerEditor.native.tsx index 7f18bae0570af6c24e8c5c3e5ed34ea7dd65ce92..9391a3814c399d305586561d9723b6474c22b2fe 100644 --- a/apps/mobile/src/native/T3ComposerEditor.native.tsx +++ b/apps/mobile/src/native/T3ComposerEditor.native.tsx @@ -16,7 +16,10 @@ import { import type { NativeSyntheticEvent, ViewProps } from "react-native"; import { Image, Platform, StyleSheet } from "react-native"; -import { markdownFileIconSource } from "@t3tools/mobile-markdown-text/file-icons"; +import { + markdownFileIconSource, + markdownIconAssetUri, +} from "@t3tools/mobile-markdown-text/file-icons"; import { composerChipSizeSuffix, contextChipPresentation, @@ -110,8 +113,8 @@ function basename(path: string): string { return separator >= 0 ? path.slice(separator + 1) : path; } -function fileIconUri(path: string): string { - return Image.resolveAssetSource(markdownFileIconSource(resolveMarkdownFileIcon(path))).uri; +function fileIconUri(path: string): string | null { + return markdownIconAssetUri(markdownFileIconSource(resolveMarkdownFileIcon(path))) ?? null; } export function ComposerEditor({ diff --git a/apps/mobile/src/native/T3ComposerEditor.tsx b/apps/mobile/src/native/T3ComposerEditor.tsx index 22cdf3b5310688315e24e3c8eadc3e41bcdf95cf..5df13972af0693956c5c13d7a02abb8ff7087f6d 100644 --- a/apps/mobile/src/native/T3ComposerEditor.tsx +++ b/apps/mobile/src/native/T3ComposerEditor.tsx @@ -1,6 +1,6 @@ import { TextInputWrapper } from "expo-paste-input"; import { useImperativeHandle, useRef } from "react"; -import { TextInput, type TextInput as RNTextInput } from "react-native"; +import { TextInput, type TextInputInstance } from "react-native"; import { useFontFamily } from "../lib/useFontFamily"; import { useScaledTextRole } from "../features/settings/appearance/useScaledTextRole"; @@ -21,7 +21,7 @@ export function ComposerEditor({ readOnly = false, ...props }: ComposerEditorProps) { - const inputRef = useRef(null); + const inputRef = useRef(null); const bodyText = useScaledTextRole("body"); const fontFamily = useFontFamily("regular"); const handlePaste = useNativePaste((uris) => onPasteImages?.(uris)); diff --git a/apps/mobile/src/native/T3KeyboardCommands.android.tsx b/apps/mobile/src/native/T3KeyboardCommands.android.tsx index ff4e817c2002fa7b43768645e32eecd6f63978c5..cc01addbad3ea6ae361fb78673746cac293be761 100644 --- a/apps/mobile/src/native/T3KeyboardCommands.android.tsx +++ b/apps/mobile/src/native/T3KeyboardCommands.android.tsx @@ -4,7 +4,7 @@ import type { NativeSyntheticEvent, ViewProps } from "react-native"; import type { HardwareKeyboardCommand } from "../features/keyboard/hardwareKeyboardCommands"; -interface NativeKeyboardCommandsProps extends ViewProps, PropsWithChildren { +interface NativeKeyboardCommandsProps extends ViewProps { readonly enabledCommands: ReadonlyArray; readonly onCommand: ( event: NativeSyntheticEvent<{ readonly command: HardwareKeyboardCommand }>, diff --git a/apps/mobile/src/native/T3KeyboardCommands.ios.tsx b/apps/mobile/src/native/T3KeyboardCommands.ios.tsx index ff4e817c2002fa7b43768645e32eecd6f63978c5..cc01addbad3ea6ae361fb78673746cac293be761 100644 --- a/apps/mobile/src/native/T3KeyboardCommands.ios.tsx +++ b/apps/mobile/src/native/T3KeyboardCommands.ios.tsx @@ -4,7 +4,7 @@ import type { NativeSyntheticEvent, ViewProps } from "react-native"; import type { HardwareKeyboardCommand } from "../features/keyboard/hardwareKeyboardCommands"; -interface NativeKeyboardCommandsProps extends ViewProps, PropsWithChildren { +interface NativeKeyboardCommandsProps extends ViewProps { readonly enabledCommands: ReadonlyArray; readonly onCommand: ( event: NativeSyntheticEvent<{ readonly command: HardwareKeyboardCommand }>, diff --git a/apps/mobile/src/widgets/SubscriptionUsage.tsx b/apps/mobile/src/widgets/SubscriptionUsage.tsx index a32454e5ff836531ac5c1e830a22c6bb14636054..78197cd2858ea0e3e8815c76490b7a039a6ef807 100644 --- a/apps/mobile/src/widgets/SubscriptionUsage.tsx +++ b/apps/mobile/src/widgets/SubscriptionUsage.tsx @@ -29,7 +29,7 @@ function SubscriptionUsage( // The extension evaluates this function without the app's module scope. const family = environment.widgetFamily; // Gallery snapshots can render an old timeline entry after it has expired. - const now = Math.max(environment.date.getTime(), Date.now()); + const now = Math.max(environment.date?.getTime() ?? 0, Date.now()); const accessory = family === "accessoryRectangular"; const compact = family === "systemSmall" || accessory || environment.levelOfDetail === "simplified"; diff --git a/apps/mobile/tsconfig.json b/apps/mobile/tsconfig.json index f6634fbc4c97efbedee44cecbd6d3f53a91f1018..146779616fa6006ef4ff7596709133a4562196ef 100644 --- a/apps/mobile/tsconfig.json +++ b/apps/mobile/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "expo/tsconfig.base", + "extends": "expo/tsconfig.base.json", "compilerOptions": { "allowImportingTsExtensions": true, "strict": true, diff --git a/apps/web/package.json b/apps/web/package.json index 92b30fba5c92c1d30749a0d558f07628e4d3860d..587faeb2ac027fe7c23495f23a2e6c115b768f35 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -68,7 +68,7 @@ "@types/compression": "^1.8.1", "@types/culori": "^4.0.1", "@types/mdast": "^4.0.4", - "@types/react": "~19.2.14", + "@types/react": "~19.3.0", "@types/react-dom": "~19.2.3", "@types/react-test-renderer": "19.1.0", "@vercel/config": "^0.3.0", diff --git a/patches/@clerk__expo@4.6.8.patch b/patches/@clerk__expo@4.6.8.patch index e9bd5bfe07dfbebffaff66229ae9f9a8db435ac2..d32b2f29d6caa6d8db63f4467b6752cab673c4f4 100644 --- a/patches/@clerk__expo@4.6.8.patch +++ b/patches/@clerk__expo@4.6.8.patch @@ -1,3 +1,20 @@ +diff --git a/android/build.gradle b/android/build.gradle +index 6bd6d5acf6ac3da78232170a6ea8c2b0f6e5504e..a827dad53dcd8c1b2f47fce30ea8bf9140787f38 100644 +--- a/android/build.gradle ++++ b/android/build.gradle +@@ -146,6 +146,12 @@ dependencies { + implementation "androidx.activity:activity-compose:$activityComposeVersion" + implementation "androidx.lifecycle:lifecycle-runtime-compose:$lifecycleVersion" + implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycleVersion" ++ // ClerkComposeNativeViewHost imports LocalSavedStateRegistryOwner and ++ // LocalLifecycleOwner from these artifacts. Earlier SDKs leaked them onto ++ // the compile classpath through clerk-android-ui's navigation3 runtime ++ // dependency; AGP 9 resolves the compile classpath on its own. ++ implementation "androidx.savedstate:savedstate-compose:1.4.0" ++ implementation "androidx.lifecycle:lifecycle-runtime-compose:2.10.0" + + testImplementation "junit:junit:4.13.2" + } diff --git a/ios/ClerkAuthNativeView.swift b/ios/ClerkAuthNativeView.swift index 5f8d2ba66d5b232890af75c22b173c86d2ef546b..b170304cbf2fbaae8032db8dd6f89b6a59c6e3fe 100644 --- a/ios/ClerkAuthNativeView.swift diff --git a/patches/@expo__metro-config@57.0.12.patch b/patches/@expo__metro-config@57.0.12.patch deleted file mode 100644 index 26ce34aed6dd450d3438fb29587bb6d0947aecd7..0000000000000000000000000000000000000000 --- a/patches/@expo__metro-config@57.0.12.patch +++ /dev/null @@ -1,86 +0,0 @@ -diff --git a/build/serializer/sourceMap.js b/build/serializer/sourceMap.js -index 547e53377a7c560db8dfd983601606de15896e07..29a0c855088bceacb7ba00a627615539cbf37738 100644 ---- a/build/serializer/sourceMap.js -+++ b/build/serializer/sourceMap.js -@@ -27,6 +27,13 @@ function loadSourcemapCodec() { - } - return _sourcemapCodec; - } -+let _traceMapping; -+function loadTraceMapping() { -+ if (!_traceMapping) { -+ _traceMapping = require('@jridgewell/trace-mapping'); -+ } -+ return _traceMapping; -+} - let _Generator; - function loadGenerator() { - if (!_Generator) { -@@ -224,6 +231,58 @@ function repairInvalidNegativeIndices(map) { - } - return changed ? { ...map, mappings: encode(decoded) } : map; - } -+// Hermes can emit mappings for Metro trailer/debug lines that have no -+// corresponding Metro source-map line. @jridgewell/remapping assumes every -+// referenced generated line exists, so strip those invalid bridge segments. -+function getGeneratedLineCount(map) { -+ const { TraceMap, decodedMappings } = loadTraceMapping(); -+ return decodedMappings(new TraceMap(map)).length; -+} -+function dropInvalidOriginalSegments(map, maxOriginalLine) { -+ const { TraceMap, decodedMappings } = loadTraceMapping(); -+ const decoded = decodedMappings(new TraceMap(map)); -+ let didChange = false; -+ const filtered = decoded.map((line) => { -+ const filteredLine = line.filter((segment) => { -+ if (segment.length < 4) { -+ return true; -+ } -+ const sourceIndex = segment[1]; -+ const sourceLine = segment[2]; -+ const sourceColumn = segment[3]; -+ return (sourceIndex >= 0 && -+ sourceIndex < map.sources.length && -+ sourceLine >= 0 && -+ sourceLine < maxOriginalLine && -+ sourceColumn >= 0); -+ }); -+ if (filteredLine.length !== line.length) { -+ didChange = true; -+ } -+ return filteredLine; -+ }); -+ if (!didChange) { -+ return map; -+ } -+ return { -+ ...map, -+ mappings: loadSourcemapCodec().encode(filtered), -+ }; -+} -+function sanitizeSourceMapsForComposition(maps) { -+ let sanitized = maps; -+ for (let index = 1; index < maps.length; index++) { -+ const maxOriginalLine = getGeneratedLineCount(sanitized[index - 1]); -+ const next = dropInvalidOriginalSegments(sanitized[index], maxOriginalLine); -+ if (next !== sanitized[index]) { -+ if (sanitized === maps) { -+ sanitized = maps.slice(); -+ } -+ sanitized[index] = next; -+ } -+ } -+ return sanitized; -+} - // `maps[0]` is the original-most transform; `maps[maps.length - 1]` is - // the most recent. Built on `@jridgewell/remapping` instead of mozilla's - // `SourceMapConsumer`-based composer. -@@ -251,7 +310,7 @@ function composeSourceMaps(maps) { - return { ...map, ignoreList: map.x_google_ignoreList }; - }); - // Metro convention is original-first; remapping is most-recent first. -- let input = normalized.slice().reverse(); -+ let input = sanitizeSourceMapsForComposition(normalized).slice().reverse(); - const remap = loadRemapping(); - let composed; - try { diff --git a/patches/@expo__metro-config@58.0.6.patch b/patches/@expo__metro-config@58.0.6.patch new file mode 100644 index 0000000000000000000000000000000000000000..9490a3db95f2905c02565c2d3b20525dd091081a --- /dev/null +++ b/patches/@expo__metro-config@58.0.6.patch @@ -0,0 +1,72 @@ +diff --git a/build/serializer/sourceMap.js b/build/serializer/sourceMap.js +index 2a58f57..a90ce77 100644 +--- a/build/serializer/sourceMap.js ++++ b/build/serializer/sourceMap.js +@@ -177,6 +177,58 @@ function repairInvalidNegativeIndices(map) { + mappings: encode(decoded) + } : map; + } ++// Hermes can emit mappings for Metro trailer/debug lines that have no ++// corresponding Metro source-map line. @jridgewell/remapping assumes every ++// referenced generated line exists, so strip those invalid bridge segments. ++function getGeneratedLineCount(map) { ++ const { TraceMap, decodedMappings } = loadTraceMapping(); ++ return decodedMappings(new TraceMap(map)).length; ++} ++function dropInvalidOriginalSegments(map, maxOriginalLine) { ++ const { TraceMap, decodedMappings } = loadTraceMapping(); ++ const decoded = decodedMappings(new TraceMap(map)); ++ let didChange = false; ++ const filtered = decoded.map((line) => { ++ const filteredLine = line.filter((segment) => { ++ if (segment.length < 4) { ++ return true; ++ } ++ const sourceIndex = segment[1]; ++ const sourceLine = segment[2]; ++ const sourceColumn = segment[3]; ++ return (sourceIndex >= 0 && ++ sourceIndex < map.sources.length && ++ sourceLine >= 0 && ++ sourceLine < maxOriginalLine && ++ sourceColumn >= 0); ++ }); ++ if (filteredLine.length !== line.length) { ++ didChange = true; ++ } ++ return filteredLine; ++ }); ++ if (!didChange) { ++ return map; ++ } ++ return { ++ ...map, ++ mappings: loadSourcemapCodec().encode(filtered), ++ }; ++} ++function sanitizeSourceMapsForComposition(maps) { ++ let sanitized = maps; ++ for (let index = 1; index < maps.length; index++) { ++ const maxOriginalLine = getGeneratedLineCount(sanitized[index - 1]); ++ const next = dropInvalidOriginalSegments(sanitized[index], maxOriginalLine); ++ if (next !== sanitized[index]) { ++ if (sanitized === maps) { ++ sanitized = maps.slice(); ++ } ++ sanitized[index] = next; ++ } ++ } ++ return sanitized; ++} + function composeSourceMaps(maps) { + if (maps.length < 1) { + throw new Error('composeSourceMaps: Expected at least one map'); +@@ -192,7 +244,7 @@ function composeSourceMaps(maps) { + }; + }); + // Metro convention is original-first; remapping is most-recent first. +- let input = normalized.slice().reverse(); ++ let input = sanitizeSourceMapsForComposition(normalized).slice().reverse(); + const remap = loadRemapping(); + let composed; + try { diff --git a/patches/@react-native-menu__menu@2.0.0.patch b/patches/@react-native-menu__menu@2.0.0.patch index 65e6f24a7901fbc0c237a5a6156daf4d23c37e75..2d79b33b2140a176faac530b4a0d168e434feb73 100644 --- a/patches/@react-native-menu__menu@2.0.0.patch +++ b/patches/@react-native-menu__menu@2.0.0.patch @@ -2,6 +2,14 @@ diff --git a/ios/MenuViewManager.mm b/ios/MenuViewManager.mm index 3d149b3e7426b8f7c999603ddf1e15e12331c33a..e80fe2caae86e339fcb03408419a7d64b3e5b04f 100644 --- a/ios/MenuViewManager.mm +++ b/ios/MenuViewManager.mm +@@ -1,6 +1,6 @@ + #import + #import +-#import "RCTBridge.h" ++#import + + #ifdef RCT_NEW_ARCH_ENABLED + // NEW ARCH @@ -65,6 +65,10 @@ - (UIView *)view * onOpenMenu: callback to be called when the menu is opened */ diff --git a/patches/expo-audio@57.0.4.patch b/patches/expo-audio@57.0.4.patch deleted file mode 100644 index 1452eca31c1572380bab1beaa950026e71ce7877..0000000000000000000000000000000000000000 --- a/patches/expo-audio@57.0.4.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git a/ios/AudioRecorder.swift b/ios/AudioRecorder.swift -index 20020bff9f8ba7bb6e7f61c99b4de5d29eee00db..284c22f12e30c8c2ed16feb141876cbfd8897c90 100644 ---- a/ios/AudioRecorder.swift -+++ b/ios/AudioRecorder.swift -@@ -216,15 +216,15 @@ class AudioRecorder: SharedRef, RecordingResultHandler { - } - - func didFinish(_ recorder: AVAudioRecorder, successfully flag: Bool) { -- // Update internal state when recording finishes automatically (e.g., from recordForDuration) -- currentState = .stopped -+ // Update internal state when AVAudioRecorder finishes or fails. -+ currentState = flag ? .stopped : .error - resetDurationTracking() - - emit(event: recordingStatus, payload: [ - "id": id, - "isFinished": true, -- "hasError": false, -- "error": nil, -+ "hasError": !flag, -+ "error": flag ? nil : "Recording failed", - "url": recorder.url.absoluteString - ]) - } diff --git a/patches/expo-audio@58.0.3.patch b/patches/expo-audio@58.0.3.patch new file mode 100644 index 0000000000000000000000000000000000000000..3b4ae1ff4463ebdd5328ebfa4dffd657fc5899f2 --- /dev/null +++ b/patches/expo-audio@58.0.3.patch @@ -0,0 +1,25 @@ +diff --git a/ios/AudioRecorder.swift b/ios/AudioRecorder.swift +index 73c6a036be6c76e219774a8d1e1cc3a7f18e6f8e..edfbbe00c2b0f3544bcbe42d02b829bf310d241c 100644 +--- a/ios/AudioRecorder.swift ++++ b/ios/AudioRecorder.swift +@@ -268,16 +268,16 @@ class AudioRecorder: SharedRef, RecordingResultHandler { + } + + func didFinish(_ recorder: AVAudioRecorder, successfully flag: Bool) { +- // Update internal state when recording finishes automatically (e.g., from recordForDuration) +- currentState = .stopped ++ // Update internal state when AVAudioRecorder finishes or fails. ++ currentState = flag ? .stopped : .error + resetDurationTracking() + durationLimitSeconds = nil + + emit(event: recordingStatus, payload: [ + "id": id, + "isFinished": true, +- "hasError": false, +- "error": nil, ++ "hasError": !flag, ++ "error": flag ? nil : "Recording failed", + "url": recorder.url.absoluteString + ]) + } diff --git a/patches/expo-blur@58.0.2.patch b/patches/expo-blur@58.0.2.patch new file mode 100644 index 0000000000000000000000000000000000000000..f88c657204ff0311a629b7af80cf10a856de229b --- /dev/null +++ b/patches/expo-blur@58.0.2.patch @@ -0,0 +1,57 @@ +diff --git a/build/BlurView.types.d.ts b/build/BlurView.types.d.ts +index cc93ffe2cd398a73ac50ebbe5427cbe4187fd83b..7246e9ffbe67af7da4fed20e1e08d0768be812a3 100644 +--- a/build/BlurView.types.d.ts ++++ b/build/BlurView.types.d.ts +@@ -1,5 +1,5 @@ + import type { RefObject } from 'react'; +-import type { ViewProps, View } from 'react-native'; ++import type { ViewProps, ViewInstance } from 'react-native'; + /** + * Blur method to use on Android. + * +@@ -24,7 +24,7 @@ export type BlurViewProps = { + * + * @platform android + */ +- blurTarget?: RefObject; ++ blurTarget?: RefObject; + /** + * A tint mode which will be applied to the view. + * +@@ -68,6 +68,6 @@ export type BlurViewProps = { + blurMethod?: BlurMethod; + } & ViewProps; + export type BlurTargetViewProps = { +- ref?: RefObject; ++ ref?: RefObject; + } & ViewProps; + export type BlurTint = 'light' | 'dark' | 'default' | 'extraLight' | 'regular' | 'prominent' | 'systemUltraThinMaterial' | 'systemThinMaterial' | 'systemMaterial' | 'systemThickMaterial' | 'systemChromeMaterial' | 'systemUltraThinMaterialLight' | 'systemThinMaterialLight' | 'systemMaterialLight' | 'systemThickMaterialLight' | 'systemChromeMaterialLight' | 'systemUltraThinMaterialDark' | 'systemThinMaterialDark' | 'systemMaterialDark' | 'systemThickMaterialDark' | 'systemChromeMaterialDark'; +diff --git a/src/BlurView.types.ts b/src/BlurView.types.ts +index b63ad6b3a9e30bd0f13cff322be79077d0cb5326..bdc3295af94bc17e8a6457b6c9567ff2d57799a7 100644 +--- a/src/BlurView.types.ts ++++ b/src/BlurView.types.ts +@@ -1,5 +1,5 @@ + import type { RefObject } from 'react'; +-import type { ViewProps, View } from 'react-native'; ++import type { ViewProps, ViewInstance } from 'react-native'; + + /** + * Blur method to use on Android. +@@ -27,7 +27,7 @@ export type BlurViewProps = { + * + * @platform android + */ +- blurTarget?: RefObject; ++ blurTarget?: RefObject; + /** + * A tint mode which will be applied to the view. + * +@@ -74,7 +74,7 @@ export type BlurViewProps = { + } & ViewProps; + + export type BlurTargetViewProps = { +- ref?: RefObject; ++ ref?: RefObject; + } & ViewProps; + + export type BlurTint = diff --git a/patches/expo-glass-effect@58.0.3.patch b/patches/expo-glass-effect@58.0.3.patch new file mode 100644 index 0000000000000000000000000000000000000000..23d09d01260801a9cbf3ad1351e5d4222c82d150 --- /dev/null +++ b/patches/expo-glass-effect@58.0.3.patch @@ -0,0 +1,72 @@ +diff --git a/build/GlassContainer.types.d.ts b/build/GlassContainer.types.d.ts +index 502f9b037900d62aa5875dc37f0fcb517dec7a44..cc521dcb7e411cba7dfe99f191bbc42ac979849f 100644 +--- a/build/GlassContainer.types.d.ts ++++ b/build/GlassContainer.types.d.ts +@@ -1,5 +1,5 @@ + import type { Ref } from 'react'; +-import type { View, ViewProps } from 'react-native'; ++import type { ViewInstance, ViewProps } from 'react-native'; + export type GlassContainerProps = { + /** + * The distance at which glass elements start affecting each other. +@@ -7,5 +7,5 @@ export type GlassContainerProps = { + * @default undefined + */ + spacing?: number; +- ref?: Ref; ++ ref?: Ref; + } & ViewProps; +diff --git a/build/GlassView.types.d.ts b/build/GlassView.types.d.ts +index a09487b1b3ef2e4d89b19e2bad81f99fc532d94d..eeadfff1dcd891bf581ef6be0493e2a6eda0849a 100644 +--- a/build/GlassView.types.d.ts ++++ b/build/GlassView.types.d.ts +@@ -1,5 +1,5 @@ + import type { Ref } from 'react'; +-import type { ColorValue, View, ViewProps } from 'react-native'; ++import type { ColorValue, ViewInstance, ViewProps } from 'react-native'; + export type GlassStyle = 'clear' | 'regular' | 'none'; + export type GlassEffectStyleConfig = { + /** +@@ -40,5 +40,5 @@ export type GlassViewProps = { + * @default 'auto' + */ + colorScheme?: GlassColorScheme; +- ref?: Ref; ++ ref?: Ref; + } & ViewProps; +diff --git a/src/GlassContainer.types.ts b/src/GlassContainer.types.ts +index f57a30713a4a2c1769e4f213a43d29fa17d8c411..fa934d45d488dcbc8cb6396e88f0a2996834367b 100644 +--- a/src/GlassContainer.types.ts ++++ b/src/GlassContainer.types.ts +@@ -1,5 +1,5 @@ + import type { Ref } from 'react'; +-import type { View, ViewProps } from 'react-native'; ++import type { ViewInstance, ViewProps } from 'react-native'; + + export type GlassContainerProps = { + /** +@@ -8,5 +8,5 @@ export type GlassContainerProps = { + * @default undefined + */ + spacing?: number; +- ref?: Ref; ++ ref?: Ref; + } & ViewProps; +diff --git a/src/GlassView.types.ts b/src/GlassView.types.ts +index 7fc30003a9337a12ffb12ffb44a050aae99e9b40..413db6b698055dd00d6ec2cf7b71e4370c85054c 100644 +--- a/src/GlassView.types.ts ++++ b/src/GlassView.types.ts +@@ -1,5 +1,5 @@ + import type { Ref } from 'react'; +-import type { ColorValue, View, ViewProps } from 'react-native'; ++import type { ColorValue, ViewInstance, ViewProps } from 'react-native'; + + export type GlassStyle = 'clear' | 'regular' | 'none'; + +@@ -44,5 +44,5 @@ export type GlassViewProps = { + * @default 'auto' + */ + colorScheme?: GlassColorScheme; +- ref?: Ref; ++ ref?: Ref; + } & ViewProps; diff --git a/patches/expo-sharing@57.0.17.patch b/patches/expo-sharing@57.0.17.patch deleted file mode 100644 index 924df6c8c7c1b26891195a4c09fc4ec2d3c320b0..0000000000000000000000000000000000000000 --- a/patches/expo-sharing@57.0.17.patch +++ /dev/null @@ -1,123 +0,0 @@ -diff --git a/android/src/main/java/expo/modules/sharing/SharingRecords.kt b/android/src/main/java/expo/modules/sharing/SharingRecords.kt -index 0b87b53f632e82f9b4c09c066d5a67e4ab2525a4..65f1c57faef3ba8caac9e137341f2b8312bb5f86 100644 ---- a/android/src/main/java/expo/modules/sharing/SharingRecords.kt -+++ b/android/src/main/java/expo/modules/sharing/SharingRecords.kt -@@ -52,7 +52,8 @@ enum class ContentType(val value: String) : Enumerable { - internal data class SharePayload( - @Field var value: String = "", - @Field var shareType: ShareType = ShareType.Text, -- @Field var mimeType: String = "text/plain" -+ @Field var mimeType: String = "text/plain", -+ @Field var originalName: String? = null - ) : Record - - @OptimizedRecord -diff --git a/android/src/main/java/expo/modules/sharing/dataParsers/SimpleShareIntentDataParser.kt b/android/src/main/java/expo/modules/sharing/dataParsers/SimpleShareIntentDataParser.kt -index 8dd50e8f04022d183884a57e4d61a7e1711b9e49..481cdb4bc64ea5ae49919071f686324f6d56d55c 100644 ---- a/android/src/main/java/expo/modules/sharing/dataParsers/SimpleShareIntentDataParser.kt -+++ b/android/src/main/java/expo/modules/sharing/dataParsers/SimpleShareIntentDataParser.kt -@@ -3,6 +3,7 @@ package expo.modules.sharing - import android.content.Context - import android.content.Intent - import android.net.Uri -+import android.provider.OpenableColumns - - internal class SimpleShareIntentDataParser { - companion object { -@@ -17,21 +18,26 @@ internal class SimpleShareIntentDataParser { - } - - private fun handleSendAction(context: Context, intent: Intent, type: String): List { -- return if (type == "text/plain") { -- val text = intent.getStringExtra(Intent.EXTRA_TEXT) ?: return emptyList() -- val isUrl = android.util.Patterns.WEB_URL.matcher(text).matches() -- -- listOf( -+ val stream = intent.getParcelableExtraCompat(Intent.EXTRA_STREAM) -+ val text = intent.getStringExtra(Intent.EXTRA_TEXT) -+ if (stream == null) { -+ if (!type.startsWith("text/") || text == null) return emptyList() -+ return listOf( - SharePayload().apply { - value = text -- shareType = if (isUrl) ShareType.Url else ShareType.Text -- mimeType = "text/plain" -+ shareType = if (android.util.Patterns.WEB_URL.matcher(text).matches()) ShareType.Url else ShareType.Text -+ mimeType = type - } - ) -- } else { -- val uri = intent.getParcelableExtraCompat(Intent.EXTRA_STREAM) -- listOfNotNull(uri?.let { createUriPayload(context, it, type) }) - } -+ val filePayload = createUriPayload(context, stream, type) -+ if (text.isNullOrBlank()) return listOf(filePayload) -+ val textPayload = SharePayload().apply { -+ value = text -+ shareType = if (android.util.Patterns.WEB_URL.matcher(text).matches()) ShareType.Url else ShareType.Text -+ mimeType = "text/plain" -+ } -+ return listOf(textPayload, filePayload) - } - - private fun handleSendMultipleAction(context: Context, intent: Intent, type: String): List { -@@ -41,10 +47,25 @@ internal class SimpleShareIntentDataParser { - - private fun createUriPayload(context: Context, uri: Uri, defaultType: String): SharePayload { - val specificType = context.contentResolver.getType(uri) ?: defaultType -+ // A blank DISPLAY_NAME must stay null: consumers treat originalName as -+ // the attachment name, and an empty name fails contract validation. -+ val displayName = runCatching { -+ context.contentResolver.query( -+ uri, -+ arrayOf(OpenableColumns.DISPLAY_NAME), -+ null, -+ null, -+ null -+ )?.use { cursor -> -+ val column = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME) -+ if (column >= 0 && cursor.moveToFirst()) cursor.getString(column) else null -+ } -+ }.getOrNull()?.takeIf { it.isNotBlank() } - return SharePayload().apply { - value = uri.toString() -- shareType = ShareType.fromMimeType(specificType) -+ shareType = if (specificType.startsWith("text/")) ShareType.File else ShareType.fromMimeType(specificType) - mimeType = specificType -+ originalName = displayName - } - } - } -diff --git a/build/Sharing.types.d.ts b/build/Sharing.types.d.ts -index e9820b061bddce91657ab7144fde98d0543a3b8e..364d63273cb3e209c6490de6dd869a01c8728fcc 100644 ---- a/build/Sharing.types.d.ts -+++ b/build/Sharing.types.d.ts -@@ -77,6 +77,11 @@ export type SharePayload = { - * @default 'text/plain' - */ - mimeType?: string; -+ /** -+ * The display name of a shared file, when the source app provided one. -+ * Populated on Android from the content resolver's `DISPLAY_NAME`. -+ */ -+ originalName?: string | null; - }; - export type BaseResolvedSharePayload = SharePayload & { - /** -diff --git a/src/Sharing.types.ts b/src/Sharing.types.ts -index d9a5ad38f5fe2856b365eb91b71abd640314a5cc..21ea45f04b88cce272e2e02de24c5e4eb8157e82 100644 ---- a/src/Sharing.types.ts -+++ b/src/Sharing.types.ts -@@ -85,6 +85,12 @@ export type SharePayload = { - * @default 'text/plain' - */ - mimeType?: string; -+ -+ /** -+ * The display name of a shared file, when the source app provided one. -+ * Populated on Android from the content resolver's `DISPLAY_NAME`. -+ */ -+ originalName?: string | null; - }; - - export type BaseResolvedSharePayload = SharePayload & { diff --git a/patches/expo-sharing@58.0.12.patch b/patches/expo-sharing@58.0.12.patch new file mode 100644 index 0000000000000000000000000000000000000000..dd3bec580b17868c211e17035e2f90f774647920 --- /dev/null +++ b/patches/expo-sharing@58.0.12.patch @@ -0,0 +1,123 @@ +diff --git a/android/src/main/java/expo/modules/sharing/SharingRecords.kt b/android/src/main/java/expo/modules/sharing/SharingRecords.kt +index 0b87b53..65f1c57 100644 +--- a/android/src/main/java/expo/modules/sharing/SharingRecords.kt ++++ b/android/src/main/java/expo/modules/sharing/SharingRecords.kt +@@ -52,7 +52,8 @@ enum class ContentType(val value: String) : Enumerable { + internal data class SharePayload( + @Field var value: String = "", + @Field var shareType: ShareType = ShareType.Text, +- @Field var mimeType: String = "text/plain" ++ @Field var mimeType: String = "text/plain", ++ @Field var originalName: String? = null + ) : Record + + @OptimizedRecord +diff --git a/android/src/main/java/expo/modules/sharing/dataParsers/SimpleShareIntentDataParser.kt b/android/src/main/java/expo/modules/sharing/dataParsers/SimpleShareIntentDataParser.kt +index 8dd50e8..481cdb4 100644 +--- a/android/src/main/java/expo/modules/sharing/dataParsers/SimpleShareIntentDataParser.kt ++++ b/android/src/main/java/expo/modules/sharing/dataParsers/SimpleShareIntentDataParser.kt +@@ -3,6 +3,7 @@ package expo.modules.sharing + import android.content.Context + import android.content.Intent + import android.net.Uri ++import android.provider.OpenableColumns + + internal class SimpleShareIntentDataParser { + companion object { +@@ -17,21 +18,26 @@ internal class SimpleShareIntentDataParser { + } + + private fun handleSendAction(context: Context, intent: Intent, type: String): List { +- return if (type == "text/plain") { +- val text = intent.getStringExtra(Intent.EXTRA_TEXT) ?: return emptyList() +- val isUrl = android.util.Patterns.WEB_URL.matcher(text).matches() +- +- listOf( ++ val stream = intent.getParcelableExtraCompat(Intent.EXTRA_STREAM) ++ val text = intent.getStringExtra(Intent.EXTRA_TEXT) ++ if (stream == null) { ++ if (!type.startsWith("text/") || text == null) return emptyList() ++ return listOf( + SharePayload().apply { + value = text +- shareType = if (isUrl) ShareType.Url else ShareType.Text +- mimeType = "text/plain" ++ shareType = if (android.util.Patterns.WEB_URL.matcher(text).matches()) ShareType.Url else ShareType.Text ++ mimeType = type + } + ) +- } else { +- val uri = intent.getParcelableExtraCompat(Intent.EXTRA_STREAM) +- listOfNotNull(uri?.let { createUriPayload(context, it, type) }) + } ++ val filePayload = createUriPayload(context, stream, type) ++ if (text.isNullOrBlank()) return listOf(filePayload) ++ val textPayload = SharePayload().apply { ++ value = text ++ shareType = if (android.util.Patterns.WEB_URL.matcher(text).matches()) ShareType.Url else ShareType.Text ++ mimeType = "text/plain" ++ } ++ return listOf(textPayload, filePayload) + } + + private fun handleSendMultipleAction(context: Context, intent: Intent, type: String): List { +@@ -41,10 +47,25 @@ internal class SimpleShareIntentDataParser { + + private fun createUriPayload(context: Context, uri: Uri, defaultType: String): SharePayload { + val specificType = context.contentResolver.getType(uri) ?: defaultType ++ // A blank DISPLAY_NAME must stay null: consumers treat originalName as ++ // the attachment name, and an empty name fails contract validation. ++ val displayName = runCatching { ++ context.contentResolver.query( ++ uri, ++ arrayOf(OpenableColumns.DISPLAY_NAME), ++ null, ++ null, ++ null ++ )?.use { cursor -> ++ val column = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME) ++ if (column >= 0 && cursor.moveToFirst()) cursor.getString(column) else null ++ } ++ }.getOrNull()?.takeIf { it.isNotBlank() } + return SharePayload().apply { + value = uri.toString() +- shareType = ShareType.fromMimeType(specificType) ++ shareType = if (specificType.startsWith("text/")) ShareType.File else ShareType.fromMimeType(specificType) + mimeType = specificType ++ originalName = displayName + } + } + } +diff --git a/build/Sharing.types.d.ts b/build/Sharing.types.d.ts +index 74544e0..92bd2f5 100644 +--- a/build/Sharing.types.d.ts ++++ b/build/Sharing.types.d.ts +@@ -100,6 +100,11 @@ export type SharePayload = { + * @default 'text/plain' + */ + mimeType?: string; ++ /** ++ * The display name of a shared file, when the source app provided one. ++ * Populated on Android from the content resolver's `DISPLAY_NAME`. ++ */ ++ originalName?: string | null; + }; + export type BaseResolvedSharePayload = SharePayload & { + /** +diff --git a/src/Sharing.types.ts b/src/Sharing.types.ts +index 18af320..3a52b70 100644 +--- a/src/Sharing.types.ts ++++ b/src/Sharing.types.ts +@@ -108,6 +108,12 @@ export type SharePayload = { + * @default 'text/plain' + */ + mimeType?: string; ++ ++ /** ++ * The display name of a shared file, when the source app provided one. ++ * Populated on Android from the content resolver's `DISPLAY_NAME`. ++ */ ++ originalName?: string | null; + }; + + export type BaseResolvedSharePayload = SharePayload & { diff --git a/patches/expo-widgets@57.0.15.patch b/patches/expo-widgets@57.0.15.patch deleted file mode 100644 index f50a3fa4f6617e927571c6ef9465b31f7d382f7a..0000000000000000000000000000000000000000 --- a/patches/expo-widgets@57.0.15.patch +++ /dev/null @@ -1,148 +0,0 @@ -diff --git a/build/Widgets.types.d.ts b/build/Widgets.types.d.ts -index 15e026868625ce20a3e359e5cc8e5c7e937c4650..f5cc83174ede4fb6e01cbce494f61e088eb4eed8 100644 ---- a/build/Widgets.types.d.ts -+++ b/build/Widgets.types.d.ts -@@ -90,6 +90,10 @@ export type LiveActivityEnvironment = { - * The color scheme of the activity's environment. - */ - colorScheme: 'light' | 'dark'; -+ /** The rendering mode supplied by WidgetKit for this presentation. */ -+ widgetRenderingMode?: WidgetRenderingMode; -+ /** Whether the presentation OS supports Liquid Glass. @platform iOS 26+ */ -+ isLiquidGlassAvailable?: boolean; - /** - * Whether the activity is displayed in a context with reduced luminance. - * @platform iOS 16+ -diff --git a/ios/Widgets/Utils.swift b/ios/Widgets/Utils.swift -index 2b4c044b597de7e0fab42dbc47af14d8bb521838..801f0aed65ea2659f221d477dd841787d9146c26 100644 ---- a/ios/Widgets/Utils.swift -+++ b/ios/Widgets/Utils.swift -@@ -91,6 +91,10 @@ func getLiveActivityEnvironment(for environment: EnvironmentValues, in context: - "colorScheme": "\(environment.colorScheme)" - ] - -+ if #available(iOS 26.0, *) { -+ env["isLiquidGlassAvailable"] = true -+ } -+ env["widgetRenderingMode"] = environment.widgetRenderingMode.description - env["isLuminanceReduced"] = environment.isLuminanceReduced - env["isActivityFullscreen"] = environment.isActivityFullscreen - if #available(iOS 16.2, *) { -diff --git a/ios/Widgets/WidgetLiveActivity.swift b/ios/Widgets/WidgetLiveActivity.swift -index 24d4571a52d3ebe9d785b5d049d8e134a149d513..7051c23b17ac91552e5b5c54606c57086c0ebbea 100644 ---- a/ios/Widgets/WidgetLiveActivity.swift -+++ b/ios/Widgets/WidgetLiveActivity.swift -@@ -20,53 +20,41 @@ struct LiveActivityAttributes: ActivityAttributes { - - @available(iOS 16.1, *) - public struct WidgetLiveActivity: Widget { -- @Environment(\.self) var env -- - let widgetContext: AppContext = AppContext() - - public init() {} - - public var body: some WidgetConfiguration { - ActivityConfiguration(for: LiveActivityAttributes.self) { context in -- let nodes = getLiveActivityNodes( -- forName: context.state.name, -- props: context.state.props, -- environment: getLiveActivityEnvironment(for: env, in: context) -- ) - // Only apply widgetURL when the activity has one: a hierarchy with more than one - // widgetURL modifier is undefined behavior, and layouts can set their own through - // the widgetURL modifier from @expo/ui. -- let banner = LiveActivityBannerView(context: context, nodes: nodes) -+ let banner = LiveActivityBannerView(context: context) - if let url = context.attributes.url.flatMap(URL.init(string:)) { - banner.widgetURL(url) - } else { - banner - } - } dynamicIsland: { context in -- let nodes = getLiveActivityNodes( -- forName: context.state.name, -- props: context.state.props, -- environment: getLiveActivityEnvironment(for: env, in: context) -- ) - let island = DynamicIsland { - DynamicIslandExpandedRegion(.center) { -- LiveActivitySectionView(context: context, nodes: nodes, sectionName: "expandedCenter") -+ LiveActivitySectionView(context: context, sectionName: "expandedCenter") - } - DynamicIslandExpandedRegion(.leading) { -- LiveActivitySectionView(context: context, nodes: nodes, sectionName: "expandedLeading") -+ LiveActivitySectionView(context: context, sectionName: "expandedLeading") - } - DynamicIslandExpandedRegion(.trailing) { -- LiveActivitySectionView(context: context, nodes: nodes, sectionName: "expandedTrailing") -+ LiveActivitySectionView(context: context, sectionName: "expandedTrailing") - } - DynamicIslandExpandedRegion(.bottom) { -- LiveActivitySectionView(context: context, nodes: nodes, sectionName: "expandedBottom") -+ LiveActivitySectionView(context: context, sectionName: "expandedBottom") - } - } compactLeading: { -- LiveActivitySectionView(context: context, nodes: nodes, sectionName: "compactLeading") -+ LiveActivitySectionView(context: context, sectionName: "compactLeading") - } compactTrailing: { -- LiveActivitySectionView(context: context, nodes: nodes, sectionName: "compactTrailing") -+ LiveActivitySectionView(context: context, sectionName: "compactTrailing") - } minimal: { -- LiveActivitySectionView(context: context, nodes: nodes, sectionName: "minimal") -+ LiveActivitySectionView(context: context, sectionName: "minimal") - } - if let url = context.attributes.url.flatMap(URL.init(string:)) { - return island.widgetURL(url) -@@ -79,11 +67,16 @@ public struct WidgetLiveActivity: Widget { - - @available(iOS 16.1, *) - private struct LiveActivitySectionView: View { -+ @Environment(\.self) var env - let context: ActivityViewContext -- let nodes: [String: Any] - let sectionName: String - - var body: some View { -+ let nodes = getLiveActivityNodes( -+ forName: context.state.name, -+ props: context.state.props, -+ environment: getLiveActivityEnvironment(for: env, in: context) -+ ) - if let node = nodes[sectionName] as? [String: Any] { - WidgetsDynamicView(name: context.activityID, kind: .liveActivity, node: node) - } else { -@@ -94,10 +87,17 @@ private struct LiveActivitySectionView: View { - - @available(iOS 16.1, *) - private struct LiveActivityBannerView: View { -+ // Read inside the rendered view: Widget-level values do not include the -+ // presentation's color scheme, rendering mode, or reduced-luminance state. -+ @Environment(\.self) var env - var context: ActivityViewContext -- let nodes: [String: Any] - - var body: some View { -+ let nodes = getLiveActivityNodes( -+ forName: context.state.name, -+ props: context.state.props, -+ environment: getLiveActivityEnvironment(for: env, in: context) -+ ) - if #available(iOS 18.0, *) { - LiveActivityBanner(context: context, nodes: nodes) - } else if let node = nodes["banner"] as? [String: Any] { -diff --git a/src/Widgets.types.ts b/src/Widgets.types.ts -index fee5c7475b52218fa0e192a1d347dd32cb0fe1f8..1d3a097b45d8eb5d13e5cedd26f0414caa83a5d6 100644 ---- a/src/Widgets.types.ts -+++ b/src/Widgets.types.ts -@@ -104,6 +104,10 @@ export type LiveActivityEnvironment = { - * The color scheme of the activity's environment. - */ - colorScheme: 'light' | 'dark'; -+ /** The rendering mode supplied by WidgetKit for this presentation. */ -+ widgetRenderingMode?: WidgetRenderingMode; -+ /** Whether the presentation OS supports Liquid Glass. @platform iOS 26+ */ -+ isLiquidGlassAvailable?: boolean; - /** - * Whether the activity is displayed in a context with reduced luminance. - * @platform iOS 16+ diff --git a/patches/expo-widgets@58.0.9.patch b/patches/expo-widgets@58.0.9.patch new file mode 100644 index 0000000000000000000000000000000000000000..f2632f180c84d340e36dfa788a2b3eed168434a9 --- /dev/null +++ b/patches/expo-widgets@58.0.9.patch @@ -0,0 +1,162 @@ +diff --git a/build/Widgets.types.d.ts b/build/Widgets.types.d.ts +index c9f4dfe..dc0792e 100644 +--- a/build/Widgets.types.d.ts ++++ b/build/Widgets.types.d.ts +@@ -93,6 +93,10 @@ export type LiveActivityEnvironment = { + * The color scheme of the activity's environment. + */ + colorScheme: 'light' | 'dark'; ++ /** The rendering mode supplied by WidgetKit for this presentation. */ ++ widgetRenderingMode?: WidgetRenderingMode; ++ /** Whether the presentation OS supports Liquid Glass. @platform iOS 26+ */ ++ isLiquidGlassAvailable?: boolean; + /** + * Whether the activity is displayed in a context with reduced luminance. + * @platform iOS 16+ +diff --git a/ios/Widgets/Utils.swift b/ios/Widgets/Utils.swift +index 76b2199..6cb52c3 100644 +--- a/ios/Widgets/Utils.swift ++++ b/ios/Widgets/Utils.swift +@@ -125,6 +125,10 @@ func getLiveActivityEnvironment(for environment: EnvironmentValues, in context: + "isStale": context.isStale + ] + ++ if #available(iOS 26.0, *) { ++ env["isLiquidGlassAvailable"] = true ++ } ++ env["widgetRenderingMode"] = environment.widgetRenderingMode.description + if #available(iOS 18.0, *) { + env["isActivityUpdateReduced"] = environment.isActivityUpdateReduced + env["activityFamily"] = "\(environment.activityFamily)" +diff --git a/ios/Widgets/WidgetLiveActivity.swift b/ios/Widgets/WidgetLiveActivity.swift +index 4d135c4..dae4744 100644 +--- a/ios/Widgets/WidgetLiveActivity.swift ++++ b/ios/Widgets/WidgetLiveActivity.swift +@@ -19,53 +19,41 @@ struct LiveActivityAttributes: ActivityAttributes { + } + + public struct WidgetLiveActivity: Widget { +- @Environment(\.self) var env +- + let widgetContext: AppContext = AppContext() + + public init() {} + + public var body: some WidgetConfiguration { + ActivityConfiguration(for: LiveActivityAttributes.self) { context in +- let nodes = getLiveActivityNodes( +- forName: context.state.name, +- props: context.state.props, +- environment: getLiveActivityEnvironment(for: env, in: context) +- ) + // Only apply widgetURL when the activity has one: a hierarchy with more than one + // widgetURL modifier is undefined behavior, and layouts can set their own through + // the widgetURL modifier from @expo/ui. +- let banner = LiveActivityBannerView(context: context, nodes: nodes) ++ let banner = LiveActivityBannerView(context: context) + if let url = context.attributes.url.flatMap(URL.init(string:)) { + banner.widgetURL(url) + } else { + banner + } + } dynamicIsland: { context in +- let nodes = getLiveActivityNodes( +- forName: context.state.name, +- props: context.state.props, +- environment: getLiveActivityEnvironment(for: env, in: context) +- ) + let island = DynamicIsland { + DynamicIslandExpandedRegion(.center) { +- LiveActivitySectionView(context: context, nodes: nodes, sectionName: "expandedCenter") ++ LiveActivitySectionView(context: context, sectionName: "expandedCenter") + } + DynamicIslandExpandedRegion(.leading) { +- LiveActivitySectionView(context: context, nodes: nodes, sectionName: "expandedLeading") ++ LiveActivitySectionView(context: context, sectionName: "expandedLeading") + } + DynamicIslandExpandedRegion(.trailing) { +- LiveActivitySectionView(context: context, nodes: nodes, sectionName: "expandedTrailing") ++ LiveActivitySectionView(context: context, sectionName: "expandedTrailing") + } + DynamicIslandExpandedRegion(.bottom) { +- LiveActivitySectionView(context: context, nodes: nodes, sectionName: "expandedBottom") ++ LiveActivitySectionView(context: context, sectionName: "expandedBottom") + } + } compactLeading: { +- LiveActivitySectionView(context: context, nodes: nodes, sectionName: "compactLeading") ++ LiveActivitySectionView(context: context, sectionName: "compactLeading") + } compactTrailing: { +- LiveActivitySectionView(context: context, nodes: nodes, sectionName: "compactTrailing") ++ LiveActivitySectionView(context: context, sectionName: "compactTrailing") + } minimal: { +- LiveActivitySectionView(context: context, nodes: nodes, sectionName: "minimal") ++ LiveActivitySectionView(context: context, sectionName: "minimal") + } + if let url = context.attributes.url.flatMap(URL.init(string:)) { + return island.widgetURL(url) +@@ -77,11 +65,16 @@ public struct WidgetLiveActivity: Widget { + } + + private struct LiveActivitySectionView: View { ++ @Environment(\.self) var env + let context: ActivityViewContext +- let nodes: [String: Any] + let sectionName: String + + var body: some View { ++ let nodes = getLiveActivityNodes( ++ forName: context.state.name, ++ props: context.state.props, ++ environment: getLiveActivityEnvironment(for: env, in: context) ++ ) + if let node = nodes[sectionName] as? [String: Any] { + WidgetsDynamicView(name: context.activityID, kind: .liveActivity, node: node) + } else { +@@ -91,10 +84,17 @@ private struct LiveActivitySectionView: View { + } + + private struct LiveActivityBannerView: View { ++ // Read inside the rendered view: Widget-level values do not include the ++ // presentation's color scheme, rendering mode, or reduced-luminance state. ++ @Environment(\.self) var env + var context: ActivityViewContext +- let nodes: [String: Any] + + var body: some View { ++ let nodes = getLiveActivityNodes( ++ forName: context.state.name, ++ props: context.state.props, ++ environment: getLiveActivityEnvironment(for: env, in: context) ++ ) + if #available(iOS 18.0, *) { + LiveActivityBanner(context: context, nodes: nodes) + } else if let node = nodes["banner"] as? [String: Any] { +diff --git a/scripts/build-layout-registry.mjs b/scripts/build-layout-registry.mjs +index d52a60e..fa9bd77 100644 +--- a/scripts/build-layout-registry.mjs ++++ b/scripts/build-layout-registry.mjs +@@ -154,6 +154,8 @@ function createLayoutRegistry(expectedWidgets, capturedLayouts) { + return registry; + } + +-if (process.argv[1] && path.resolve(process.argv[1]) === __filename) { ++// Compare real paths: pnpm exposes the package through a symlink, so the ++// invoked path and import.meta.url differ while naming the same file. ++if (process.argv[1] && fs.realpathSync(path.resolve(process.argv[1])) === fs.realpathSync(__filename)) { + await main(); + } +diff --git a/src/Widgets.types.ts b/src/Widgets.types.ts +index 0770613..924fa00 100644 +--- a/src/Widgets.types.ts ++++ b/src/Widgets.types.ts +@@ -107,6 +107,10 @@ export type LiveActivityEnvironment = { + * The color scheme of the activity's environment. + */ + colorScheme: 'light' | 'dark'; ++ /** The rendering mode supplied by WidgetKit for this presentation. */ ++ widgetRenderingMode?: WidgetRenderingMode; ++ /** Whether the presentation OS supports Liquid Glass. @platform iOS 26+ */ ++ isLiquidGlassAvailable?: boolean; + /** + * Whether the activity is displayed in a context with reduced luminance. + * @platform iOS 16+ diff --git a/patches/react-native-gesture-handler@2.32.0.patch b/patches/react-native-gesture-handler@2.32.0.patch deleted file mode 100644 index ae3568fa64a98ee99429f8708eed00920de9c5dd..0000000000000000000000000000000000000000 --- a/patches/react-native-gesture-handler@2.32.0.patch +++ /dev/null @@ -1,237 +0,0 @@ -diff --git a/apple/Handlers/RNHoverHandler.m b/apple/Handlers/RNHoverHandler.m -index 320cb8cb2652bfcfe1ecc65ebd81a8d208e4260f..a88ac5f04a9663fd7a62ee89e42d85ec41dcaf55 100644 ---- a/apple/Handlers/RNHoverHandler.m -+++ b/apple/Handlers/RNHoverHandler.m -@@ -132,8 +132,10 @@ - (void)unbindFromView - { - #if CHECK_TARGET(13_4) - if (@available(iOS 13.4, *)) { -+ // The superclass detaches the recognizer, clearing recognizer.view. Remove -+ // the interaction from its own view before it can be recycled by Fabric. -+ [_pointerInteraction.view removeInteraction:_pointerInteraction]; - [super unbindFromView]; -- [self.recognizer.view removeInteraction:_pointerInteraction]; - } - #endif - } -diff --git a/lib/commonjs/components/ReanimatedSwipeable/ReanimatedSwipeable.js b/lib/commonjs/components/ReanimatedSwipeable/ReanimatedSwipeable.js -index 551ab92bf58db0b79d428dcd2f2df898ef686493..13db26d88bff975bc5d46bb6432cbf9fda3d489a 100644 ---- a/lib/commonjs/components/ReanimatedSwipeable/ReanimatedSwipeable.js -+++ b/lib/commonjs/components/ReanimatedSwipeable/ReanimatedSwipeable.js -@@ -34,11 +34,13 @@ const Swipeable = props => { - enableTrackpadTwoFingerGesture = DEFAULT_ENABLE_TRACKING_TWO_FINGER_GESTURE, - dragOffsetFromLeftEdge = DEFAULT_DRAG_OFFSET, - dragOffsetFromRightEdge = DEFAULT_DRAG_OFFSET, -+ failOffsetY, - friction = DEFAULT_FRICTION, - overshootFriction = DEFAULT_OVERSHOOT_FRICTION, - onSwipeableOpenStartDrag, - onSwipeableCloseStartDrag, - onSwipeableWillOpen, -+ onSwipeableRelease, - onSwipeableWillClose, - onSwipeableOpen, - onSwipeableClose, -@@ -248,8 +250,13 @@ const Swipeable = props => { - toValue = -rightWidth.value; - } - } -+ // Let a UI-thread full-swipe commit take over before the return spring. -+ if (onSwipeableRelease?.(appliedTranslation)) { -+ return; -+ } -+ - animateRow(toValue, velocityX / friction); -- }, [animateRow, friction, leftThreshold, leftWidth, rightThreshold, rightWidth, rowState, userDrag]); -+ }, [animateRow, friction, leftThreshold, leftWidth, rightThreshold, rightWidth, rowState, userDrag, onSwipeableRelease, appliedTranslation]); - const close = (0, _react.useCallback)(() => { - 'worklet'; - -@@ -285,11 +292,14 @@ const Swipeable = props => { - }).onFinalize(() => { - dragStarted.value = false; - }); -+ if (failOffsetY !== undefined) { -+ pan.failOffsetY(failOffsetY); -+ } - Object.entries(relationProps).forEach(([relationName, relation]) => { - (0, _utils.applyRelationProp)(pan, relationName, relation); - }); - return pan; -- }, [enabled, hitSlop, enableTrackpadTwoFingerGesture, dragOffsetFromRightEdge, dragOffsetFromLeftEdge, updateElementWidths, relationProps, userDrag, rowState, dragStarted, updateAnimatedEvent, onSwipeableOpenStartDrag, onSwipeableCloseStartDrag, handleRelease]); -+ }, [enabled, hitSlop, enableTrackpadTwoFingerGesture, dragOffsetFromRightEdge, dragOffsetFromLeftEdge, failOffsetY, updateElementWidths, relationProps, userDrag, rowState, dragStarted, updateAnimatedEvent, onSwipeableOpenStartDrag, onSwipeableCloseStartDrag, handleRelease]); - (0, _react.useImperativeHandle)(ref, () => swipeableMethods, [swipeableMethods]); - const animatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => ({ - transform: [{ -diff --git a/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js b/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js -index a2835d5416ffd5cf9a04e98774516b9e6569691e..055afce410d6eb655532e7a09371dfc22eae5e9c 100644 ---- a/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js -+++ b/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js -@@ -29,11 +29,13 @@ const Swipeable = props => { - enableTrackpadTwoFingerGesture = DEFAULT_ENABLE_TRACKING_TWO_FINGER_GESTURE, - dragOffsetFromLeftEdge = DEFAULT_DRAG_OFFSET, - dragOffsetFromRightEdge = DEFAULT_DRAG_OFFSET, -+ failOffsetY, - friction = DEFAULT_FRICTION, - overshootFriction = DEFAULT_OVERSHOOT_FRICTION, - onSwipeableOpenStartDrag, - onSwipeableCloseStartDrag, - onSwipeableWillOpen, -+ onSwipeableRelease, - onSwipeableWillClose, - onSwipeableOpen, - onSwipeableClose, -@@ -243,8 +245,13 @@ const Swipeable = props => { - toValue = -rightWidth.value; - } - } -+ // Let a UI-thread full-swipe commit take over before the return spring. -+ if (onSwipeableRelease?.(appliedTranslation)) { -+ return; -+ } -+ - animateRow(toValue, velocityX / friction); -- }, [animateRow, friction, leftThreshold, leftWidth, rightThreshold, rightWidth, rowState, userDrag]); -+ }, [animateRow, friction, leftThreshold, leftWidth, rightThreshold, rightWidth, rowState, userDrag, onSwipeableRelease, appliedTranslation]); - const close = useCallback(() => { - 'worklet'; - -@@ -280,11 +287,14 @@ const Swipeable = props => { - }).onFinalize(() => { - dragStarted.value = false; - }); -+ if (failOffsetY !== undefined) { -+ pan.failOffsetY(failOffsetY); -+ } - Object.entries(relationProps).forEach(([relationName, relation]) => { - applyRelationProp(pan, relationName, relation); - }); - return pan; -- }, [enabled, hitSlop, enableTrackpadTwoFingerGesture, dragOffsetFromRightEdge, dragOffsetFromLeftEdge, updateElementWidths, relationProps, userDrag, rowState, dragStarted, updateAnimatedEvent, onSwipeableOpenStartDrag, onSwipeableCloseStartDrag, handleRelease]); -+ }, [enabled, hitSlop, enableTrackpadTwoFingerGesture, dragOffsetFromRightEdge, dragOffsetFromLeftEdge, failOffsetY, updateElementWidths, relationProps, userDrag, rowState, dragStarted, updateAnimatedEvent, onSwipeableOpenStartDrag, onSwipeableCloseStartDrag, handleRelease]); - useImperativeHandle(ref, () => swipeableMethods, [swipeableMethods]); - const animatedStyle = useAnimatedStyle(() => ({ - transform: [{ -diff --git a/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeableProps.d.ts b/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeableProps.d.ts -index ac8b76830d468edfbc29052b452a36221323c3de..cac72ebaafaf746af7640783a16e99c93ecad2a4 100644 ---- a/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeableProps.d.ts -+++ b/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeableProps.d.ts -@@ -64,6 +64,13 @@ export interface SwipeableProps { - * a swipe. The default value is 10. - */ - dragOffsetFromRightEdge?: number; -+ /** -+ * Range along the Y axis (in points) that, once exceeded before the swipe -+ * activates, makes the pan fail. Lets vertically-dominant pans (list -+ * scrolling, especially trackpad two-finger pans) skip the swipe entirely. -+ * Passed straight to the underlying Pan gesture's `failOffsetY`. -+ */ -+ failOffsetY?: number | [start: number, end: number]; - /** - * Value indicating if the swipeable panel can be pulled further than the left - * actions panel's width. It is set to true by default as long as the left -@@ -90,6 +97,13 @@ export interface SwipeableProps { - * Called when action panel is closed. - */ - onSwipeableClose?: (direction: SwipeDirection.LEFT | SwipeDirection.RIGHT) => void; -+ /** -+ * UI-thread worklet called on release before the built-in spring starts. -+ * Return true to consume the release and take ownership of translation. -+ * The caller must reset or remove the row after its custom animation. -+ */ -+ onSwipeableRelease?: (translation: SharedValue) => boolean; -+ - /** - * Called when action panel starts animating on open (either right or left). - */ -diff --git a/src/components/ReanimatedSwipeable/ReanimatedSwipeable.tsx b/src/components/ReanimatedSwipeable/ReanimatedSwipeable.tsx -index b6134c908624adc590ebd264e90e558b88e235d5..fa4b1c1749bd0e86cbf5f5546f295d8099e1a481 100644 ---- a/src/components/ReanimatedSwipeable/ReanimatedSwipeable.tsx -+++ b/src/components/ReanimatedSwipeable/ReanimatedSwipeable.tsx -@@ -58,11 +58,13 @@ const Swipeable = (props: SwipeableProps) => { - enableTrackpadTwoFingerGesture = DEFAULT_ENABLE_TRACKING_TWO_FINGER_GESTURE, - dragOffsetFromLeftEdge = DEFAULT_DRAG_OFFSET, - dragOffsetFromRightEdge = DEFAULT_DRAG_OFFSET, -+ failOffsetY, - friction = DEFAULT_FRICTION, - overshootFriction = DEFAULT_OVERSHOOT_FRICTION, - onSwipeableOpenStartDrag, - onSwipeableCloseStartDrag, - onSwipeableWillOpen, -+ onSwipeableRelease, - onSwipeableWillClose, - onSwipeableOpen, - onSwipeableClose, -@@ -457,6 +459,11 @@ const Swipeable = (props: SwipeableProps) => { - } - } - -+ // Let a UI-thread full-swipe commit take over before the return spring. -+ if (onSwipeableRelease?.(appliedTranslation)) { -+ return; -+ } -+ - animateRow(toValue, velocityX / friction); - }, - [ -@@ -468,6 +475,8 @@ const Swipeable = (props: SwipeableProps) => { - rightWidth, - rowState, - userDrag, -+ onSwipeableRelease, -+ appliedTranslation, - ] - ); - -@@ -537,6 +546,10 @@ const Swipeable = (props: SwipeableProps) => { - dragStarted.value = false; - }); - -+ if (failOffsetY !== undefined) { -+ pan.failOffsetY(failOffsetY); -+ } -+ - Object.entries(relationProps).forEach(([relationName, relation]) => { - applyRelationProp( - pan, -@@ -552,6 +565,7 @@ const Swipeable = (props: SwipeableProps) => { - enableTrackpadTwoFingerGesture, - dragOffsetFromRightEdge, - dragOffsetFromLeftEdge, -+ failOffsetY, - updateElementWidths, - relationProps, - userDrag, -diff --git a/src/components/ReanimatedSwipeable/ReanimatedSwipeableProps.ts b/src/components/ReanimatedSwipeable/ReanimatedSwipeableProps.ts -index 0c0e517e0d340faf50ff78c3d48e7a2bbcf808ec..3ab14d240da346b1927792e480f5b1e902b03bf8 100644 ---- a/src/components/ReanimatedSwipeable/ReanimatedSwipeableProps.ts -+++ b/src/components/ReanimatedSwipeable/ReanimatedSwipeableProps.ts -@@ -77,6 +77,14 @@ export interface SwipeableProps { - */ - dragOffsetFromRightEdge?: number; - -+ /** -+ * Range along the Y axis (in points) that, once exceeded before the swipe -+ * activates, makes the pan fail. Lets vertically-dominant pans (list -+ * scrolling, especially trackpad two-finger pans) skip the swipe entirely. -+ * Passed straight to the underlying Pan gesture's `failOffsetY`. -+ */ -+ failOffsetY?: number | [start: number, end: number]; -+ - /** - * Value indicating if the swipeable panel can be pulled further than the left - * actions panel's width. It is set to true by default as long as the left -@@ -112,6 +120,13 @@ export interface SwipeableProps { - direction: SwipeDirection.LEFT | SwipeDirection.RIGHT - ) => void; - -+ /** -+ * UI-thread worklet called on release before the built-in spring starts. -+ * Return true to consume the release and take ownership of translation. -+ * The caller must reset or remove the row after its custom animation. -+ */ -+ onSwipeableRelease?: (translation: SharedValue) => boolean; -+ - /** - * Called when action panel starts animating on open (either right or left). - */ diff --git a/patches/react-native-gesture-handler@3.2.1.patch b/patches/react-native-gesture-handler@3.2.1.patch new file mode 100644 index 0000000000000000000000000000000000000000..8fe606a1fad6b9a27540f5dcb5a61cb056692b49 --- /dev/null +++ b/patches/react-native-gesture-handler@3.2.1.patch @@ -0,0 +1,151 @@ +diff --git a/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js b/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js +index 4ab38424d1f5fc8b2686dd4a0a8058c454a9874d..0c5e0eaa995af50e5f8c02909dc6825121cc61af 100644 +--- a/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js ++++ b/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js +@@ -31,11 +31,13 @@ const Swipeable = props => { + enableTrackpadTwoFingerGesture = DEFAULT_ENABLE_TRACKING_TWO_FINGER_GESTURE, + dragOffsetFromLeft = DEFAULT_DRAG_OFFSET, + dragOffsetFromRight = -DEFAULT_DRAG_OFFSET, ++ failOffsetY, + friction = DEFAULT_FRICTION, + overshootFriction = DEFAULT_OVERSHOOT_FRICTION, + onSwipeableOpenStartDrag, + onSwipeableCloseStartDrag, + onSwipeableWillOpen, ++ onSwipeableRelease, + onSwipeableWillClose, + onSwipeableOpen, + onSwipeableClose, +@@ -276,8 +278,12 @@ const Swipeable = props => { + toValue = -rightWidth.value; + } + } ++ // Let a UI-thread full-swipe commit take over before the return spring. ++ if (onSwipeableRelease?.(appliedTranslation)) { ++ return; ++ } + animateRow(toValue, velocityX / friction); +- }, [animateRow, friction, leftThreshold, leftWidth, rightThreshold, rightWidth, rowState, userDrag]); ++ }, [animateRow, friction, leftThreshold, leftWidth, rightThreshold, rightWidth, rowState, userDrag, onSwipeableRelease, appliedTranslation]); + const close = useCallback(() => { + 'worklet'; + +@@ -302,6 +308,7 @@ const Swipeable = props => { + enabled: enabled ?? true, + enableTrackpadTwoFingerGesture: enableTrackpadTwoFingerGesture, + activeOffsetX: [dragOffsetFromRight, dragOffsetFromLeft], ++ failOffsetY, + simultaneousWith, + requireToFail, + block, +diff --git a/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeableProps.d.ts b/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeableProps.d.ts +index e97b6dbbced1bcbd359cf35293b7f10cbf13b0e7..de07f26423bee66ecd7d0f9bb33233bcb3215751 100644 +--- a/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeableProps.d.ts ++++ b/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeableProps.d.ts +@@ -59,6 +59,12 @@ export type SwipeableProps = { + * Called when action panel is closed. + */ + onSwipeableClose?: (direction: SwipeDirection.LEFT | SwipeDirection.RIGHT) => void; ++ /** ++ * UI-thread worklet called on release before the built-in spring starts. ++ * Return true to consume the release and take ownership of translation. ++ * The caller must reset or remove the row after its custom animation. ++ */ ++ onSwipeableRelease?: (translation: SharedValue) => boolean; + /** + * Called when action panel starts animating on open (either right or left). + */ +@@ -150,6 +156,13 @@ export type SwipeableProps = { + * The horizontal offset from the starting point required to trigger a left-swipe gesture. Defaults to -10. + */ + dragOffsetFromRight?: number; ++ /** ++ * Range along the Y axis (in points) that, once exceeded before the swipe ++ * activates, makes the pan fail. Lets vertically-dominant pans (list ++ * scrolling, especially trackpad two-finger pans) skip the swipe entirely. ++ * Passed straight to the underlying Pan gesture's `failOffsetY`. ++ */ ++ failOffsetY?: number | [start: number, end: number]; + }>; + export interface SwipeableMethods { + close: () => void; +diff --git a/src/components/ReanimatedSwipeable/ReanimatedSwipeable.tsx b/src/components/ReanimatedSwipeable/ReanimatedSwipeable.tsx +index 4881db1dc7575adc6610569035a8990cee414f3e..8431b738a9ffd09df48e1106b2bd5b62251d536c 100644 +--- a/src/components/ReanimatedSwipeable/ReanimatedSwipeable.tsx ++++ b/src/components/ReanimatedSwipeable/ReanimatedSwipeable.tsx +@@ -61,11 +61,13 @@ const Swipeable = (props: SwipeableProps) => { + enableTrackpadTwoFingerGesture = DEFAULT_ENABLE_TRACKING_TWO_FINGER_GESTURE, + dragOffsetFromLeft = DEFAULT_DRAG_OFFSET, + dragOffsetFromRight = -DEFAULT_DRAG_OFFSET, ++ failOffsetY, + friction = DEFAULT_FRICTION, + overshootFriction = DEFAULT_OVERSHOOT_FRICTION, + onSwipeableOpenStartDrag, + onSwipeableCloseStartDrag, + onSwipeableWillOpen, ++ onSwipeableRelease, + onSwipeableWillClose, + onSwipeableOpen, + onSwipeableClose, +@@ -491,6 +493,11 @@ const Swipeable = (props: SwipeableProps) => { + } + } + ++ // Let a UI-thread full-swipe commit take over before the return spring. ++ if (onSwipeableRelease?.(appliedTranslation)) { ++ return; ++ } ++ + animateRow(toValue, velocityX / friction); + }, + [ +@@ -502,6 +509,8 @@ const Swipeable = (props: SwipeableProps) => { + rightWidth, + rowState, + userDrag, ++ onSwipeableRelease, ++ appliedTranslation, + ] + ); + +@@ -530,6 +539,7 @@ const Swipeable = (props: SwipeableProps) => { + enabled: enabled ?? true, + enableTrackpadTwoFingerGesture: enableTrackpadTwoFingerGesture, + activeOffsetX: [dragOffsetFromRight, dragOffsetFromLeft], ++ failOffsetY, + simultaneousWith, + requireToFail, + block, +diff --git a/src/components/ReanimatedSwipeable/ReanimatedSwipeableProps.ts b/src/components/ReanimatedSwipeable/ReanimatedSwipeableProps.ts +index 1e1246f709feb04c01cf3221472cc1219a8fffac..f526d4fe2d2738becbe8d29c59d1105afa11ae60 100644 +--- a/src/components/ReanimatedSwipeable/ReanimatedSwipeableProps.ts ++++ b/src/components/ReanimatedSwipeable/ReanimatedSwipeableProps.ts +@@ -77,6 +77,13 @@ export type SwipeableProps = { + direction: SwipeDirection.LEFT | SwipeDirection.RIGHT + ) => void; + ++ /** ++ * UI-thread worklet called on release before the built-in spring starts. ++ * Return true to consume the release and take ownership of translation. ++ * The caller must reset or remove the row after its custom animation. ++ */ ++ onSwipeableRelease?: (translation: SharedValue) => boolean; ++ + /** + * Called when action panel starts animating on open (either right or left). + */ +@@ -196,6 +203,14 @@ export type SwipeableProps = { + * The horizontal offset from the starting point required to trigger a left-swipe gesture. Defaults to -10. + */ + dragOffsetFromRight?: number; ++ ++ /** ++ * Range along the Y axis (in points) that, once exceeded before the swipe ++ * activates, makes the pan fail. Lets vertically-dominant pans (list ++ * scrolling, especially trackpad two-finger pans) skip the swipe entirely. ++ * Passed straight to the underlying Pan gesture's `failOffsetY`. ++ */ ++ failOffsetY?: number | [start: number, end: number]; + }>; + + export interface SwipeableMethods { diff --git a/patches/react-native-keyboard-controller@1.21.13.patch b/patches/react-native-keyboard-controller@1.21.13.patch deleted file mode 100644 index f2e510a940bf173f5c569d949b961aa76a2b42ad..0000000000000000000000000000000000000000 --- a/patches/react-native-keyboard-controller@1.21.13.patch +++ /dev/null @@ -1,869 +0,0 @@ -diff --git a/lib/commonjs/components/KeyboardChatScrollView/index.js b/lib/commonjs/components/KeyboardChatScrollView/index.js -index db8cfb1d289f91563f13c4dd842c783c99facc32..64c7e38ad8d9e866b15a53e561509e6b0ad33cb9 100644 ---- a/lib/commonjs/components/KeyboardChatScrollView/index.js -+++ b/lib/commonjs/components/KeyboardChatScrollView/index.js -@@ -26,9 +26,12 @@ const KeyboardChatScrollView = /*#__PURE__*/(0, _react.forwardRef)(({ - offset = 0, - extraContentPadding = ZERO_CONTENT_PADDING, - blankSpace = ZERO_BLANK_SPACE, -+ adjustedInsetCompensation = 0, -+ adjustedStartInsetCompensation = 0, - applyWorkaroundForContentInsetHitTestBug = false, - onLayout: onLayoutProp, - onContentSizeChange: onContentSizeChangeProp, -+ onContentInsetChange, - onEndVisible, - ...rest - }, ref) => { -@@ -50,13 +53,17 @@ const KeyboardChatScrollView = /*#__PURE__*/(0, _react.forwardRef)(({ - freeze: freezeSV, - offset, - blankSpace, -- extraContentPadding -+ extraContentPadding, -+ adjustedInsetCompensation, -+ adjustedStartInsetCompensation - }); - (0, _useExtraContentPadding.useExtraContentPadding)({ - scrollViewRef, - extraContentPadding, - keyboardPadding: padding, - blankSpace, -+ adjustedInsetCompensation, -+ adjustedStartInsetCompensation, - scroll, - layout, - size, -@@ -82,10 +89,26 @@ const KeyboardChatScrollView = /*#__PURE__*/(0, _react.forwardRef)(({ - // a bug for you, please open an issue. - const totalPadding = (0, _reactNativeReanimated.useDerivedValue)(() => Math.min(layout.value.height, Math.max(blankSpace.value, padding.value + extraContentPadding.value))); - -+ // iOS applies the destination contentInset and contentOffset together at -+ // keyboard-animation start. Keep that native target behavior, but report -+ // the presentation height so virtualized-list layout follows the keyboard. -+ const reportedPadding = (0, _reactNativeReanimated.useDerivedValue)(() => _reactNative.Platform.OS === "ios" ? Math.min(layout.value.height, Math.max(blankSpace.value, currentHeight.value + extraContentPadding.value)) : totalPadding.value); -+ -+ // Mirror the effective bottom padding (keyboard + composer + blank floor) -+ // to the consumer - a virtualized list needs it in its own scroll math or -+ // its end/maintain targets point at the under-the-keyboard resting offset. -+ (0, _reactNativeReanimated.useAnimatedReaction)(() => reportedPadding.value, (current, previous) => { -+ if (onContentInsetChange && current !== previous) { -+ (0, _reactNativeReanimated.runOnJS)(onContentInsetChange)({ -+ bottom: current -+ }); -+ } -+ }, [onContentInsetChange]); -+ - // Scroll indicator inset = keyboard + extraContentPadding (excludes blankSpace). - // Apps that render into the unsafe area can supply a negative - // scrollIndicatorInsets adjustment at the application layer. -- const indicatorPadding = (0, _reactNativeReanimated.useDerivedValue)(() => padding.value + extraContentPadding.value); -+ const indicatorPadding = (0, _reactNativeReanimated.useDerivedValue)(() => padding.value); - const onLayout = (0, _react.useCallback)(e => { - onLayoutInternal(e); - onLayoutProp === null || onLayoutProp === void 0 || onLayoutProp(e); -diff --git a/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/helpers.js b/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/helpers.js -index 4d33b3fe426070cf312fc493ce902b2c24d853ea..e619708b95865afd8b43dd8f0a6523fcf67b1f53 100644 ---- a/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/helpers.js -+++ b/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/helpers.js -@@ -206,7 +206,7 @@ const clampedScrollTarget = (offsetBeforeScroll, keyboardHeight, contentHeight, - * ``` - */ - exports.clampedScrollTarget = clampedScrollTarget; --const computeIOSContentOffset = (relativeScroll, keyboardHeight, contentHeight, layoutHeight, inverted, totalPaddingForMaxScroll) => { -+const computeIOSContentOffset = (relativeScroll, keyboardHeight, contentHeight, layoutHeight, inverted, totalPaddingForMaxScroll, startInsetCompensation = 0) => { - "worklet"; - - const paddingForMax = totalPaddingForMaxScroll !== undefined ? totalPaddingForMaxScroll : keyboardHeight; -@@ -214,8 +214,9 @@ const computeIOSContentOffset = (relativeScroll, keyboardHeight, contentHeight, - const maxScroll = Math.max(contentHeight - layoutHeight, 0); - return Math.max(Math.min(relativeScroll - keyboardHeight, maxScroll), -paddingForMax); - } -- const maxScroll = Math.max(contentHeight - layoutHeight + paddingForMax, 0); -- return Math.min(Math.max(keyboardHeight + relativeScroll, 0), maxScroll); -+ const minScroll = -startInsetCompensation; -+ const maxScroll = Math.max(contentHeight - layoutHeight + paddingForMax, minScroll); -+ return Math.min(Math.max(keyboardHeight + relativeScroll, minScroll), maxScroll); - }; - exports.computeIOSContentOffset = computeIOSContentOffset; - //# sourceMappingURL=helpers.js.map -diff --git a/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js b/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js -index 2073da84b8b2be291aa3181700c2b18a75d0fc56..7ae9bb220ce3cc23c788a79677afdc7d9547a27c 100644 ---- a/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js -+++ b/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js -@@ -32,7 +32,9 @@ function useChatKeyboard(scrollViewRef, options) { - freeze, - offset, - blankSpace, -- extraContentPadding -+ extraContentPadding, -+ adjustedInsetCompensation, -+ adjustedStartInsetCompensation - } = options; - const padding = (0, _reactNativeReanimated.useSharedValue)(0); - const currentHeight = (0, _reactNativeReanimated.useSharedValue)(0); -@@ -58,6 +60,9 @@ function useChatKeyboard(scrollViewRef, options) { - targetKeyboardHeight.value = e.height; - } - const effective = (0, _helpers.getEffectiveHeight)(e.height, targetKeyboardHeight.value, offset); -+ if (e.duration === 0) { -+ currentHeight.value = effective; -+ } - const atEnd = (0, _helpers.isScrollAtEnd)(scroll.value, layout.value.height, size.value.height, inverted); - - // Scale minimum padding absorption by how much of it is visible. -@@ -66,7 +71,7 @@ function useChatKeyboard(scrollViewRef, options) { - const visiblePadding = visibleFraction * blankSpace.value; - const minimumPaddingAbsorbed = Math.max(0, visiblePadding - extraContentPadding.value); - const scrollEffective = (0, _helpers.getScrollEffective)(effective, minimumPaddingAbsorbed); -- const actualTotalPadding = Math.max(blankSpace.value, effective + extraContentPadding.value); -+ const actualTotalPadding = Math.max(blankSpace.value, effective + extraContentPadding.value) + adjustedInsetCompensation; - - // persistent mode: when keyboard shrinks, clamp to valid range - if (keyboardLiftBehavior === "persistent" && effective < padding.value) { -@@ -76,8 +81,8 @@ function useChatKeyboard(scrollViewRef, options) { - const maxScroll = Math.max(size.value.height - layout.value.height, 0); - contentOffsetY.value = Math.max(-actualTotalPadding, Math.min(scroll.value, maxScroll)); - } else { -- const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, 0); -- contentOffsetY.value = Math.max(0, Math.min(scroll.value, maxScroll)); -+ const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, -adjustedStartInsetCompensation); -+ contentOffsetY.value = Math.max(-adjustedStartInsetCompensation, Math.min(scroll.value, maxScroll)); - } - return; - } -@@ -91,8 +96,8 @@ function useChatKeyboard(scrollViewRef, options) { - const maxScroll = Math.max(size.value.height - layout.value.height, 0); - contentOffsetY.value = Math.max(-actualTotalPadding, Math.min(scroll.value, maxScroll)); - } else { -- const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, 0); -- contentOffsetY.value = Math.max(0, Math.min(scroll.value, maxScroll)); -+ const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, -adjustedStartInsetCompensation); -+ contentOffsetY.value = Math.max(-adjustedStartInsetCompensation, Math.min(scroll.value, maxScroll)); - } - return; - } -@@ -118,12 +123,23 @@ function useChatKeyboard(scrollViewRef, options) { - contentOffsetY.value = scroll.value; - return; - } -- contentOffsetY.value = (0, _helpers.computeIOSContentOffset)(relativeScroll, scrollEffective, size.value.height, layout.value.height, inverted, actualTotalPadding); -+ contentOffsetY.value = (0, _helpers.computeIOSContentOffset)(relativeScroll, scrollEffective, size.value.height, layout.value.height, inverted, actualTotalPadding, adjustedStartInsetCompensation); -+ }, -+ onMove: e => { -+ "worklet"; -+ -+ if (freeze.value) { -+ return; -+ } -+ currentHeight.value = (0, _helpers.getEffectiveHeight)(e.height, targetKeyboardHeight.value, offset); - }, -- onMove: () => { -+ onInteractive: e => { - "worklet"; - -- // iOS doesn't need per-frame updates (contentOffset handles it) -+ if (freeze.value) { -+ return; -+ } -+ currentHeight.value = (0, _helpers.getEffectiveHeight)(e.height, targetKeyboardHeight.value, offset); - }, - onEnd: e => { - "worklet"; -@@ -132,9 +148,10 @@ function useChatKeyboard(scrollViewRef, options) { - return; - } - const effective = (0, _helpers.getEffectiveHeight)(e.height, targetKeyboardHeight.value, offset); -+ currentHeight.value = effective; - padding.value = effective; - } -- }, [inverted, keyboardLiftBehavior, offset, extraContentPadding]); -+ }, [inverted, keyboardLiftBehavior, offset, extraContentPadding, adjustedInsetCompensation, adjustedStartInsetCompensation]); - return { - padding, - currentHeight, -diff --git a/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js b/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js -index 0d50bdfeb7bbc5c14a31ed344f8a690e4fd340b3..e0b73653fd1dd23f0f2e2c85835a3d107e3f666d 100644 ---- a/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js -+++ b/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js -@@ -29,6 +29,8 @@ function useExtraContentPadding(options) { - extraContentPadding, - keyboardPadding, - blankSpace, -+ adjustedInsetCompensation, -+ adjustedStartInsetCompensation, - scroll, - layout, - size, -@@ -68,8 +70,8 @@ function useExtraContentPadding(options) { - } - - // Compute effective delta considering blankSpace floor -- const previousTotal = Math.max(blankSpace.value, keyboardPadding.value + previous); -- const currentTotal = Math.max(blankSpace.value, keyboardPadding.value + current); -+ const previousTotal = Math.max(blankSpace.value, keyboardPadding.value + previous) + adjustedInsetCompensation; -+ const currentTotal = Math.max(blankSpace.value, keyboardPadding.value + current) + adjustedInsetCompensation; - const effectiveDelta = currentTotal - previousTotal; - if (effectiveDelta === 0) { - // blankSpace absorbed the change -@@ -88,10 +90,11 @@ function useExtraContentPadding(options) { - const target = Math.max(scroll.value - effectiveDelta, -currentTotal); - scrollToTarget(target); - } else { -- const maxScroll = Math.max(size.value.height - layout.value.height + currentTotal, 0); -- const target = Math.min(scroll.value + effectiveDelta, maxScroll); -+ const minScroll = -adjustedStartInsetCompensation; -+ const maxScroll = Math.max(size.value.height - layout.value.height + currentTotal, minScroll); -+ const target = Math.max(minScroll, Math.min(scroll.value + effectiveDelta, maxScroll)); - scrollToTarget(target); - } -- }, [inverted, keyboardLiftBehavior]); -+ }, [inverted, keyboardLiftBehavior, adjustedInsetCompensation, adjustedStartInsetCompensation]); - } - //# sourceMappingURL=index.js.map -diff --git a/lib/module/components/KeyboardChatScrollView/index.js b/lib/module/components/KeyboardChatScrollView/index.js -index 612dd8bd9bd6cc3e30a5acac937ea3383eb1b630..76b858a6590ad0592cc663864ea822db55eaeceb 100644 ---- a/lib/module/components/KeyboardChatScrollView/index.js -+++ b/lib/module/components/KeyboardChatScrollView/index.js -@@ -1,7 +1,7 @@ - function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } - import React, { forwardRef, useCallback, useMemo } from "react"; --import { StyleSheet } from "react-native"; --import { makeMutable, useAnimatedRef, useAnimatedStyle, useDerivedValue } from "react-native-reanimated"; -+import { Platform, StyleSheet } from "react-native"; -+import { makeMutable, runOnJS, useAnimatedReaction, useAnimatedRef, useAnimatedStyle, useDerivedValue } from "react-native-reanimated"; - import Reanimated from "react-native-reanimated"; - import useCombinedRef from "../hooks/useCombinedRef"; - import ScrollViewWithBottomPadding from "../ScrollViewWithBottomPadding"; -@@ -19,9 +19,12 @@ const KeyboardChatScrollView = /*#__PURE__*/forwardRef(({ - offset = 0, - extraContentPadding = ZERO_CONTENT_PADDING, - blankSpace = ZERO_BLANK_SPACE, -+ adjustedInsetCompensation = 0, -+ adjustedStartInsetCompensation = 0, - applyWorkaroundForContentInsetHitTestBug = false, - onLayout: onLayoutProp, - onContentSizeChange: onContentSizeChangeProp, -+ onContentInsetChange, - onEndVisible, - ...rest - }, ref) => { -@@ -43,13 +46,17 @@ const KeyboardChatScrollView = /*#__PURE__*/forwardRef(({ - freeze: freezeSV, - offset, - blankSpace, -- extraContentPadding -+ extraContentPadding, -+ adjustedInsetCompensation, -+ adjustedStartInsetCompensation - }); - useExtraContentPadding({ - scrollViewRef, - extraContentPadding, - keyboardPadding: padding, - blankSpace, -+ adjustedInsetCompensation, -+ adjustedStartInsetCompensation, - scroll, - layout, - size, -@@ -75,10 +82,26 @@ const KeyboardChatScrollView = /*#__PURE__*/forwardRef(({ - // a bug for you, please open an issue. - const totalPadding = useDerivedValue(() => Math.min(layout.value.height, Math.max(blankSpace.value, padding.value + extraContentPadding.value))); - -+ // iOS applies the destination contentInset and contentOffset together at -+ // keyboard-animation start. Keep that native target behavior, but report -+ // the presentation height so virtualized-list layout follows the keyboard. -+ const reportedPadding = useDerivedValue(() => Platform.OS === "ios" ? Math.min(layout.value.height, Math.max(blankSpace.value, currentHeight.value + extraContentPadding.value)) : totalPadding.value); -+ -+ // Mirror the effective bottom padding (keyboard + composer + blank floor) -+ // to the consumer - a virtualized list needs it in its own scroll math or -+ // its end/maintain targets point at the under-the-keyboard resting offset. -+ useAnimatedReaction(() => reportedPadding.value, (current, previous) => { -+ if (onContentInsetChange && current !== previous) { -+ runOnJS(onContentInsetChange)({ -+ bottom: current -+ }); -+ } -+ }, [onContentInsetChange]); -+ - // Scroll indicator inset = keyboard + extraContentPadding (excludes blankSpace). - // Apps that render into the unsafe area can supply a negative - // scrollIndicatorInsets adjustment at the application layer. -- const indicatorPadding = useDerivedValue(() => padding.value + extraContentPadding.value); -+ const indicatorPadding = useDerivedValue(() => padding.value); - const onLayout = useCallback(e => { - onLayoutInternal(e); - onLayoutProp === null || onLayoutProp === void 0 || onLayoutProp(e); -diff --git a/lib/module/components/KeyboardChatScrollView/useChatKeyboard/helpers.js b/lib/module/components/KeyboardChatScrollView/useChatKeyboard/helpers.js -index 295e2219b560519b8d033968b5105d1da3e77315..ff7ee3fe0d880c2287a7b70d5ecf952e99357adf 100644 ---- a/lib/module/components/KeyboardChatScrollView/useChatKeyboard/helpers.js -+++ b/lib/module/components/KeyboardChatScrollView/useChatKeyboard/helpers.js -@@ -193,7 +193,7 @@ export const clampedScrollTarget = (offsetBeforeScroll, keyboardHeight, contentH - * computeIOSContentOffset(100, 300, 1000, 800, false); // 400 - * ``` - */ --export const computeIOSContentOffset = (relativeScroll, keyboardHeight, contentHeight, layoutHeight, inverted, totalPaddingForMaxScroll) => { -+export const computeIOSContentOffset = (relativeScroll, keyboardHeight, contentHeight, layoutHeight, inverted, totalPaddingForMaxScroll, startInsetCompensation = 0) => { - "worklet"; - - const paddingForMax = totalPaddingForMaxScroll !== undefined ? totalPaddingForMaxScroll : keyboardHeight; -@@ -201,7 +201,8 @@ export const computeIOSContentOffset = (relativeScroll, keyboardHeight, contentH - const maxScroll = Math.max(contentHeight - layoutHeight, 0); - return Math.max(Math.min(relativeScroll - keyboardHeight, maxScroll), -paddingForMax); - } -- const maxScroll = Math.max(contentHeight - layoutHeight + paddingForMax, 0); -- return Math.min(Math.max(keyboardHeight + relativeScroll, 0), maxScroll); -+ const minScroll = -startInsetCompensation; -+ const maxScroll = Math.max(contentHeight - layoutHeight + paddingForMax, minScroll); -+ return Math.min(Math.max(keyboardHeight + relativeScroll, minScroll), maxScroll); - }; - //# sourceMappingURL=helpers.js.map -diff --git a/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js b/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js -index 52943c3a7d6a68fe2094dc1d112c07e6b9d890e4..cc4bfae859191aeb848179028b7217098cba2340 100644 ---- a/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js -+++ b/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js -@@ -25,7 +25,9 @@ function useChatKeyboard(scrollViewRef, options) { - freeze, - offset, - blankSpace, -- extraContentPadding -+ extraContentPadding, -+ adjustedInsetCompensation, -+ adjustedStartInsetCompensation - } = options; - const padding = useSharedValue(0); - const currentHeight = useSharedValue(0); -@@ -51,6 +53,9 @@ function useChatKeyboard(scrollViewRef, options) { - targetKeyboardHeight.value = e.height; - } - const effective = getEffectiveHeight(e.height, targetKeyboardHeight.value, offset); -+ if (e.duration === 0) { -+ currentHeight.value = effective; -+ } - const atEnd = isScrollAtEnd(scroll.value, layout.value.height, size.value.height, inverted); - - // Scale minimum padding absorption by how much of it is visible. -@@ -59,7 +64,7 @@ function useChatKeyboard(scrollViewRef, options) { - const visiblePadding = visibleFraction * blankSpace.value; - const minimumPaddingAbsorbed = Math.max(0, visiblePadding - extraContentPadding.value); - const scrollEffective = getScrollEffective(effective, minimumPaddingAbsorbed); -- const actualTotalPadding = Math.max(blankSpace.value, effective + extraContentPadding.value); -+ const actualTotalPadding = Math.max(blankSpace.value, effective + extraContentPadding.value) + adjustedInsetCompensation; - - // persistent mode: when keyboard shrinks, clamp to valid range - if (keyboardLiftBehavior === "persistent" && effective < padding.value) { -@@ -69,8 +74,8 @@ function useChatKeyboard(scrollViewRef, options) { - const maxScroll = Math.max(size.value.height - layout.value.height, 0); - contentOffsetY.value = Math.max(-actualTotalPadding, Math.min(scroll.value, maxScroll)); - } else { -- const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, 0); -- contentOffsetY.value = Math.max(0, Math.min(scroll.value, maxScroll)); -+ const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, -adjustedStartInsetCompensation); -+ contentOffsetY.value = Math.max(-adjustedStartInsetCompensation, Math.min(scroll.value, maxScroll)); - } - return; - } -@@ -84,8 +89,8 @@ function useChatKeyboard(scrollViewRef, options) { - const maxScroll = Math.max(size.value.height - layout.value.height, 0); - contentOffsetY.value = Math.max(-actualTotalPadding, Math.min(scroll.value, maxScroll)); - } else { -- const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, 0); -- contentOffsetY.value = Math.max(0, Math.min(scroll.value, maxScroll)); -+ const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, -adjustedStartInsetCompensation); -+ contentOffsetY.value = Math.max(-adjustedStartInsetCompensation, Math.min(scroll.value, maxScroll)); - } - return; - } -@@ -111,12 +116,23 @@ function useChatKeyboard(scrollViewRef, options) { - contentOffsetY.value = scroll.value; - return; - } -- contentOffsetY.value = computeIOSContentOffset(relativeScroll, scrollEffective, size.value.height, layout.value.height, inverted, actualTotalPadding); -+ contentOffsetY.value = computeIOSContentOffset(relativeScroll, scrollEffective, size.value.height, layout.value.height, inverted, actualTotalPadding, adjustedStartInsetCompensation); -+ }, -+ onMove: e => { -+ "worklet"; -+ -+ if (freeze.value) { -+ return; -+ } -+ currentHeight.value = getEffectiveHeight(e.height, targetKeyboardHeight.value, offset); - }, -- onMove: () => { -+ onInteractive: e => { - "worklet"; - -- // iOS doesn't need per-frame updates (contentOffset handles it) -+ if (freeze.value) { -+ return; -+ } -+ currentHeight.value = getEffectiveHeight(e.height, targetKeyboardHeight.value, offset); - }, - onEnd: e => { - "worklet"; -@@ -125,9 +141,10 @@ function useChatKeyboard(scrollViewRef, options) { - return; - } - const effective = getEffectiveHeight(e.height, targetKeyboardHeight.value, offset); -+ currentHeight.value = effective; - padding.value = effective; - } -- }, [inverted, keyboardLiftBehavior, offset, extraContentPadding]); -+ }, [inverted, keyboardLiftBehavior, offset, extraContentPadding, adjustedInsetCompensation, adjustedStartInsetCompensation]); - return { - padding, - currentHeight, -diff --git a/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js b/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js -index 1afa50987a8d2a5fe3f36b20945efe804d48a873..7b05d0721c50e118cf78c07913b580a31293db77 100644 ---- a/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js -+++ b/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js -@@ -23,6 +23,8 @@ function useExtraContentPadding(options) { - extraContentPadding, - keyboardPadding, - blankSpace, -+ adjustedInsetCompensation, -+ adjustedStartInsetCompensation, - scroll, - layout, - size, -@@ -62,8 +64,8 @@ function useExtraContentPadding(options) { - } - - // Compute effective delta considering blankSpace floor -- const previousTotal = Math.max(blankSpace.value, keyboardPadding.value + previous); -- const currentTotal = Math.max(blankSpace.value, keyboardPadding.value + current); -+ const previousTotal = Math.max(blankSpace.value, keyboardPadding.value + previous) + adjustedInsetCompensation; -+ const currentTotal = Math.max(blankSpace.value, keyboardPadding.value + current) + adjustedInsetCompensation; - const effectiveDelta = currentTotal - previousTotal; - if (effectiveDelta === 0) { - // blankSpace absorbed the change -@@ -82,11 +84,12 @@ function useExtraContentPadding(options) { - const target = Math.max(scroll.value - effectiveDelta, -currentTotal); - scrollToTarget(target); - } else { -- const maxScroll = Math.max(size.value.height - layout.value.height + currentTotal, 0); -- const target = Math.min(scroll.value + effectiveDelta, maxScroll); -+ const minScroll = -adjustedStartInsetCompensation; -+ const maxScroll = Math.max(size.value.height - layout.value.height + currentTotal, minScroll); -+ const target = Math.max(minScroll, Math.min(scroll.value + effectiveDelta, maxScroll)); - scrollToTarget(target); - } -- }, [inverted, keyboardLiftBehavior]); -+ }, [inverted, keyboardLiftBehavior, adjustedInsetCompensation, adjustedStartInsetCompensation]); - } - export { useExtraContentPadding }; - //# sourceMappingURL=index.js.map -diff --git a/lib/typescript/components/KeyboardChatScrollView/types.d.ts b/lib/typescript/components/KeyboardChatScrollView/types.d.ts -index a036b431f03efb9d5379527c17db6fce62bfee09..5e56bf7edec9161698a745e8e6292bfccd68d3db 100644 ---- a/lib/typescript/components/KeyboardChatScrollView/types.d.ts -+++ b/lib/typescript/components/KeyboardChatScrollView/types.d.ts -@@ -86,6 +86,10 @@ export type KeyboardChatScrollViewProps = { - * Default is `undefined` (equivalent to `0` — no minimum floor). - */ - blankSpace?: SharedValue; -+ /** Extra bottom inset UIKit adds beyond the raw contentInset (safe area). Offset math only. */ -+ adjustedInsetCompensation?: number; -+ /** Leading inset UIKit adds outside raw contentInset. Offset math only. */ -+ adjustedStartInsetCompensation?: number; - /** - * Fires whenever the effective content inset changes — the static `contentInset` - * prop combined with the dynamic keyboard-driven padding. -diff --git a/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/helpers.d.ts b/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/helpers.d.ts -index 2b51cc4737b4a05b5396da31e67e54177f43c498..3acec1fbddee6227915590a6c8d449757cb4d7b2 100644 ---- a/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/helpers.d.ts -+++ b/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/helpers.d.ts -@@ -129,4 +129,4 @@ export declare const clampedScrollTarget: (offsetBeforeScroll: number, keyboardH - * computeIOSContentOffset(100, 300, 1000, 800, false); // 400 - * ``` - */ --export declare const computeIOSContentOffset: (relativeScroll: number, keyboardHeight: number, contentHeight: number, layoutHeight: number, inverted: boolean, totalPaddingForMaxScroll?: number) => number; -+export declare const computeIOSContentOffset: (relativeScroll: number, keyboardHeight: number, contentHeight: number, layoutHeight: number, inverted: boolean, totalPaddingForMaxScroll?: number, startInsetCompensation?: number) => number; -diff --git a/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/types.d.ts b/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/types.d.ts -index aff9b5a8dbc2464546396437eaf6c5ae955b9f29..fdd83953271123be6caefaa786c469f0d92cce2b 100644 ---- a/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/types.d.ts -+++ b/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/types.d.ts -@@ -9,6 +9,10 @@ type UseChatKeyboardOptions = { - blankSpace: SharedValue; - /** Extra content padding shared value — needed on iOS to correctly clamp contentOffset. */ - extraContentPadding: SharedValue; -+ /** Safe-area extra beyond raw contentInset. Offset math only. */ -+ adjustedInsetCompensation: number; -+ /** Leading inset UIKit adds beyond the raw contentInset. Offset math only. */ -+ adjustedStartInsetCompensation: number; - }; - type UseChatKeyboardReturn = { - /** Extra scrollable space (= keyboard height). Used as contentInset on iOS, contentInsetBottom/contentInsetTop on Android. */ -diff --git a/lib/typescript/components/KeyboardChatScrollView/useExtraContentPadding/index.d.ts b/lib/typescript/components/KeyboardChatScrollView/useExtraContentPadding/index.d.ts -index ec73f70544a062fbecfc1d8be92d839d3e0bea6f..45b387446587fd3e611fa02a01534bb5d9fa6bbd 100644 ---- a/lib/typescript/components/KeyboardChatScrollView/useExtraContentPadding/index.d.ts -+++ b/lib/typescript/components/KeyboardChatScrollView/useExtraContentPadding/index.d.ts -@@ -8,6 +8,10 @@ type UseExtraContentPaddingOptions = { - keyboardPadding: SharedValue; - /** Minimum inset floor — used to absorb keyboard and extraContentPadding changes. */ - blankSpace: SharedValue; -+ /** Safe-area extra beyond raw contentInset. Offset math only. */ -+ adjustedInsetCompensation: number; -+ /** Leading inset UIKit adds beyond raw contentInset. Offset math only. */ -+ adjustedStartInsetCompensation: number; - /** Current vertical scroll offset. */ - scroll: SharedValue; - /** Visible viewport dimensions. */ -diff --git a/src/components/KeyboardChatScrollView/index.tsx b/src/components/KeyboardChatScrollView/index.tsx -index 03f5f74e9aaaabc75db1c01643a655ee4fdfa5f2..277a1ecada428ffbae517d6edc720d029c8ecc10 100644 ---- a/src/components/KeyboardChatScrollView/index.tsx -+++ b/src/components/KeyboardChatScrollView/index.tsx -@@ -1,7 +1,9 @@ - import React, { forwardRef, useCallback, useMemo } from "react"; --import { StyleSheet } from "react-native"; -+import { Platform, StyleSheet } from "react-native"; - import { - makeMutable, -+ runOnJS, -+ useAnimatedReaction, - useAnimatedRef, - useAnimatedStyle, - useDerivedValue, -@@ -35,9 +37,12 @@ const KeyboardChatScrollView = forwardRef< - offset = 0, - extraContentPadding = ZERO_CONTENT_PADDING, - blankSpace = ZERO_BLANK_SPACE, -+ adjustedInsetCompensation = 0, -+ adjustedStartInsetCompensation = 0, - applyWorkaroundForContentInsetHitTestBug = false, - onLayout: onLayoutProp, - onContentSizeChange: onContentSizeChangeProp, -+ onContentInsetChange, - onEndVisible, - ...rest - }, -@@ -64,6 +69,8 @@ const KeyboardChatScrollView = forwardRef< - offset, - blankSpace, - extraContentPadding, -+ adjustedInsetCompensation, -+ adjustedStartInsetCompensation, - }); - - useExtraContentPadding({ -@@ -71,6 +78,8 @@ const KeyboardChatScrollView = forwardRef< - extraContentPadding, - keyboardPadding: padding, - blankSpace, -+ adjustedInsetCompensation, -+ adjustedStartInsetCompensation, - scroll, - layout, - size, -@@ -102,13 +111,40 @@ const KeyboardChatScrollView = forwardRef< - ), - ); - -- // Scroll indicator inset = keyboard + extraContentPadding (excludes blankSpace). -- // Apps that render into the unsafe area can supply a negative -- // scrollIndicatorInsets adjustment at the application layer. -- const indicatorPadding = useDerivedValue( -- () => padding.value + extraContentPadding.value, -+ // iOS applies the destination contentInset and contentOffset together at -+ // keyboard-animation start. Keep that native target behavior, but report -+ // the presentation height so virtualized-list layout follows the keyboard. -+ const reportedPadding = useDerivedValue(() => -+ Platform.OS === "ios" -+ ? Math.min( -+ layout.value.height, -+ Math.max( -+ blankSpace.value, -+ currentHeight.value + extraContentPadding.value, -+ ), -+ ) -+ : totalPadding.value, - ); - -+ // Mirror the effective bottom padding (keyboard + composer + blank floor) -+ // to the consumer — a virtualized list needs it in its own scroll math or -+ // its end/maintain targets point at the under-the-keyboard resting offset. -+ useAnimatedReaction( -+ () => reportedPadding.value, -+ (current, previous) => { -+ if (onContentInsetChange && current !== previous) { -+ runOnJS(onContentInsetChange)({ bottom: current }); -+ } -+ }, -+ [onContentInsetChange], -+ ); -+ -+ // Scroll indicator inset = keyboard only (excludes extraContentPadding and -+ // blankSpace): with a floating composer the indicator track should run the -+ // full height of the scroll view, behind the composer, like iOS Messages. -+ // The keyboard still lifts it so it never disappears under the keyboard. -+ const indicatorPadding = useDerivedValue(() => padding.value); -+ - const onLayout = useCallback( - (e: LayoutChangeEvent) => { - onLayoutInternal(e); -diff --git a/src/components/KeyboardChatScrollView/types.ts b/src/components/KeyboardChatScrollView/types.ts -index dd222b57bc7a71729524670bad3812f30920bd73..7be71b5460eb143ddf460ce5c87b843c66bfb2cd 100644 ---- a/src/components/KeyboardChatScrollView/types.ts -+++ b/src/components/KeyboardChatScrollView/types.ts -@@ -90,6 +90,17 @@ export type KeyboardChatScrollViewProps = { - * Default is `undefined` (equivalent to `0` — no minimum floor). - */ - blankSpace?: SharedValue; -+ /** -+ * Extra bottom inset UIKit adds on top of the raw `contentInset` this -+ * component writes (e.g. the home-indicator safe area under -+ * `contentInsetAdjustmentBehavior="automatic"`). Used ONLY in scroll-offset -+ * math (max scroll / end pinning) — never written into `contentInset`. -+ * -+ * Default is `0`. -+ */ -+ adjustedInsetCompensation?: number; -+ /** Leading inset UIKit adds outside raw contentInset. Offset math only. */ -+ adjustedStartInsetCompensation?: number; - /** - * Fires whenever the effective content inset changes — the static `contentInset` - * prop combined with the dynamic keyboard-driven padding. -diff --git a/src/components/KeyboardChatScrollView/useChatKeyboard/helpers.ts b/src/components/KeyboardChatScrollView/useChatKeyboard/helpers.ts -index 37eacd10857cd70c51b3468c4b466e4959d0a415..3d77ab27c614f44b64da8270823942cb670b097b 100644 ---- a/src/components/KeyboardChatScrollView/useChatKeyboard/helpers.ts -+++ b/src/components/KeyboardChatScrollView/useChatKeyboard/helpers.ts -@@ -245,6 +245,7 @@ export const computeIOSContentOffset = ( - layoutHeight: number, - inverted: boolean, - totalPaddingForMaxScroll?: number, -+ startInsetCompensation: number = 0, - ): number => { - "worklet"; - -@@ -262,7 +263,14 @@ export const computeIOSContentOffset = ( - ); - } - -- const maxScroll = Math.max(contentHeight - layoutHeight + paddingForMax, 0); -+ const minScroll = -startInsetCompensation; -+ const maxScroll = Math.max( -+ contentHeight - layoutHeight + paddingForMax, -+ minScroll, -+ ); - -- return Math.min(Math.max(keyboardHeight + relativeScroll, 0), maxScroll); -+ return Math.min( -+ Math.max(keyboardHeight + relativeScroll, minScroll), -+ maxScroll, -+ ); - }; -diff --git a/src/components/KeyboardChatScrollView/useChatKeyboard/index.ios.ts b/src/components/KeyboardChatScrollView/useChatKeyboard/index.ios.ts -index 560df54bae1a8c41a2e9ac0e2a8d2fd9b843968a..c375a8c4cc889c2fc2c0c1034788c605633192ed 100644 ---- a/src/components/KeyboardChatScrollView/useChatKeyboard/index.ios.ts -+++ b/src/components/KeyboardChatScrollView/useChatKeyboard/index.ios.ts -@@ -43,6 +43,8 @@ function useChatKeyboard( - offset, - blankSpace, - extraContentPadding, -+ adjustedInsetCompensation, -+ adjustedStartInsetCompensation, - } = options; - - const padding = useSharedValue(0); -@@ -79,6 +81,10 @@ function useChatKeyboard( - offset, - ); - -+ if (e.duration === 0) { -+ currentHeight.value = effective; -+ } -+ - const atEnd = isScrollAtEnd( - scroll.value, - layout.value.height, -@@ -104,10 +110,12 @@ function useChatKeyboard( - effective, - minimumPaddingAbsorbed, - ); -- const actualTotalPadding = Math.max( -- blankSpace.value, -- effective + extraContentPadding.value, -- ); -+ // UIKit adds adjustedInsetCompensation (safe area) on top of the raw -+ // inset; include it here so end/max-scroll targets match the real -+ // resting offsets. -+ const actualTotalPadding = -+ Math.max(blankSpace.value, effective + extraContentPadding.value) + -+ adjustedInsetCompensation; - - // persistent mode: when keyboard shrinks, clamp to valid range - if ( -@@ -130,11 +138,11 @@ function useChatKeyboard( - } else { - const maxScroll = Math.max( - size.value.height - layout.value.height + actualTotalPadding, -- 0, -+ -adjustedStartInsetCompensation, - ); - - contentOffsetY.value = Math.max( -- 0, -+ -adjustedStartInsetCompensation, - Math.min(scroll.value, maxScroll), - ); - } -@@ -165,11 +173,11 @@ function useChatKeyboard( - } else { - const maxScroll = Math.max( - size.value.height - layout.value.height + actualTotalPadding, -- 0, -+ -adjustedStartInsetCompensation, - ); - - contentOffsetY.value = Math.max( -- 0, -+ -adjustedStartInsetCompensation, - Math.min(scroll.value, maxScroll), - ); - } -@@ -219,12 +227,34 @@ function useChatKeyboard( - layout.value.height, - inverted, - actualTotalPadding, -+ adjustedStartInsetCompensation, - ); - }, -- onMove: () => { -+ onMove: (e) => { - "worklet"; - -- // iOS doesn't need per-frame updates (contentOffset handles it) -+ if (freeze.value) { -+ return; -+ } -+ -+ currentHeight.value = getEffectiveHeight( -+ e.height, -+ targetKeyboardHeight.value, -+ offset, -+ ); -+ }, -+ onInteractive: (e) => { -+ "worklet"; -+ -+ if (freeze.value) { -+ return; -+ } -+ -+ currentHeight.value = getEffectiveHeight( -+ e.height, -+ targetKeyboardHeight.value, -+ offset, -+ ); - }, - onEnd: (e) => { - "worklet"; -@@ -239,10 +269,18 @@ function useChatKeyboard( - offset, - ); - -+ currentHeight.value = effective; - padding.value = effective; - }, - }, -- [inverted, keyboardLiftBehavior, offset, extraContentPadding], -+ [ -+ inverted, -+ keyboardLiftBehavior, -+ offset, -+ extraContentPadding, -+ adjustedInsetCompensation, -+ adjustedStartInsetCompensation, -+ ], - ); - - return { -diff --git a/src/components/KeyboardChatScrollView/useChatKeyboard/types.ts b/src/components/KeyboardChatScrollView/useChatKeyboard/types.ts -index 02abf5cd9490900826678175462b234e07e30e92..4ee0ddd65e0b105568ab43b73997af4be8adae00 100644 ---- a/src/components/KeyboardChatScrollView/useChatKeyboard/types.ts -+++ b/src/components/KeyboardChatScrollView/useChatKeyboard/types.ts -@@ -11,6 +11,10 @@ type UseChatKeyboardOptions = { - blankSpace: SharedValue; - /** Extra content padding shared value — needed on iOS to correctly clamp contentOffset. */ - extraContentPadding: SharedValue; -+ /** Extra bottom inset UIKit adds beyond the raw contentInset (safe area). Offset math only. */ -+ adjustedInsetCompensation: number; -+ /** Leading inset UIKit adds beyond the raw contentInset. Offset math only. */ -+ adjustedStartInsetCompensation: number; - }; - - type UseChatKeyboardReturn = { -diff --git a/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts b/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts -index 833acbe78f1b1245251ddd3431d6546decdd0ade..8f7c10cb6ab392f10df4ca43549b89c25844f0b8 100644 ---- a/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts -+++ b/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts -@@ -16,6 +16,10 @@ type UseExtraContentPaddingOptions = { - keyboardPadding: SharedValue; - /** Minimum inset floor — used to absorb keyboard and extraContentPadding changes. */ - blankSpace: SharedValue; -+ /** Extra bottom inset UIKit adds beyond the raw contentInset (safe area). Offset math only. */ -+ adjustedInsetCompensation: number; -+ /** Leading inset UIKit adds beyond raw contentInset. Offset math only. */ -+ adjustedStartInsetCompensation: number; - /** Current vertical scroll offset. */ - scroll: SharedValue; - /** Visible viewport dimensions. */ -@@ -49,6 +53,8 @@ function useExtraContentPadding(options: UseExtraContentPaddingOptions): void { - extraContentPadding, - keyboardPadding, - blankSpace, -+ adjustedInsetCompensation, -+ adjustedStartInsetCompensation, - scroll, - layout, - size, -@@ -97,14 +103,12 @@ function useExtraContentPadding(options: UseExtraContentPaddingOptions): void { - } - - // Compute effective delta considering blankSpace floor -- const previousTotal = Math.max( -- blankSpace.value, -- keyboardPadding.value + previous, -- ); -- const currentTotal = Math.max( -- blankSpace.value, -- keyboardPadding.value + current, -- ); -+ const previousTotal = -+ Math.max(blankSpace.value, keyboardPadding.value + previous) + -+ adjustedInsetCompensation; -+ const currentTotal = -+ Math.max(blankSpace.value, keyboardPadding.value + current) + -+ adjustedInsetCompensation; - const effectiveDelta = currentTotal - previousTotal; - - if (effectiveDelta === 0) { -@@ -137,16 +141,25 @@ function useExtraContentPadding(options: UseExtraContentPaddingOptions): void { - - scrollToTarget(target); - } else { -+ const minScroll = -adjustedStartInsetCompensation; - const maxScroll = Math.max( - size.value.height - layout.value.height + currentTotal, -- 0, -+ minScroll, -+ ); -+ const target = Math.max( -+ minScroll, -+ Math.min(scroll.value + effectiveDelta, maxScroll), - ); -- const target = Math.min(scroll.value + effectiveDelta, maxScroll); - - scrollToTarget(target); - } - }, -- [inverted, keyboardLiftBehavior], -+ [ -+ inverted, -+ keyboardLiftBehavior, -+ adjustedInsetCompensation, -+ adjustedStartInsetCompensation, -+ ], - ); - } - diff --git a/patches/react-native-keyboard-controller@1.22.4.patch b/patches/react-native-keyboard-controller@1.22.4.patch new file mode 100644 index 0000000000000000000000000000000000000000..58c26f740a6cb8bc34f6673d4c67ed0305cb2901 --- /dev/null +++ b/patches/react-native-keyboard-controller@1.22.4.patch @@ -0,0 +1,885 @@ +diff --git a/lib/commonjs/components/KeyboardChatScrollView/index.js b/lib/commonjs/components/KeyboardChatScrollView/index.js +index 5617394..4f2222a 100644 +--- a/lib/commonjs/components/KeyboardChatScrollView/index.js ++++ b/lib/commonjs/components/KeyboardChatScrollView/index.js +@@ -27,9 +27,12 @@ const KeyboardChatScrollView = /*#__PURE__*/(0, _react.forwardRef)(({ + offset = 0, + extraContentPadding = ZERO_CONTENT_PADDING, + blankSpace = ZERO_BLANK_SPACE, ++ adjustedInsetCompensation = 0, ++ adjustedStartInsetCompensation = 0, + applyWorkaroundForContentInsetHitTestBug = false, + onLayout: onLayoutProp, + onContentSizeChange: onContentSizeChangeProp, ++ onContentInsetChange, + onEndVisible, + ...rest + }, ref) => { +@@ -51,13 +54,17 @@ const KeyboardChatScrollView = /*#__PURE__*/(0, _react.forwardRef)(({ + freeze: freezeSV, + offset, + blankSpace, +- extraContentPadding ++ extraContentPadding, ++ adjustedInsetCompensation, ++ adjustedStartInsetCompensation + }); + (0, _useExtraContentPadding.useExtraContentPadding)({ + scrollViewRef, + extraContentPadding, + keyboardPadding: padding, + blankSpace, ++ adjustedInsetCompensation, ++ adjustedStartInsetCompensation, + scroll, + layout, + size, +@@ -88,10 +95,26 @@ const KeyboardChatScrollView = /*#__PURE__*/(0, _react.forwardRef)(({ + // a bug for you, please open an issue. + const totalPadding = (0, _reactNativeReanimated.useDerivedValue)(() => Math.min(layout.value.height, Math.max(blankSpace.value, padding.value + extraContentPadding.value))); + ++ // iOS applies the destination contentInset and contentOffset together at ++ // keyboard-animation start. Keep that native target behavior, but report ++ // the presentation height so virtualized-list layout follows the keyboard. ++ const reportedPadding = (0, _reactNativeReanimated.useDerivedValue)(() => _reactNative.Platform.OS === "ios" ? Math.min(layout.value.height, Math.max(blankSpace.value, currentHeight.value + extraContentPadding.value)) : totalPadding.value); ++ ++ // Mirror the effective bottom padding (keyboard + composer + blank floor) ++ // to the consumer - a virtualized list needs it in its own scroll math or ++ // its end/maintain targets point at the under-the-keyboard resting offset. ++ (0, _reactNativeReanimated.useAnimatedReaction)(() => reportedPadding.value, (current, previous) => { ++ if (onContentInsetChange && current !== previous) { ++ (0, _reactNativeReanimated.runOnJS)(onContentInsetChange)({ ++ bottom: current ++ }); ++ } ++ }, [onContentInsetChange]); ++ + // Scroll indicator inset = keyboard + extraContentPadding (excludes blankSpace). + // Apps that render into the unsafe area can supply a negative + // scrollIndicatorInsets adjustment at the application layer. +- const indicatorPadding = (0, _reactNativeReanimated.useDerivedValue)(() => padding.value + extraContentPadding.value); ++ const indicatorPadding = (0, _reactNativeReanimated.useDerivedValue)(() => padding.value); + const onLayout = (0, _react.useCallback)(e => { + onLayoutInternal(e); + onLayoutProp === null || onLayoutProp === void 0 || onLayoutProp(e); +diff --git a/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/helpers.js b/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/helpers.js +index 4d33b3f..6a787d3 100644 +--- a/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/helpers.js ++++ b/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/helpers.js +@@ -206,7 +206,7 @@ const clampedScrollTarget = (offsetBeforeScroll, keyboardHeight, contentHeight, + * ``` + */ + exports.clampedScrollTarget = clampedScrollTarget; +-const computeIOSContentOffset = (relativeScroll, keyboardHeight, contentHeight, layoutHeight, inverted, totalPaddingForMaxScroll) => { ++const computeIOSContentOffset = (relativeScroll, keyboardHeight, contentHeight, layoutHeight, inverted, totalPaddingForMaxScroll, startInsetCompensation = 0) => { + "worklet"; + + const paddingForMax = totalPaddingForMaxScroll !== undefined ? totalPaddingForMaxScroll : keyboardHeight; +@@ -214,8 +214,9 @@ const computeIOSContentOffset = (relativeScroll, keyboardHeight, contentHeight, + const maxScroll = Math.max(contentHeight - layoutHeight, 0); + return Math.max(Math.min(relativeScroll - keyboardHeight, maxScroll), -paddingForMax); + } +- const maxScroll = Math.max(contentHeight - layoutHeight + paddingForMax, 0); +- return Math.min(Math.max(keyboardHeight + relativeScroll, 0), maxScroll); ++ const minScroll = -startInsetCompensation; ++ const maxScroll = Math.max(contentHeight - layoutHeight + paddingForMax, minScroll); ++ return Math.min(Math.max(keyboardHeight + relativeScroll, minScroll), maxScroll); + }; + exports.computeIOSContentOffset = computeIOSContentOffset; + //# sourceMappingURL=helpers.js.map +\ No newline at end of file +diff --git a/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js b/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js +index cecee07..533a9e9 100644 +--- a/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js ++++ b/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js +@@ -32,7 +32,9 @@ function useChatKeyboard(scrollViewRef, options) { + freeze, + offset, + blankSpace, +- extraContentPadding ++ extraContentPadding, ++ adjustedInsetCompensation, ++ adjustedStartInsetCompensation + } = options; + const padding = (0, _reactNativeReanimated.useSharedValue)(0); + const currentHeight = (0, _reactNativeReanimated.useSharedValue)(0); +@@ -59,6 +61,9 @@ function useChatKeyboard(scrollViewRef, options) { + targetKeyboardHeight.value = e.height; + } + const effective = (0, _helpers.getEffectiveHeight)(e.height, targetKeyboardHeight.value, offset); ++ if (e.duration === 0) { ++ currentHeight.value = effective; ++ } + const atEnd = (0, _helpers.isScrollAtEnd)(scroll.value, layout.value.height, size.value.height, inverted); + + // Scale minimum padding absorption by how much of it is visible. +@@ -67,7 +72,7 @@ function useChatKeyboard(scrollViewRef, options) { + const visiblePadding = visibleFraction * blankSpace.value; + const minimumPaddingAbsorbed = Math.max(0, visiblePadding - extraContentPadding.value); + const scrollEffective = (0, _helpers.getScrollEffective)(effective, minimumPaddingAbsorbed); +- const actualTotalPadding = Math.max(blankSpace.value, effective + extraContentPadding.value); ++ const actualTotalPadding = Math.max(blankSpace.value, effective + extraContentPadding.value) + adjustedInsetCompensation; + + // `onInteractive` owns the native scroll offset. When its final + // keyboardWillHide event arrives, consume the marker so this +@@ -87,8 +92,8 @@ function useChatKeyboard(scrollViewRef, options) { + const maxScroll = Math.max(size.value.height - layout.value.height, 0); + contentOffsetY.value = Math.max(-actualTotalPadding, Math.min(scroll.value, maxScroll)); + } else { +- const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, 0); +- contentOffsetY.value = Math.max(0, Math.min(scroll.value, maxScroll)); ++ const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, -adjustedStartInsetCompensation); ++ contentOffsetY.value = Math.max(-adjustedStartInsetCompensation, Math.min(scroll.value, maxScroll)); + } + return; + } +@@ -102,8 +107,8 @@ function useChatKeyboard(scrollViewRef, options) { + const maxScroll = Math.max(size.value.height - layout.value.height, 0); + contentOffsetY.value = Math.max(-actualTotalPadding, Math.min(scroll.value, maxScroll)); + } else { +- const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, 0); +- contentOffsetY.value = Math.max(0, Math.min(scroll.value, maxScroll)); ++ const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, -adjustedStartInsetCompensation); ++ contentOffsetY.value = Math.max(-adjustedStartInsetCompensation, Math.min(scroll.value, maxScroll)); + } + return; + } +@@ -129,17 +134,25 @@ function useChatKeyboard(scrollViewRef, options) { + contentOffsetY.value = scroll.value; + return; + } +- contentOffsetY.value = (0, _helpers.computeIOSContentOffset)(relativeScroll, scrollEffective, size.value.height, layout.value.height, inverted, actualTotalPadding); ++ contentOffsetY.value = (0, _helpers.computeIOSContentOffset)(relativeScroll, scrollEffective, size.value.height, layout.value.height, inverted, actualTotalPadding, adjustedStartInsetCompensation); + }, +- onInteractive: () => { ++ onMove: e => { + "worklet"; + +- isInteractiveDismissal.value = true; ++ if (freeze.value) { ++ return; ++ } ++ currentHeight.value = (0, _helpers.getEffectiveHeight)(e.height, targetKeyboardHeight.value, offset); + }, +- onMove: () => { ++ onInteractive: e => { + "worklet"; + +- // iOS doesn't need per-frame updates (contentOffset handles it) ++ isInteractiveDismissal.value = true; ++ ++ if (freeze.value) { ++ return; ++ } ++ currentHeight.value = (0, _helpers.getEffectiveHeight)(e.height, targetKeyboardHeight.value, offset); + }, + onEnd: e => { + "worklet"; +@@ -148,9 +161,10 @@ function useChatKeyboard(scrollViewRef, options) { + return; + } + const effective = (0, _helpers.getEffectiveHeight)(e.height, targetKeyboardHeight.value, offset); ++ currentHeight.value = effective; + padding.value = effective; + } +- }, [inverted, keyboardLiftBehavior, offset, extraContentPadding]); ++ }, [inverted, keyboardLiftBehavior, offset, extraContentPadding, adjustedInsetCompensation, adjustedStartInsetCompensation]); + return { + padding, + currentHeight, +diff --git a/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js b/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js +index 54a1c57..19b44fc 100644 +--- a/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js ++++ b/lib/commonjs/components/KeyboardChatScrollView/useExtraContentPadding/index.js +@@ -31,6 +31,8 @@ function useExtraContentPadding(options) { + extraContentPadding, + keyboardPadding, + blankSpace, ++ adjustedInsetCompensation, ++ adjustedStartInsetCompensation, + scroll, + layout, + size, +@@ -70,8 +72,8 @@ function useExtraContentPadding(options) { + } + + // Compute effective delta considering blankSpace floor +- const previousTotal = Math.max(blankSpace.value, keyboardPadding.value + previous); +- const currentTotal = Math.max(blankSpace.value, keyboardPadding.value + current); ++ const previousTotal = Math.max(blankSpace.value, keyboardPadding.value + previous) + adjustedInsetCompensation; ++ const currentTotal = Math.max(blankSpace.value, keyboardPadding.value + current) + adjustedInsetCompensation; + const effectiveDelta = currentTotal - previousTotal; + if (effectiveDelta === 0) { + // blankSpace absorbed the change +@@ -90,10 +92,11 @@ function useExtraContentPadding(options) { + const target = Math.max(scroll.value - effectiveDelta, -currentTotal); + scrollToTarget(target); + } else { +- const maxScroll = Math.max(size.value.height - layout.value.height + currentTotal, 0); +- const target = Math.min(scroll.value + effectiveDelta, maxScroll); ++ const minScroll = -adjustedStartInsetCompensation; ++ const maxScroll = Math.max(size.value.height - layout.value.height + currentTotal, minScroll); ++ const target = Math.max(minScroll, Math.min(scroll.value + effectiveDelta, maxScroll)); + scrollToTarget(target); + } +- }, [inverted, keyboardLiftBehavior]); ++ }, [inverted, keyboardLiftBehavior, adjustedInsetCompensation, adjustedStartInsetCompensation]); + } + //# sourceMappingURL=index.js.map +\ No newline at end of file +diff --git a/lib/module/components/KeyboardChatScrollView/index.js b/lib/module/components/KeyboardChatScrollView/index.js +index d085394..a57c2f9 100644 +--- a/lib/module/components/KeyboardChatScrollView/index.js ++++ b/lib/module/components/KeyboardChatScrollView/index.js +@@ -1,7 +1,7 @@ + function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } + import React, { forwardRef, useCallback, useMemo } from "react"; +-import { StyleSheet } from "react-native"; +-import { makeMutable, useAnimatedRef, useAnimatedStyle, useDerivedValue } from "react-native-reanimated"; ++import { Platform, StyleSheet } from "react-native"; ++import { makeMutable, runOnJS, useAnimatedReaction, useAnimatedRef, useAnimatedStyle, useDerivedValue } from "react-native-reanimated"; + import Reanimated from "react-native-reanimated"; + import useCombinedRef from "../hooks/useCombinedRef"; + import ScrollViewWithBottomPadding from "../ScrollViewWithBottomPadding"; +@@ -20,9 +20,12 @@ const KeyboardChatScrollView = /*#__PURE__*/forwardRef(({ + offset = 0, + extraContentPadding = ZERO_CONTENT_PADDING, + blankSpace = ZERO_BLANK_SPACE, ++ adjustedInsetCompensation = 0, ++ adjustedStartInsetCompensation = 0, + applyWorkaroundForContentInsetHitTestBug = false, + onLayout: onLayoutProp, + onContentSizeChange: onContentSizeChangeProp, ++ onContentInsetChange, + onEndVisible, + ...rest + }, ref) => { +@@ -44,13 +47,17 @@ const KeyboardChatScrollView = /*#__PURE__*/forwardRef(({ + freeze: freezeSV, + offset, + blankSpace, +- extraContentPadding ++ extraContentPadding, ++ adjustedInsetCompensation, ++ adjustedStartInsetCompensation + }); + useExtraContentPadding({ + scrollViewRef, + extraContentPadding, + keyboardPadding: padding, + blankSpace, ++ adjustedInsetCompensation, ++ adjustedStartInsetCompensation, + scroll, + layout, + size, +@@ -81,10 +88,26 @@ const KeyboardChatScrollView = /*#__PURE__*/forwardRef(({ + // a bug for you, please open an issue. + const totalPadding = useDerivedValue(() => Math.min(layout.value.height, Math.max(blankSpace.value, padding.value + extraContentPadding.value))); + ++ // iOS applies the destination contentInset and contentOffset together at ++ // keyboard-animation start. Keep that native target behavior, but report ++ // the presentation height so virtualized-list layout follows the keyboard. ++ const reportedPadding = useDerivedValue(() => Platform.OS === "ios" ? Math.min(layout.value.height, Math.max(blankSpace.value, currentHeight.value + extraContentPadding.value)) : totalPadding.value); ++ ++ // Mirror the effective bottom padding (keyboard + composer + blank floor) ++ // to the consumer - a virtualized list needs it in its own scroll math or ++ // its end/maintain targets point at the under-the-keyboard resting offset. ++ useAnimatedReaction(() => reportedPadding.value, (current, previous) => { ++ if (onContentInsetChange && current !== previous) { ++ runOnJS(onContentInsetChange)({ ++ bottom: current ++ }); ++ } ++ }, [onContentInsetChange]); ++ + // Scroll indicator inset = keyboard + extraContentPadding (excludes blankSpace). + // Apps that render into the unsafe area can supply a negative + // scrollIndicatorInsets adjustment at the application layer. +- const indicatorPadding = useDerivedValue(() => padding.value + extraContentPadding.value); ++ const indicatorPadding = useDerivedValue(() => padding.value); + const onLayout = useCallback(e => { + onLayoutInternal(e); + onLayoutProp === null || onLayoutProp === void 0 || onLayoutProp(e); +diff --git a/lib/module/components/KeyboardChatScrollView/useChatKeyboard/helpers.js b/lib/module/components/KeyboardChatScrollView/useChatKeyboard/helpers.js +index 295e221..2f7b87e 100644 +--- a/lib/module/components/KeyboardChatScrollView/useChatKeyboard/helpers.js ++++ b/lib/module/components/KeyboardChatScrollView/useChatKeyboard/helpers.js +@@ -193,7 +193,7 @@ export const clampedScrollTarget = (offsetBeforeScroll, keyboardHeight, contentH + * computeIOSContentOffset(100, 300, 1000, 800, false); // 400 + * ``` + */ +-export const computeIOSContentOffset = (relativeScroll, keyboardHeight, contentHeight, layoutHeight, inverted, totalPaddingForMaxScroll) => { ++export const computeIOSContentOffset = (relativeScroll, keyboardHeight, contentHeight, layoutHeight, inverted, totalPaddingForMaxScroll, startInsetCompensation = 0) => { + "worklet"; + + const paddingForMax = totalPaddingForMaxScroll !== undefined ? totalPaddingForMaxScroll : keyboardHeight; +@@ -201,7 +201,8 @@ export const computeIOSContentOffset = (relativeScroll, keyboardHeight, contentH + const maxScroll = Math.max(contentHeight - layoutHeight, 0); + return Math.max(Math.min(relativeScroll - keyboardHeight, maxScroll), -paddingForMax); + } +- const maxScroll = Math.max(contentHeight - layoutHeight + paddingForMax, 0); +- return Math.min(Math.max(keyboardHeight + relativeScroll, 0), maxScroll); ++ const minScroll = -startInsetCompensation; ++ const maxScroll = Math.max(contentHeight - layoutHeight + paddingForMax, minScroll); ++ return Math.min(Math.max(keyboardHeight + relativeScroll, minScroll), maxScroll); + }; + //# sourceMappingURL=helpers.js.map +\ No newline at end of file +diff --git a/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js b/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js +index 407275d..19427d7 100644 +--- a/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js ++++ b/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js +@@ -25,7 +25,9 @@ function useChatKeyboard(scrollViewRef, options) { + freeze, + offset, + blankSpace, +- extraContentPadding ++ extraContentPadding, ++ adjustedInsetCompensation, ++ adjustedStartInsetCompensation + } = options; + const padding = useSharedValue(0); + const currentHeight = useSharedValue(0); +@@ -52,6 +54,9 @@ function useChatKeyboard(scrollViewRef, options) { + targetKeyboardHeight.value = e.height; + } + const effective = getEffectiveHeight(e.height, targetKeyboardHeight.value, offset); ++ if (e.duration === 0) { ++ currentHeight.value = effective; ++ } + const atEnd = isScrollAtEnd(scroll.value, layout.value.height, size.value.height, inverted); + + // Scale minimum padding absorption by how much of it is visible. +@@ -60,7 +65,7 @@ function useChatKeyboard(scrollViewRef, options) { + const visiblePadding = visibleFraction * blankSpace.value; + const minimumPaddingAbsorbed = Math.max(0, visiblePadding - extraContentPadding.value); + const scrollEffective = getScrollEffective(effective, minimumPaddingAbsorbed); +- const actualTotalPadding = Math.max(blankSpace.value, effective + extraContentPadding.value); ++ const actualTotalPadding = Math.max(blankSpace.value, effective + extraContentPadding.value) + adjustedInsetCompensation; + + // `onInteractive` owns the native scroll offset. When its final + // keyboardWillHide event arrives, consume the marker so this +@@ -80,8 +85,8 @@ function useChatKeyboard(scrollViewRef, options) { + const maxScroll = Math.max(size.value.height - layout.value.height, 0); + contentOffsetY.value = Math.max(-actualTotalPadding, Math.min(scroll.value, maxScroll)); + } else { +- const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, 0); +- contentOffsetY.value = Math.max(0, Math.min(scroll.value, maxScroll)); ++ const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, -adjustedStartInsetCompensation); ++ contentOffsetY.value = Math.max(-adjustedStartInsetCompensation, Math.min(scroll.value, maxScroll)); + } + return; + } +@@ -95,8 +100,8 @@ function useChatKeyboard(scrollViewRef, options) { + const maxScroll = Math.max(size.value.height - layout.value.height, 0); + contentOffsetY.value = Math.max(-actualTotalPadding, Math.min(scroll.value, maxScroll)); + } else { +- const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, 0); +- contentOffsetY.value = Math.max(0, Math.min(scroll.value, maxScroll)); ++ const maxScroll = Math.max(size.value.height - layout.value.height + actualTotalPadding, -adjustedStartInsetCompensation); ++ contentOffsetY.value = Math.max(-adjustedStartInsetCompensation, Math.min(scroll.value, maxScroll)); + } + return; + } +@@ -122,17 +127,25 @@ function useChatKeyboard(scrollViewRef, options) { + contentOffsetY.value = scroll.value; + return; + } +- contentOffsetY.value = computeIOSContentOffset(relativeScroll, scrollEffective, size.value.height, layout.value.height, inverted, actualTotalPadding); ++ contentOffsetY.value = computeIOSContentOffset(relativeScroll, scrollEffective, size.value.height, layout.value.height, inverted, actualTotalPadding, adjustedStartInsetCompensation); + }, +- onInteractive: () => { ++ onMove: e => { + "worklet"; + +- isInteractiveDismissal.value = true; ++ if (freeze.value) { ++ return; ++ } ++ currentHeight.value = getEffectiveHeight(e.height, targetKeyboardHeight.value, offset); + }, +- onMove: () => { ++ onInteractive: e => { + "worklet"; + +- // iOS doesn't need per-frame updates (contentOffset handles it) ++ isInteractiveDismissal.value = true; ++ ++ if (freeze.value) { ++ return; ++ } ++ currentHeight.value = getEffectiveHeight(e.height, targetKeyboardHeight.value, offset); + }, + onEnd: e => { + "worklet"; +@@ -141,9 +154,10 @@ function useChatKeyboard(scrollViewRef, options) { + return; + } + const effective = getEffectiveHeight(e.height, targetKeyboardHeight.value, offset); ++ currentHeight.value = effective; + padding.value = effective; + } +- }, [inverted, keyboardLiftBehavior, offset, extraContentPadding]); ++ }, [inverted, keyboardLiftBehavior, offset, extraContentPadding, adjustedInsetCompensation, adjustedStartInsetCompensation]); + return { + padding, + currentHeight, +diff --git a/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js b/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js +index 5885415..6e694fa 100644 +--- a/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js ++++ b/lib/module/components/KeyboardChatScrollView/useExtraContentPadding/index.js +@@ -25,6 +25,8 @@ function useExtraContentPadding(options) { + extraContentPadding, + keyboardPadding, + blankSpace, ++ adjustedInsetCompensation, ++ adjustedStartInsetCompensation, + scroll, + layout, + size, +@@ -64,8 +66,8 @@ function useExtraContentPadding(options) { + } + + // Compute effective delta considering blankSpace floor +- const previousTotal = Math.max(blankSpace.value, keyboardPadding.value + previous); +- const currentTotal = Math.max(blankSpace.value, keyboardPadding.value + current); ++ const previousTotal = Math.max(blankSpace.value, keyboardPadding.value + previous) + adjustedInsetCompensation; ++ const currentTotal = Math.max(blankSpace.value, keyboardPadding.value + current) + adjustedInsetCompensation; + const effectiveDelta = currentTotal - previousTotal; + if (effectiveDelta === 0) { + // blankSpace absorbed the change +@@ -84,11 +86,12 @@ function useExtraContentPadding(options) { + const target = Math.max(scroll.value - effectiveDelta, -currentTotal); + scrollToTarget(target); + } else { +- const maxScroll = Math.max(size.value.height - layout.value.height + currentTotal, 0); +- const target = Math.min(scroll.value + effectiveDelta, maxScroll); ++ const minScroll = -adjustedStartInsetCompensation; ++ const maxScroll = Math.max(size.value.height - layout.value.height + currentTotal, minScroll); ++ const target = Math.max(minScroll, Math.min(scroll.value + effectiveDelta, maxScroll)); + scrollToTarget(target); + } +- }, [inverted, keyboardLiftBehavior]); ++ }, [inverted, keyboardLiftBehavior, adjustedInsetCompensation, adjustedStartInsetCompensation]); + } + export { useExtraContentPadding }; + //# sourceMappingURL=index.js.map +\ No newline at end of file +diff --git a/lib/typescript/components/KeyboardChatScrollView/types.d.ts b/lib/typescript/components/KeyboardChatScrollView/types.d.ts +index eba1514..6597d80 100644 +--- a/lib/typescript/components/KeyboardChatScrollView/types.d.ts ++++ b/lib/typescript/components/KeyboardChatScrollView/types.d.ts +@@ -88,6 +88,10 @@ export type KeyboardChatScrollViewProps = { + * Default is `undefined` (equivalent to `0` — no minimum floor). + */ + blankSpace?: SharedValue; ++ /** Extra bottom inset UIKit adds beyond the raw contentInset (safe area). Offset math only. */ ++ adjustedInsetCompensation?: number; ++ /** Leading inset UIKit adds outside raw contentInset. Offset math only. */ ++ adjustedStartInsetCompensation?: number; + /** + * Fires whenever the effective content inset changes — the static `contentInset` + * prop combined with the dynamic keyboard-driven padding. +diff --git a/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/helpers.d.ts b/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/helpers.d.ts +index 2b51cc4..3acec1f 100644 +--- a/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/helpers.d.ts ++++ b/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/helpers.d.ts +@@ -129,4 +129,4 @@ export declare const clampedScrollTarget: (offsetBeforeScroll: number, keyboardH + * computeIOSContentOffset(100, 300, 1000, 800, false); // 400 + * ``` + */ +-export declare const computeIOSContentOffset: (relativeScroll: number, keyboardHeight: number, contentHeight: number, layoutHeight: number, inverted: boolean, totalPaddingForMaxScroll?: number) => number; ++export declare const computeIOSContentOffset: (relativeScroll: number, keyboardHeight: number, contentHeight: number, layoutHeight: number, inverted: boolean, totalPaddingForMaxScroll?: number, startInsetCompensation?: number) => number; +diff --git a/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/types.d.ts b/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/types.d.ts +index aff9b5a..fdd8395 100644 +--- a/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/types.d.ts ++++ b/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/types.d.ts +@@ -9,6 +9,10 @@ type UseChatKeyboardOptions = { + blankSpace: SharedValue; + /** Extra content padding shared value — needed on iOS to correctly clamp contentOffset. */ + extraContentPadding: SharedValue; ++ /** Safe-area extra beyond raw contentInset. Offset math only. */ ++ adjustedInsetCompensation: number; ++ /** Leading inset UIKit adds beyond the raw contentInset. Offset math only. */ ++ adjustedStartInsetCompensation: number; + }; + type UseChatKeyboardReturn = { + /** Extra scrollable space (= keyboard height). Used as contentInset on iOS, contentInsetBottom/contentInsetTop on Android. */ +diff --git a/lib/typescript/components/KeyboardChatScrollView/useExtraContentPadding/index.d.ts b/lib/typescript/components/KeyboardChatScrollView/useExtraContentPadding/index.d.ts +index ec73f70..45b3874 100644 +--- a/lib/typescript/components/KeyboardChatScrollView/useExtraContentPadding/index.d.ts ++++ b/lib/typescript/components/KeyboardChatScrollView/useExtraContentPadding/index.d.ts +@@ -8,6 +8,10 @@ type UseExtraContentPaddingOptions = { + keyboardPadding: SharedValue; + /** Minimum inset floor — used to absorb keyboard and extraContentPadding changes. */ + blankSpace: SharedValue; ++ /** Safe-area extra beyond raw contentInset. Offset math only. */ ++ adjustedInsetCompensation: number; ++ /** Leading inset UIKit adds beyond raw contentInset. Offset math only. */ ++ adjustedStartInsetCompensation: number; + /** Current vertical scroll offset. */ + scroll: SharedValue; + /** Visible viewport dimensions. */ +diff --git a/src/components/KeyboardChatScrollView/index.tsx b/src/components/KeyboardChatScrollView/index.tsx +index 554b38c..725d546 100644 +--- a/src/components/KeyboardChatScrollView/index.tsx ++++ b/src/components/KeyboardChatScrollView/index.tsx +@@ -1,7 +1,9 @@ + import React, { forwardRef, useCallback, useMemo } from "react"; +-import { StyleSheet } from "react-native"; ++import { Platform, StyleSheet } from "react-native"; + import { + makeMutable, ++ runOnJS, ++ useAnimatedReaction, + useAnimatedRef, + useAnimatedStyle, + useDerivedValue, +@@ -39,9 +41,12 @@ const KeyboardChatScrollView: React.ForwardRefExoticComponent< + offset = 0, + extraContentPadding = ZERO_CONTENT_PADDING, + blankSpace = ZERO_BLANK_SPACE, ++ adjustedInsetCompensation = 0, ++ adjustedStartInsetCompensation = 0, + applyWorkaroundForContentInsetHitTestBug = false, + onLayout: onLayoutProp, + onContentSizeChange: onContentSizeChangeProp, ++ onContentInsetChange, + onEndVisible, + ...rest + }, +@@ -68,6 +73,8 @@ const KeyboardChatScrollView: React.ForwardRefExoticComponent< + offset, + blankSpace, + extraContentPadding, ++ adjustedInsetCompensation, ++ adjustedStartInsetCompensation, + }); + + useExtraContentPadding({ +@@ -75,6 +82,8 @@ const KeyboardChatScrollView: React.ForwardRefExoticComponent< + extraContentPadding, + keyboardPadding: padding, + blankSpace, ++ adjustedInsetCompensation, ++ adjustedStartInsetCompensation, + scroll, + layout, + size, +@@ -112,13 +121,40 @@ const KeyboardChatScrollView: React.ForwardRefExoticComponent< + ), + ); + +- // Scroll indicator inset = keyboard + extraContentPadding (excludes blankSpace). +- // Apps that render into the unsafe area can supply a negative +- // scrollIndicatorInsets adjustment at the application layer. +- const indicatorPadding = useDerivedValue( +- () => padding.value + extraContentPadding.value, ++ // iOS applies the destination contentInset and contentOffset together at ++ // keyboard-animation start. Keep that native target behavior, but report ++ // the presentation height so virtualized-list layout follows the keyboard. ++ const reportedPadding = useDerivedValue(() => ++ Platform.OS === "ios" ++ ? Math.min( ++ layout.value.height, ++ Math.max( ++ blankSpace.value, ++ currentHeight.value + extraContentPadding.value, ++ ), ++ ) ++ : totalPadding.value, + ); + ++ // Mirror the effective bottom padding (keyboard + composer + blank floor) ++ // to the consumer — a virtualized list needs it in its own scroll math or ++ // its end/maintain targets point at the under-the-keyboard resting offset. ++ useAnimatedReaction( ++ () => reportedPadding.value, ++ (current, previous) => { ++ if (onContentInsetChange && current !== previous) { ++ runOnJS(onContentInsetChange)({ bottom: current }); ++ } ++ }, ++ [onContentInsetChange], ++ ); ++ ++ // Scroll indicator inset = keyboard only (excludes extraContentPadding and ++ // blankSpace): with a floating composer the indicator track should run the ++ // full height of the scroll view, behind the composer, like iOS Messages. ++ // The keyboard still lifts it so it never disappears under the keyboard. ++ const indicatorPadding = useDerivedValue(() => padding.value); ++ + const onLayout = useCallback( + (e: LayoutChangeEvent) => { + onLayoutInternal(e); +diff --git a/src/components/KeyboardChatScrollView/types.ts b/src/components/KeyboardChatScrollView/types.ts +index b7c98c8..e1012a8 100644 +--- a/src/components/KeyboardChatScrollView/types.ts ++++ b/src/components/KeyboardChatScrollView/types.ts +@@ -93,6 +93,17 @@ export type KeyboardChatScrollViewProps = { + * Default is `undefined` (equivalent to `0` — no minimum floor). + */ + blankSpace?: SharedValue; ++ /** ++ * Extra bottom inset UIKit adds on top of the raw `contentInset` this ++ * component writes (e.g. the home-indicator safe area under ++ * `contentInsetAdjustmentBehavior="automatic"`). Used ONLY in scroll-offset ++ * math (max scroll / end pinning) — never written into `contentInset`. ++ * ++ * Default is `0`. ++ */ ++ adjustedInsetCompensation?: number; ++ /** Leading inset UIKit adds outside raw contentInset. Offset math only. */ ++ adjustedStartInsetCompensation?: number; + /** + * Fires whenever the effective content inset changes — the static `contentInset` + * prop combined with the dynamic keyboard-driven padding. +diff --git a/src/components/KeyboardChatScrollView/useChatKeyboard/helpers.ts b/src/components/KeyboardChatScrollView/useChatKeyboard/helpers.ts +index 37eacd1..3d77ab2 100644 +--- a/src/components/KeyboardChatScrollView/useChatKeyboard/helpers.ts ++++ b/src/components/KeyboardChatScrollView/useChatKeyboard/helpers.ts +@@ -245,6 +245,7 @@ export const computeIOSContentOffset = ( + layoutHeight: number, + inverted: boolean, + totalPaddingForMaxScroll?: number, ++ startInsetCompensation: number = 0, + ): number => { + "worklet"; + +@@ -262,7 +263,14 @@ export const computeIOSContentOffset = ( + ); + } + +- const maxScroll = Math.max(contentHeight - layoutHeight + paddingForMax, 0); ++ const minScroll = -startInsetCompensation; ++ const maxScroll = Math.max( ++ contentHeight - layoutHeight + paddingForMax, ++ minScroll, ++ ); + +- return Math.min(Math.max(keyboardHeight + relativeScroll, 0), maxScroll); ++ return Math.min( ++ Math.max(keyboardHeight + relativeScroll, minScroll), ++ maxScroll, ++ ); + }; +diff --git a/src/components/KeyboardChatScrollView/useChatKeyboard/index.ios.ts b/src/components/KeyboardChatScrollView/useChatKeyboard/index.ios.ts +index 129a74b..168ce1a 100644 +--- a/src/components/KeyboardChatScrollView/useChatKeyboard/index.ios.ts ++++ b/src/components/KeyboardChatScrollView/useChatKeyboard/index.ios.ts +@@ -43,6 +43,8 @@ function useChatKeyboard( + offset, + blankSpace, + extraContentPadding, ++ adjustedInsetCompensation, ++ adjustedStartInsetCompensation, + } = options; + + const padding = useSharedValue(0); +@@ -80,6 +82,10 @@ function useChatKeyboard( + offset, + ); + ++ if (e.duration === 0) { ++ currentHeight.value = effective; ++ } ++ + const atEnd = isScrollAtEnd( + scroll.value, + layout.value.height, +@@ -105,10 +111,12 @@ function useChatKeyboard( + effective, + minimumPaddingAbsorbed, + ); +- const actualTotalPadding = Math.max( +- blankSpace.value, +- effective + extraContentPadding.value, +- ); ++ // UIKit adds adjustedInsetCompensation (safe area) on top of the raw ++ // inset; include it here so end/max-scroll targets match the real ++ // resting offsets. ++ const actualTotalPadding = ++ Math.max(blankSpace.value, effective + extraContentPadding.value) + ++ adjustedInsetCompensation; + + // `onInteractive` owns the native scroll offset. When its final + // keyboardWillHide event arrives, consume the marker so this +@@ -142,11 +150,11 @@ function useChatKeyboard( + } else { + const maxScroll = Math.max( + size.value.height - layout.value.height + actualTotalPadding, +- 0, ++ -adjustedStartInsetCompensation, + ); + + contentOffsetY.value = Math.max( +- 0, ++ -adjustedStartInsetCompensation, + Math.min(scroll.value, maxScroll), + ); + } +@@ -177,11 +185,11 @@ function useChatKeyboard( + } else { + const maxScroll = Math.max( + size.value.height - layout.value.height + actualTotalPadding, +- 0, ++ -adjustedStartInsetCompensation, + ); + + contentOffsetY.value = Math.max( +- 0, ++ -adjustedStartInsetCompensation, + Math.min(scroll.value, maxScroll), + ); + } +@@ -231,17 +239,36 @@ function useChatKeyboard( + layout.value.height, + inverted, + actualTotalPadding, ++ adjustedStartInsetCompensation, + ); + }, +- onInteractive: () => { ++ onMove: (e) => { + "worklet"; + +- isInteractiveDismissal.value = true; ++ if (freeze.value) { ++ return; ++ } ++ ++ currentHeight.value = getEffectiveHeight( ++ e.height, ++ targetKeyboardHeight.value, ++ offset, ++ ); + }, +- onMove: () => { ++ onInteractive: (e) => { + "worklet"; + +- // iOS doesn't need per-frame updates (contentOffset handles it) ++ isInteractiveDismissal.value = true; ++ ++ if (freeze.value) { ++ return; ++ } ++ ++ currentHeight.value = getEffectiveHeight( ++ e.height, ++ targetKeyboardHeight.value, ++ offset, ++ ); + }, + onEnd: (e) => { + "worklet"; +@@ -256,10 +283,18 @@ function useChatKeyboard( + offset, + ); + ++ currentHeight.value = effective; + padding.value = effective; + }, + }, +- [inverted, keyboardLiftBehavior, offset, extraContentPadding], ++ [ ++ inverted, ++ keyboardLiftBehavior, ++ offset, ++ extraContentPadding, ++ adjustedInsetCompensation, ++ adjustedStartInsetCompensation, ++ ], + ); + + return { +diff --git a/src/components/KeyboardChatScrollView/useChatKeyboard/types.ts b/src/components/KeyboardChatScrollView/useChatKeyboard/types.ts +index 02abf5c..4ee0ddd 100644 +--- a/src/components/KeyboardChatScrollView/useChatKeyboard/types.ts ++++ b/src/components/KeyboardChatScrollView/useChatKeyboard/types.ts +@@ -11,6 +11,10 @@ type UseChatKeyboardOptions = { + blankSpace: SharedValue; + /** Extra content padding shared value — needed on iOS to correctly clamp contentOffset. */ + extraContentPadding: SharedValue; ++ /** Extra bottom inset UIKit adds beyond the raw contentInset (safe area). Offset math only. */ ++ adjustedInsetCompensation: number; ++ /** Leading inset UIKit adds beyond the raw contentInset. Offset math only. */ ++ adjustedStartInsetCompensation: number; + }; + + type UseChatKeyboardReturn = { +diff --git a/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts b/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts +index c9c93f3..76a201d 100644 +--- a/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts ++++ b/src/components/KeyboardChatScrollView/useExtraContentPadding/index.ts +@@ -16,6 +16,10 @@ type UseExtraContentPaddingOptions = { + keyboardPadding: SharedValue; + /** Minimum inset floor — used to absorb keyboard and extraContentPadding changes. */ + blankSpace: SharedValue; ++ /** Extra bottom inset UIKit adds beyond the raw contentInset (safe area). Offset math only. */ ++ adjustedInsetCompensation: number; ++ /** Leading inset UIKit adds beyond raw contentInset. Offset math only. */ ++ adjustedStartInsetCompensation: number; + /** Current vertical scroll offset. */ + scroll: SharedValue; + /** Visible viewport dimensions. */ +@@ -51,6 +55,8 @@ function useExtraContentPadding(options: UseExtraContentPaddingOptions): void { + extraContentPadding, + keyboardPadding, + blankSpace, ++ adjustedInsetCompensation, ++ adjustedStartInsetCompensation, + scroll, + layout, + size, +@@ -99,14 +105,12 @@ function useExtraContentPadding(options: UseExtraContentPaddingOptions): void { + } + + // Compute effective delta considering blankSpace floor +- const previousTotal = Math.max( +- blankSpace.value, +- keyboardPadding.value + previous, +- ); +- const currentTotal = Math.max( +- blankSpace.value, +- keyboardPadding.value + current, +- ); ++ const previousTotal = ++ Math.max(blankSpace.value, keyboardPadding.value + previous) + ++ adjustedInsetCompensation; ++ const currentTotal = ++ Math.max(blankSpace.value, keyboardPadding.value + current) + ++ adjustedInsetCompensation; + const effectiveDelta = currentTotal - previousTotal; + + if (effectiveDelta === 0) { +@@ -139,16 +143,25 @@ function useExtraContentPadding(options: UseExtraContentPaddingOptions): void { + + scrollToTarget(target); + } else { ++ const minScroll = -adjustedStartInsetCompensation; + const maxScroll = Math.max( + size.value.height - layout.value.height + currentTotal, +- 0, ++ minScroll, ++ ); ++ const target = Math.max( ++ minScroll, ++ Math.min(scroll.value + effectiveDelta, maxScroll), + ); +- const target = Math.min(scroll.value + effectiveDelta, maxScroll); + + scrollToTarget(target); + } + }, +- [inverted, keyboardLiftBehavior], ++ [ ++ inverted, ++ keyboardLiftBehavior, ++ adjustedInsetCompensation, ++ adjustedStartInsetCompensation, ++ ], + ); + } + diff --git a/patches/react-native-nitro-modules@0.35.9.patch b/patches/react-native-nitro-modules@0.35.9.patch index d70069dd4d1a9d0e83f5006b19b34fbd2b279d78..a58d3d5f97ee9648f4a99cf22afba5bc32f2ed56 100644 --- a/patches/react-native-nitro-modules@0.35.9.patch +++ b/patches/react-native-nitro-modules@0.35.9.patch @@ -1,3 +1,19 @@ +diff --git a/ios/turbomodule/NativeNitroModules+NewArch.mm b/ios/turbomodule/NativeNitroModules+NewArch.mm +--- a/ios/turbomodule/NativeNitroModules+NewArch.mm ++++ b/ios/turbomodule/NativeNitroModules+NewArch.mm +@@ -34,6 +34,12 @@ + } + RCT_EXPORT_MODULE(NitroModules) + ++// RN 0.87+ passes the CallInvoker directly when installing JSI bindings. ++- (void)installJSIBindingsWithRuntime:(jsi::Runtime&)runtime callInvoker:(const std::shared_ptr&)callInvoker { ++ _callInvoker = callInvoker; ++ [self installJSIBindingsWithRuntime:runtime]; ++} ++ + - (void)installJSIBindingsWithRuntime:(jsi::Runtime&)runtime { + // 1. Get CallInvoker we cached statically + std::shared_ptr callInvoker = _callInvoker.lock(); diff --git a/package.json b/package.json index 4e4366fb9d05a6c250acfc62e79487475d8ac05b..200e4680d77cbb4f14d22eb986efde1275a0d3e8 100644 --- a/package.json diff --git a/patches/react-native-reanimated@4.5.5.patch b/patches/react-native-reanimated@4.5.5.patch deleted file mode 100644 index c0cc66e407892efef272c2e10aa0a87ce01c501e..0000000000000000000000000000000000000000 --- a/patches/react-native-reanimated@4.5.5.patch +++ /dev/null @@ -1,69 +0,0 @@ -diff --git a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h -index 20d042b00e4655a6647eff1a9a0890fae7e45175..fd08d36fd6c1f79adcfa0dc675420e42a9815d25 100644 ---- a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h -+++ b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h -@@ -22,6 +22,7 @@ struct LayoutAnimation { - Tag parentTag; - std::optional opacity; - bool isViewAlreadyMounted = false; -+ bool isExitingWhenSettled = false; - int count = 1; - LayoutAnimation &operator=(const LayoutAnimation &other) = default; - -diff --git a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.cpp b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.cpp -index 0f08622518910486bb724b664e0a5dd692470b18..9f71dbc301e77656ab0c5dc453ade03eea7649f8 100644 ---- a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.cpp -+++ b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.cpp -@@ -353,6 +353,7 @@ std::optional LayoutAnimationsProxy_Experimental::endLayoutAnimation( - if (--layoutAnimation.count > 0) { - return {}; - } -+ layoutAnimation.isExitingWhenSettled = shouldRemove; - maybeSettledAnimationTags_.insert(tag); - auto surfaceId = layoutAnimation.finalView.surfaceId; - -@@ -478,7 +479,8 @@ void LayoutAnimationsProxy_Experimental::addOngoingAnimations(SurfaceId surfaceI - - const auto layoutAnimationIt = layoutAnimations_.find(tag); - -- if (layoutAnimationIt == layoutAnimations_.end() || layoutAnimationIt->second.isSettled()) { -+ if (layoutAnimationIt == layoutAnimations_.end() || -+ (layoutAnimationIt->second.isSettled() && layoutAnimationIt->second.isExitingWhenSettled)) { - continue; - } - -@@ -635,6 +637,8 @@ void LayoutAnimationsProxy_Experimental::maybeCancelAnimation(const int tag) con - } - if (layoutAnimationIt->second.isSettled()) { - // Already settled - cleanupAnimations will erase it together with its updateMap entry. -+ // Do not flush a pending Update after the caller queues this view for removal. -+ layoutAnimationIt->second.isExitingWhenSettled = true; - return; - } - layoutAnimations_.erase(layoutAnimationIt); -diff --git a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp -index f9711f4eb6185ea99e08280ff90edd45e4152e12..ca812666ca54ec55d9d4409910b21ae97c721f2f 100644 ---- a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp -+++ b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp -@@ -228,6 +228,7 @@ std::optional LayoutAnimationsProxy_Legacy::endLayoutAnimation(int ta - if (--layoutAnimation.count > 0) { - return {}; - } -+ layoutAnimation.isExitingWhenSettled = shouldRemove; - maybeSettledAnimationTags_.insert(tag); - auto surfaceId = layoutAnimation.finalView.surfaceId; - -@@ -531,12 +532,7 @@ void LayoutAnimationsProxy_Legacy::addOngoingAnimations(SurfaceId surfaceId, Sha - auto layoutAnimationIt = layoutAnimations_.find(tag); - - if (layoutAnimationIt == layoutAnimations_.end() || -- // A settled animation is normally cleaned up without applying further -- // updates. The exception is a flaky entering animation whose opacity was -- // never restored (the view wasn't mounted in time) - we still need to -- // apply that pending opacity, otherwise the view stays invisible. Only -- // entering animations carry an opacity value. -- (layoutAnimationIt->second.isSettled() && !layoutAnimationIt->second.opacity.has_value())) { -+ (layoutAnimationIt->second.isSettled() && layoutAnimationIt->second.isExitingWhenSettled)) { - continue; - } - diff --git a/patches/react-native-screens@4.26.2.patch b/patches/react-native-screens@4.26.2.patch deleted file mode 100644 index 9212cfc7b0ff2a6060a17dd936d3d900b1cee802..0000000000000000000000000000000000000000 --- a/patches/react-native-screens@4.26.2.patch +++ /dev/null @@ -1,2226 +0,0 @@ -diff --git a/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt b/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt -index fa1b77317f609983ae2434764174072e51130550..270c81c90971b0ff3038b999973dd4d128a9d140 100644 ---- a/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt -+++ b/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt -@@ -124,6 +124,34 @@ class ScreenStackHeaderConfigViewManager : - config.setTitle(title) - } - -+ // The t3 patch adds these iOS glass-chrome props to the native spec; they have -+ // no Android implementation, but the codegen-generated interface requires the -+ // setters to exist. No-ops keep the Android build compiling. -+ override fun setSubtitle( -+ config: ScreenStackHeaderConfig, -+ subtitle: String?, -+ ) = Unit -+ -+ override fun setLargeSubtitle( -+ config: ScreenStackHeaderConfig, -+ largeSubtitle: String?, -+ ) = Unit -+ -+ override fun setNavigationItemStyle( -+ config: ScreenStackHeaderConfig, -+ navigationItemStyle: String?, -+ ) = Unit -+ -+ override fun setHeaderCenterBarButtonItems( -+ config: ScreenStackHeaderConfig, -+ headerCenterBarButtonItems: ReadableArray?, -+ ) = Unit -+ -+ override fun setHeaderToolbarItems( -+ config: ScreenStackHeaderConfig, -+ headerToolbarItems: ReadableArray?, -+ ) = Unit -+ - override fun setTitleFontFamily( - config: ScreenStackHeaderConfig, - titleFontFamily: String?, -diff --git a/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt b/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt -index 64f14f0c5ade16eb9519b8780d4ce013f88fbd3a..6cb1d69f97a95759c662a6006a9626925d9fefd9 100644 ---- a/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt -+++ b/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt -@@ -47,6 +47,12 @@ class ScreenStackHeaderSubviewManager : - Log.w("[RNScreens]", "hidesSharedBackground prop is not available on Android") - } - -+ // Bar button transition identifiers only apply on iOS. -+ override fun setIdentifier( -+ view: ScreenStackHeaderSubview, -+ identifier: String?, -+ ) = Unit -+ - // synchronousShadowStateUpdatesEnabled is not available on Android atm, - // however we must override their setters - override fun setSynchronousShadowStateUpdatesEnabled( -diff --git a/ios/RNSBarButtonItem.h b/ios/RNSBarButtonItem.h -index a26d1254eafd89268f65d968988cf6a3b8c1e457..62eea42ac26c532801189556c5f51012c3df3a52 100644 ---- a/ios/RNSBarButtonItem.h -+++ b/ios/RNSBarButtonItem.h -@@ -15,6 +15,10 @@ typedef void (^RNSBarButtonMenuItemAction)(NSString *menuId); - action:(RNSBarButtonItemAction)action - menuAction:(RNSBarButtonMenuItemAction)menuAction - imageLoader:(RCTImageLoader *)imageLoader; -+ -++ (UIMenu *)initUIMenuWithDict:(NSDictionary *)dict -+ menuAction:(RNSBarButtonMenuItemAction)menuAction -+ imageLoader:(RCTImageLoader *)imageLoader; - #endif // defined(__cplusplus) - - @end -diff --git a/ios/RNSBarButtonItem.mm b/ios/RNSBarButtonItem.mm -index 0eb1f09dee82edd99e3e614938233db5cdeaebfe..73298f10807520970f625e166d7f5dd1338206f1 100644 ---- a/ios/RNSBarButtonItem.mm -+++ b/ios/RNSBarButtonItem.mm -@@ -110,6 +110,58 @@ - (instancetype)initWithConfig:(NSDictionary *)dict - if (dict[@"accessibilityHint"]) { - self.accessibilityHint = dict[@"accessibilityHint"]; - } -+#if !TARGET_OS_TV && RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) -+ NSNumber *glassEffectNum = dict[@"glassEffect"]; -+ if (@available(iOS 26.0, *)) { -+ if ([glassEffectNum boolValue]) { -+ UIButtonConfiguration *configuration = [UIButtonConfiguration glassButtonConfiguration]; -+ configuration.cornerStyle = UIButtonConfigurationCornerStyleCapsule; -+ UIBackgroundConfiguration *background = configuration.background; -+ background.strokeWidth = 0.0; -+ background.strokeColor = UIColor.clearColor; -+ configuration.background = background; -+ configuration.contentInsets = NSDirectionalEdgeInsetsZero; -+ if (title != nil) { -+ configuration.title = title; -+ } -+ -+ UIButton *button = [UIButton buttonWithConfiguration:configuration primaryAction:nil]; -+ button.translatesAutoresizingMaskIntoConstraints = NO; -+ button.enabled = self.enabled; -+ button.accessibilityLabel = self.accessibilityLabel; -+ button.accessibilityHint = self.accessibilityHint; -+ -+ CGFloat resolvedWidth = width != nil ? width.doubleValue : 56.0; -+ [button.widthAnchor constraintEqualToConstant:resolvedWidth].active = YES; -+ [button.heightAnchor constraintEqualToConstant:50.0].active = YES; -+ -+ [[self class] resolveImageFromConfig:dict -+ imageLoader:imageLoader -+ completionBlock:^(UIImage *img) { -+ UIButtonConfiguration *updatedConfiguration = button.configuration; -+ updatedConfiguration.image = img; -+ button.configuration = updatedConfiguration; -+ }]; -+ -+ NSDictionary *menu = dict[@"menu"]; -+ if (menu) { -+ button.menu = [[self class] initUIMenuWithDict:menu menuAction:menuAction imageLoader:imageLoader]; -+ button.showsMenuAsPrimaryAction = YES; -+ } else { -+ NSString *buttonId = dict[@"buttonId"]; -+ if (buttonId && action) { -+ UIAction *pressAction = [UIAction actionWithHandler:^(__kindof UIAction *_Nonnull sender) { -+ action(buttonId); -+ }]; -+ [button addAction:pressAction forControlEvents:UIControlEventTouchUpInside]; -+ } -+ } -+ -+ self.customView = button; -+ return self; -+ } -+ } -+#endif - - #if !TARGET_OS_TV || __TV_OS_VERSION_MAX_ALLOWED >= 170000 - if (@available(tvOS 17.0, *)) { -diff --git a/ios/RNSScreenStackHeaderConfig.h b/ios/RNSScreenStackHeaderConfig.h -index 8a41697223f6c4b5cb2dd6d450fc58cbb3b27536..309ba2f762068dcf452c172f7c7cbf2a55d03cb2 100644 ---- a/ios/RNSScreenStackHeaderConfig.h -+++ b/ios/RNSScreenStackHeaderConfig.h -@@ -23,6 +23,8 @@ - NS_ASSUME_NONNULL_BEGIN - - @property (nonatomic, retain) NSString *title; -+@property (nonatomic, retain) NSString *subtitle; -+@property (nonatomic, retain) NSString *largeSubtitle; - @property (nonatomic, retain) NSString *titleFontFamily; - @property (nonatomic, retain) NSNumber *titleFontSize; - @property (nonatomic, retain) NSString *titleFontWeight; -@@ -47,9 +49,12 @@ NS_ASSUME_NONNULL_BEGIN - @property (nonatomic) BOOL backButtonInCustomView; - @property (nonatomic) UISemanticContentAttribute direction; - @property (nonatomic) UINavigationItemBackButtonDisplayMode backButtonDisplayMode; -+@property (nonatomic) NSInteger navigationItemStyle; - @property (nonatomic) RNSBlurEffectStyle blurEffect; - @property (nonatomic, copy, nullable) NSArray *> *headerRightBarButtonItems; - @property (nonatomic, copy, nullable) NSArray *> *headerLeftBarButtonItems; -+@property (nonatomic, copy, nullable) NSArray *> *headerCenterBarButtonItems; -+@property (nonatomic, copy, nullable) NSArray *> *headerToolbarItems; - @property (nonatomic, readwrite) BOOL synchronousShadowStateUpdatesEnabled; - - NS_ASSUME_NONNULL_END -diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm -index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..a60b96b44e85d3f4b29dc0d190b95ab60e185033 100644 ---- a/ios/RNSScreenStackHeaderConfig.mm -+++ b/ios/RNSScreenStackHeaderConfig.mm -@@ -24,11 +24,46 @@ - #import "RNSSearchBar.h" - #import "UINavigationBar+RNSUtility.h" - -+#import -+ - namespace react = facebook::react; - - static const NSNumber *const DEFAULT_TITLE_FONT_SIZE = @17; -+ -+#if !TARGET_OS_TV -+// Each placement keeps its own cache so changes to one side do not move live -+// items on the other side into new groups during a navigation transition. -+static char RNSAppliedLeadingHeaderItemsKey; -+static char RNSAppliedTrailingHeaderItemsKey; -+static char RNSAppliedCenterHeaderItemsKey; -+ -+// Records a placement's owner and contents, returning whether they changed. -+static BOOL RNSUpdateHeaderItemsCache(UINavigationItem *navitem, const void *key, NSArray *itemsKey) -+{ -+ if ([objc_getAssociatedObject(navitem, key) isEqual:itemsKey]) { -+ return NO; -+ } -+ objc_setAssociatedObject(navitem, key, itemsKey, OBJC_ASSOCIATION_RETAIN_NONATOMIC); -+ return YES; -+} -+#endif -+static char RNSAppliedToolbarConfigsKey; - static const NSNumber *const DEFAULT_TITLE_LARGE_FONT_SIZE = @34; - -+static NSInteger navigationItemStyleFromCppEquivalent( -+ react::RNSScreenStackHeaderConfigNavigationItemStyle navigationItemStyle) -+{ -+ switch (navigationItemStyle) { -+ case react::RNSScreenStackHeaderConfigNavigationItemStyle::Browser: -+ return UINavigationItemStyleBrowser; -+ case react::RNSScreenStackHeaderConfigNavigationItemStyle::Editor: -+ return UINavigationItemStyleEditor; -+ case react::RNSScreenStackHeaderConfigNavigationItemStyle::Navigator: -+ default: -+ return UINavigationItemStyleNavigator; -+ } -+} -+ - @interface RCTImageLoader (Private) - - (id)imageCache; - @end -@@ -46,6 +81,9 @@ + (BOOL)rnscreens_isBlankOrNull:(NSString *)string - @end - - @interface RNSScreenStackHeaderConfig () -+#if !TARGET_OS_TV -+- (NSArray *)barButtonItemGroupsFromItems:(NSArray *)items; -+#endif - @end - - @implementation RNSScreenStackHeaderConfig { -@@ -80,6 +118,7 @@ - (void)initProps - self.hidden = YES; - _reactSubviews = [NSMutableArray new]; - _backTitleVisible = YES; -+ _navigationItemStyle = UINavigationItemStyleNavigator; - _blurEffect = RNSBlurEffectStyleNone; - _synchronousShadowStateUpdatesEnabled = YES; - } -@@ -507,6 +546,10 @@ + (void)updateViewController:(UIViewController *)vc - - if (shouldHide) { - navitem.title = config.title; -+ if (@available(iOS 26.0, *)) { -+ navitem.subtitle = config.subtitle; -+ navitem.largeSubtitle = config.largeSubtitle; -+ } - - // Setting navigation bar visibility is split to mitigate iOS 26 bug with bar button items. - [navctr setNavigationBarHidden:YES animated:animated]; -@@ -523,11 +566,19 @@ + (void)updateViewController:(UIViewController *)vc - } - navitem.largeTitleDisplayMode = - config.largeTitle ? UINavigationItemLargeTitleDisplayModeAlways : UINavigationItemLargeTitleDisplayModeNever; -+ -+ if (@available(iOS 16.0, *)) { -+ navitem.style = (UINavigationItemStyle)config.navigationItemStyle; -+ } - #endif - - UINavigationBarAppearance *appearance = [self buildAppearance:vc withConfig:config]; - navitem.standardAppearance = appearance; - navitem.compactAppearance = appearance; -+ if (@available(iOS 26.0, *)) { -+ navitem.subtitle = config.subtitle; -+ navitem.largeSubtitle = config.largeSubtitle; -+ } - - // appearance does not apply to the tvOS so we need to use lagacy customization - #if TARGET_OS_TV -@@ -559,8 +610,6 @@ + (void)updateViewController:(UIViewController *)vc - navitem.leftItemsSupplementBackButton = config.backButtonInCustomView; - #endif - navitem.titleView = nil; -- navitem.leftBarButtonItems = nil; -- navitem.rightBarButtonItems = nil; - - #if !TARGET_OS_TV - // We want to set navitem.searchController to nil only if we are sure -@@ -568,22 +617,18 @@ + (void)updateViewController:(UIViewController *)vc - bool searchBarPresent = false; - #endif /* !TARGET_OS_TV */ - -+ NSMutableArray *subviewLeftItems = [NSMutableArray array]; -+ NSMutableArray *subviewRightItems = [NSMutableArray array]; - for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) { - // This code should be kept in sync on Fabric with analogous switch statement in - // `- [RNSScreenStackHeaderConfig replaceNavigationBarViewsWithSnapshotOfSubview:]` method. - switch (subview.type) { - case RNSScreenStackHeaderSubviewTypeLeft: { -- NSArray *currentItems = navitem.leftBarButtonItems ?: @[]; -- NSMutableArray *mutableItems = [currentItems mutableCopy]; -- [mutableItems addObject:[subview getUIBarButtonItem]]; -- navitem.leftBarButtonItems = mutableItems; -+ [subviewLeftItems addObject:[subview getUIBarButtonItem]]; - break; - } - case RNSScreenStackHeaderSubviewTypeRight: { -- NSArray *currentItems = navitem.rightBarButtonItems ?: @[]; -- NSMutableArray *mutableItems = [currentItems mutableCopy]; -- [mutableItems addObject:[subview getUIBarButtonItem]]; -- navitem.rightBarButtonItems = mutableItems; -+ [subviewRightItems addObject:[subview getUIBarButtonItem]]; - break; - } - case RNSScreenStackHeaderSubviewTypeCenter: -@@ -648,10 +693,479 @@ + (void)updateViewController:(UIViewController *)vc - // This assignment should be done after `navitem.titleView = ...` assignment (iOS 16.0 bug). - // See: https://github.com/software-mansion/react-native-screens/issues/1570 (comments) - navitem.title = config.title; -- navitem.leftBarButtonItems = [config barButtonItemsFromConfigs:config.headerLeftBarButtonItems -- withCurrentItems:navitem.leftBarButtonItems]; -- navitem.rightBarButtonItems = [config barButtonItemsFromConfigs:config.headerRightBarButtonItems -- withCurrentItems:navitem.rightBarButtonItems]; -+ // Retain the config in the key so its address cannot be reused while cached. -+ // Items capture this config's event emitter in their press handlers, so a -+ // remounted header-config view with value-equal configs must still rebuild -+ // instead of dispatching presses into the old config's emitter. -+ // getUIBarButtonItem is stable for the lifetime of its React header -+ // subview. Include those native identities in the key so React-backed -+ // items can use the same cache without reusing a group after its view was -+ // replaced. -+ // A bar button item can belong to only one group. Even if the item itself -+ // is reused, constructing a new group removes it from the old group that -+ // UIKit may still be animating. Preserve each unchanged placement's group, -+ // including the empty leading group beside the system back button. -+#if !TARGET_OS_TV -+ if (@available(iOS 16.0, *)) { -+ NSArray *headerLeftConfigs = config.headerLeftBarButtonItems ?: @[]; -+ NSArray *headerRightConfigs = config.headerRightBarButtonItems ?: @[]; -+ NSArray *headerCenterConfigs = config.headerCenterBarButtonItems ?: @[]; -+ if (RNSUpdateHeaderItemsCache( -+ navitem, &RNSAppliedLeadingHeaderItemsKey, @[ config, headerLeftConfigs, subviewLeftItems ])) { -+ NSArray *items = [config barButtonItemsFromConfigs:config.headerLeftBarButtonItems -+ withCurrentItems:subviewLeftItems -+ navigationItem:navitem -+ allowsSearchBarPlacement:NO]; -+ navitem.leadingItemGroups = [config barButtonItemGroupsFromItems:items]; -+ } -+ if (RNSUpdateHeaderItemsCache( -+ navitem, &RNSAppliedTrailingHeaderItemsKey, @[ config, headerRightConfigs, subviewRightItems ])) { -+ NSArray *items = [config barButtonItemsFromConfigs:config.headerRightBarButtonItems -+ withCurrentItems:subviewRightItems -+ navigationItem:navitem -+ allowsSearchBarPlacement:NO]; -+ navitem.trailingItemGroups = [config barButtonItemGroupsFromItems:items]; -+ } -+ if (@available(iOS 26.0, *)) { -+ if (RNSUpdateHeaderItemsCache(navitem, &RNSAppliedCenterHeaderItemsKey, @[ config, headerCenterConfigs ])) { -+ NSArray *items = [config barButtonItemsFromConfigs:config.headerCenterBarButtonItems -+ withCurrentItems:@[] -+ navigationItem:navitem -+ allowsSearchBarPlacement:NO]; -+ navitem.centerItemGroups = [config barButtonItemGroupsFromItems:items]; -+ } -+ } -+ } else -+#endif -+ { -+ NSArray *leftBarButtonItems = [config barButtonItemsFromConfigs:config.headerLeftBarButtonItems -+ withCurrentItems:subviewLeftItems -+ navigationItem:navitem -+ allowsSearchBarPlacement:NO]; -+ NSArray *rightBarButtonItems = [config barButtonItemsFromConfigs:config.headerRightBarButtonItems -+ withCurrentItems:subviewRightItems -+ navigationItem:navitem -+ allowsSearchBarPlacement:NO]; -+ navitem.leftBarButtonItems = leftBarButtonItems; -+ navitem.rightBarButtonItems = rightBarButtonItems; -+ } -+ NSDictionary *mailSearchToolbarConfig = nil; -+ NSMutableArray *> *nonMailSearchToolbarConfigs = [NSMutableArray array]; -+ for (NSDictionary *toolbarConfig in config.headerToolbarItems) { -+ if (toolbarConfig[@"mailSearchToolbar"]) { -+ if (mailSearchToolbarConfig == nil) { -+ mailSearchToolbarConfig = toolbarConfig; -+ } -+ } else { -+ [nonMailSearchToolbarConfigs addObject:toolbarConfig]; -+ } -+ } -+ NSArray *> *navigationToolbarConfigs = [nonMailSearchToolbarConfigs copy]; -+ if (mailSearchToolbarConfig == nil) { -+ for (NSDictionary *rightConfig in config.headerRightBarButtonItems) { -+ if ([rightConfig[@"bottomMailSearchToolbar"] boolValue]) { -+ mailSearchToolbarConfig = rightConfig; -+ break; -+ } -+ } -+ } -+ -+ static NSInteger const RNSMailSearchToolbarViewTag = 260628; -+ UIView *chromeHostView = vc.view; -+ UIView *existingMailSearchToolbar = [chromeHostView viewWithTag:RNSMailSearchToolbarViewTag]; -+ if (existingMailSearchToolbar == nil) { -+ existingMailSearchToolbar = [vc.view viewWithTag:RNSMailSearchToolbarViewTag]; -+ } -+ // Reuse the live toolbar when nothing it was built from changed: rebuilding -+ // replaces the fallback UISearchTextField with a fresh empty one, dropping -+ // the user's in-progress search text and first responder on every unrelated -+ // header update. Keyed on the config instance (the button/search blocks -+ // capture its event emitter), the toolbar config values, and the host width -+ // (the width constraint constant is resolved from it at build time). -+ static char RNSAppliedMailSearchToolbarConfigKey; -+ NSArray *mailSearchToolbarKey = mailSearchToolbarConfig != nil -+ ? @[ @((uintptr_t)config), mailSearchToolbarConfig, @(chromeHostView.bounds.size.width) ] -+ : nil; -+ BOOL reuseMailSearchToolbar = existingMailSearchToolbar != nil && mailSearchToolbarKey != nil && -+ [objc_getAssociatedObject(existingMailSearchToolbar, &RNSAppliedMailSearchToolbarConfigKey) -+ isEqual:mailSearchToolbarKey]; -+ if (!reuseMailSearchToolbar) { -+ [existingMailSearchToolbar removeFromSuperview]; -+ } -+ -+ if (mailSearchToolbarConfig != nil && !reuseMailSearchToolbar) { -+#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) -+ if (@available(iOS 26.0, *)) { -+ CGFloat horizontalInset = 18.0; -+ NSNumber *width = mailSearchToolbarConfig[@"width"]; -+ CGFloat hostWidth = chromeHostView.bounds.size.width; -+ if (hostWidth <= 0.0) { -+ hostWidth = vc.view.bounds.size.width; -+ } -+ if (hostWidth <= 0.0) { -+ hostWidth = [UIScreen mainScreen].bounds.size.width; -+ } -+ CGFloat fallbackWidth = MIN(560.0, MAX(300.0, hostWidth - (horizontalInset * 2.0))); -+ CGFloat resolvedWidth = width != nil ? width.doubleValue : fallbackWidth; -+ if (hostWidth > 0.0) { -+ resolvedWidth = MIN(resolvedWidth, MAX(260.0, hostWidth - 12.0)); -+ } -+ -+ CGFloat toolbarHeight = 48.0; -+ CGFloat toolbarRadius = toolbarHeight / 2.0; -+ CGFloat buttonSize = toolbarHeight; -+ CGFloat sideButtonReserve = buttonSize + 8.0; -+ CGFloat searchFieldHeight = 42.0; -+ CGFloat toolbarBottomSpacing = 4.0; -+ UIFont *searchFont = [UIFont preferredFontForTextStyle:UIFontTextStyleTitle3]; -+ NSDictionary *placeholderAttributes = @{ -+ NSForegroundColorAttributeName : UIColor.secondaryLabelColor, -+ NSFontAttributeName : searchFont, -+ }; -+ UIKeyboardLayoutGuide *keyboardLayoutGuide = chromeHostView.keyboardLayoutGuide; -+ -+ UIView *toolbarHost = [[UIView alloc] init]; -+ toolbarHost.tag = RNSMailSearchToolbarViewTag; -+ objc_setAssociatedObject( -+ toolbarHost, -+ &RNSAppliedMailSearchToolbarConfigKey, -+ mailSearchToolbarKey, -+ OBJC_ASSOCIATION_RETAIN_NONATOMIC); -+ toolbarHost.translatesAutoresizingMaskIntoConstraints = NO; -+ [chromeHostView addSubview:toolbarHost]; -+ // The screen stays mounted beneath pushed routes, so its keyboard layout -+ // guide can track a keyboard owned by another screen. Keep the toolbar at -+ // rest unless its own search field is editing. -+ NSLayoutConstraint *keyboardAvoidConstraint = -+ [toolbarHost.bottomAnchor constraintEqualToAnchor:keyboardLayoutGuide.topAnchor -+ constant:-toolbarBottomSpacing]; -+ keyboardAvoidConstraint.priority = UILayoutPriorityDefaultLow; -+ NSLayoutConstraint *restingBottomConstraint = -+ [toolbarHost.bottomAnchor constraintEqualToAnchor:chromeHostView.safeAreaLayoutGuide.bottomAnchor -+ constant:-toolbarBottomSpacing]; -+ restingBottomConstraint.priority = UILayoutPriorityDefaultHigh; -+ [NSLayoutConstraint activateConstraints:@[ -+ [toolbarHost.centerXAnchor constraintEqualToAnchor:chromeHostView.centerXAnchor], -+ [toolbarHost.bottomAnchor constraintLessThanOrEqualToAnchor:chromeHostView.safeAreaLayoutGuide.bottomAnchor -+ constant:-toolbarBottomSpacing], -+ keyboardAvoidConstraint, -+ restingBottomConstraint, -+ [toolbarHost.widthAnchor constraintEqualToConstant:resolvedWidth], -+ [toolbarHost.heightAnchor constraintEqualToConstant:toolbarHeight], -+ ]]; -+ [chromeHostView bringSubviewToFront:toolbarHost]; -+ -+ UIGlassEffect *glassEffect = [UIGlassEffect effectWithStyle:UIGlassEffectStyleRegular]; -+ glassEffect.interactive = YES; -+ UIVisualEffectView *glassView = [[UIVisualEffectView alloc] initWithEffect:glassEffect]; -+ glassView.clipsToBounds = YES; -+ glassView.layer.cornerRadius = toolbarRadius; -+ glassView.translatesAutoresizingMaskIntoConstraints = NO; -+ [toolbarHost addSubview:glassView]; -+ BOOL hasFilterButton = -+ mailSearchToolbarConfig[@"filterButtonId"] != nil || mailSearchToolbarConfig[@"filterMenu"] != nil; -+ BOOL hasComposeButton = -+ mailSearchToolbarConfig[@"composeButtonId"] != nil || mailSearchToolbarConfig[@"composeMenu"] != nil; -+ CGFloat glassLeadingInset = hasFilterButton ? sideButtonReserve : 0.0; -+ CGFloat glassTrailingInset = hasComposeButton ? -sideButtonReserve : 0.0; -+ NSLayoutConstraint *glassLeadingConstraint = -+ [glassView.leadingAnchor constraintEqualToAnchor:toolbarHost.leadingAnchor constant:glassLeadingInset]; -+ NSLayoutConstraint *glassTrailingConstraint = -+ [glassView.trailingAnchor constraintEqualToAnchor:toolbarHost.trailingAnchor constant:glassTrailingInset]; -+ [NSLayoutConstraint activateConstraints:@[ -+ glassLeadingConstraint, -+ glassTrailingConstraint, -+ [glassView.centerYAnchor constraintEqualToAnchor:toolbarHost.centerYAnchor], -+ [glassView.heightAnchor constraintEqualToConstant:toolbarHeight], -+ ]]; -+ -+ void (^emitButtonPress)(NSString *) = ^(NSString *buttonId) { -+ auto eventEmitter = std::static_pointer_cast( -+ config->_eventEmitter); -+ if (eventEmitter && buttonId) { -+ eventEmitter->onPressHeaderBarButtonItem( -+ facebook::react::RNSScreenStackHeaderConfigEventEmitter::OnPressHeaderBarButtonItem{ -+ .buttonId = std::string([buttonId UTF8String])}); -+ } -+ }; -+ -+ void (^emitMenuPress)(NSString *) = ^(NSString *menuId) { -+ auto eventEmitter = std::static_pointer_cast( -+ config->_eventEmitter); -+ if (eventEmitter && menuId) { -+ eventEmitter->onPressHeaderBarButtonMenuItem( -+ facebook::react::RNSScreenStackHeaderConfigEventEmitter::OnPressHeaderBarButtonMenuItem{ -+ .menuId = std::string([menuId UTF8String])}); -+ } -+ }; -+ -+ UIButton *(^makeGlassButton)(NSString *, NSString *, NSDictionary *) = -+ ^UIButton *(NSString *systemImageName, NSString *buttonId, NSDictionary *menuConfig) { -+ UIButtonConfiguration *configuration = [UIButtonConfiguration glassButtonConfiguration]; -+ configuration.cornerStyle = UIButtonConfigurationCornerStyleCapsule; -+ configuration.image = [UIImage systemImageNamed:systemImageName ?: @"circle"]; -+ configuration.baseForegroundColor = UIColor.labelColor; -+ UIButton *button = [UIButton buttonWithConfiguration:configuration primaryAction:nil]; -+ if (menuConfig != nil) { -+ button.menu = [RNSBarButtonItem initUIMenuWithDict:menuConfig -+ menuAction:emitMenuPress -+ imageLoader:config->_imageLoader]; -+ button.showsMenuAsPrimaryAction = YES; -+ } else if (buttonId != nil) { -+ UIAction *action = [UIAction actionWithHandler:^(__kindof UIAction *_Nonnull action) { -+ emitButtonPress(buttonId); -+ }]; -+ [button addAction:action forControlEvents:UIControlEventTouchUpInside]; -+ } -+ return button; -+ }; -+ -+ BOOL useFallbackSearchField = [mailSearchToolbarConfig[@"useFallbackSearchField"] boolValue]; -+ UISearchBar *searchBar = -+ !useFallbackSearchField && navitem.searchController != nil ? navitem.searchController.searchBar : nil; -+ NSString *placeholder = mailSearchToolbarConfig[@"placeholder"]; -+ UITextField *resolvedSearchTextField = nil; -+ if (searchBar != nil) { -+ if (placeholder != nil) { -+ searchBar.placeholder = placeholder; -+ } -+ searchBar.hidden = NO; -+ searchBar.alpha = 1.0; -+ searchBar.userInteractionEnabled = YES; -+ searchBar.searchBarStyle = UISearchBarStyleMinimal; -+ searchBar.backgroundImage = [UIImage new]; -+ searchBar.searchTextField.hidden = NO; -+ searchBar.searchTextField.alpha = 1.0; -+ searchBar.searchTextField.backgroundColor = UIColor.clearColor; -+ searchBar.searchTextField.font = searchFont; -+ searchBar.searchTextField.adjustsFontForContentSizeCategory = YES; -+ searchBar.searchTextField.textColor = UIColor.labelColor; -+ searchBar.searchTextField.tintColor = UIColor.labelColor; -+ resolvedSearchTextField = searchBar.searchTextField; -+ if (placeholder != nil) { -+ searchBar.searchTextField.attributedPlaceholder = -+ [[NSAttributedString alloc] initWithString:placeholder attributes:placeholderAttributes]; -+ } -+ searchBar.translatesAutoresizingMaskIntoConstraints = NO; -+ [glassView.contentView addSubview:searchBar]; -+ [NSLayoutConstraint activateConstraints:@[ -+ [searchBar.leadingAnchor constraintEqualToAnchor:glassView.contentView.leadingAnchor constant:8.0], -+ [searchBar.trailingAnchor constraintEqualToAnchor:glassView.contentView.trailingAnchor constant:-8.0], -+ [searchBar.centerYAnchor constraintEqualToAnchor:glassView.contentView.centerYAnchor], -+ [searchBar.heightAnchor constraintEqualToConstant:searchFieldHeight], -+ ]]; -+ } else { -+ UISearchTextField *searchField = [UISearchTextField new]; -+ if (placeholder != nil) { -+ searchField.placeholder = placeholder; -+ searchField.attributedPlaceholder = -+ [[NSAttributedString alloc] initWithString:placeholder attributes:placeholderAttributes]; -+ } -+ searchField.borderStyle = UITextBorderStyleNone; -+ searchField.font = searchFont; -+ searchField.adjustsFontForContentSizeCategory = YES; -+ searchField.textColor = UIColor.labelColor; -+ searchField.tintColor = UIColor.labelColor; -+ resolvedSearchTextField = searchField; -+ searchField.translatesAutoresizingMaskIntoConstraints = NO; -+ [glassView.contentView addSubview:searchField]; -+ [NSLayoutConstraint activateConstraints:@[ -+ [searchField.leadingAnchor constraintEqualToAnchor:glassView.contentView.leadingAnchor constant:14.0], -+ [searchField.trailingAnchor constraintEqualToAnchor:glassView.contentView.trailingAnchor constant:-14.0], -+ [searchField.centerYAnchor constraintEqualToAnchor:glassView.contentView.centerYAnchor], -+ [searchField.heightAnchor constraintEqualToConstant:searchFieldHeight], -+ ]]; -+ } -+ -+ // A bare UISearchTextField keeps UITextField defaults (sentence -+ // capitalization, autocorrect), unlike UISearchBar. Search queries are -+ // identifiers, so match the autoCapitalize "none" the JS fallbacks use. -+ if (resolvedSearchTextField != nil) { -+ resolvedSearchTextField.autocapitalizationType = UITextAutocapitalizationTypeNone; -+ resolvedSearchTextField.autocorrectionType = UITextAutocorrectionTypeNo; -+ resolvedSearchTextField.spellCheckingType = UITextSpellCheckingTypeNo; -+ } -+ -+ NSString *searchTextChangeId = mailSearchToolbarConfig[@"searchTextChangeId"]; -+ NSString *searchTextChangeActionIdentifier = @"org.react-native-screens.mail-search-toolbar.text-change"; -+ if (resolvedSearchTextField != nil) { -+ [resolvedSearchTextField removeActionForIdentifier:searchTextChangeActionIdentifier -+ forControlEvents:UIControlEventEditingChanged]; -+ } -+ if (searchTextChangeId != nil && resolvedSearchTextField != nil) { -+ [resolvedSearchTextField -+ addAction:[UIAction actionWithTitle:@"" -+ image:nil -+ identifier:searchTextChangeActionIdentifier -+ handler:^(__kindof UIAction *_Nonnull action) { -+ UITextField *field = (UITextField *)action.sender; -+ emitButtonPress( -+ [NSString stringWithFormat:@"%@:%@", searchTextChangeId, field.text ?: @""]); -+ }] -+ forControlEvents:UIControlEventEditingChanged]; -+ } -+ -+ UIButton *filterButton = nil; -+ if (hasFilterButton) { -+ filterButton = makeGlassButton( -+ mailSearchToolbarConfig[@"filterSystemImageName"] ?: @"line.3.horizontal.decrease", -+ mailSearchToolbarConfig[@"filterButtonId"], -+ mailSearchToolbarConfig[@"filterMenu"]); -+ filterButton.translatesAutoresizingMaskIntoConstraints = NO; -+ [toolbarHost addSubview:filterButton]; -+ [NSLayoutConstraint activateConstraints:@[ -+ [filterButton.leadingAnchor constraintEqualToAnchor:toolbarHost.leadingAnchor], -+ [filterButton.centerYAnchor constraintEqualToAnchor:toolbarHost.centerYAnchor], -+ [filterButton.widthAnchor constraintEqualToConstant:buttonSize], -+ [filterButton.heightAnchor constraintEqualToConstant:buttonSize], -+ ]]; -+ } -+ -+ UIButton *composeButton = nil; -+ if (hasComposeButton) { -+ composeButton = makeGlassButton( -+ mailSearchToolbarConfig[@"composeSystemImageName"] ?: @"square.and.pencil", -+ mailSearchToolbarConfig[@"composeButtonId"], -+ mailSearchToolbarConfig[@"composeMenu"]); -+ composeButton.translatesAutoresizingMaskIntoConstraints = NO; -+ [toolbarHost addSubview:composeButton]; -+ [NSLayoutConstraint activateConstraints:@[ -+ [composeButton.trailingAnchor constraintEqualToAnchor:toolbarHost.trailingAnchor], -+ [composeButton.centerYAnchor constraintEqualToAnchor:toolbarHost.centerYAnchor], -+ [composeButton.widthAnchor constraintEqualToConstant:buttonSize], -+ [composeButton.heightAnchor constraintEqualToConstant:buttonSize], -+ ]]; -+ } -+ -+ BOOL showsSearchDismissButton = -+ [mailSearchToolbarConfig[@"showsSearchDismissButton"] boolValue] && resolvedSearchTextField != nil; -+ UIButton *searchDismissButton = nil; -+ if (showsSearchDismissButton) { -+ searchDismissButton = makeGlassButton(@"xmark", nil, nil); -+ searchDismissButton.accessibilityLabel = @"Dismiss search keyboard"; -+ searchDismissButton.alpha = 0.0; -+ searchDismissButton.hidden = YES; -+ searchDismissButton.translatesAutoresizingMaskIntoConstraints = NO; -+ [toolbarHost addSubview:searchDismissButton]; -+ [NSLayoutConstraint activateConstraints:@[ -+ [searchDismissButton.trailingAnchor constraintEqualToAnchor:toolbarHost.trailingAnchor], -+ [searchDismissButton.centerYAnchor constraintEqualToAnchor:toolbarHost.centerYAnchor], -+ [searchDismissButton.widthAnchor constraintEqualToConstant:buttonSize], -+ [searchDismissButton.heightAnchor constraintEqualToConstant:buttonSize], -+ ]]; -+ __weak UITextField *weakSearchTextField = resolvedSearchTextField; -+ [searchDismissButton -+ addAction:[UIAction actionWithHandler:^(__kindof UIAction *_Nonnull action) { -+ [weakSearchTextField resignFirstResponder]; -+ }] -+ forControlEvents:UIControlEventTouchUpInside]; -+ } -+ -+ __weak UIButton *weakFilterButton = filterButton; -+ __weak UIButton *weakComposeButton = composeButton; -+ __weak UIButton *weakSearchDismissButton = searchDismissButton; -+ __weak NSLayoutConstraint *weakGlassLeadingConstraint = glassLeadingConstraint; -+ __weak NSLayoutConstraint *weakGlassTrailingConstraint = glassTrailingConstraint; -+ __weak NSLayoutConstraint *weakKeyboardAvoidConstraint = keyboardAvoidConstraint; -+ __weak NSLayoutConstraint *weakRestingBottomConstraint = restingBottomConstraint; -+ __weak UIView *weakToolbarHost = toolbarHost; -+ __weak UITextField *weakSearchTextField = resolvedSearchTextField; -+ void (^setSearchEditingAppearance)(BOOL, BOOL) = ^(BOOL isEditing, BOOL animated) { -+ weakKeyboardAvoidConstraint.priority = -+ isEditing ? UILayoutPriorityDefaultHigh : UILayoutPriorityDefaultLow; -+ weakRestingBottomConstraint.priority = -+ isEditing ? UILayoutPriorityDefaultLow : UILayoutPriorityDefaultHigh; -+ -+ if (showsSearchDismissButton) { -+ if (isEditing) { -+ weakSearchDismissButton.hidden = NO; -+ } else { -+ weakFilterButton.hidden = NO; -+ weakComposeButton.hidden = NO; -+ } -+ weakGlassLeadingConstraint.constant = isEditing ? 0.0 : glassLeadingInset; -+ weakGlassTrailingConstraint.constant = isEditing ? -sideButtonReserve : glassTrailingInset; -+ -+ void (^changes)(void) = ^{ -+ weakFilterButton.alpha = isEditing ? 0.0 : 1.0; -+ weakComposeButton.alpha = isEditing ? 0.0 : 1.0; -+ weakSearchDismissButton.alpha = isEditing ? 1.0 : 0.0; -+ [weakToolbarHost layoutIfNeeded]; -+ }; -+ void (^completion)(BOOL) = ^(BOOL finished) { -+ if (!finished || weakSearchTextField.isFirstResponder != isEditing) { -+ return; -+ } -+ weakFilterButton.hidden = isEditing; -+ weakComposeButton.hidden = isEditing; -+ weakSearchDismissButton.hidden = !isEditing; -+ }; -+ if (animated) { -+ [UIView animateWithDuration:0.2 -+ delay:0.0 -+ options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseInOut -+ animations:changes -+ completion:completion]; -+ } else { -+ changes(); -+ completion(YES); -+ } -+ } -+ [weakToolbarHost setNeedsLayout]; -+ }; -+ -+ setSearchEditingAppearance(resolvedSearchTextField.isFirstResponder, NO); -+ NSString *beginActionIdentifier = @"org.react-native-screens.mail-search-toolbar.keyboard-begin"; -+ NSString *endActionIdentifier = @"org.react-native-screens.mail-search-toolbar.keyboard-end"; -+ [resolvedSearchTextField removeActionForIdentifier:beginActionIdentifier -+ forControlEvents:UIControlEventEditingDidBegin]; -+ [resolvedSearchTextField removeActionForIdentifier:endActionIdentifier -+ forControlEvents:UIControlEventEditingDidEnd]; -+ [resolvedSearchTextField -+ addAction:[UIAction actionWithTitle:@"" -+ image:nil -+ identifier:beginActionIdentifier -+ handler:^(__kindof UIAction *_Nonnull action) { -+ setSearchEditingAppearance(YES, YES); -+ }] -+ forControlEvents:UIControlEventEditingDidBegin]; -+ [resolvedSearchTextField -+ addAction:[UIAction actionWithTitle:@"" -+ image:nil -+ identifier:endActionIdentifier -+ handler:^(__kindof UIAction *_Nonnull action) { -+ setSearchEditingAppearance(NO, YES); -+ }] -+ forControlEvents:UIControlEventEditingDidEnd]; -+ } -+#endif -+ } -+ -+ NSArray *toolbarConfigsKey = navigationToolbarConfigs ?: @[]; -+ // Same reuse rule as the header item groups above (including the config -+ // identity — cached toolbar items capture this config's event emitter). -+ // The top-view-controller and hidden-state checks scope the skip to -+ // same-screen refreshes, so transitions between screens with different -+ // toolbars still reapply. -+ NSArray *toolbarCacheKey = @[ @((uintptr_t)config), toolbarConfigsKey ]; -+ BOOL reuseToolbarItems = navctr.topViewController == vc && -+ navctr.isToolbarHidden == (toolbarConfigsKey.count == 0) && -+ [objc_getAssociatedObject(navitem, &RNSAppliedToolbarConfigsKey) isEqual:toolbarCacheKey]; -+ if (!reuseToolbarItems) { -+ NSArray *toolbarItems = [config barButtonItemsFromConfigs:navigationToolbarConfigs -+ withCurrentItems:@[] -+ navigationItem:navitem -+ allowsSearchBarPlacement:YES]; -+ if (toolbarItems.count > 0) { -+ vc.toolbarItems = toolbarItems; -+ [navctr setToolbarHidden:NO animated:animated]; -+ } else { -+ vc.toolbarItems = nil; -+ [navctr setToolbarHidden:YES animated:animated]; -+ } -+ objc_setAssociatedObject( -+ navitem, &RNSAppliedToolbarConfigsKey, toolbarCacheKey, OBJC_ASSOCIATION_RETAIN_NONATOMIC); -+ } - - // Setting navigation bar visibility is split to mitigate iOS 26 bug with bar button items - // (setting nav bar visibility should be done after `navitem.*BarButtonItems`). -@@ -784,6 +1289,8 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController * - - - (NSArray *)barButtonItemsFromConfigs:(NSArray *> *)dicts - withCurrentItems:(NSArray *)currentItems -+ navigationItem:(UINavigationItem *)navitem -+ allowsSearchBarPlacement:(BOOL)allowsSearchBarPlacement - { - if (dicts.count == 0) { - return currentItems; -@@ -792,7 +1299,200 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController * - [items addObjectsFromArray:currentItems]; - for (NSUInteger i = 0; i < dicts.count; i++) { - NSDictionary *dict = dicts[i]; -- if (dict[@"buttonId"] || dict[@"menu"]) { -+ if (dict[@"mailSearchToolbar"]) { -+#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) -+ if (@available(iOS 26.0, *)) { -+ NSNumber *width = dict[@"width"]; -+ CGFloat resolvedWidth = width != nil ? width.doubleValue : MAX(320.0, [UIScreen mainScreen].bounds.size.width - 56.0); -+ CGFloat resolvedHeight = 58.0; -+ UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, resolvedWidth, resolvedHeight)]; -+ container.translatesAutoresizingMaskIntoConstraints = NO; -+ [container.widthAnchor constraintEqualToConstant:resolvedWidth].active = YES; -+ [container.heightAnchor constraintEqualToConstant:resolvedHeight].active = YES; -+ -+ UIStackView *stackView = [[UIStackView alloc] initWithFrame:container.bounds]; -+ stackView.axis = UILayoutConstraintAxisHorizontal; -+ stackView.alignment = UIStackViewAlignmentCenter; -+ stackView.distribution = UIStackViewDistributionFill; -+ stackView.spacing = 10.0; -+ stackView.translatesAutoresizingMaskIntoConstraints = NO; -+ [container addSubview:stackView]; -+ [NSLayoutConstraint activateConstraints:@[ -+ [stackView.leadingAnchor constraintEqualToAnchor:container.leadingAnchor], -+ [stackView.trailingAnchor constraintEqualToAnchor:container.trailingAnchor], -+ [stackView.centerYAnchor constraintEqualToAnchor:container.centerYAnchor], -+ [stackView.heightAnchor constraintEqualToConstant:50.0], -+ ]]; -+ -+ void (^emitButtonPress)(NSString *) = ^(NSString *buttonId) { -+ auto eventEmitter = std::static_pointer_cast( -+ self->_eventEmitter); -+ if (eventEmitter && buttonId) { -+ eventEmitter->onPressHeaderBarButtonItem( -+ facebook::react::RNSScreenStackHeaderConfigEventEmitter::OnPressHeaderBarButtonItem{ -+ .buttonId = std::string([buttonId UTF8String])}); -+ } -+ }; -+ -+ void (^emitMenuPress)(NSString *) = ^(NSString *menuId) { -+ auto eventEmitter = std::static_pointer_cast( -+ self->_eventEmitter); -+ if (eventEmitter && menuId) { -+ eventEmitter->onPressHeaderBarButtonMenuItem( -+ facebook::react::RNSScreenStackHeaderConfigEventEmitter::OnPressHeaderBarButtonMenuItem{ -+ .menuId = std::string([menuId UTF8String])}); -+ } -+ }; -+ -+ UIButton *(^makeGlassButton)(NSString *, NSString *, NSDictionary *) = -+ ^UIButton *(NSString *systemImageName, NSString *buttonId, NSDictionary *menuConfig) { -+ UIButtonConfiguration *configuration = [UIButtonConfiguration glassButtonConfiguration]; -+ configuration.cornerStyle = UIButtonConfigurationCornerStyleCapsule; -+ configuration.image = [UIImage systemImageNamed:systemImageName ?: @"circle"]; -+ -+ UIButton *button = [UIButton buttonWithConfiguration:configuration primaryAction:nil]; -+ button.translatesAutoresizingMaskIntoConstraints = NO; -+ [button.widthAnchor constraintEqualToConstant:58.0].active = YES; -+ [button.heightAnchor constraintEqualToConstant:50.0].active = YES; -+ if (menuConfig != nil) { -+ button.menu = [RNSBarButtonItem initUIMenuWithDict:menuConfig -+ menuAction:emitMenuPress -+ imageLoader:self->_imageLoader]; -+ button.showsMenuAsPrimaryAction = YES; -+ } else if (buttonId != nil) { -+ UIAction *action = [UIAction actionWithHandler:^(__kindof UIAction *_Nonnull action) { -+ emitButtonPress(buttonId); -+ }]; -+ [button addAction:action forControlEvents:UIControlEventTouchUpInside]; -+ } -+ return button; -+ }; -+ -+ BOOL hasFilterButton = dict[@"filterButtonId"] != nil || dict[@"filterMenu"] != nil; -+ BOOL hasComposeButton = dict[@"composeButtonId"] != nil || dict[@"composeMenu"] != nil; -+ -+ if (hasFilterButton) { -+ UIButton *filterButton = makeGlassButton( -+ dict[@"filterSystemImageName"] ?: @"line.3.horizontal.decrease", -+ dict[@"filterButtonId"], -+ dict[@"filterMenu"]); -+ [stackView addArrangedSubview:filterButton]; -+ } -+ -+ UISearchBar *searchBar = navitem.searchController != nil ? navitem.searchController.searchBar : [UISearchBar new]; -+ NSString *placeholder = dict[@"placeholder"]; -+ if (placeholder != nil) { -+ searchBar.placeholder = placeholder; -+ } -+ searchBar.searchBarStyle = UISearchBarStyleMinimal; -+ searchBar.translatesAutoresizingMaskIntoConstraints = NO; -+ [searchBar.heightAnchor constraintEqualToConstant:50.0].active = YES; -+ [stackView addArrangedSubview:searchBar]; -+ -+ if (hasComposeButton) { -+ UIButton *composeButton = makeGlassButton( -+ dict[@"composeSystemImageName"] ?: @"square.and.pencil", -+ dict[@"composeButtonId"], -+ dict[@"composeMenu"]); -+ [stackView addArrangedSubview:composeButton]; -+ } -+ -+ UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:container]; -+ [items addObject:item]; -+ } -+#endif -+ } else if (dict[@"searchField"]) { -+#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) -+ if (@available(iOS 26.0, *)) { -+ NSNumber *width = dict[@"width"]; -+ CGFloat resolvedWidth = width != nil ? width.doubleValue : 280.0; -+ UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, resolvedWidth, 44.0)]; -+ container.translatesAutoresizingMaskIntoConstraints = NO; -+ [container.widthAnchor constraintEqualToConstant:resolvedWidth].active = YES; -+ [container.heightAnchor constraintEqualToConstant:44.0].active = YES; -+ -+ UISearchTextField *searchField = [UISearchTextField new]; -+ NSString *placeholder = dict[@"placeholder"]; -+ if (placeholder != nil) { -+ searchField.placeholder = placeholder; -+ } -+ searchField.translatesAutoresizingMaskIntoConstraints = NO; -+ [container addSubview:searchField]; -+ [NSLayoutConstraint activateConstraints:@[ -+ [searchField.leadingAnchor constraintEqualToAnchor:container.leadingAnchor], -+ [searchField.trailingAnchor constraintEqualToAnchor:container.trailingAnchor], -+ [searchField.centerYAnchor constraintEqualToAnchor:container.centerYAnchor], -+ [searchField.heightAnchor constraintEqualToConstant:40.0], -+ ]]; -+ -+ UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:container]; -+ [items addObject:item]; -+ } -+#endif -+ } else if (dict[@"searchBarPlacement"]) { -+ if (!allowsSearchBarPlacement) { -+ continue; -+ } -+#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) -+ if (@available(iOS 26.0, *)) { -+ NSNumber *width = dict[@"width"]; -+ UIBarButtonItem *item = nil; -+ if ([dict[@"activatesSearchController"] boolValue]) { -+ UIButtonConfiguration *configuration = [UIButtonConfiguration glassButtonConfiguration]; -+ configuration.cornerStyle = UIButtonConfigurationCornerStyleCapsule; -+ configuration.image = [UIImage systemImageNamed:@"magnifyingglass"]; -+ configuration.baseForegroundColor = UIColor.labelColor; -+ UIButton *button = [UIButton buttonWithConfiguration:configuration primaryAction:nil]; -+ button.translatesAutoresizingMaskIntoConstraints = NO; -+ [button.widthAnchor constraintEqualToConstant:56.0].active = YES; -+ [button.heightAnchor constraintEqualToConstant:56.0].active = YES; -+ UIAction *action = [UIAction actionWithHandler:^(__kindof UIAction *_Nonnull action) { -+ if (navitem.searchController != nil) { -+ [navitem.searchController setActive:YES]; -+ [navitem.searchController.searchBar becomeFirstResponder]; -+ } -+ }]; -+ [button addAction:action forControlEvents:UIControlEventTouchUpInside]; -+ item = [[UIBarButtonItem alloc] initWithCustomView:button]; -+ } else if ([dict[@"customView"] boolValue] && navitem.searchController != nil) { -+ UISearchBar *searchBar = navitem.searchController.searchBar; -+ CGFloat resolvedWidth = width != nil ? width.doubleValue : searchBar.frame.size.width; -+ CGFloat resolvedHeight = searchBar.frame.size.height > 0 ? searchBar.frame.size.height : 44.0; -+ UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, resolvedWidth, resolvedHeight)]; -+ container.translatesAutoresizingMaskIntoConstraints = NO; -+ [container.widthAnchor constraintEqualToConstant:resolvedWidth].active = YES; -+ [container.heightAnchor constraintEqualToConstant:resolvedHeight].active = YES; -+ searchBar.frame = container.bounds; -+ searchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; -+ [container addSubview:searchBar]; -+ item = [[UIBarButtonItem alloc] initWithCustomView:container]; -+ } else { -+ item = navitem.searchBarPlacementBarButtonItem; -+ if (width != nil) { -+ item.width = width.doubleValue; -+ } -+ } -+ NSNumber *index = dict[@"index"]; -+#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) -+ if (@available(iOS 26.0, *)) { -+ NSNumber *sharesBackground = dict[@"sharesBackground"]; -+ if (sharesBackground != nil) { -+ item.sharesBackground = sharesBackground.boolValue; -+ } -+ NSNumber *hidesSharedBackground = dict[@"hidesSharedBackground"]; -+ if (hidesSharedBackground != nil) { -+ item.hidesSharedBackground = hidesSharedBackground.boolValue; -+ } -+ } -+#endif -+ if (index != nil && index.integerValue >= 0 && index.integerValue < items.count) { -+ [items insertObject:item atIndex:index.integerValue]; -+ } else { -+ [items addObject:item]; -+ } -+ } -+#endif -+ } else if (dict[@"buttonId"] || dict[@"menu"]) { - RNSBarButtonItem *item = [[RNSBarButtonItem alloc] initWithConfig:dict - action:^(NSString *buttonId) { - auto eventEmitter = std::static_pointer_cast( -@@ -814,19 +1514,23 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController * - } - imageLoader:_imageLoader]; - NSNumber *index = dict[@"index"]; -- if (index.integerValue < items.count) { -+ if (index != nil && index.integerValue >= 0 && index.integerValue < items.count) { - [items insertObject:item atIndex:index.integerValue]; - } else { - [items addObject:item]; - } - } else if (dict[@"spacing"]) { -- UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace -- target:nil -- action:nil]; -+ BOOL flexible = [dict[@"flexible"] boolValue]; -+ UIBarButtonItem *item = [[UIBarButtonItem alloc] -+ initWithBarButtonSystemItem:(flexible ? UIBarButtonSystemItemFlexibleSpace : UIBarButtonSystemItemFixedSpace) -+ target:nil -+ action:nil]; - NSNumber *spacingValue = dict[@"spacing"]; -- item.width = [spacingValue doubleValue]; -+ if (!flexible) { -+ item.width = [spacingValue doubleValue]; -+ } - NSNumber *index = dict[@"index"]; -- if (index.integerValue < items.count) { -+ if (index != nil && index.integerValue >= 0 && index.integerValue < items.count) { - [items insertObject:item atIndex:index.integerValue]; - } else { - [items addObject:item]; -@@ -836,6 +1540,47 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController * - return items; - } - -+#if !TARGET_OS_TV -+- (NSArray *)barButtonItemGroupsFromItems:(NSArray *)items -+{ -+ if (items.count == 0) { -+ return @[]; -+ } -+ -+ NSMutableArray *groups = [NSMutableArray array]; -+ NSMutableArray *sharedRun = [NSMutableArray array]; -+ -+ void (^flushSharedRun)(void) = ^{ -+ if (sharedRun.count == 0) { -+ return; -+ } -+ [groups addObject:[UIBarButtonItemGroup fixedGroupWithRepresentativeItem:nil -+ items:[sharedRun copy]]]; -+ [sharedRun removeAllObjects]; -+ }; -+ -+ for (UIBarButtonItem *item in items) { -+ BOOL shouldShareBackground = NO; -+#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) -+ if (@available(iOS 26.0, *)) { -+ shouldShareBackground = item.sharesBackground && !item.hidesSharedBackground; -+ } -+#endif -+ -+ if (shouldShareBackground) { -+ [sharedRun addObject:item]; -+ continue; -+ } -+ -+ flushSharedRun(); -+ [groups addObject:[UIBarButtonItemGroup fixedGroupWithRepresentativeItem:nil items:@[ item ]]]; -+ } -+ -+ flushSharedRun(); -+ return groups; -+} -+#endif -+ - RNS_IGNORE_SUPER_CALL_BEGIN - - (void)insertReactSubview:(RNSScreenStackHeaderSubview *)subview atIndex:(NSInteger)atIndex - { -@@ -1023,6 +1768,8 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props:: - } - - _title = RCTNSStringFromStringNilIfEmpty(newScreenProps.title); -+ _subtitle = RCTNSStringFromStringNilIfEmpty(newScreenProps.subtitle); -+ _largeSubtitle = RCTNSStringFromStringNilIfEmpty(newScreenProps.largeSubtitle); - if (newScreenProps.titleFontFamily != oldScreenProps.titleFontFamily) { - _titleFontFamily = RCTNSStringFromStringNilIfEmpty(newScreenProps.titleFontFamily); - } -@@ -1048,6 +1795,7 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props:: - _disableBackButtonMenu = newScreenProps.disableBackButtonMenu; - _backButtonDisplayMode = - [RNSConvert UINavigationItemBackButtonDisplayModeFromCppEquivalent:newScreenProps.backButtonDisplayMode]; -+ _navigationItemStyle = navigationItemStyleFromCppEquivalent(newScreenProps.navigationItemStyle); - - if (newScreenProps.userInterfaceStyle != oldScreenProps.userInterfaceStyle) { - _userInterfaceStyle = [RNSConvert UIUserInterfaceStyleFromCppEquivalent:newScreenProps.userInterfaceStyle]; -@@ -1094,6 +1842,30 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props:: - _headerRightBarButtonItems = array; - } - -+ if (newScreenProps.headerCenterBarButtonItems != oldScreenProps.headerCenterBarButtonItems) { -+ const auto &vec = newScreenProps.headerCenterBarButtonItems; -+ NSMutableArray *> *array = [NSMutableArray arrayWithCapacity:vec.size()]; -+ for (const auto &item : vec) { -+ NSDictionary *dict = [RNSConvert idFromFollyDynamic:item]; -+ if ([dict isKindOfClass:[NSDictionary class]]) { -+ [array addObject:dict]; -+ } -+ } -+ _headerCenterBarButtonItems = array; -+ } -+ -+ if (newScreenProps.headerToolbarItems != oldScreenProps.headerToolbarItems) { -+ const auto &vec = newScreenProps.headerToolbarItems; -+ NSMutableArray *> *array = [NSMutableArray arrayWithCapacity:vec.size()]; -+ for (const auto &item : vec) { -+ NSDictionary *dict = [RNSConvert idFromFollyDynamic:item]; -+ if ([dict isKindOfClass:[NSDictionary class]]) { -+ [array addObject:dict]; -+ } -+ } -+ _headerToolbarItems = array; -+ } -+ - [self updateViewControllerIfNeeded]; - - if (needsNavigationControllerLayout) { -diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm ---- a/ios/RNSScreenStack.mm -+++ b/ios/RNSScreenStack.mm -@@ -1074,6 +1074,15 @@ RNS_IGNORE_SUPER_CALL_END - return scrollView.contentSize.width > scrollView.frame.size.width; - } - -+// Whether a horizontally scrollable ScrollView is resting at its leading edge, so a -+// pan in the back-gesture direction has nothing left to scroll. Checked in the -+// ScrollView's own coordinate space: React Native mirrors the view for RTL layout, -+// which keeps the leading edge at the minimum content offset in both directions. -+- (BOOL)scrollViewIsAtLeadingEdge:(UIScrollView *)scrollView -+{ -+ return scrollView.contentOffset.x <= -scrollView.adjustedContentInset.left + 1.0; -+} -+ - // Custom method for compatibility with iOS < 13.4 - // RNSScreenStackView is a UIGestureRecognizerDelegate for three types of gesture recognizers: - // RNSPanGestureRecognizer, RNSScreenEdgeGestureRecognizer, _UIParallaxTransitionPanGestureRecognizer -@@ -1167,9 +1176,11 @@ RNS_IGNORE_SUPER_CALL_END - if (gestureRecognizer == _controller.interactiveContentPopGestureRecognizer && - [self isScrollViewPanGestureRecognizer:otherGestureRecognizer]) { - // ScrollView should take precedence when scrolling horizontally (it should be required to fail). -- // However, if it does not allow for horizontal scrolling, there should be no such restriction, -+ // However, if it does not allow for horizontal scrolling, or is already resting at its leading -+ // edge so a back swipe has nothing left to scroll, there should be no such restriction, - // and swiping horizontally should dismiss the screen. -- return [self scrollViewHasHorizontalPart:static_cast(otherGestureRecognizer.view)]; -+ UIScrollView *scrollView = static_cast(otherGestureRecognizer.view); -+ return [self scrollViewHasHorizontalPart:scrollView] && ![self scrollViewIsAtLeadingEdge:scrollView]; - } - } - -@@ -1189,6 +1200,15 @@ RNS_IGNORE_SUPER_CALL_END - // gestureRecognizer:shouldRequireFailureOfGestureRecognizer - isEdgeSwipeGestureRecognizer = - isEdgeSwipeGestureRecognizer && gestureRecognizer != _controller.interactiveContentPopGestureRecognizer; -+ -+ // The exception is a horizontal ScrollView resting at its leading edge: its pan recognizer would -+ // still begin (and merely bounce) on a back swipe, so it must yield to the pop gesture the same -+ // way plain content does. -+ if (gestureRecognizer == _controller.interactiveContentPopGestureRecognizer && -+ [self isScrollViewPanGestureRecognizer:otherGestureRecognizer]) { -+ UIScrollView *scrollView = static_cast(otherGestureRecognizer.view); -+ return [self scrollViewHasHorizontalPart:scrollView] && [self scrollViewIsAtLeadingEdge:scrollView]; -+ } - } - #endif // check for iOS >= 26 - -diff --git a/ios/RNSScreenStackHeaderSubview.mm b/ios/RNSScreenStackHeaderSubview.mm -index add33c4807e038dcd846f6c72b2fc472ded02809..489afa5fa2da09c1ec6986d1832b58bb595396ae 100644 ---- a/ios/RNSScreenStackHeaderSubview.mm -+++ b/ios/RNSScreenStackHeaderSubview.mm -@@ -20,7 +20,9 @@ @implementation RNSScreenStackHeaderSubview { - // This is a strong reference to UIBarButtonItem which creates a retain cycle. - // The cycle is cleared via `invalidateUIBarButtonItem` method, called by `invalidate` callback. - UIBarButtonItem *_barButtonItem; -+ NSString *_barButtonItemIdentifier; - BOOL _hidesSharedBackground; -+ UILabel *_titleScrollEdgeEffectGuide; - } - - #pragma mark - Common -@@ -102,5 +104,24 @@ - (void)updateShadowStateWithFrame:(CGRect)frame - - (void)layoutSubviews - { - [super layoutSubviews]; -+#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) -+ if (@available(iOS 26.0, *)) { -+ if (_type == RNSScreenStackHeaderSubviewTypeTitle || _type == RNSScreenStackHeaderSubviewTypeCenter) { -+ // UIKit shapes the navigation bar's scroll-edge fade around native labels, -+ // but does not recognize Fabric's custom text views. An empty, non-interactive -+ // label supplies the title's geometry without drawing or becoming a bar item. -+ if (_titleScrollEdgeEffectGuide == nil) { -+ _titleScrollEdgeEffectGuide = [UILabel new]; -+ _titleScrollEdgeEffectGuide.accessibilityElementsHidden = YES; -+ // Append after Fabric's children so their mount/unmount indices stay intact. -+ [self addSubview:_titleScrollEdgeEffectGuide]; -+ } -+ _titleScrollEdgeEffectGuide.frame = self.bounds; -+ } else { -+ [_titleScrollEdgeEffectGuide removeFromSuperview]; -+ _titleScrollEdgeEffectGuide = nil; -+ } -+ } -+#endif - [self updateShadowStateInContextOfAncestorView:[self findNavigationBar]]; - } -@@ -124,6 +145,7 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props:: - const auto &newHeaderSubviewProps = *std::static_pointer_cast(props); - - [self setType:[RNSConvert RNSScreenStackHeaderSubviewTypeFromCppEquivalent:newHeaderSubviewProps.type]]; -+ [self setBarButtonItemIdentifier:RCTNSStringFromStringNilIfEmpty(newHeaderSubviewProps.identifier)]; - [self setHidesSharedBackground:newHeaderSubviewProps.hidesSharedBackground]; - [self setSynchronousShadowStateUpdatesEnabled:newHeaderSubviewProps.synchronousShadowStateUpdatesEnabled]; - [super updateProps:props oldProps:oldProps]; -@@ -276,7 +298,14 @@ - (void)configureBarButtonItem - #if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) - if (@available(iOS 26.0, *)) { - if (_barButtonItem != nil) { -- [_barButtonItem setHidesSharedBackground:_hidesSharedBackground]; -+ NSString *currentIdentifier = _barButtonItem.identifier; -+ if (currentIdentifier != _barButtonItemIdentifier && -+ ![currentIdentifier isEqualToString:_barButtonItemIdentifier]) { -+ _barButtonItem.identifier = _barButtonItemIdentifier; -+ } -+ if (_barButtonItem.hidesSharedBackground != _hidesSharedBackground) { -+ _barButtonItem.hidesSharedBackground = _hidesSharedBackground; -+ } - } - } - #endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) -@@ -284,10 +313,22 @@ - (void)configureBarButtonItem - - - (void)setHidesSharedBackground:(BOOL)hidesSharedBackground - { -+ if (_hidesSharedBackground == hidesSharedBackground) { -+ return; -+ } - _hidesSharedBackground = hidesSharedBackground; - [self configureBarButtonItem]; - } - -+- (void)setBarButtonItemIdentifier:(nullable NSString *)identifier -+{ -+ if (_barButtonItemIdentifier == identifier || [_barButtonItemIdentifier isEqualToString:identifier]) { -+ return; -+ } -+ _barButtonItemIdentifier = [identifier copy]; -+ [self configureBarButtonItem]; -+} -+ - #pragma mark - Dynamic frameworks support - - // Needed because of this: https://github.com/facebook/react-native/pull/37274 -diff --git a/lib/commonjs/components/ScreenStackHeaderConfig.js b/lib/commonjs/components/ScreenStackHeaderConfig.js -index 8c509f2657105cfd86448347c1a01fb73651ff9e..e668e089a1788973cb122a150be7846364a2a2cf 100644 ---- a/lib/commonjs/components/ScreenStackHeaderConfig.js -+++ b/lib/commonjs/components/ScreenStackHeaderConfig.js -@@ -26,17 +26,42 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_ - } = (0, _EdgeInsetApplicationContext.useEdgeInsetApplication)(!props.hidden, props.disableTopInsetApplication ?? false, props.disableLeftInsetApplication ?? false, props.disableRightInsetApplication ?? false, props.disableBottomInsetApplication ?? false); - const { - headerLeftBarButtonItems, -- headerRightBarButtonItems -+ headerRightBarButtonItems, -+ headerCenterBarButtonItems, -+ headerToolbarItems - } = props; - const preparedHeaderLeftBarButtonItems = headerLeftBarButtonItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerLeftBarButtonItems, 'left') : undefined; - const preparedHeaderRightBarButtonItems = headerRightBarButtonItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerRightBarButtonItems, 'right') : undefined; -- const hasHeaderBarButtonItems = _utils.isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length); -+ const preparedHeaderCenterBarButtonItems = headerCenterBarButtonItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerCenterBarButtonItems, 'center') : undefined; -+ const preparedHeaderToolbarItems = headerToolbarItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerToolbarItems, 'toolbar') : undefined; -+ const hasHeaderBarButtonItems = _utils.isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length || preparedHeaderCenterBarButtonItems?.length || preparedHeaderToolbarItems?.length); - - // Handle bar button item presses - const onPressHeaderBarButtonItem = hasHeaderBarButtonItems ? event => { -- const pressedItem = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? [])].find(item => item && 'buttonId' in item && item.buttonId === event.nativeEvent.buttonId); -+ const buttonId = event.nativeEvent.buttonId; -+ const allItems = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? []), ...(preparedHeaderCenterBarButtonItems ?? []), ...(preparedHeaderToolbarItems ?? [])]; -+ const pressedItem = allItems.find(item => item && 'buttonId' in item && item.buttonId === buttonId); - if (pressedItem && pressedItem.type === 'button' && pressedItem.onPress) { - pressedItem.onPress(); -+ return; -+ } -+ for (const item of allItems) { -+ if (!item || item.type !== 'mailSearchToolbar') { -+ continue; -+ } -+ if (item.filterButtonId === buttonId) { -+ item.onFilterPress?.(); -+ return; -+ } -+ if (item.composeButtonId === buttonId) { -+ item.onComposePress?.(); -+ return; -+ } -+ const searchTextChangePrefix = item.searchTextChangeId ? `${item.searchTextChangeId}:` : undefined; -+ if (searchTextChangePrefix && buttonId.startsWith(searchTextChangePrefix)) { -+ item.onSearchTextChange?.(buttonId.slice(searchTextChangePrefix.length)); -+ return; -+ } - } - } : undefined; - -@@ -59,7 +84,7 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_ - }; - - // Check each bar-button item with a menu -- const allItems = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? [])]; -+ const allItems = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? []), ...(preparedHeaderCenterBarButtonItems ?? []), ...(preparedHeaderToolbarItems ?? [])]; - for (const item of allItems) { - if (item && item.type === 'menu' && item.menu) { - const action = findInMenu(item.menu, event.nativeEvent.menuId); -@@ -67,6 +92,15 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_ - action.onPress(); - return; - } -+ } else if (item && item.type === 'mailSearchToolbar') { -+ const toolbarMenus = [item.filterMenu, item.composeMenu].filter(Boolean); -+ for (const toolbarMenu of toolbarMenus) { -+ const action = findInMenu(toolbarMenu, event.nativeEvent.menuId); -+ if (action) { -+ action.onPress(); -+ return; -+ } -+ } - } - } - } : undefined; -@@ -74,6 +108,8 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_ - userInterfaceStyle: props.experimental_userInterfaceStyle, - headerLeftBarButtonItems: preparedHeaderLeftBarButtonItems, - headerRightBarButtonItems: preparedHeaderRightBarButtonItems, -+ headerCenterBarButtonItems: preparedHeaderCenterBarButtonItems, -+ headerToolbarItems: preparedHeaderToolbarItems, - onPressHeaderBarButtonItem: onPressHeaderBarButtonItem, - onPressHeaderBarButtonMenuItem: onPressHeaderBarButtonMenuItem, - ref: ref, -diff --git a/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js b/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js -index ab93f62e4a7049d63c6681cecbd6cf8b1d07ce10..9dca2ab640e92161eb647b819a989acd0d41d9fe 100644 ---- a/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js -+++ b/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js -@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", { - }); - exports.prepareHeaderBarButtonItems = void 0; - var _reactNative = require("react-native"); --const prepareMenu = (menu, index, side, path = '') => { -+const prepareMenu = (menu, index, placement, path = '') => { - return { - ...menu, - items: menu.items.map((menuItem, menuIndex) => { -@@ -26,7 +26,7 @@ const prepareMenu = (menu, index, side, path = '') => { - xcassetName, - imageSource, - templateSource, -- ...prepareMenu(menuItem, index, side, currentPath) -+ ...prepareMenu(menuItem, index, placement, currentPath) - }; - } - return { -@@ -35,16 +35,40 @@ const prepareMenu = (menu, index, side, path = '') => { - xcassetName, - imageSource, - templateSource, -- menuId: `${currentPath}-${index}-${side}` -+ menuId: `${currentPath}-${index}-${placement}` - }; - }) - }; - }; --const prepareHeaderBarButtonItems = (barButtonItems, side) => { -- return barButtonItems?.map((item, index) => { -+const prepareHeaderBarButtonItems = (barButtonItems, placement) => { -+ const items = Array.isArray(barButtonItems) ? barButtonItems : barButtonItems && typeof barButtonItems === 'object' && 'type' in barButtonItems ? [barButtonItems] : undefined; -+ return items?.map((item, index) => { - if (item.type === 'spacing') { - return item; - } -+ if (item.type === 'searchBarPlacement') { -+ if (placement !== 'toolbar') { -+ return null; -+ } -+ return { -+ ...item, -+ searchBarPlacement: true -+ }; -+ } -+ if (item.type === 'searchField') { -+ return { -+ ...item, -+ searchField: true -+ }; -+ } -+ if (item.type === 'mailSearchToolbar') { -+ return { -+ ...item, -+ mailSearchToolbar: true, -+ filterMenu: item.filterMenu ? prepareMenu(item.filterMenu, index, placement, 'filter') : undefined, -+ composeMenu: item.composeMenu ? prepareMenu(item.composeMenu, index, placement, 'compose') : undefined -+ }; -+ } - let imageSource, templateSource; - if (item.icon?.type === 'imageSource') { - imageSource = _reactNative.Image.resolveAssetSource(item.icon.imageSource); -@@ -77,17 +101,17 @@ const prepareHeaderBarButtonItems = (barButtonItems, side) => { - if (item.type === 'button') { - return { - ...processedItem, -- buttonId: `${index}-${side}` -+ buttonId: `${index}-${placement}` - }; - } - if (item.type === 'menu') { - return { - ...processedItem, -- menu: prepareMenu(item.menu, index, side) -+ menu: prepareMenu(item.menu, index, placement) - }; - } - return null; -- }); -+ }).filter(item => item !== null); - }; - exports.prepareHeaderBarButtonItems = prepareHeaderBarButtonItems; - //# sourceMappingURL=prepareHeaderBarButtonItems.js.map -\ No newline at end of file -diff --git a/lib/module/components/ScreenStackHeaderConfig.js b/lib/module/components/ScreenStackHeaderConfig.js -index 68e3ba6a78314aba908d07098bb6982d11e6ee80..db5d17bfdac19ed3e664b55b6a73ce49766ac7c5 100644 ---- a/lib/module/components/ScreenStackHeaderConfig.js -+++ b/lib/module/components/ScreenStackHeaderConfig.js -@@ -22,17 +22,42 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref - } = useEdgeInsetApplication(!props.hidden, props.disableTopInsetApplication ?? false, props.disableLeftInsetApplication ?? false, props.disableRightInsetApplication ?? false, props.disableBottomInsetApplication ?? false); - const { - headerLeftBarButtonItems, -- headerRightBarButtonItems -+ headerRightBarButtonItems, -+ headerCenterBarButtonItems, -+ headerToolbarItems - } = props; - const preparedHeaderLeftBarButtonItems = headerLeftBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerLeftBarButtonItems, 'left') : undefined; - const preparedHeaderRightBarButtonItems = headerRightBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerRightBarButtonItems, 'right') : undefined; -- const hasHeaderBarButtonItems = isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length); -+ const preparedHeaderCenterBarButtonItems = headerCenterBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerCenterBarButtonItems, 'center') : undefined; -+ const preparedHeaderToolbarItems = headerToolbarItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerToolbarItems, 'toolbar') : undefined; -+ const hasHeaderBarButtonItems = isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length || preparedHeaderCenterBarButtonItems?.length || preparedHeaderToolbarItems?.length); - - // Handle bar button item presses - const onPressHeaderBarButtonItem = hasHeaderBarButtonItems ? event => { -- const pressedItem = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? [])].find(item => item && 'buttonId' in item && item.buttonId === event.nativeEvent.buttonId); -+ const buttonId = event.nativeEvent.buttonId; -+ const allItems = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? []), ...(preparedHeaderCenterBarButtonItems ?? []), ...(preparedHeaderToolbarItems ?? [])]; -+ const pressedItem = allItems.find(item => item && 'buttonId' in item && item.buttonId === buttonId); - if (pressedItem && pressedItem.type === 'button' && pressedItem.onPress) { - pressedItem.onPress(); -+ return; -+ } -+ for (const item of allItems) { -+ if (!item || item.type !== 'mailSearchToolbar') { -+ continue; -+ } -+ if (item.filterButtonId === buttonId) { -+ item.onFilterPress?.(); -+ return; -+ } -+ if (item.composeButtonId === buttonId) { -+ item.onComposePress?.(); -+ return; -+ } -+ const searchTextChangePrefix = item.searchTextChangeId ? `${item.searchTextChangeId}:` : undefined; -+ if (searchTextChangePrefix && buttonId.startsWith(searchTextChangePrefix)) { -+ item.onSearchTextChange?.(buttonId.slice(searchTextChangePrefix.length)); -+ return; -+ } - } - } : undefined; - -@@ -55,7 +80,7 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref - }; - - // Check each bar-button item with a menu -- const allItems = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? [])]; -+ const allItems = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? []), ...(preparedHeaderCenterBarButtonItems ?? []), ...(preparedHeaderToolbarItems ?? [])]; - for (const item of allItems) { - if (item && item.type === 'menu' && item.menu) { - const action = findInMenu(item.menu, event.nativeEvent.menuId); -@@ -63,6 +88,15 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref - action.onPress(); - return; - } -+ } else if (item && item.type === 'mailSearchToolbar') { -+ const toolbarMenus = [item.filterMenu, item.composeMenu].filter(Boolean); -+ for (const toolbarMenu of toolbarMenus) { -+ const action = findInMenu(toolbarMenu, event.nativeEvent.menuId); -+ if (action) { -+ action.onPress(); -+ return; -+ } -+ } - } - } - } : undefined; -@@ -70,6 +104,8 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref - userInterfaceStyle: props.experimental_userInterfaceStyle, - headerLeftBarButtonItems: preparedHeaderLeftBarButtonItems, - headerRightBarButtonItems: preparedHeaderRightBarButtonItems, -+ headerCenterBarButtonItems: preparedHeaderCenterBarButtonItems, -+ headerToolbarItems: preparedHeaderToolbarItems, - onPressHeaderBarButtonItem: onPressHeaderBarButtonItem, - onPressHeaderBarButtonMenuItem: onPressHeaderBarButtonMenuItem, - ref: ref, -diff --git a/lib/module/components/helpers/prepareHeaderBarButtonItems.js b/lib/module/components/helpers/prepareHeaderBarButtonItems.js -index 8a70ffd78617147418d628c03c580bb7ff9a8a72..bca930372d2a7c3f8e0a35c3dcf28474f899f21c 100644 ---- a/lib/module/components/helpers/prepareHeaderBarButtonItems.js -+++ b/lib/module/components/helpers/prepareHeaderBarButtonItems.js -@@ -1,5 +1,5 @@ - import { Image, processColor } from 'react-native'; --const prepareMenu = (menu, index, side, path = '') => { -+const prepareMenu = (menu, index, placement, path = '') => { - return { - ...menu, - items: menu.items.map((menuItem, menuIndex) => { -@@ -20,7 +20,7 @@ const prepareMenu = (menu, index, side, path = '') => { - xcassetName, - imageSource, - templateSource, -- ...prepareMenu(menuItem, index, side, currentPath) -+ ...prepareMenu(menuItem, index, placement, currentPath) - }; - } - return { -@@ -29,16 +29,40 @@ const prepareMenu = (menu, index, side, path = '') => { - xcassetName, - imageSource, - templateSource, -- menuId: `${currentPath}-${index}-${side}` -+ menuId: `${currentPath}-${index}-${placement}` - }; - }) - }; - }; --export const prepareHeaderBarButtonItems = (barButtonItems, side) => { -- return barButtonItems?.map((item, index) => { -+export const prepareHeaderBarButtonItems = (barButtonItems, placement) => { -+ const items = Array.isArray(barButtonItems) ? barButtonItems : barButtonItems && typeof barButtonItems === 'object' && 'type' in barButtonItems ? [barButtonItems] : undefined; -+ return items?.map((item, index) => { - if (item.type === 'spacing') { - return item; - } -+ if (item.type === 'searchBarPlacement') { -+ if (placement !== 'toolbar') { -+ return null; -+ } -+ return { -+ ...item, -+ searchBarPlacement: true -+ }; -+ } -+ if (item.type === 'searchField') { -+ return { -+ ...item, -+ searchField: true -+ }; -+ } -+ if (item.type === 'mailSearchToolbar') { -+ return { -+ ...item, -+ mailSearchToolbar: true, -+ filterMenu: item.filterMenu ? prepareMenu(item.filterMenu, index, placement, 'filter') : undefined, -+ composeMenu: item.composeMenu ? prepareMenu(item.composeMenu, index, placement, 'compose') : undefined -+ }; -+ } - let imageSource, templateSource; - if (item.icon?.type === 'imageSource') { - imageSource = Image.resolveAssetSource(item.icon.imageSource); -@@ -71,16 +95,16 @@ export const prepareHeaderBarButtonItems = (barButtonItems, side) => { - if (item.type === 'button') { - return { - ...processedItem, -- buttonId: `${index}-${side}` -+ buttonId: `${index}-${placement}` - }; - } - if (item.type === 'menu') { - return { - ...processedItem, -- menu: prepareMenu(item.menu, index, side) -+ menu: prepareMenu(item.menu, index, placement) - }; - } - return null; -- }); -+ }).filter(item => item !== null); - }; - //# sourceMappingURL=prepareHeaderBarButtonItems.js.map -\ No newline at end of file -diff --git a/lib/typescript/components/helpers/prepareHeaderBarButtonItems.d.ts b/lib/typescript/components/helpers/prepareHeaderBarButtonItems.d.ts -index c41ef943e554754f599f2fcd157dd0dc61d78b7e..ed02d44f78ee3f1387ba93bf292be2b99bb0e3b3 100644 ---- a/lib/typescript/components/helpers/prepareHeaderBarButtonItems.d.ts -+++ b/lib/typescript/components/helpers/prepareHeaderBarButtonItems.d.ts -@@ -1,5 +1,5 @@ - import { HeaderBarButtonItem } from 'react-native-screens/types'; --export declare const prepareHeaderBarButtonItems: (barButtonItems: HeaderBarButtonItem[], side: "left" | "right") => (import("react-native-screens/types").HeaderBarButtonItemSpacing | { -+export declare const prepareHeaderBarButtonItems: (barButtonItems: HeaderBarButtonItem[], side: "left" | "right" | "center" | "toolbar") => (import("react-native-screens/types").HeaderBarButtonItemSpacing | { - buttonId: string; - imageSource: import("react-native").ImageResolvedAssetSource | undefined; - templateSource: import("react-native").ImageResolvedAssetSource | undefined; -@@ -161,5 +161,5 @@ export declare const prepareHeaderBarButtonItems: (barButtonItems: HeaderBarButt - identifier?: string | undefined; - accessibilityLabel?: string | undefined; - accessibilityHint?: string | undefined; --} | null)[]; -+})[]; - //# sourceMappingURL=prepareHeaderBarButtonItems.d.ts.map -\ No newline at end of file -diff --git a/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts b/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts -index a51d8648567cff29cd2be0d5262bd15c6fc69c61..8b7439aff4d7e6fe8a72bf0bac93c3c19568b1a6 100644 ---- a/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts -+++ b/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts -@@ -9,6 +9,7 @@ type OnPressHeaderBarButtonMenuItemEvent = Readonly<{ - menuId: string; - }>; - type BackButtonDisplayMode = 'minimal' | 'default' | 'generic'; -+type NavigationItemStyle = 'navigator' | 'browser' | 'editor'; - type BlurEffect = 'none' | 'extraLight' | 'light' | 'dark' | 'regular' | 'prominent' | 'systemUltraThinMaterial' | 'systemThinMaterial' | 'systemMaterial' | 'systemThickMaterial' | 'systemChromeMaterial' | 'systemUltraThinMaterialLight' | 'systemThinMaterialLight' | 'systemMaterialLight' | 'systemThickMaterialLight' | 'systemChromeMaterialLight' | 'systemUltraThinMaterialDark' | 'systemThinMaterialDark' | 'systemMaterialDark' | 'systemThickMaterialDark' | 'systemChromeMaterialDark'; - type UserInterfaceStyle = 'unspecified' | 'light' | 'dark'; - export interface NativeProps extends ViewProps { -@@ -32,18 +33,23 @@ export interface NativeProps extends ViewProps { - largeTitleColor?: ColorValue | undefined; - translucent?: boolean | undefined; - title?: string | undefined; -+ subtitle?: string | undefined; -+ largeSubtitle?: string | undefined; - titleFontFamily?: string | undefined; - titleFontSize?: CT.Int32 | undefined; - titleFontWeight?: string | undefined; - titleColor?: ColorValue | undefined; - disableBackButtonMenu?: boolean | undefined; - backButtonDisplayMode?: CT.WithDefault; -+ navigationItemStyle?: CT.WithDefault; - hideBackButton?: boolean | undefined; - backButtonInCustomView?: boolean | undefined; - blurEffect?: CT.WithDefault; - topInsetEnabled?: boolean | undefined; - headerLeftBarButtonItems?: CT.UnsafeMixed[] | undefined; - headerRightBarButtonItems?: CT.UnsafeMixed[] | undefined; -+ headerCenterBarButtonItems?: CT.UnsafeMixed[] | undefined; -+ headerToolbarItems?: CT.UnsafeMixed[] | undefined; - onPressHeaderBarButtonItem?: CT.DirectEventHandler | undefined; - onPressHeaderBarButtonMenuItem?: CT.DirectEventHandler | undefined; - synchronousShadowStateUpdatesEnabled?: CT.WithDefault; -diff --git a/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts b/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts -index 1ca926e6753294861f5f79ab6267dc7999f70639..94e676fdb08ff9d1cf81a1cf06a45e931b5461f1 100644 ---- a/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts -+++ b/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts -@@ -3,6 +3,7 @@ export type HeaderSubviewTypes = 'back' | 'right' | 'left' | 'title' | 'center' - export interface NativeProps extends ViewProps { - type?: CT.WithDefault; - hidesSharedBackground?: boolean | undefined; -+ identifier?: string | undefined; - synchronousShadowStateUpdatesEnabled?: CT.WithDefault; - } - declare const _default: import("react-native").HostComponent; -diff --git a/lib/typescript/types.d.ts b/lib/typescript/types.d.ts -index 10a31341f4eff258a7f8ea6abae3eddf0dd21218..bab5031f5f9b246f15e5396f3f2fee90b91d826a 100644 ---- a/lib/typescript/types.d.ts -+++ b/lib/typescript/types.d.ts -@@ -10,6 +10,7 @@ export type SearchBarCommands = { - cancelSearch: () => void; - }; - export type BackButtonDisplayMode = 'default' | 'generic' | 'minimal'; -+export type NavigationItemStyle = 'navigator' | 'browser' | 'editor'; - export type StackPresentationTypes = 'push' | 'modal' | 'transparentModal' | 'containedModal' | 'containedTransparentModal' | 'fullScreenModal' | 'formSheet' | 'pageSheet'; - export type StackAnimationTypes = 'default' | 'fade' | 'fade_from_bottom' | 'flip' | 'none' | 'simple_push' | 'slide_from_bottom' | 'slide_from_right' | 'slide_from_left' | 'ios_from_right' | 'ios_from_left'; - export type BlurEffectTypes = BlurEffect; -@@ -631,6 +632,14 @@ export interface ScreenStackHeaderConfigProps extends ViewProps { - * @platform ios - */ - backButtonDisplayMode?: BackButtonDisplayMode | undefined; -+ /** -+ * Controls the UIKit `UINavigationItem.style` used by native iOS headers. -+ * -+ * `editor` matches modern document/editor-style bars with leading-aligned compact titles and glass controls. -+ * -+ * @platform ios -+ */ -+ navigationItemStyle?: NavigationItemStyle | undefined; - /** - * Array of UIBarButtomItems to the left side of the header. - * -@@ -643,6 +652,26 @@ export interface ScreenStackHeaderConfigProps extends ViewProps { - * @platform ios - */ - headerRightBarButtonItems?: HeaderBarButtonItem[] | undefined; -+ /** -+ * Array of UIBarButtonItems to the centered item group in modern iOS headers. -+ * -+ * This maps to `UINavigationItem.centerItemGroups` on iOS 26+ and lets -+ * document/editor-style chrome keep primary actions visually centered while -+ * leaving trailing search separate. -+ * -+ * @platform ios -+ */ -+ headerCenterBarButtonItems?: HeaderBarButtonItem[] | undefined; -+ /** -+ * Array of UIBarButtonItems to display in the native toolbar attached to -+ * the current screen's navigation controller. -+ * -+ * On iOS 26+, this can contain a `searchBarPlacement` item to let UIKit -+ * render integrated Mail-style search chrome using the attached SearchBar. -+ * -+ * @platform ios -+ */ -+ headerToolbarItems?: HeaderBarButtonItem[] | undefined; - /** - * When set to true the header will be hidden while the parent Screen is on the top of the stack. The default value is false. - */ -@@ -704,6 +733,20 @@ export interface ScreenStackHeaderConfigProps extends ViewProps { - * String that can be displayed in the header as a fallback for `headerTitle`. - */ - title?: string | undefined; -+ /** -+ * String displayed below the compact navigation title on iOS 26+. -+ * -+ * @platform ios -+ */ -+ subtitle?: string | undefined; -+ /** -+ * String displayed below the large navigation title on iOS 26+. -+ * -+ * Falls back to `subtitle` when omitted. -+ * -+ * @platform ios -+ */ -+ largeSubtitle?: string | undefined; - /** - * Allows for setting text color of the title. - */ -@@ -999,6 +1042,13 @@ export interface SearchBarProps { - shouldShowHintSearchIcon?: boolean | undefined; - } - export interface ScreenStackHeaderSubviewProps { -+ /** -+ * An identifier used to match this item across navigation bar transitions. -+ * Only applicable to type="right" and type="left" subviews on iOS 26.0 and later. -+ * -+ * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/identifier -+ */ -+ identifier?: string | undefined; - /** - * A boolean value indicating whether the background this item may share with other items in the bar should be hidden. - * Only applicable to type="right" and type="left" subviews. -@@ -1037,6 +1087,11 @@ interface SharedHeaderBarButtonItem { - * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/style-swift.property - */ - variant?: 'plain' | 'done' | 'prominent' | undefined; -+ /** -+ * Render the item with UIButtonConfiguration.glassButtonConfiguration. -+ * Only available from iOS 26.0 and later. -+ */ -+ glassEffect?: boolean | undefined; - /** - * The tint color to apply to the item. - * -@@ -1181,8 +1236,38 @@ export interface HeaderBarButtonItemWithMenu extends SharedHeaderBarButtonItem { - export interface HeaderBarButtonItemSpacing { - type: 'spacing'; - spacing: number; -+ flexible?: boolean | undefined; -+} -+export interface HeaderBarButtonSearchBarPlacementItem { -+ type: 'searchBarPlacement'; -+ activatesSearchController?: boolean | undefined; -+ customView?: boolean | undefined; -+ index?: number | undefined; -+ width?: number | undefined; -+} -+export interface HeaderBarButtonSearchFieldItem { -+ type: 'searchField'; -+ placeholder?: string | undefined; -+ width?: number | undefined; -+} -+export interface HeaderBarButtonMailSearchToolbarItem { -+ type: 'mailSearchToolbar'; -+ composeButtonId?: string | undefined; -+ composeMenu?: HeaderBarButtonItemWithMenu['menu'] | undefined; -+ composeSystemImageName?: string | undefined; -+ filterButtonId?: string | undefined; -+ filterMenu?: HeaderBarButtonItemWithMenu['menu'] | undefined; -+ filterSystemImageName?: string | undefined; -+ onComposePress?: (() => void) | undefined; -+ onFilterPress?: (() => void) | undefined; -+ onSearchTextChange?: ((text: string) => void) | undefined; -+ placeholder?: string | undefined; -+ searchTextChangeId?: string | undefined; -+ showsSearchDismissButton?: boolean | undefined; -+ useFallbackSearchField?: boolean | undefined; -+ width?: number | undefined; - } --export type HeaderBarButtonItem = HeaderBarButtonItemWithAction | HeaderBarButtonItemWithMenu | HeaderBarButtonItemSpacing; -+export type HeaderBarButtonItem = HeaderBarButtonItemWithAction | HeaderBarButtonItemWithMenu | HeaderBarButtonMailSearchToolbarItem | HeaderBarButtonSearchFieldItem | HeaderBarButtonSearchBarPlacementItem | HeaderBarButtonItemSpacing; - /** - * Custom Screen Transition - */ -diff --git a/src/components/ScreenStackHeaderConfig.tsx b/src/components/ScreenStackHeaderConfig.tsx -index c3a88b6f6c8362cf717372a35cdc35a6b397bdd0..9e8173da567933fd3f6819fb26bf4a0e87640767 100644 ---- a/src/components/ScreenStackHeaderConfig.tsx -+++ b/src/components/ScreenStackHeaderConfig.tsx -@@ -48,7 +48,12 @@ export const ScreenStackHeaderConfig = React.forwardRef< - props.disableBottomInsetApplication ?? false, - ); - -- const { headerLeftBarButtonItems, headerRightBarButtonItems } = props; -+ const { -+ headerLeftBarButtonItems, -+ headerRightBarButtonItems, -+ headerCenterBarButtonItems, -+ headerToolbarItems, -+ } = props; - - const preparedHeaderLeftBarButtonItems = - headerLeftBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform -@@ -58,22 +63,36 @@ export const ScreenStackHeaderConfig = React.forwardRef< - headerRightBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform - ? prepareHeaderBarButtonItems(headerRightBarButtonItems, 'right') - : undefined; -+ const preparedHeaderCenterBarButtonItems = -+ headerCenterBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform -+ ? prepareHeaderBarButtonItems(headerCenterBarButtonItems, 'center') -+ : undefined; -+ const preparedHeaderToolbarItems = -+ headerToolbarItems && isHeaderBarButtonsAvailableForCurrentPlatform -+ ? prepareHeaderBarButtonItems(headerToolbarItems, 'toolbar') -+ : undefined; - const hasHeaderBarButtonItems = - isHeaderBarButtonsAvailableForCurrentPlatform && - (preparedHeaderLeftBarButtonItems?.length || -- preparedHeaderRightBarButtonItems?.length); -+ preparedHeaderRightBarButtonItems?.length || -+ preparedHeaderCenterBarButtonItems?.length || -+ preparedHeaderToolbarItems?.length); - - // Handle bar button item presses - const onPressHeaderBarButtonItem = hasHeaderBarButtonItems - ? (event: NativeSyntheticEvent<{ buttonId: string }>) => { -- const pressedItem = [ -+ const buttonId = event.nativeEvent.buttonId; -+ const allItems = [ - ...(preparedHeaderLeftBarButtonItems ?? []), - ...(preparedHeaderRightBarButtonItems ?? []), -- ].find( -+ ...(preparedHeaderCenterBarButtonItems ?? []), -+ ...(preparedHeaderToolbarItems ?? []), -+ ]; -+ const pressedItem = allItems.find( - item => - item && - 'buttonId' in item && -- item.buttonId === event.nativeEvent.buttonId, -+ item.buttonId === buttonId, - ); - if ( - pressedItem && -@@ -81,6 +100,32 @@ export const ScreenStackHeaderConfig = React.forwardRef< - pressedItem.onPress - ) { - pressedItem.onPress(); -+ return; -+ } -+ for (const item of allItems) { -+ if (!item || item.type !== 'mailSearchToolbar') { -+ continue; -+ } -+ if (item.filterButtonId === buttonId) { -+ item.onFilterPress?.(); -+ return; -+ } -+ if (item.composeButtonId === buttonId) { -+ item.onComposePress?.(); -+ return; -+ } -+ const searchTextChangePrefix = item.searchTextChangeId -+ ? `${item.searchTextChangeId}:` -+ : undefined; -+ if ( -+ searchTextChangePrefix && -+ buttonId.startsWith(searchTextChangePrefix) -+ ) { -+ item.onSearchTextChange?.( -+ buttonId.slice(searchTextChangePrefix.length), -+ ); -+ return; -+ } - } - } - : undefined; -@@ -111,6 +156,8 @@ export const ScreenStackHeaderConfig = React.forwardRef< - const allItems = [ - ...(preparedHeaderLeftBarButtonItems ?? []), - ...(preparedHeaderRightBarButtonItems ?? []), -+ ...(preparedHeaderCenterBarButtonItems ?? []), -+ ...(preparedHeaderToolbarItems ?? []), - ]; - for (const item of allItems) { - if (item && item.type === 'menu' && item.menu) { -@@ -119,6 +166,17 @@ export const ScreenStackHeaderConfig = React.forwardRef< - action.onPress(); - return; - } -+ } else if (item && item.type === 'mailSearchToolbar') { -+ const toolbarMenus = [item.filterMenu, item.composeMenu].filter( -+ Boolean, -+ ); -+ for (const toolbarMenu of toolbarMenus) { -+ const action = findInMenu(toolbarMenu, event.nativeEvent.menuId); -+ if (action) { -+ action.onPress(); -+ return; -+ } -+ } - } - } - } -@@ -130,6 +188,8 @@ export const ScreenStackHeaderConfig = React.forwardRef< - userInterfaceStyle={props.experimental_userInterfaceStyle} - headerLeftBarButtonItems={preparedHeaderLeftBarButtonItems} - headerRightBarButtonItems={preparedHeaderRightBarButtonItems} -+ headerCenterBarButtonItems={preparedHeaderCenterBarButtonItems} -+ headerToolbarItems={preparedHeaderToolbarItems} - onPressHeaderBarButtonItem={onPressHeaderBarButtonItem} - onPressHeaderBarButtonMenuItem={onPressHeaderBarButtonMenuItem} - ref={ref} -diff --git a/src/components/helpers/prepareHeaderBarButtonItems.ts b/src/components/helpers/prepareHeaderBarButtonItems.ts -index be2c24dfee77f5883b5ab1d7473be80933b5dc6f..2008a342f13806641909c19a9f4ab6829f239016 100644 ---- a/src/components/helpers/prepareHeaderBarButtonItems.ts -+++ b/src/components/helpers/prepareHeaderBarButtonItems.ts -@@ -7,7 +7,7 @@ import { - const prepareMenu = ( - menu: HeaderBarButtonItemWithMenu['menu'], - index: number, -- side: 'left' | 'right', -+ placement: 'left' | 'right' | 'center' | 'toolbar', - path: string = '', - ): HeaderBarButtonItemWithMenu['menu'] => { - return { -@@ -34,7 +34,7 @@ const prepareMenu = ( - xcassetName, - imageSource, - templateSource, -- ...prepareMenu(menuItem, index, side, currentPath), -+ ...prepareMenu(menuItem, index, placement, currentPath), - }; - } - return { -@@ -43,20 +43,53 @@ const prepareMenu = ( - xcassetName, - imageSource, - templateSource, -- menuId: `${currentPath}-${index}-${side}`, -+ menuId: `${currentPath}-${index}-${placement}`, - }; - }), - }; - }; - - export const prepareHeaderBarButtonItems = ( -- barButtonItems: HeaderBarButtonItem[], -- side: 'left' | 'right', -+ barButtonItems: -+ | HeaderBarButtonItem[] -+ | HeaderBarButtonItem -+ | null -+ | undefined, -+ placement: 'left' | 'right' | 'center' | 'toolbar', - ) => { -- return barButtonItems?.map((item, index) => { -+ const items = Array.isArray(barButtonItems) -+ ? barButtonItems -+ : barButtonItems && typeof barButtonItems === 'object' && 'type' in barButtonItems -+ ? [barButtonItems] -+ : undefined; -+ -+ return items?.map((item, index) => { - if (item.type === 'spacing') { - return item; - } -+ if (item.type === 'searchBarPlacement') { -+ if (placement !== 'toolbar') { -+ return null; -+ } -+ return { -+ ...item, -+ searchBarPlacement: true, -+ }; -+ } -+ if (item.type === 'searchField') { -+ return { -+ ...item, -+ searchField: true, -+ }; -+ } -+ if (item.type === 'mailSearchToolbar') { -+ return { -+ ...item, -+ mailSearchToolbar: true, -+ filterMenu: item.filterMenu ? prepareMenu(item.filterMenu, index, placement, 'filter') : undefined, -+ composeMenu: item.composeMenu ? prepareMenu(item.composeMenu, index, placement, 'compose') : undefined, -+ }; -+ } - let imageSource, templateSource; - if (item.icon?.type === 'imageSource') { - imageSource = Image.resolveAssetSource(item.icon.imageSource); -@@ -91,15 +124,15 @@ export const prepareHeaderBarButtonItems = ( - if (item.type === 'button') { - return { - ...processedItem, -- buttonId: `${index}-${side}`, -+ buttonId: `${index}-${placement}`, - }; - } - if (item.type === 'menu') { - return { - ...processedItem, -- menu: prepareMenu(item.menu, index, side), -+ menu: prepareMenu(item.menu, index, placement), - }; - } - return null; -- }); -+ }).filter(item => item !== null); - }; -diff --git a/src/fabric/ScreenStackHeaderConfigNativeComponent.ts b/src/fabric/ScreenStackHeaderConfigNativeComponent.ts -index a80d9fef0c0ab5ce8221c5e0c7fae65162bc6164..fc16f51425702a418c09de553a54753331f19d15 100644 ---- a/src/fabric/ScreenStackHeaderConfigNativeComponent.ts -+++ b/src/fabric/ScreenStackHeaderConfigNativeComponent.ts -@@ -14,6 +14,7 @@ type OnPressHeaderBarButtonItemEvent = Readonly<{ buttonId: string }>; - type OnPressHeaderBarButtonMenuItemEvent = Readonly<{ menuId: string }>; - - type BackButtonDisplayMode = 'minimal' | 'default' | 'generic'; -+type NavigationItemStyle = 'navigator' | 'browser' | 'editor'; - - type BlurEffect = - | 'none' -@@ -61,12 +62,15 @@ export interface NativeProps extends ViewProps { - largeTitleColor?: ColorValue | undefined; - translucent?: boolean | undefined; - title?: string | undefined; -+ subtitle?: string | undefined; -+ largeSubtitle?: string | undefined; - titleFontFamily?: string | undefined; - titleFontSize?: CT.Int32 | undefined; - titleFontWeight?: string | undefined; - titleColor?: ColorValue | undefined; - disableBackButtonMenu?: boolean | undefined; - backButtonDisplayMode?: CT.WithDefault; -+ navigationItemStyle?: CT.WithDefault; - hideBackButton?: boolean | undefined; - backButtonInCustomView?: boolean | undefined; - blurEffect?: CT.WithDefault; -@@ -74,6 +78,8 @@ export interface NativeProps extends ViewProps { - topInsetEnabled?: boolean | undefined; - headerLeftBarButtonItems?: CT.UnsafeMixed[] | undefined; - headerRightBarButtonItems?: CT.UnsafeMixed[] | undefined; -+ headerCenterBarButtonItems?: CT.UnsafeMixed[] | undefined; -+ headerToolbarItems?: CT.UnsafeMixed[] | undefined; - onPressHeaderBarButtonItem?: - | CT.DirectEventHandler - | undefined; -diff --git a/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts b/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts -index 7d3fbfe08c70461936832a40a1ce8d9c11b22457..1f9caca6271b68d182b70a180f180d6a4ce3988c 100644 ---- a/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts -+++ b/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts -@@ -14,6 +14,7 @@ export type HeaderSubviewTypes = - export interface NativeProps extends ViewProps { - type?: CT.WithDefault; - hidesSharedBackground?: boolean | undefined; -+ identifier?: string | undefined; - synchronousShadowStateUpdatesEnabled?: CT.WithDefault; - } - -diff --git a/src/types.tsx b/src/types.tsx -index 9c3ab4c3653ee1769addda8a6464cdf49695a601..6f242ad2bbd7152ea9f873ef7754ad47caf2466d 100644 ---- a/src/types.tsx -+++ b/src/types.tsx -@@ -26,6 +26,7 @@ export type SearchBarCommands = { - }; - - export type BackButtonDisplayMode = 'default' | 'generic' | 'minimal'; -+export type NavigationItemStyle = 'navigator' | 'browser' | 'editor'; - export type StackPresentationTypes = - | 'push' - | 'modal' -@@ -735,6 +736,14 @@ export interface ScreenStackHeaderConfigProps extends ViewProps { - * @platform ios - */ - backButtonDisplayMode?: BackButtonDisplayMode | undefined; -+ /** -+ * Controls the UIKit `UINavigationItem.style` used by native iOS headers. -+ * -+ * `editor` matches modern document/editor-style bars with leading-aligned compact titles and glass controls. -+ * -+ * @platform ios -+ */ -+ navigationItemStyle?: NavigationItemStyle | undefined; - /** - * Array of UIBarButtomItems to the left side of the header. - * -@@ -747,6 +756,26 @@ export interface ScreenStackHeaderConfigProps extends ViewProps { - * @platform ios - */ - headerRightBarButtonItems?: HeaderBarButtonItem[] | undefined; -+ /** -+ * Array of UIBarButtonItems to the centered item group in modern iOS headers. -+ * -+ * This maps to `UINavigationItem.centerItemGroups` on iOS 26+ and lets -+ * document/editor-style chrome keep primary actions visually centered while -+ * leaving trailing search separate. -+ * -+ * @platform ios -+ */ -+ headerCenterBarButtonItems?: HeaderBarButtonItem[] | undefined; -+ /** -+ * Array of UIBarButtonItems to display in the native toolbar attached to -+ * the current screen's navigation controller. -+ * -+ * On iOS 26+, this can contain a `searchBarPlacement` item to let UIKit -+ * render integrated Mail-style search chrome using the attached SearchBar. -+ * -+ * @platform ios -+ */ -+ headerToolbarItems?: HeaderBarButtonItem[] | undefined; - /** - * When set to true the header will be hidden while the parent Screen is on the top of the stack. The default value is false. - */ -@@ -808,6 +837,20 @@ export interface ScreenStackHeaderConfigProps extends ViewProps { - * String that can be displayed in the header as a fallback for `headerTitle`. - */ - title?: string | undefined; -+ /** -+ * String displayed below the compact navigation title on iOS 26+. -+ * -+ * @platform ios -+ */ -+ subtitle?: string | undefined; -+ /** -+ * String displayed below the large navigation title on iOS 26+. -+ * -+ * Falls back to `subtitle` when omitted. -+ * -+ * @platform ios -+ */ -+ largeSubtitle?: string | undefined; - /** - * Allows for setting text color of the title. - */ -@@ -1120,6 +1163,13 @@ export interface SearchBarProps { - } - - export interface ScreenStackHeaderSubviewProps { -+ /** -+ * An identifier used to match this item across navigation bar transitions. -+ * Only applicable to type="right" and type="left" subviews on iOS 26.0 and later. -+ * -+ * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/identifier -+ */ -+ identifier?: string | undefined; - /** - * A boolean value indicating whether the background this item may share with other items in the bar should be hidden. - * Only applicable to type="right" and type="left" subviews. -@@ -1161,6 +1211,11 @@ interface SharedHeaderBarButtonItem { - * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/style-swift.property - */ - variant?: 'plain' | 'done' | 'prominent' | undefined; -+ /** -+ * Render the item with UIButtonConfiguration.glassButtonConfiguration. -+ * Only available from iOS 26.0 and later. -+ */ -+ glassEffect?: boolean | undefined; - /** - * The tint color to apply to the item. - * -@@ -1315,11 +1370,47 @@ export interface HeaderBarButtonItemWithMenu extends SharedHeaderBarButtonItem { - export interface HeaderBarButtonItemSpacing { - type: 'spacing'; - spacing: number; -+ flexible?: boolean | undefined; -+} -+ -+export interface HeaderBarButtonSearchBarPlacementItem { -+ type: 'searchBarPlacement'; -+ activatesSearchController?: boolean | undefined; -+ customView?: boolean | undefined; -+ index?: number | undefined; -+ width?: number | undefined; -+} -+ -+export interface HeaderBarButtonSearchFieldItem { -+ type: 'searchField'; -+ placeholder?: string | undefined; -+ width?: number | undefined; -+} -+ -+export interface HeaderBarButtonMailSearchToolbarItem { -+ type: 'mailSearchToolbar'; -+ composeButtonId?: string | undefined; -+ composeMenu?: HeaderBarButtonItemWithMenu['menu'] | undefined; -+ composeSystemImageName?: string | undefined; -+ filterButtonId?: string | undefined; -+ filterMenu?: HeaderBarButtonItemWithMenu['menu'] | undefined; -+ filterSystemImageName?: string | undefined; -+ onComposePress?: (() => void) | undefined; -+ onFilterPress?: (() => void) | undefined; -+ onSearchTextChange?: ((text: string) => void) | undefined; -+ placeholder?: string | undefined; -+ searchTextChangeId?: string | undefined; -+ showsSearchDismissButton?: boolean | undefined; -+ useFallbackSearchField?: boolean | undefined; -+ width?: number | undefined; - } - - export type HeaderBarButtonItem = - | HeaderBarButtonItemWithAction - | HeaderBarButtonItemWithMenu -+ | HeaderBarButtonMailSearchToolbarItem -+ | HeaderBarButtonSearchFieldItem -+ | HeaderBarButtonSearchBarPlacementItem - | HeaderBarButtonItemSpacing; - - /** diff --git a/patches/react-native-screens@4.28.0.patch b/patches/react-native-screens@4.28.0.patch new file mode 100644 index 0000000000000000000000000000000000000000..8b07155c5afe0d7b5cf3d35391663dda5a0085f6 --- /dev/null +++ b/patches/react-native-screens@4.28.0.patch @@ -0,0 +1,2232 @@ +diff --git a/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt b/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +index fa1b773..270c81c 100644 +--- a/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt ++++ b/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +@@ -124,6 +124,34 @@ class ScreenStackHeaderConfigViewManager : + config.setTitle(title) + } + ++ // The t3 patch adds these iOS glass-chrome props to the native spec; they have ++ // no Android implementation, but the codegen-generated interface requires the ++ // setters to exist. No-ops keep the Android build compiling. ++ override fun setSubtitle( ++ config: ScreenStackHeaderConfig, ++ subtitle: String?, ++ ) = Unit ++ ++ override fun setLargeSubtitle( ++ config: ScreenStackHeaderConfig, ++ largeSubtitle: String?, ++ ) = Unit ++ ++ override fun setNavigationItemStyle( ++ config: ScreenStackHeaderConfig, ++ navigationItemStyle: String?, ++ ) = Unit ++ ++ override fun setHeaderCenterBarButtonItems( ++ config: ScreenStackHeaderConfig, ++ headerCenterBarButtonItems: ReadableArray?, ++ ) = Unit ++ ++ override fun setHeaderToolbarItems( ++ config: ScreenStackHeaderConfig, ++ headerToolbarItems: ReadableArray?, ++ ) = Unit ++ + override fun setTitleFontFamily( + config: ScreenStackHeaderConfig, + titleFontFamily: String?, +diff --git a/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt b/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +index 64f14f0..6cb1d69 100644 +--- a/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt ++++ b/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +@@ -47,6 +47,12 @@ class ScreenStackHeaderSubviewManager : + Log.w("[RNScreens]", "hidesSharedBackground prop is not available on Android") + } + ++ // Bar button transition identifiers only apply on iOS. ++ override fun setIdentifier( ++ view: ScreenStackHeaderSubview, ++ identifier: String?, ++ ) = Unit ++ + // synchronousShadowStateUpdatesEnabled is not available on Android atm, + // however we must override their setters + override fun setSynchronousShadowStateUpdatesEnabled( +diff --git a/ios/RNSBarButtonItem.h b/ios/RNSBarButtonItem.h +index a26d125..62eea42 100644 +--- a/ios/RNSBarButtonItem.h ++++ b/ios/RNSBarButtonItem.h +@@ -15,6 +15,10 @@ typedef void (^RNSBarButtonMenuItemAction)(NSString *menuId); + action:(RNSBarButtonItemAction)action + menuAction:(RNSBarButtonMenuItemAction)menuAction + imageLoader:(RCTImageLoader *)imageLoader; ++ +++ (UIMenu *)initUIMenuWithDict:(NSDictionary *)dict ++ menuAction:(RNSBarButtonMenuItemAction)menuAction ++ imageLoader:(RCTImageLoader *)imageLoader; + #endif // defined(__cplusplus) + + @end +diff --git a/ios/RNSBarButtonItem.mm b/ios/RNSBarButtonItem.mm +index 76a39d4..15bd5a9 100644 +--- a/ios/RNSBarButtonItem.mm ++++ b/ios/RNSBarButtonItem.mm +@@ -110,6 +110,58 @@ - (instancetype)initWithConfig:(NSDictionary *)dict + if (dict[@"accessibilityHint"]) { + self.accessibilityHint = dict[@"accessibilityHint"]; + } ++#if !TARGET_OS_TV && RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) ++ NSNumber *glassEffectNum = dict[@"glassEffect"]; ++ if (@available(iOS 26.0, *)) { ++ if ([glassEffectNum boolValue]) { ++ UIButtonConfiguration *configuration = [UIButtonConfiguration glassButtonConfiguration]; ++ configuration.cornerStyle = UIButtonConfigurationCornerStyleCapsule; ++ UIBackgroundConfiguration *background = configuration.background; ++ background.strokeWidth = 0.0; ++ background.strokeColor = UIColor.clearColor; ++ configuration.background = background; ++ configuration.contentInsets = NSDirectionalEdgeInsetsZero; ++ if (title != nil) { ++ configuration.title = title; ++ } ++ ++ UIButton *button = [UIButton buttonWithConfiguration:configuration primaryAction:nil]; ++ button.translatesAutoresizingMaskIntoConstraints = NO; ++ button.enabled = self.enabled; ++ button.accessibilityLabel = self.accessibilityLabel; ++ button.accessibilityHint = self.accessibilityHint; ++ ++ CGFloat resolvedWidth = width != nil ? width.doubleValue : 56.0; ++ [button.widthAnchor constraintEqualToConstant:resolvedWidth].active = YES; ++ [button.heightAnchor constraintEqualToConstant:50.0].active = YES; ++ ++ [[self class] resolveImageFromConfig:dict ++ imageLoader:imageLoader ++ completionBlock:^(UIImage *img) { ++ UIButtonConfiguration *updatedConfiguration = button.configuration; ++ updatedConfiguration.image = img; ++ button.configuration = updatedConfiguration; ++ }]; ++ ++ NSDictionary *menu = dict[@"menu"]; ++ if (menu) { ++ button.menu = [[self class] initUIMenuWithDict:menu menuAction:menuAction imageLoader:imageLoader]; ++ button.showsMenuAsPrimaryAction = YES; ++ } else { ++ NSString *buttonId = dict[@"buttonId"]; ++ if (buttonId && action) { ++ UIAction *pressAction = [UIAction actionWithHandler:^(__kindof UIAction *_Nonnull sender) { ++ action(buttonId); ++ }]; ++ [button addAction:pressAction forControlEvents:UIControlEventTouchUpInside]; ++ } ++ } ++ ++ self.customView = button; ++ return self; ++ } ++ } ++#endif + + #if !TARGET_OS_TV || __TV_OS_VERSION_MAX_ALLOWED >= 170000 + if (@available(tvOS 17.0, *)) { +diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm +index c233036..0c2db42 100644 +--- a/ios/RNSScreenStack.mm ++++ b/ios/RNSScreenStack.mm +@@ -1076,6 +1076,15 @@ - (BOOL)scrollViewHasHorizontalPart:(UIScrollView *)scrollView + return scrollView.contentSize.width > scrollView.frame.size.width; + } + ++// Whether a horizontally scrollable ScrollView is resting at its leading edge, so a ++// pan in the back-gesture direction has nothing left to scroll. Checked in the ++// ScrollView's own coordinate space: React Native mirrors the view for RTL layout, ++// which keeps the leading edge at the minimum content offset in both directions. ++- (BOOL)scrollViewIsAtLeadingEdge:(UIScrollView *)scrollView ++{ ++ return scrollView.contentOffset.x <= -scrollView.adjustedContentInset.left + 1.0; ++} ++ + // Custom method for compatibility with iOS < 13.4 + // RNSScreenStackView is a UIGestureRecognizerDelegate for three types of gesture recognizers: + // RNSPanGestureRecognizer, RNSScreenEdgeGestureRecognizer, _UIParallaxTransitionPanGestureRecognizer +@@ -1169,9 +1178,11 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer + if (gestureRecognizer == _controller.interactiveContentPopGestureRecognizer && + [self isScrollViewPanGestureRecognizer:otherGestureRecognizer]) { + // ScrollView should take precedence when scrolling horizontally (it should be required to fail). +- // However, if it does not allow for horizontal scrolling, there should be no such restriction, ++ // However, if it does not allow for horizontal scrolling, or is already resting at its leading ++ // edge so a back swipe has nothing left to scroll, there should be no such restriction, + // and swiping horizontally should dismiss the screen. +- return [self scrollViewHasHorizontalPart:static_cast(otherGestureRecognizer.view)]; ++ UIScrollView *scrollView = static_cast(otherGestureRecognizer.view); ++ return [self scrollViewHasHorizontalPart:scrollView] && ![self scrollViewIsAtLeadingEdge:scrollView]; + } + } + +@@ -1191,6 +1202,15 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer + // gestureRecognizer:shouldRequireFailureOfGestureRecognizer + isEdgeSwipeGestureRecognizer = + isEdgeSwipeGestureRecognizer && gestureRecognizer != _controller.interactiveContentPopGestureRecognizer; ++ ++ // The exception is a horizontal ScrollView resting at its leading edge: its pan recognizer would ++ // still begin (and merely bounce) on a back swipe, so it must yield to the pop gesture the same ++ // way plain content does. ++ if (gestureRecognizer == _controller.interactiveContentPopGestureRecognizer && ++ [self isScrollViewPanGestureRecognizer:otherGestureRecognizer]) { ++ UIScrollView *scrollView = static_cast(otherGestureRecognizer.view); ++ return [self scrollViewHasHorizontalPart:scrollView] && [self scrollViewIsAtLeadingEdge:scrollView]; ++ } + } + #endif // check for iOS >= 26 + +diff --git a/ios/RNSScreenStackHeaderConfig.h b/ios/RNSScreenStackHeaderConfig.h +index 8a41697..309ba2f 100644 +--- a/ios/RNSScreenStackHeaderConfig.h ++++ b/ios/RNSScreenStackHeaderConfig.h +@@ -23,6 +23,8 @@ + NS_ASSUME_NONNULL_BEGIN + + @property (nonatomic, retain) NSString *title; ++@property (nonatomic, retain) NSString *subtitle; ++@property (nonatomic, retain) NSString *largeSubtitle; + @property (nonatomic, retain) NSString *titleFontFamily; + @property (nonatomic, retain) NSNumber *titleFontSize; + @property (nonatomic, retain) NSString *titleFontWeight; +@@ -47,9 +49,12 @@ NS_ASSUME_NONNULL_BEGIN + @property (nonatomic) BOOL backButtonInCustomView; + @property (nonatomic) UISemanticContentAttribute direction; + @property (nonatomic) UINavigationItemBackButtonDisplayMode backButtonDisplayMode; ++@property (nonatomic) NSInteger navigationItemStyle; + @property (nonatomic) RNSBlurEffectStyle blurEffect; + @property (nonatomic, copy, nullable) NSArray *> *headerRightBarButtonItems; + @property (nonatomic, copy, nullable) NSArray *> *headerLeftBarButtonItems; ++@property (nonatomic, copy, nullable) NSArray *> *headerCenterBarButtonItems; ++@property (nonatomic, copy, nullable) NSArray *> *headerToolbarItems; + @property (nonatomic, readwrite) BOOL synchronousShadowStateUpdatesEnabled; + + NS_ASSUME_NONNULL_END +diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm +index a54cb63..4ff30b3 100644 +--- a/ios/RNSScreenStackHeaderConfig.mm ++++ b/ios/RNSScreenStackHeaderConfig.mm +@@ -24,11 +24,46 @@ + #import "RNSSearchBar.h" + #import "UINavigationBar+RNSUtility.h" + ++#import ++ + namespace react = facebook::react; + + static const NSNumber *const DEFAULT_TITLE_FONT_SIZE = @17; ++ ++#if !TARGET_OS_TV ++// Each placement keeps its own cache so changes to one side do not move live ++// items on the other side into new groups during a navigation transition. ++static char RNSAppliedLeadingHeaderItemsKey; ++static char RNSAppliedTrailingHeaderItemsKey; ++static char RNSAppliedCenterHeaderItemsKey; ++ ++// Records a placement's owner and contents, returning whether they changed. ++static BOOL RNSUpdateHeaderItemsCache(UINavigationItem *navitem, const void *key, NSArray *itemsKey) ++{ ++ if ([objc_getAssociatedObject(navitem, key) isEqual:itemsKey]) { ++ return NO; ++ } ++ objc_setAssociatedObject(navitem, key, itemsKey, OBJC_ASSOCIATION_RETAIN_NONATOMIC); ++ return YES; ++} ++#endif ++static char RNSAppliedToolbarConfigsKey; + static const NSNumber *const DEFAULT_TITLE_LARGE_FONT_SIZE = @34; + ++static NSInteger navigationItemStyleFromCppEquivalent( ++ react::RNSScreenStackHeaderConfigNavigationItemStyle navigationItemStyle) ++{ ++ switch (navigationItemStyle) { ++ case react::RNSScreenStackHeaderConfigNavigationItemStyle::Browser: ++ return UINavigationItemStyleBrowser; ++ case react::RNSScreenStackHeaderConfigNavigationItemStyle::Editor: ++ return UINavigationItemStyleEditor; ++ case react::RNSScreenStackHeaderConfigNavigationItemStyle::Navigator: ++ default: ++ return UINavigationItemStyleNavigator; ++ } ++} ++ + @interface RCTImageLoader (Private) + - (id)imageCache; + @end +@@ -46,6 +81,9 @@ + (BOOL)rnscreens_isBlankOrNull:(NSString *)string + @end + + @interface RNSScreenStackHeaderConfig () ++#if !TARGET_OS_TV ++- (NSArray *)barButtonItemGroupsFromItems:(NSArray *)items; ++#endif + @end + + @implementation RNSScreenStackHeaderConfig { +@@ -80,6 +118,7 @@ - (void)initProps + self.hidden = YES; + _reactSubviews = [NSMutableArray new]; + _backTitleVisible = YES; ++ _navigationItemStyle = UINavigationItemStyleNavigator; + _blurEffect = RNSBlurEffectStyleNone; + _synchronousShadowStateUpdatesEnabled = YES; + } +@@ -507,6 +546,10 @@ + (void)updateViewController:(UIViewController *)vc + + if (shouldHide) { + navitem.title = config.title; ++ if (@available(iOS 26.0, *)) { ++ navitem.subtitle = config.subtitle; ++ navitem.largeSubtitle = config.largeSubtitle; ++ } + + // Setting navigation bar visibility is split to mitigate iOS 26 bug with bar button items. + [navctr setNavigationBarHidden:YES animated:animated]; +@@ -523,11 +566,19 @@ + (void)updateViewController:(UIViewController *)vc + } + navitem.largeTitleDisplayMode = + config.largeTitle ? UINavigationItemLargeTitleDisplayModeAlways : UINavigationItemLargeTitleDisplayModeNever; ++ ++ if (@available(iOS 16.0, *)) { ++ navitem.style = (UINavigationItemStyle)config.navigationItemStyle; ++ } + #endif + + UINavigationBarAppearance *appearance = [self buildAppearance:vc withConfig:config]; + navitem.standardAppearance = appearance; + navitem.compactAppearance = appearance; ++ if (@available(iOS 26.0, *)) { ++ navitem.subtitle = config.subtitle; ++ navitem.largeSubtitle = config.largeSubtitle; ++ } + + // appearance does not apply to the tvOS so we need to use lagacy customization + #if TARGET_OS_TV +@@ -559,8 +610,6 @@ + (void)updateViewController:(UIViewController *)vc + navitem.leftItemsSupplementBackButton = config.backButtonInCustomView; + #endif + navitem.titleView = nil; +- navitem.leftBarButtonItems = nil; +- navitem.rightBarButtonItems = nil; + + #if !TARGET_OS_TV + // We want to set navitem.searchController to nil only if we are sure +@@ -568,22 +617,18 @@ + (void)updateViewController:(UIViewController *)vc + bool searchBarPresent = false; + #endif /* !TARGET_OS_TV */ + ++ NSMutableArray *subviewLeftItems = [NSMutableArray array]; ++ NSMutableArray *subviewRightItems = [NSMutableArray array]; + for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) { + // This code should be kept in sync on Fabric with analogous switch statement in + // `- [RNSScreenStackHeaderConfig replaceNavigationBarViewsWithSnapshotOfSubview:]` method. + switch (subview.type) { + case RNSScreenStackHeaderSubviewTypeLeft: { +- NSArray *currentItems = navitem.leftBarButtonItems ?: @[]; +- NSMutableArray *mutableItems = [currentItems mutableCopy]; +- [mutableItems addObject:[subview getUIBarButtonItem]]; +- navitem.leftBarButtonItems = mutableItems; ++ [subviewLeftItems addObject:[subview getUIBarButtonItem]]; + break; + } + case RNSScreenStackHeaderSubviewTypeRight: { +- NSArray *currentItems = navitem.rightBarButtonItems ?: @[]; +- NSMutableArray *mutableItems = [currentItems mutableCopy]; +- [mutableItems addObject:[subview getUIBarButtonItem]]; +- navitem.rightBarButtonItems = mutableItems; ++ [subviewRightItems addObject:[subview getUIBarButtonItem]]; + break; + } + case RNSScreenStackHeaderSubviewTypeCenter: +@@ -648,10 +693,479 @@ + (void)updateViewController:(UIViewController *)vc + // This assignment should be done after `navitem.titleView = ...` assignment (iOS 16.0 bug). + // See: https://github.com/software-mansion/react-native-screens/issues/1570 (comments) + navitem.title = config.title; +- navitem.leftBarButtonItems = [config barButtonItemsFromConfigs:config.headerLeftBarButtonItems +- withCurrentItems:navitem.leftBarButtonItems]; +- navitem.rightBarButtonItems = [config barButtonItemsFromConfigs:config.headerRightBarButtonItems +- withCurrentItems:navitem.rightBarButtonItems]; ++ // Retain the config in the key so its address cannot be reused while cached. ++ // Items capture this config's event emitter in their press handlers, so a ++ // remounted header-config view with value-equal configs must still rebuild ++ // instead of dispatching presses into the old config's emitter. ++ // getUIBarButtonItem is stable for the lifetime of its React header ++ // subview. Include those native identities in the key so React-backed ++ // items can use the same cache without reusing a group after its view was ++ // replaced. ++ // A bar button item can belong to only one group. Even if the item itself ++ // is reused, constructing a new group removes it from the old group that ++ // UIKit may still be animating. Preserve each unchanged placement's group, ++ // including the empty leading group beside the system back button. ++#if !TARGET_OS_TV ++ if (@available(iOS 16.0, *)) { ++ NSArray *headerLeftConfigs = config.headerLeftBarButtonItems ?: @[]; ++ NSArray *headerRightConfigs = config.headerRightBarButtonItems ?: @[]; ++ NSArray *headerCenterConfigs = config.headerCenterBarButtonItems ?: @[]; ++ if (RNSUpdateHeaderItemsCache( ++ navitem, &RNSAppliedLeadingHeaderItemsKey, @[ config, headerLeftConfigs, subviewLeftItems ])) { ++ NSArray *items = [config barButtonItemsFromConfigs:config.headerLeftBarButtonItems ++ withCurrentItems:subviewLeftItems ++ navigationItem:navitem ++ allowsSearchBarPlacement:NO]; ++ navitem.leadingItemGroups = [config barButtonItemGroupsFromItems:items]; ++ } ++ if (RNSUpdateHeaderItemsCache( ++ navitem, &RNSAppliedTrailingHeaderItemsKey, @[ config, headerRightConfigs, subviewRightItems ])) { ++ NSArray *items = [config barButtonItemsFromConfigs:config.headerRightBarButtonItems ++ withCurrentItems:subviewRightItems ++ navigationItem:navitem ++ allowsSearchBarPlacement:NO]; ++ navitem.trailingItemGroups = [config barButtonItemGroupsFromItems:items]; ++ } ++ if (@available(iOS 26.0, *)) { ++ if (RNSUpdateHeaderItemsCache(navitem, &RNSAppliedCenterHeaderItemsKey, @[ config, headerCenterConfigs ])) { ++ NSArray *items = [config barButtonItemsFromConfigs:config.headerCenterBarButtonItems ++ withCurrentItems:@[] ++ navigationItem:navitem ++ allowsSearchBarPlacement:NO]; ++ navitem.centerItemGroups = [config barButtonItemGroupsFromItems:items]; ++ } ++ } ++ } else ++#endif ++ { ++ NSArray *leftBarButtonItems = [config barButtonItemsFromConfigs:config.headerLeftBarButtonItems ++ withCurrentItems:subviewLeftItems ++ navigationItem:navitem ++ allowsSearchBarPlacement:NO]; ++ NSArray *rightBarButtonItems = [config barButtonItemsFromConfigs:config.headerRightBarButtonItems ++ withCurrentItems:subviewRightItems ++ navigationItem:navitem ++ allowsSearchBarPlacement:NO]; ++ navitem.leftBarButtonItems = leftBarButtonItems; ++ navitem.rightBarButtonItems = rightBarButtonItems; ++ } ++ NSDictionary *mailSearchToolbarConfig = nil; ++ NSMutableArray *> *nonMailSearchToolbarConfigs = [NSMutableArray array]; ++ for (NSDictionary *toolbarConfig in config.headerToolbarItems) { ++ if (toolbarConfig[@"mailSearchToolbar"]) { ++ if (mailSearchToolbarConfig == nil) { ++ mailSearchToolbarConfig = toolbarConfig; ++ } ++ } else { ++ [nonMailSearchToolbarConfigs addObject:toolbarConfig]; ++ } ++ } ++ NSArray *> *navigationToolbarConfigs = [nonMailSearchToolbarConfigs copy]; ++ if (mailSearchToolbarConfig == nil) { ++ for (NSDictionary *rightConfig in config.headerRightBarButtonItems) { ++ if ([rightConfig[@"bottomMailSearchToolbar"] boolValue]) { ++ mailSearchToolbarConfig = rightConfig; ++ break; ++ } ++ } ++ } ++ ++ static NSInteger const RNSMailSearchToolbarViewTag = 260628; ++ UIView *chromeHostView = vc.view; ++ UIView *existingMailSearchToolbar = [chromeHostView viewWithTag:RNSMailSearchToolbarViewTag]; ++ if (existingMailSearchToolbar == nil) { ++ existingMailSearchToolbar = [vc.view viewWithTag:RNSMailSearchToolbarViewTag]; ++ } ++ // Reuse the live toolbar when nothing it was built from changed: rebuilding ++ // replaces the fallback UISearchTextField with a fresh empty one, dropping ++ // the user's in-progress search text and first responder on every unrelated ++ // header update. Keyed on the config instance (the button/search blocks ++ // capture its event emitter), the toolbar config values, and the host width ++ // (the width constraint constant is resolved from it at build time). ++ static char RNSAppliedMailSearchToolbarConfigKey; ++ NSArray *mailSearchToolbarKey = mailSearchToolbarConfig != nil ++ ? @[ @((uintptr_t)config), mailSearchToolbarConfig, @(chromeHostView.bounds.size.width) ] ++ : nil; ++ BOOL reuseMailSearchToolbar = existingMailSearchToolbar != nil && mailSearchToolbarKey != nil && ++ [objc_getAssociatedObject(existingMailSearchToolbar, &RNSAppliedMailSearchToolbarConfigKey) ++ isEqual:mailSearchToolbarKey]; ++ if (!reuseMailSearchToolbar) { ++ [existingMailSearchToolbar removeFromSuperview]; ++ } ++ ++ if (mailSearchToolbarConfig != nil && !reuseMailSearchToolbar) { ++#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) ++ if (@available(iOS 26.0, *)) { ++ CGFloat horizontalInset = 18.0; ++ NSNumber *width = mailSearchToolbarConfig[@"width"]; ++ CGFloat hostWidth = chromeHostView.bounds.size.width; ++ if (hostWidth <= 0.0) { ++ hostWidth = vc.view.bounds.size.width; ++ } ++ if (hostWidth <= 0.0) { ++ hostWidth = [UIScreen mainScreen].bounds.size.width; ++ } ++ CGFloat fallbackWidth = MIN(560.0, MAX(300.0, hostWidth - (horizontalInset * 2.0))); ++ CGFloat resolvedWidth = width != nil ? width.doubleValue : fallbackWidth; ++ if (hostWidth > 0.0) { ++ resolvedWidth = MIN(resolvedWidth, MAX(260.0, hostWidth - 12.0)); ++ } ++ ++ CGFloat toolbarHeight = 48.0; ++ CGFloat toolbarRadius = toolbarHeight / 2.0; ++ CGFloat buttonSize = toolbarHeight; ++ CGFloat sideButtonReserve = buttonSize + 8.0; ++ CGFloat searchFieldHeight = 42.0; ++ CGFloat toolbarBottomSpacing = 4.0; ++ UIFont *searchFont = [UIFont preferredFontForTextStyle:UIFontTextStyleTitle3]; ++ NSDictionary *placeholderAttributes = @{ ++ NSForegroundColorAttributeName : UIColor.secondaryLabelColor, ++ NSFontAttributeName : searchFont, ++ }; ++ UIKeyboardLayoutGuide *keyboardLayoutGuide = chromeHostView.keyboardLayoutGuide; ++ ++ UIView *toolbarHost = [[UIView alloc] init]; ++ toolbarHost.tag = RNSMailSearchToolbarViewTag; ++ objc_setAssociatedObject( ++ toolbarHost, ++ &RNSAppliedMailSearchToolbarConfigKey, ++ mailSearchToolbarKey, ++ OBJC_ASSOCIATION_RETAIN_NONATOMIC); ++ toolbarHost.translatesAutoresizingMaskIntoConstraints = NO; ++ [chromeHostView addSubview:toolbarHost]; ++ // The screen stays mounted beneath pushed routes, so its keyboard layout ++ // guide can track a keyboard owned by another screen. Keep the toolbar at ++ // rest unless its own search field is editing. ++ NSLayoutConstraint *keyboardAvoidConstraint = ++ [toolbarHost.bottomAnchor constraintEqualToAnchor:keyboardLayoutGuide.topAnchor ++ constant:-toolbarBottomSpacing]; ++ keyboardAvoidConstraint.priority = UILayoutPriorityDefaultLow; ++ NSLayoutConstraint *restingBottomConstraint = ++ [toolbarHost.bottomAnchor constraintEqualToAnchor:chromeHostView.safeAreaLayoutGuide.bottomAnchor ++ constant:-toolbarBottomSpacing]; ++ restingBottomConstraint.priority = UILayoutPriorityDefaultHigh; ++ [NSLayoutConstraint activateConstraints:@[ ++ [toolbarHost.centerXAnchor constraintEqualToAnchor:chromeHostView.centerXAnchor], ++ [toolbarHost.bottomAnchor constraintLessThanOrEqualToAnchor:chromeHostView.safeAreaLayoutGuide.bottomAnchor ++ constant:-toolbarBottomSpacing], ++ keyboardAvoidConstraint, ++ restingBottomConstraint, ++ [toolbarHost.widthAnchor constraintEqualToConstant:resolvedWidth], ++ [toolbarHost.heightAnchor constraintEqualToConstant:toolbarHeight], ++ ]]; ++ [chromeHostView bringSubviewToFront:toolbarHost]; ++ ++ UIGlassEffect *glassEffect = [UIGlassEffect effectWithStyle:UIGlassEffectStyleRegular]; ++ glassEffect.interactive = YES; ++ UIVisualEffectView *glassView = [[UIVisualEffectView alloc] initWithEffect:glassEffect]; ++ glassView.clipsToBounds = YES; ++ glassView.layer.cornerRadius = toolbarRadius; ++ glassView.translatesAutoresizingMaskIntoConstraints = NO; ++ [toolbarHost addSubview:glassView]; ++ BOOL hasFilterButton = ++ mailSearchToolbarConfig[@"filterButtonId"] != nil || mailSearchToolbarConfig[@"filterMenu"] != nil; ++ BOOL hasComposeButton = ++ mailSearchToolbarConfig[@"composeButtonId"] != nil || mailSearchToolbarConfig[@"composeMenu"] != nil; ++ CGFloat glassLeadingInset = hasFilterButton ? sideButtonReserve : 0.0; ++ CGFloat glassTrailingInset = hasComposeButton ? -sideButtonReserve : 0.0; ++ NSLayoutConstraint *glassLeadingConstraint = ++ [glassView.leadingAnchor constraintEqualToAnchor:toolbarHost.leadingAnchor constant:glassLeadingInset]; ++ NSLayoutConstraint *glassTrailingConstraint = ++ [glassView.trailingAnchor constraintEqualToAnchor:toolbarHost.trailingAnchor constant:glassTrailingInset]; ++ [NSLayoutConstraint activateConstraints:@[ ++ glassLeadingConstraint, ++ glassTrailingConstraint, ++ [glassView.centerYAnchor constraintEqualToAnchor:toolbarHost.centerYAnchor], ++ [glassView.heightAnchor constraintEqualToConstant:toolbarHeight], ++ ]]; ++ ++ void (^emitButtonPress)(NSString *) = ^(NSString *buttonId) { ++ auto eventEmitter = std::static_pointer_cast( ++ config->_eventEmitter); ++ if (eventEmitter && buttonId) { ++ eventEmitter->onPressHeaderBarButtonItem( ++ facebook::react::RNSScreenStackHeaderConfigEventEmitter::OnPressHeaderBarButtonItem{ ++ .buttonId = std::string([buttonId UTF8String])}); ++ } ++ }; ++ ++ void (^emitMenuPress)(NSString *) = ^(NSString *menuId) { ++ auto eventEmitter = std::static_pointer_cast( ++ config->_eventEmitter); ++ if (eventEmitter && menuId) { ++ eventEmitter->onPressHeaderBarButtonMenuItem( ++ facebook::react::RNSScreenStackHeaderConfigEventEmitter::OnPressHeaderBarButtonMenuItem{ ++ .menuId = std::string([menuId UTF8String])}); ++ } ++ }; ++ ++ UIButton *(^makeGlassButton)(NSString *, NSString *, NSDictionary *) = ++ ^UIButton *(NSString *systemImageName, NSString *buttonId, NSDictionary *menuConfig) { ++ UIButtonConfiguration *configuration = [UIButtonConfiguration glassButtonConfiguration]; ++ configuration.cornerStyle = UIButtonConfigurationCornerStyleCapsule; ++ configuration.image = [UIImage systemImageNamed:systemImageName ?: @"circle"]; ++ configuration.baseForegroundColor = UIColor.labelColor; ++ UIButton *button = [UIButton buttonWithConfiguration:configuration primaryAction:nil]; ++ if (menuConfig != nil) { ++ button.menu = [RNSBarButtonItem initUIMenuWithDict:menuConfig ++ menuAction:emitMenuPress ++ imageLoader:config->_imageLoader]; ++ button.showsMenuAsPrimaryAction = YES; ++ } else if (buttonId != nil) { ++ UIAction *action = [UIAction actionWithHandler:^(__kindof UIAction *_Nonnull action) { ++ emitButtonPress(buttonId); ++ }]; ++ [button addAction:action forControlEvents:UIControlEventTouchUpInside]; ++ } ++ return button; ++ }; ++ ++ BOOL useFallbackSearchField = [mailSearchToolbarConfig[@"useFallbackSearchField"] boolValue]; ++ UISearchBar *searchBar = ++ !useFallbackSearchField && navitem.searchController != nil ? navitem.searchController.searchBar : nil; ++ NSString *placeholder = mailSearchToolbarConfig[@"placeholder"]; ++ UITextField *resolvedSearchTextField = nil; ++ if (searchBar != nil) { ++ if (placeholder != nil) { ++ searchBar.placeholder = placeholder; ++ } ++ searchBar.hidden = NO; ++ searchBar.alpha = 1.0; ++ searchBar.userInteractionEnabled = YES; ++ searchBar.searchBarStyle = UISearchBarStyleMinimal; ++ searchBar.backgroundImage = [UIImage new]; ++ searchBar.searchTextField.hidden = NO; ++ searchBar.searchTextField.alpha = 1.0; ++ searchBar.searchTextField.backgroundColor = UIColor.clearColor; ++ searchBar.searchTextField.font = searchFont; ++ searchBar.searchTextField.adjustsFontForContentSizeCategory = YES; ++ searchBar.searchTextField.textColor = UIColor.labelColor; ++ searchBar.searchTextField.tintColor = UIColor.labelColor; ++ resolvedSearchTextField = searchBar.searchTextField; ++ if (placeholder != nil) { ++ searchBar.searchTextField.attributedPlaceholder = ++ [[NSAttributedString alloc] initWithString:placeholder attributes:placeholderAttributes]; ++ } ++ searchBar.translatesAutoresizingMaskIntoConstraints = NO; ++ [glassView.contentView addSubview:searchBar]; ++ [NSLayoutConstraint activateConstraints:@[ ++ [searchBar.leadingAnchor constraintEqualToAnchor:glassView.contentView.leadingAnchor constant:8.0], ++ [searchBar.trailingAnchor constraintEqualToAnchor:glassView.contentView.trailingAnchor constant:-8.0], ++ [searchBar.centerYAnchor constraintEqualToAnchor:glassView.contentView.centerYAnchor], ++ [searchBar.heightAnchor constraintEqualToConstant:searchFieldHeight], ++ ]]; ++ } else { ++ UISearchTextField *searchField = [UISearchTextField new]; ++ if (placeholder != nil) { ++ searchField.placeholder = placeholder; ++ searchField.attributedPlaceholder = ++ [[NSAttributedString alloc] initWithString:placeholder attributes:placeholderAttributes]; ++ } ++ searchField.borderStyle = UITextBorderStyleNone; ++ searchField.font = searchFont; ++ searchField.adjustsFontForContentSizeCategory = YES; ++ searchField.textColor = UIColor.labelColor; ++ searchField.tintColor = UIColor.labelColor; ++ resolvedSearchTextField = searchField; ++ searchField.translatesAutoresizingMaskIntoConstraints = NO; ++ [glassView.contentView addSubview:searchField]; ++ [NSLayoutConstraint activateConstraints:@[ ++ [searchField.leadingAnchor constraintEqualToAnchor:glassView.contentView.leadingAnchor constant:14.0], ++ [searchField.trailingAnchor constraintEqualToAnchor:glassView.contentView.trailingAnchor constant:-14.0], ++ [searchField.centerYAnchor constraintEqualToAnchor:glassView.contentView.centerYAnchor], ++ [searchField.heightAnchor constraintEqualToConstant:searchFieldHeight], ++ ]]; ++ } ++ ++ // A bare UISearchTextField keeps UITextField defaults (sentence ++ // capitalization, autocorrect), unlike UISearchBar. Search queries are ++ // identifiers, so match the autoCapitalize "none" the JS fallbacks use. ++ if (resolvedSearchTextField != nil) { ++ resolvedSearchTextField.autocapitalizationType = UITextAutocapitalizationTypeNone; ++ resolvedSearchTextField.autocorrectionType = UITextAutocorrectionTypeNo; ++ resolvedSearchTextField.spellCheckingType = UITextSpellCheckingTypeNo; ++ } ++ ++ NSString *searchTextChangeId = mailSearchToolbarConfig[@"searchTextChangeId"]; ++ NSString *searchTextChangeActionIdentifier = @"org.react-native-screens.mail-search-toolbar.text-change"; ++ if (resolvedSearchTextField != nil) { ++ [resolvedSearchTextField removeActionForIdentifier:searchTextChangeActionIdentifier ++ forControlEvents:UIControlEventEditingChanged]; ++ } ++ if (searchTextChangeId != nil && resolvedSearchTextField != nil) { ++ [resolvedSearchTextField ++ addAction:[UIAction actionWithTitle:@"" ++ image:nil ++ identifier:searchTextChangeActionIdentifier ++ handler:^(__kindof UIAction *_Nonnull action) { ++ UITextField *field = (UITextField *)action.sender; ++ emitButtonPress( ++ [NSString stringWithFormat:@"%@:%@", searchTextChangeId, field.text ?: @""]); ++ }] ++ forControlEvents:UIControlEventEditingChanged]; ++ } ++ ++ UIButton *filterButton = nil; ++ if (hasFilterButton) { ++ filterButton = makeGlassButton( ++ mailSearchToolbarConfig[@"filterSystemImageName"] ?: @"line.3.horizontal.decrease", ++ mailSearchToolbarConfig[@"filterButtonId"], ++ mailSearchToolbarConfig[@"filterMenu"]); ++ filterButton.translatesAutoresizingMaskIntoConstraints = NO; ++ [toolbarHost addSubview:filterButton]; ++ [NSLayoutConstraint activateConstraints:@[ ++ [filterButton.leadingAnchor constraintEqualToAnchor:toolbarHost.leadingAnchor], ++ [filterButton.centerYAnchor constraintEqualToAnchor:toolbarHost.centerYAnchor], ++ [filterButton.widthAnchor constraintEqualToConstant:buttonSize], ++ [filterButton.heightAnchor constraintEqualToConstant:buttonSize], ++ ]]; ++ } ++ ++ UIButton *composeButton = nil; ++ if (hasComposeButton) { ++ composeButton = makeGlassButton( ++ mailSearchToolbarConfig[@"composeSystemImageName"] ?: @"square.and.pencil", ++ mailSearchToolbarConfig[@"composeButtonId"], ++ mailSearchToolbarConfig[@"composeMenu"]); ++ composeButton.translatesAutoresizingMaskIntoConstraints = NO; ++ [toolbarHost addSubview:composeButton]; ++ [NSLayoutConstraint activateConstraints:@[ ++ [composeButton.trailingAnchor constraintEqualToAnchor:toolbarHost.trailingAnchor], ++ [composeButton.centerYAnchor constraintEqualToAnchor:toolbarHost.centerYAnchor], ++ [composeButton.widthAnchor constraintEqualToConstant:buttonSize], ++ [composeButton.heightAnchor constraintEqualToConstant:buttonSize], ++ ]]; ++ } ++ ++ BOOL showsSearchDismissButton = ++ [mailSearchToolbarConfig[@"showsSearchDismissButton"] boolValue] && resolvedSearchTextField != nil; ++ UIButton *searchDismissButton = nil; ++ if (showsSearchDismissButton) { ++ searchDismissButton = makeGlassButton(@"xmark", nil, nil); ++ searchDismissButton.accessibilityLabel = @"Dismiss search keyboard"; ++ searchDismissButton.alpha = 0.0; ++ searchDismissButton.hidden = YES; ++ searchDismissButton.translatesAutoresizingMaskIntoConstraints = NO; ++ [toolbarHost addSubview:searchDismissButton]; ++ [NSLayoutConstraint activateConstraints:@[ ++ [searchDismissButton.trailingAnchor constraintEqualToAnchor:toolbarHost.trailingAnchor], ++ [searchDismissButton.centerYAnchor constraintEqualToAnchor:toolbarHost.centerYAnchor], ++ [searchDismissButton.widthAnchor constraintEqualToConstant:buttonSize], ++ [searchDismissButton.heightAnchor constraintEqualToConstant:buttonSize], ++ ]]; ++ __weak UITextField *weakSearchTextField = resolvedSearchTextField; ++ [searchDismissButton ++ addAction:[UIAction actionWithHandler:^(__kindof UIAction *_Nonnull action) { ++ [weakSearchTextField resignFirstResponder]; ++ }] ++ forControlEvents:UIControlEventTouchUpInside]; ++ } ++ ++ __weak UIButton *weakFilterButton = filterButton; ++ __weak UIButton *weakComposeButton = composeButton; ++ __weak UIButton *weakSearchDismissButton = searchDismissButton; ++ __weak NSLayoutConstraint *weakGlassLeadingConstraint = glassLeadingConstraint; ++ __weak NSLayoutConstraint *weakGlassTrailingConstraint = glassTrailingConstraint; ++ __weak NSLayoutConstraint *weakKeyboardAvoidConstraint = keyboardAvoidConstraint; ++ __weak NSLayoutConstraint *weakRestingBottomConstraint = restingBottomConstraint; ++ __weak UIView *weakToolbarHost = toolbarHost; ++ __weak UITextField *weakSearchTextField = resolvedSearchTextField; ++ void (^setSearchEditingAppearance)(BOOL, BOOL) = ^(BOOL isEditing, BOOL animated) { ++ weakKeyboardAvoidConstraint.priority = ++ isEditing ? UILayoutPriorityDefaultHigh : UILayoutPriorityDefaultLow; ++ weakRestingBottomConstraint.priority = ++ isEditing ? UILayoutPriorityDefaultLow : UILayoutPriorityDefaultHigh; ++ ++ if (showsSearchDismissButton) { ++ if (isEditing) { ++ weakSearchDismissButton.hidden = NO; ++ } else { ++ weakFilterButton.hidden = NO; ++ weakComposeButton.hidden = NO; ++ } ++ weakGlassLeadingConstraint.constant = isEditing ? 0.0 : glassLeadingInset; ++ weakGlassTrailingConstraint.constant = isEditing ? -sideButtonReserve : glassTrailingInset; ++ ++ void (^changes)(void) = ^{ ++ weakFilterButton.alpha = isEditing ? 0.0 : 1.0; ++ weakComposeButton.alpha = isEditing ? 0.0 : 1.0; ++ weakSearchDismissButton.alpha = isEditing ? 1.0 : 0.0; ++ [weakToolbarHost layoutIfNeeded]; ++ }; ++ void (^completion)(BOOL) = ^(BOOL finished) { ++ if (!finished || weakSearchTextField.isFirstResponder != isEditing) { ++ return; ++ } ++ weakFilterButton.hidden = isEditing; ++ weakComposeButton.hidden = isEditing; ++ weakSearchDismissButton.hidden = !isEditing; ++ }; ++ if (animated) { ++ [UIView animateWithDuration:0.2 ++ delay:0.0 ++ options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseInOut ++ animations:changes ++ completion:completion]; ++ } else { ++ changes(); ++ completion(YES); ++ } ++ } ++ [weakToolbarHost setNeedsLayout]; ++ }; ++ ++ setSearchEditingAppearance(resolvedSearchTextField.isFirstResponder, NO); ++ NSString *beginActionIdentifier = @"org.react-native-screens.mail-search-toolbar.keyboard-begin"; ++ NSString *endActionIdentifier = @"org.react-native-screens.mail-search-toolbar.keyboard-end"; ++ [resolvedSearchTextField removeActionForIdentifier:beginActionIdentifier ++ forControlEvents:UIControlEventEditingDidBegin]; ++ [resolvedSearchTextField removeActionForIdentifier:endActionIdentifier ++ forControlEvents:UIControlEventEditingDidEnd]; ++ [resolvedSearchTextField ++ addAction:[UIAction actionWithTitle:@"" ++ image:nil ++ identifier:beginActionIdentifier ++ handler:^(__kindof UIAction *_Nonnull action) { ++ setSearchEditingAppearance(YES, YES); ++ }] ++ forControlEvents:UIControlEventEditingDidBegin]; ++ [resolvedSearchTextField ++ addAction:[UIAction actionWithTitle:@"" ++ image:nil ++ identifier:endActionIdentifier ++ handler:^(__kindof UIAction *_Nonnull action) { ++ setSearchEditingAppearance(NO, YES); ++ }] ++ forControlEvents:UIControlEventEditingDidEnd]; ++ } ++#endif ++ } ++ ++ NSArray *toolbarConfigsKey = navigationToolbarConfigs ?: @[]; ++ // Same reuse rule as the header item groups above (including the config ++ // identity — cached toolbar items capture this config's event emitter). ++ // The top-view-controller and hidden-state checks scope the skip to ++ // same-screen refreshes, so transitions between screens with different ++ // toolbars still reapply. ++ NSArray *toolbarCacheKey = @[ @((uintptr_t)config), toolbarConfigsKey ]; ++ BOOL reuseToolbarItems = navctr.topViewController == vc && ++ navctr.isToolbarHidden == (toolbarConfigsKey.count == 0) && ++ [objc_getAssociatedObject(navitem, &RNSAppliedToolbarConfigsKey) isEqual:toolbarCacheKey]; ++ if (navctr.topViewController == vc && !reuseToolbarItems) { ++ NSArray *toolbarItems = [config barButtonItemsFromConfigs:navigationToolbarConfigs ++ withCurrentItems:@[] ++ navigationItem:navitem ++ allowsSearchBarPlacement:YES]; ++ if (toolbarItems.count > 0) { ++ vc.toolbarItems = toolbarItems; ++ [navctr setToolbarHidden:NO animated:animated]; ++ } else { ++ vc.toolbarItems = nil; ++ [navctr setToolbarHidden:YES animated:animated]; ++ } ++ objc_setAssociatedObject( ++ navitem, &RNSAppliedToolbarConfigsKey, toolbarCacheKey, OBJC_ASSOCIATION_RETAIN_NONATOMIC); ++ } + + // Setting navigation bar visibility is split to mitigate iOS 26 bug with bar button items + // (setting nav bar visibility should be done after `navitem.*BarButtonItems`). +@@ -784,6 +1298,8 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController * + + - (NSArray *)barButtonItemsFromConfigs:(NSArray *> *)dicts + withCurrentItems:(NSArray *)currentItems ++ navigationItem:(UINavigationItem *)navitem ++ allowsSearchBarPlacement:(BOOL)allowsSearchBarPlacement + { + if (dicts.count == 0) { + return currentItems; +@@ -792,7 +1308,200 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController * + [items addObjectsFromArray:currentItems]; + for (NSUInteger i = 0; i < dicts.count; i++) { + NSDictionary *dict = dicts[i]; +- if (dict[@"buttonId"] || dict[@"menu"]) { ++ if (dict[@"mailSearchToolbar"]) { ++#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) ++ if (@available(iOS 26.0, *)) { ++ NSNumber *width = dict[@"width"]; ++ CGFloat resolvedWidth = width != nil ? width.doubleValue : MAX(320.0, [UIScreen mainScreen].bounds.size.width - 56.0); ++ CGFloat resolvedHeight = 58.0; ++ UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, resolvedWidth, resolvedHeight)]; ++ container.translatesAutoresizingMaskIntoConstraints = NO; ++ [container.widthAnchor constraintEqualToConstant:resolvedWidth].active = YES; ++ [container.heightAnchor constraintEqualToConstant:resolvedHeight].active = YES; ++ ++ UIStackView *stackView = [[UIStackView alloc] initWithFrame:container.bounds]; ++ stackView.axis = UILayoutConstraintAxisHorizontal; ++ stackView.alignment = UIStackViewAlignmentCenter; ++ stackView.distribution = UIStackViewDistributionFill; ++ stackView.spacing = 10.0; ++ stackView.translatesAutoresizingMaskIntoConstraints = NO; ++ [container addSubview:stackView]; ++ [NSLayoutConstraint activateConstraints:@[ ++ [stackView.leadingAnchor constraintEqualToAnchor:container.leadingAnchor], ++ [stackView.trailingAnchor constraintEqualToAnchor:container.trailingAnchor], ++ [stackView.centerYAnchor constraintEqualToAnchor:container.centerYAnchor], ++ [stackView.heightAnchor constraintEqualToConstant:50.0], ++ ]]; ++ ++ void (^emitButtonPress)(NSString *) = ^(NSString *buttonId) { ++ auto eventEmitter = std::static_pointer_cast( ++ self->_eventEmitter); ++ if (eventEmitter && buttonId) { ++ eventEmitter->onPressHeaderBarButtonItem( ++ facebook::react::RNSScreenStackHeaderConfigEventEmitter::OnPressHeaderBarButtonItem{ ++ .buttonId = std::string([buttonId UTF8String])}); ++ } ++ }; ++ ++ void (^emitMenuPress)(NSString *) = ^(NSString *menuId) { ++ auto eventEmitter = std::static_pointer_cast( ++ self->_eventEmitter); ++ if (eventEmitter && menuId) { ++ eventEmitter->onPressHeaderBarButtonMenuItem( ++ facebook::react::RNSScreenStackHeaderConfigEventEmitter::OnPressHeaderBarButtonMenuItem{ ++ .menuId = std::string([menuId UTF8String])}); ++ } ++ }; ++ ++ UIButton *(^makeGlassButton)(NSString *, NSString *, NSDictionary *) = ++ ^UIButton *(NSString *systemImageName, NSString *buttonId, NSDictionary *menuConfig) { ++ UIButtonConfiguration *configuration = [UIButtonConfiguration glassButtonConfiguration]; ++ configuration.cornerStyle = UIButtonConfigurationCornerStyleCapsule; ++ configuration.image = [UIImage systemImageNamed:systemImageName ?: @"circle"]; ++ ++ UIButton *button = [UIButton buttonWithConfiguration:configuration primaryAction:nil]; ++ button.translatesAutoresizingMaskIntoConstraints = NO; ++ [button.widthAnchor constraintEqualToConstant:58.0].active = YES; ++ [button.heightAnchor constraintEqualToConstant:50.0].active = YES; ++ if (menuConfig != nil) { ++ button.menu = [RNSBarButtonItem initUIMenuWithDict:menuConfig ++ menuAction:emitMenuPress ++ imageLoader:self->_imageLoader]; ++ button.showsMenuAsPrimaryAction = YES; ++ } else if (buttonId != nil) { ++ UIAction *action = [UIAction actionWithHandler:^(__kindof UIAction *_Nonnull action) { ++ emitButtonPress(buttonId); ++ }]; ++ [button addAction:action forControlEvents:UIControlEventTouchUpInside]; ++ } ++ return button; ++ }; ++ ++ BOOL hasFilterButton = dict[@"filterButtonId"] != nil || dict[@"filterMenu"] != nil; ++ BOOL hasComposeButton = dict[@"composeButtonId"] != nil || dict[@"composeMenu"] != nil; ++ ++ if (hasFilterButton) { ++ UIButton *filterButton = makeGlassButton( ++ dict[@"filterSystemImageName"] ?: @"line.3.horizontal.decrease", ++ dict[@"filterButtonId"], ++ dict[@"filterMenu"]); ++ [stackView addArrangedSubview:filterButton]; ++ } ++ ++ UISearchBar *searchBar = navitem.searchController != nil ? navitem.searchController.searchBar : [UISearchBar new]; ++ NSString *placeholder = dict[@"placeholder"]; ++ if (placeholder != nil) { ++ searchBar.placeholder = placeholder; ++ } ++ searchBar.searchBarStyle = UISearchBarStyleMinimal; ++ searchBar.translatesAutoresizingMaskIntoConstraints = NO; ++ [searchBar.heightAnchor constraintEqualToConstant:50.0].active = YES; ++ [stackView addArrangedSubview:searchBar]; ++ ++ if (hasComposeButton) { ++ UIButton *composeButton = makeGlassButton( ++ dict[@"composeSystemImageName"] ?: @"square.and.pencil", ++ dict[@"composeButtonId"], ++ dict[@"composeMenu"]); ++ [stackView addArrangedSubview:composeButton]; ++ } ++ ++ UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:container]; ++ [items addObject:item]; ++ } ++#endif ++ } else if (dict[@"searchField"]) { ++#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) ++ if (@available(iOS 26.0, *)) { ++ NSNumber *width = dict[@"width"]; ++ CGFloat resolvedWidth = width != nil ? width.doubleValue : 280.0; ++ UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, resolvedWidth, 44.0)]; ++ container.translatesAutoresizingMaskIntoConstraints = NO; ++ [container.widthAnchor constraintEqualToConstant:resolvedWidth].active = YES; ++ [container.heightAnchor constraintEqualToConstant:44.0].active = YES; ++ ++ UISearchTextField *searchField = [UISearchTextField new]; ++ NSString *placeholder = dict[@"placeholder"]; ++ if (placeholder != nil) { ++ searchField.placeholder = placeholder; ++ } ++ searchField.translatesAutoresizingMaskIntoConstraints = NO; ++ [container addSubview:searchField]; ++ [NSLayoutConstraint activateConstraints:@[ ++ [searchField.leadingAnchor constraintEqualToAnchor:container.leadingAnchor], ++ [searchField.trailingAnchor constraintEqualToAnchor:container.trailingAnchor], ++ [searchField.centerYAnchor constraintEqualToAnchor:container.centerYAnchor], ++ [searchField.heightAnchor constraintEqualToConstant:40.0], ++ ]]; ++ ++ UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:container]; ++ [items addObject:item]; ++ } ++#endif ++ } else if (dict[@"searchBarPlacement"]) { ++ if (!allowsSearchBarPlacement) { ++ continue; ++ } ++#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) ++ if (@available(iOS 26.0, *)) { ++ NSNumber *width = dict[@"width"]; ++ UIBarButtonItem *item = nil; ++ if ([dict[@"activatesSearchController"] boolValue]) { ++ UIButtonConfiguration *configuration = [UIButtonConfiguration glassButtonConfiguration]; ++ configuration.cornerStyle = UIButtonConfigurationCornerStyleCapsule; ++ configuration.image = [UIImage systemImageNamed:@"magnifyingglass"]; ++ configuration.baseForegroundColor = UIColor.labelColor; ++ UIButton *button = [UIButton buttonWithConfiguration:configuration primaryAction:nil]; ++ button.translatesAutoresizingMaskIntoConstraints = NO; ++ [button.widthAnchor constraintEqualToConstant:56.0].active = YES; ++ [button.heightAnchor constraintEqualToConstant:56.0].active = YES; ++ UIAction *action = [UIAction actionWithHandler:^(__kindof UIAction *_Nonnull action) { ++ if (navitem.searchController != nil) { ++ [navitem.searchController setActive:YES]; ++ [navitem.searchController.searchBar becomeFirstResponder]; ++ } ++ }]; ++ [button addAction:action forControlEvents:UIControlEventTouchUpInside]; ++ item = [[UIBarButtonItem alloc] initWithCustomView:button]; ++ } else if ([dict[@"customView"] boolValue] && navitem.searchController != nil) { ++ UISearchBar *searchBar = navitem.searchController.searchBar; ++ CGFloat resolvedWidth = width != nil ? width.doubleValue : searchBar.frame.size.width; ++ CGFloat resolvedHeight = searchBar.frame.size.height > 0 ? searchBar.frame.size.height : 44.0; ++ UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, resolvedWidth, resolvedHeight)]; ++ container.translatesAutoresizingMaskIntoConstraints = NO; ++ [container.widthAnchor constraintEqualToConstant:resolvedWidth].active = YES; ++ [container.heightAnchor constraintEqualToConstant:resolvedHeight].active = YES; ++ searchBar.frame = container.bounds; ++ searchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; ++ [container addSubview:searchBar]; ++ item = [[UIBarButtonItem alloc] initWithCustomView:container]; ++ } else { ++ item = navitem.searchBarPlacementBarButtonItem; ++ if (width != nil) { ++ item.width = width.doubleValue; ++ } ++ } ++ NSNumber *index = dict[@"index"]; ++#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) ++ if (@available(iOS 26.0, *)) { ++ NSNumber *sharesBackground = dict[@"sharesBackground"]; ++ if (sharesBackground != nil) { ++ item.sharesBackground = sharesBackground.boolValue; ++ } ++ NSNumber *hidesSharedBackground = dict[@"hidesSharedBackground"]; ++ if (hidesSharedBackground != nil) { ++ item.hidesSharedBackground = hidesSharedBackground.boolValue; ++ } ++ } ++#endif ++ if (index != nil && index.integerValue >= 0 && index.integerValue < items.count) { ++ [items insertObject:item atIndex:index.integerValue]; ++ } else { ++ [items addObject:item]; ++ } ++ } ++#endif ++ } else if (dict[@"buttonId"] || dict[@"menu"]) { + RNSBarButtonItem *item = [[RNSBarButtonItem alloc] initWithConfig:dict + action:^(NSString *buttonId) { + auto eventEmitter = std::static_pointer_cast( +@@ -814,19 +1523,23 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController * + } + imageLoader:_imageLoader]; + NSNumber *index = dict[@"index"]; +- if (index.integerValue < items.count) { ++ if (index != nil && index.integerValue >= 0 && index.integerValue < items.count) { + [items insertObject:item atIndex:index.integerValue]; + } else { + [items addObject:item]; + } + } else if (dict[@"spacing"]) { +- UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace +- target:nil +- action:nil]; ++ BOOL flexible = [dict[@"flexible"] boolValue]; ++ UIBarButtonItem *item = [[UIBarButtonItem alloc] ++ initWithBarButtonSystemItem:(flexible ? UIBarButtonSystemItemFlexibleSpace : UIBarButtonSystemItemFixedSpace) ++ target:nil ++ action:nil]; + NSNumber *spacingValue = dict[@"spacing"]; +- item.width = [spacingValue doubleValue]; ++ if (!flexible) { ++ item.width = [spacingValue doubleValue]; ++ } + NSNumber *index = dict[@"index"]; +- if (index.integerValue < items.count) { ++ if (index != nil && index.integerValue >= 0 && index.integerValue < items.count) { + [items insertObject:item atIndex:index.integerValue]; + } else { + [items addObject:item]; +@@ -836,6 +1549,47 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController * + return items; + } + ++#if !TARGET_OS_TV ++- (NSArray *)barButtonItemGroupsFromItems:(NSArray *)items ++{ ++ if (items.count == 0) { ++ return @[]; ++ } ++ ++ NSMutableArray *groups = [NSMutableArray array]; ++ NSMutableArray *sharedRun = [NSMutableArray array]; ++ ++ void (^flushSharedRun)(void) = ^{ ++ if (sharedRun.count == 0) { ++ return; ++ } ++ [groups addObject:[UIBarButtonItemGroup fixedGroupWithRepresentativeItem:nil ++ items:[sharedRun copy]]]; ++ [sharedRun removeAllObjects]; ++ }; ++ ++ for (UIBarButtonItem *item in items) { ++ BOOL shouldShareBackground = NO; ++#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) ++ if (@available(iOS 26.0, *)) { ++ shouldShareBackground = item.sharesBackground && !item.hidesSharedBackground; ++ } ++#endif ++ ++ if (shouldShareBackground) { ++ [sharedRun addObject:item]; ++ continue; ++ } ++ ++ flushSharedRun(); ++ [groups addObject:[UIBarButtonItemGroup fixedGroupWithRepresentativeItem:nil items:@[ item ]]]; ++ } ++ ++ flushSharedRun(); ++ return groups; ++} ++#endif ++ + RNS_IGNORE_SUPER_CALL_BEGIN + - (void)insertReactSubview:(RNSScreenStackHeaderSubview *)subview atIndex:(NSInteger)atIndex + { +@@ -1025,6 +1779,8 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props:: + } + + _title = RCTNSStringFromStringNilIfEmpty(newScreenProps.title); ++ _subtitle = RCTNSStringFromStringNilIfEmpty(newScreenProps.subtitle); ++ _largeSubtitle = RCTNSStringFromStringNilIfEmpty(newScreenProps.largeSubtitle); + if (newScreenProps.titleFontFamily != oldScreenProps.titleFontFamily) { + _titleFontFamily = RCTNSStringFromStringNilIfEmpty(newScreenProps.titleFontFamily); + } +@@ -1050,6 +1806,7 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props:: + _disableBackButtonMenu = newScreenProps.disableBackButtonMenu; + _backButtonDisplayMode = + [RNSConvert UINavigationItemBackButtonDisplayModeFromCppEquivalent:newScreenProps.backButtonDisplayMode]; ++ _navigationItemStyle = navigationItemStyleFromCppEquivalent(newScreenProps.navigationItemStyle); + + if (newScreenProps.userInterfaceStyle != oldScreenProps.userInterfaceStyle) { + _userInterfaceStyle = [RNSConvert UIUserInterfaceStyleFromCppEquivalent:newScreenProps.userInterfaceStyle]; +@@ -1096,6 +1853,30 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props:: + _headerRightBarButtonItems = array; + } + ++ if (newScreenProps.headerCenterBarButtonItems != oldScreenProps.headerCenterBarButtonItems) { ++ const auto &vec = newScreenProps.headerCenterBarButtonItems; ++ NSMutableArray *> *array = [NSMutableArray arrayWithCapacity:vec.size()]; ++ for (const auto &item : vec) { ++ NSDictionary *dict = [RNSConvert idFromFollyDynamic:item]; ++ if ([dict isKindOfClass:[NSDictionary class]]) { ++ [array addObject:dict]; ++ } ++ } ++ _headerCenterBarButtonItems = array; ++ } ++ ++ if (newScreenProps.headerToolbarItems != oldScreenProps.headerToolbarItems) { ++ const auto &vec = newScreenProps.headerToolbarItems; ++ NSMutableArray *> *array = [NSMutableArray arrayWithCapacity:vec.size()]; ++ for (const auto &item : vec) { ++ NSDictionary *dict = [RNSConvert idFromFollyDynamic:item]; ++ if ([dict isKindOfClass:[NSDictionary class]]) { ++ [array addObject:dict]; ++ } ++ } ++ _headerToolbarItems = array; ++ } ++ + [self updateViewControllerIfNeeded]; + + if (needsNavigationControllerLayout) { +diff --git a/ios/RNSScreenStackHeaderSubview.mm b/ios/RNSScreenStackHeaderSubview.mm +index add33c4..489afa5 100644 +--- a/ios/RNSScreenStackHeaderSubview.mm ++++ b/ios/RNSScreenStackHeaderSubview.mm +@@ -20,7 +20,9 @@ @implementation RNSScreenStackHeaderSubview { + // This is a strong reference to UIBarButtonItem which creates a retain cycle. + // The cycle is cleared via `invalidateUIBarButtonItem` method, called by `invalidate` callback. + UIBarButtonItem *_barButtonItem; ++ NSString *_barButtonItemIdentifier; + BOOL _hidesSharedBackground; ++ UILabel *_titleScrollEdgeEffectGuide; + } + + #pragma mark - Common +@@ -102,6 +104,25 @@ - (void)updateShadowStateWithFrame:(CGRect)frame + - (void)layoutSubviews + { + [super layoutSubviews]; ++#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) ++ if (@available(iOS 26.0, *)) { ++ if (_type == RNSScreenStackHeaderSubviewTypeTitle || _type == RNSScreenStackHeaderSubviewTypeCenter) { ++ // UIKit shapes the navigation bar's scroll-edge fade around native labels, ++ // but does not recognize Fabric's custom text views. An empty, non-interactive ++ // label supplies the title's geometry without drawing or becoming a bar item. ++ if (_titleScrollEdgeEffectGuide == nil) { ++ _titleScrollEdgeEffectGuide = [UILabel new]; ++ _titleScrollEdgeEffectGuide.accessibilityElementsHidden = YES; ++ // Append after Fabric's children so their mount/unmount indices stay intact. ++ [self addSubview:_titleScrollEdgeEffectGuide]; ++ } ++ _titleScrollEdgeEffectGuide.frame = self.bounds; ++ } else { ++ [_titleScrollEdgeEffectGuide removeFromSuperview]; ++ _titleScrollEdgeEffectGuide = nil; ++ } ++ } ++#endif + [self updateShadowStateInContextOfAncestorView:[self findNavigationBar]]; + } + +@@ -124,6 +145,7 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props:: + const auto &newHeaderSubviewProps = *std::static_pointer_cast(props); + + [self setType:[RNSConvert RNSScreenStackHeaderSubviewTypeFromCppEquivalent:newHeaderSubviewProps.type]]; ++ [self setBarButtonItemIdentifier:RCTNSStringFromStringNilIfEmpty(newHeaderSubviewProps.identifier)]; + [self setHidesSharedBackground:newHeaderSubviewProps.hidesSharedBackground]; + [self setSynchronousShadowStateUpdatesEnabled:newHeaderSubviewProps.synchronousShadowStateUpdatesEnabled]; + [super updateProps:props oldProps:oldProps]; +@@ -276,7 +298,14 @@ - (void)configureBarButtonItem + #if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) + if (@available(iOS 26.0, *)) { + if (_barButtonItem != nil) { +- [_barButtonItem setHidesSharedBackground:_hidesSharedBackground]; ++ NSString *currentIdentifier = _barButtonItem.identifier; ++ if (currentIdentifier != _barButtonItemIdentifier && ++ ![currentIdentifier isEqualToString:_barButtonItemIdentifier]) { ++ _barButtonItem.identifier = _barButtonItemIdentifier; ++ } ++ if (_barButtonItem.hidesSharedBackground != _hidesSharedBackground) { ++ _barButtonItem.hidesSharedBackground = _hidesSharedBackground; ++ } + } + } + #endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) +@@ -284,10 +313,22 @@ - (void)configureBarButtonItem + + - (void)setHidesSharedBackground:(BOOL)hidesSharedBackground + { ++ if (_hidesSharedBackground == hidesSharedBackground) { ++ return; ++ } + _hidesSharedBackground = hidesSharedBackground; + [self configureBarButtonItem]; + } + ++- (void)setBarButtonItemIdentifier:(nullable NSString *)identifier ++{ ++ if (_barButtonItemIdentifier == identifier || [_barButtonItemIdentifier isEqualToString:identifier]) { ++ return; ++ } ++ _barButtonItemIdentifier = [identifier copy]; ++ [self configureBarButtonItem]; ++} ++ + #pragma mark - Dynamic frameworks support + + // Needed because of this: https://github.com/facebook/react-native/pull/37274 +diff --git a/lib/commonjs/components/ScreenStackHeaderConfig.js b/lib/commonjs/components/ScreenStackHeaderConfig.js +index 6e68cd1..9e09485 100644 +--- a/lib/commonjs/components/ScreenStackHeaderConfig.js ++++ b/lib/commonjs/components/ScreenStackHeaderConfig.js +@@ -31,17 +31,42 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_ + } = (0, _EdgeInsetApplicationContext.useEdgeInsetApplication)(!props.hidden, props.disableTopInsetApplication ?? false, props.disableLeftInsetApplication ?? false, props.disableRightInsetApplication ?? false, props.disableBottomInsetApplication ?? false); + const { + headerLeftBarButtonItems, +- headerRightBarButtonItems ++ headerRightBarButtonItems, ++ headerCenterBarButtonItems, ++ headerToolbarItems + } = props; + const preparedHeaderLeftBarButtonItems = headerLeftBarButtonItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerLeftBarButtonItems, 'left') : undefined; + const preparedHeaderRightBarButtonItems = headerRightBarButtonItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerRightBarButtonItems, 'right') : undefined; +- const hasHeaderBarButtonItems = _utils.isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length); ++ const preparedHeaderCenterBarButtonItems = headerCenterBarButtonItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerCenterBarButtonItems, 'center') : undefined; ++ const preparedHeaderToolbarItems = headerToolbarItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerToolbarItems, 'toolbar') : undefined; ++ const hasHeaderBarButtonItems = _utils.isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length || preparedHeaderCenterBarButtonItems?.length || preparedHeaderToolbarItems?.length); + + // Handle bar button item presses + const onPressHeaderBarButtonItem = hasHeaderBarButtonItems ? event => { +- const pressedItem = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? [])].find(item => item && 'buttonId' in item && item.buttonId === event.nativeEvent.buttonId); ++ const buttonId = event.nativeEvent.buttonId; ++ const allItems = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? []), ...(preparedHeaderCenterBarButtonItems ?? []), ...(preparedHeaderToolbarItems ?? [])]; ++ const pressedItem = allItems.find(item => item && 'buttonId' in item && item.buttonId === buttonId); + if (pressedItem && pressedItem.type === 'button' && pressedItem.onPress) { + pressedItem.onPress(); ++ return; ++ } ++ for (const item of allItems) { ++ if (!item || item.type !== 'mailSearchToolbar') { ++ continue; ++ } ++ if (item.filterButtonId === buttonId) { ++ item.onFilterPress?.(); ++ return; ++ } ++ if (item.composeButtonId === buttonId) { ++ item.onComposePress?.(); ++ return; ++ } ++ const searchTextChangePrefix = item.searchTextChangeId ? `${item.searchTextChangeId}:` : undefined; ++ if (searchTextChangePrefix && buttonId.startsWith(searchTextChangePrefix)) { ++ item.onSearchTextChange?.(buttonId.slice(searchTextChangePrefix.length)); ++ return; ++ } + } + } : undefined; + +@@ -64,7 +89,7 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_ + }; + + // Check each bar-button item with a menu +- const allItems = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? [])]; ++ const allItems = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? []), ...(preparedHeaderCenterBarButtonItems ?? []), ...(preparedHeaderToolbarItems ?? [])]; + for (const item of allItems) { + if (item && item.type === 'menu' && item.menu) { + const action = findInMenu(item.menu, event.nativeEvent.menuId); +@@ -72,6 +97,15 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_ + action.onPress(); + return; + } ++ } else if (item && item.type === 'mailSearchToolbar') { ++ const toolbarMenus = [item.filterMenu, item.composeMenu].filter(Boolean); ++ for (const toolbarMenu of toolbarMenus) { ++ const action = findInMenu(toolbarMenu, event.nativeEvent.menuId); ++ if (action) { ++ action.onPress(); ++ return; ++ } ++ } + } + } + } : undefined; +@@ -79,6 +113,8 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_ + userInterfaceStyle: props.experimental_userInterfaceStyle, + headerLeftBarButtonItems: preparedHeaderLeftBarButtonItems, + headerRightBarButtonItems: preparedHeaderRightBarButtonItems, ++ headerCenterBarButtonItems: preparedHeaderCenterBarButtonItems, ++ headerToolbarItems: preparedHeaderToolbarItems, + onPressHeaderBarButtonItem: onPressHeaderBarButtonItem, + onPressHeaderBarButtonMenuItem: onPressHeaderBarButtonMenuItem, + ref: ref, +diff --git a/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js b/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js +index 589b6cc..b584624 100644 +--- a/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js ++++ b/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js +@@ -8,7 +8,7 @@ var _reactNative = require("react-native"); + // Local nominal type so declaration emit doesn't resolve the RN alias down to + // the non-public `types_generated/.../AssetSourceResolver#ResolvedAssetSource`. + +-const prepareMenu = (menu, index, side, path = '') => { ++const prepareMenu = (menu, index, placement, path = '') => { + return { + ...menu, + items: menu.items.map((menuItem, menuIndex) => { +@@ -29,7 +29,7 @@ const prepareMenu = (menu, index, side, path = '') => { + xcassetName, + imageSource, + templateSource, +- ...prepareMenu(menuItem, index, side, currentPath) ++ ...prepareMenu(menuItem, index, placement, currentPath) + }; + } + return { +@@ -38,16 +38,40 @@ const prepareMenu = (menu, index, side, path = '') => { + xcassetName, + imageSource, + templateSource, +- menuId: `${currentPath}-${index}-${side}` ++ menuId: `${currentPath}-${index}-${placement}` + }; + }) + }; + }; +-const prepareHeaderBarButtonItems = (barButtonItems, side) => { +- return barButtonItems?.map((item, index) => { ++const prepareHeaderBarButtonItems = (barButtonItems, placement) => { ++ const items = Array.isArray(barButtonItems) ? barButtonItems : barButtonItems && typeof barButtonItems === 'object' && 'type' in barButtonItems ? [barButtonItems] : undefined; ++ return items?.map((item, index) => { + if (item.type === 'spacing') { + return item; + } ++ if (item.type === 'searchBarPlacement') { ++ if (placement !== 'toolbar') { ++ return null; ++ } ++ return { ++ ...item, ++ searchBarPlacement: true ++ }; ++ } ++ if (item.type === 'searchField') { ++ return { ++ ...item, ++ searchField: true ++ }; ++ } ++ if (item.type === 'mailSearchToolbar') { ++ return { ++ ...item, ++ mailSearchToolbar: true, ++ filterMenu: item.filterMenu ? prepareMenu(item.filterMenu, index, placement, 'filter') : undefined, ++ composeMenu: item.composeMenu ? prepareMenu(item.composeMenu, index, placement, 'compose') : undefined ++ }; ++ } + let imageSource, templateSource; + if (item.icon?.type === 'imageSource') { + imageSource = _reactNative.Image.resolveAssetSource(item.icon.imageSource); +@@ -80,17 +104,17 @@ const prepareHeaderBarButtonItems = (barButtonItems, side) => { + if (item.type === 'button') { + return { + ...processedItem, +- buttonId: `${index}-${side}` ++ buttonId: `${index}-${placement}` + }; + } + if (item.type === 'menu') { + return { + ...processedItem, +- menu: prepareMenu(item.menu, index, side) ++ menu: prepareMenu(item.menu, index, placement) + }; + } + return null; +- }); ++ }).filter(item => item !== null); + }; + exports.prepareHeaderBarButtonItems = prepareHeaderBarButtonItems; + //# sourceMappingURL=prepareHeaderBarButtonItems.js.map +\ No newline at end of file +diff --git a/lib/module/components/ScreenStackHeaderConfig.js b/lib/module/components/ScreenStackHeaderConfig.js +index 242898c..7cebaa3 100644 +--- a/lib/module/components/ScreenStackHeaderConfig.js ++++ b/lib/module/components/ScreenStackHeaderConfig.js +@@ -27,17 +27,42 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref + } = useEdgeInsetApplication(!props.hidden, props.disableTopInsetApplication ?? false, props.disableLeftInsetApplication ?? false, props.disableRightInsetApplication ?? false, props.disableBottomInsetApplication ?? false); + const { + headerLeftBarButtonItems, +- headerRightBarButtonItems ++ headerRightBarButtonItems, ++ headerCenterBarButtonItems, ++ headerToolbarItems + } = props; + const preparedHeaderLeftBarButtonItems = headerLeftBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerLeftBarButtonItems, 'left') : undefined; + const preparedHeaderRightBarButtonItems = headerRightBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerRightBarButtonItems, 'right') : undefined; +- const hasHeaderBarButtonItems = isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length); ++ const preparedHeaderCenterBarButtonItems = headerCenterBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerCenterBarButtonItems, 'center') : undefined; ++ const preparedHeaderToolbarItems = headerToolbarItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerToolbarItems, 'toolbar') : undefined; ++ const hasHeaderBarButtonItems = isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length || preparedHeaderCenterBarButtonItems?.length || preparedHeaderToolbarItems?.length); + + // Handle bar button item presses + const onPressHeaderBarButtonItem = hasHeaderBarButtonItems ? event => { +- const pressedItem = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? [])].find(item => item && 'buttonId' in item && item.buttonId === event.nativeEvent.buttonId); ++ const buttonId = event.nativeEvent.buttonId; ++ const allItems = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? []), ...(preparedHeaderCenterBarButtonItems ?? []), ...(preparedHeaderToolbarItems ?? [])]; ++ const pressedItem = allItems.find(item => item && 'buttonId' in item && item.buttonId === buttonId); + if (pressedItem && pressedItem.type === 'button' && pressedItem.onPress) { + pressedItem.onPress(); ++ return; ++ } ++ for (const item of allItems) { ++ if (!item || item.type !== 'mailSearchToolbar') { ++ continue; ++ } ++ if (item.filterButtonId === buttonId) { ++ item.onFilterPress?.(); ++ return; ++ } ++ if (item.composeButtonId === buttonId) { ++ item.onComposePress?.(); ++ return; ++ } ++ const searchTextChangePrefix = item.searchTextChangeId ? `${item.searchTextChangeId}:` : undefined; ++ if (searchTextChangePrefix && buttonId.startsWith(searchTextChangePrefix)) { ++ item.onSearchTextChange?.(buttonId.slice(searchTextChangePrefix.length)); ++ return; ++ } + } + } : undefined; + +@@ -60,7 +85,7 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref + }; + + // Check each bar-button item with a menu +- const allItems = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? [])]; ++ const allItems = [...(preparedHeaderLeftBarButtonItems ?? []), ...(preparedHeaderRightBarButtonItems ?? []), ...(preparedHeaderCenterBarButtonItems ?? []), ...(preparedHeaderToolbarItems ?? [])]; + for (const item of allItems) { + if (item && item.type === 'menu' && item.menu) { + const action = findInMenu(item.menu, event.nativeEvent.menuId); +@@ -68,6 +93,15 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref + action.onPress(); + return; + } ++ } else if (item && item.type === 'mailSearchToolbar') { ++ const toolbarMenus = [item.filterMenu, item.composeMenu].filter(Boolean); ++ for (const toolbarMenu of toolbarMenus) { ++ const action = findInMenu(toolbarMenu, event.nativeEvent.menuId); ++ if (action) { ++ action.onPress(); ++ return; ++ } ++ } + } + } + } : undefined; +@@ -75,6 +109,8 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref + userInterfaceStyle: props.experimental_userInterfaceStyle, + headerLeftBarButtonItems: preparedHeaderLeftBarButtonItems, + headerRightBarButtonItems: preparedHeaderRightBarButtonItems, ++ headerCenterBarButtonItems: preparedHeaderCenterBarButtonItems, ++ headerToolbarItems: preparedHeaderToolbarItems, + onPressHeaderBarButtonItem: onPressHeaderBarButtonItem, + onPressHeaderBarButtonMenuItem: onPressHeaderBarButtonMenuItem, + ref: ref, +diff --git a/lib/module/components/helpers/prepareHeaderBarButtonItems.js b/lib/module/components/helpers/prepareHeaderBarButtonItems.js +index 24bf271..693cfad 100644 +--- a/lib/module/components/helpers/prepareHeaderBarButtonItems.js ++++ b/lib/module/components/helpers/prepareHeaderBarButtonItems.js +@@ -3,7 +3,7 @@ import { Image, processColor } from 'react-native'; + // Local nominal type so declaration emit doesn't resolve the RN alias down to + // the non-public `types_generated/.../AssetSourceResolver#ResolvedAssetSource`. + +-const prepareMenu = (menu, index, side, path = '') => { ++const prepareMenu = (menu, index, placement, path = '') => { + return { + ...menu, + items: menu.items.map((menuItem, menuIndex) => { +@@ -24,7 +24,7 @@ const prepareMenu = (menu, index, side, path = '') => { + xcassetName, + imageSource, + templateSource, +- ...prepareMenu(menuItem, index, side, currentPath) ++ ...prepareMenu(menuItem, index, placement, currentPath) + }; + } + return { +@@ -33,16 +33,40 @@ const prepareMenu = (menu, index, side, path = '') => { + xcassetName, + imageSource, + templateSource, +- menuId: `${currentPath}-${index}-${side}` ++ menuId: `${currentPath}-${index}-${placement}` + }; + }) + }; + }; +-export const prepareHeaderBarButtonItems = (barButtonItems, side) => { +- return barButtonItems?.map((item, index) => { ++export const prepareHeaderBarButtonItems = (barButtonItems, placement) => { ++ const items = Array.isArray(barButtonItems) ? barButtonItems : barButtonItems && typeof barButtonItems === 'object' && 'type' in barButtonItems ? [barButtonItems] : undefined; ++ return items?.map((item, index) => { + if (item.type === 'spacing') { + return item; + } ++ if (item.type === 'searchBarPlacement') { ++ if (placement !== 'toolbar') { ++ return null; ++ } ++ return { ++ ...item, ++ searchBarPlacement: true ++ }; ++ } ++ if (item.type === 'searchField') { ++ return { ++ ...item, ++ searchField: true ++ }; ++ } ++ if (item.type === 'mailSearchToolbar') { ++ return { ++ ...item, ++ mailSearchToolbar: true, ++ filterMenu: item.filterMenu ? prepareMenu(item.filterMenu, index, placement, 'filter') : undefined, ++ composeMenu: item.composeMenu ? prepareMenu(item.composeMenu, index, placement, 'compose') : undefined ++ }; ++ } + let imageSource, templateSource; + if (item.icon?.type === 'imageSource') { + imageSource = Image.resolveAssetSource(item.icon.imageSource); +@@ -75,16 +99,16 @@ export const prepareHeaderBarButtonItems = (barButtonItems, side) => { + if (item.type === 'button') { + return { + ...processedItem, +- buttonId: `${index}-${side}` ++ buttonId: `${index}-${placement}` + }; + } + if (item.type === 'menu') { + return { + ...processedItem, +- menu: prepareMenu(item.menu, index, side) ++ menu: prepareMenu(item.menu, index, placement) + }; + } + return null; +- }); ++ }).filter(item => item !== null); + }; + //# sourceMappingURL=prepareHeaderBarButtonItems.js.map +\ No newline at end of file +diff --git a/lib/typescript/components/helpers/prepareHeaderBarButtonItems.d.ts b/lib/typescript/components/helpers/prepareHeaderBarButtonItems.d.ts +index 4704a14..e2e2b78 100644 +--- a/lib/typescript/components/helpers/prepareHeaderBarButtonItems.d.ts ++++ b/lib/typescript/components/helpers/prepareHeaderBarButtonItems.d.ts +@@ -2,7 +2,7 @@ import type { ImageResolvedAssetSource } from 'react-native'; + import type { HeaderBarButtonItem } from '../../types'; + export interface ResolvedImageAsset extends ImageResolvedAssetSource { + } +-export declare const prepareHeaderBarButtonItems: (barButtonItems: HeaderBarButtonItem[], side: "left" | "right") => (import("../..").HeaderBarButtonItemSpacing | { ++export declare const prepareHeaderBarButtonItems: (barButtonItems: HeaderBarButtonItem[], side: "left" | "right" | "center" | "toolbar") => (import("../..").HeaderBarButtonItemSpacing | { + buttonId: string; + imageSource: ResolvedImageAsset | undefined; + templateSource: ResolvedImageAsset | undefined; +@@ -164,5 +164,5 @@ export declare const prepareHeaderBarButtonItems: (barButtonItems: HeaderBarButt + identifier?: string | undefined; + accessibilityLabel?: string | undefined; + accessibilityHint?: string | undefined; +-} | null)[]; ++})[]; + //# sourceMappingURL=prepareHeaderBarButtonItems.d.ts.map +\ No newline at end of file +diff --git a/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts b/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts +index ec39792..434bccf 100644 +--- a/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts ++++ b/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts +@@ -9,6 +9,7 @@ type OnPressHeaderBarButtonMenuItemEvent = Readonly<{ + menuId: string; + }>; + type BackButtonDisplayMode = 'minimal' | 'default' | 'generic'; ++type NavigationItemStyle = 'navigator' | 'browser' | 'editor'; + type BlurEffect = 'none' | 'extraLight' | 'light' | 'dark' | 'regular' | 'prominent' | 'systemUltraThinMaterial' | 'systemThinMaterial' | 'systemMaterial' | 'systemThickMaterial' | 'systemChromeMaterial' | 'systemUltraThinMaterialLight' | 'systemThinMaterialLight' | 'systemMaterialLight' | 'systemThickMaterialLight' | 'systemChromeMaterialLight' | 'systemUltraThinMaterialDark' | 'systemThinMaterialDark' | 'systemMaterialDark' | 'systemThickMaterialDark' | 'systemChromeMaterialDark'; + type UserInterfaceStyle = 'unspecified' | 'light' | 'dark'; + export interface NativeProps extends ViewProps { +@@ -32,18 +33,23 @@ export interface NativeProps extends ViewProps { + largeTitleColor?: ColorValue | undefined; + translucent?: boolean | undefined; + title?: string | undefined; ++ subtitle?: string | undefined; ++ largeSubtitle?: string | undefined; + titleFontFamily?: string | undefined; + titleFontSize?: CT.Int32 | undefined; + titleFontWeight?: string | undefined; + titleColor?: ColorValue | undefined; + disableBackButtonMenu?: boolean | undefined; + backButtonDisplayMode?: CT.WithDefault; ++ navigationItemStyle?: CT.WithDefault; + hideBackButton?: boolean | undefined; + backButtonInCustomView?: boolean | undefined; + blurEffect?: CT.WithDefault; + topInsetEnabled?: boolean | undefined; + headerLeftBarButtonItems?: CT.UnsafeMixed[] | undefined; + headerRightBarButtonItems?: CT.UnsafeMixed[] | undefined; ++ headerCenterBarButtonItems?: CT.UnsafeMixed[] | undefined; ++ headerToolbarItems?: CT.UnsafeMixed[] | undefined; + onPressHeaderBarButtonItem?: CT.DirectEventHandler | undefined; + onPressHeaderBarButtonMenuItem?: CT.DirectEventHandler | undefined; + synchronousShadowStateUpdatesEnabled?: CT.WithDefault; +diff --git a/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts b/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts +index 2cb1a79..d6ca5a4 100644 +--- a/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts ++++ b/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts +@@ -3,6 +3,7 @@ export type HeaderSubviewTypes = 'back' | 'right' | 'left' | 'title' | 'center' + export interface NativeProps extends ViewProps { + type?: CT.WithDefault; + hidesSharedBackground?: boolean | undefined; ++ identifier?: string | undefined; + synchronousShadowStateUpdatesEnabled?: CT.WithDefault; + } + declare const _default: HostComponent; +diff --git a/lib/typescript/types.d.ts b/lib/typescript/types.d.ts +index ff37881..b487303 100644 +--- a/lib/typescript/types.d.ts ++++ b/lib/typescript/types.d.ts +@@ -19,6 +19,7 @@ export type SearchBarCommands = { + cancelSearch: () => void; + }; + export type BackButtonDisplayMode = 'default' | 'generic' | 'minimal'; ++export type NavigationItemStyle = 'navigator' | 'browser' | 'editor'; + export type StackPresentationTypes = 'push' | 'modal' | 'transparentModal' | 'containedModal' | 'containedTransparentModal' | 'fullScreenModal' | 'formSheet' | 'pageSheet'; + export type StackAnimationTypes = 'default' | 'fade' | 'fade_from_bottom' | 'flip' | 'none' | 'simple_push' | 'slide_from_bottom' | 'slide_from_right' | 'slide_from_left' | 'ios_from_right' | 'ios_from_left'; + export type BlurEffectTypes = BlurEffect; +@@ -650,6 +651,14 @@ export interface ScreenStackHeaderConfigProps extends ViewProps { + * @platform ios + */ + backButtonDisplayMode?: BackButtonDisplayMode | undefined; ++ /** ++ * Controls the UIKit `UINavigationItem.style` used by native iOS headers. ++ * ++ * `editor` matches modern document/editor-style bars with leading-aligned compact titles and glass controls. ++ * ++ * @platform ios ++ */ ++ navigationItemStyle?: NavigationItemStyle | undefined; + /** + * Array of UIBarButtomItems to the left side of the header. + * +@@ -662,6 +671,26 @@ export interface ScreenStackHeaderConfigProps extends ViewProps { + * @platform ios + */ + headerRightBarButtonItems?: HeaderBarButtonItem[] | undefined; ++ /** ++ * Array of UIBarButtonItems to the centered item group in modern iOS headers. ++ * ++ * This maps to `UINavigationItem.centerItemGroups` on iOS 26+ and lets ++ * document/editor-style chrome keep primary actions visually centered while ++ * leaving trailing search separate. ++ * ++ * @platform ios ++ */ ++ headerCenterBarButtonItems?: HeaderBarButtonItem[] | undefined; ++ /** ++ * Array of UIBarButtonItems to display in the native toolbar attached to ++ * the current screen's navigation controller. ++ * ++ * On iOS 26+, this can contain a `searchBarPlacement` item to let UIKit ++ * render integrated Mail-style search chrome using the attached SearchBar. ++ * ++ * @platform ios ++ */ ++ headerToolbarItems?: HeaderBarButtonItem[] | undefined; + /** + * When set to true the header will be hidden while the parent Screen is on the top of the stack. The default value is false. + */ +@@ -723,6 +752,20 @@ export interface ScreenStackHeaderConfigProps extends ViewProps { + * String that can be displayed in the header as a fallback for `headerTitle`. + */ + title?: string | undefined; ++ /** ++ * String displayed below the compact navigation title on iOS 26+. ++ * ++ * @platform ios ++ */ ++ subtitle?: string | undefined; ++ /** ++ * String displayed below the large navigation title on iOS 26+. ++ * ++ * Falls back to `subtitle` when omitted. ++ * ++ * @platform ios ++ */ ++ largeSubtitle?: string | undefined; + /** + * Allows for setting text color of the title. + */ +@@ -1018,6 +1061,13 @@ export interface SearchBarProps { + shouldShowHintSearchIcon?: boolean | undefined; + } + export interface ScreenStackHeaderSubviewProps { ++ /** ++ * An identifier used to match this item across navigation bar transitions. ++ * Only applicable to type="right" and type="left" subviews on iOS 26.0 and later. ++ * ++ * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/identifier ++ */ ++ identifier?: string | undefined; + /** + * A boolean value indicating whether the background this item may share with other items in the bar should be hidden. + * Only applicable to type="right" and type="left" subviews. +@@ -1056,6 +1106,11 @@ interface SharedHeaderBarButtonItem { + * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/style-swift.property + */ + variant?: 'plain' | 'done' | 'prominent' | undefined; ++ /** ++ * Render the item with UIButtonConfiguration.glassButtonConfiguration. ++ * Only available from iOS 26.0 and later. ++ */ ++ glassEffect?: boolean | undefined; + /** + * The tint color to apply to the item. + * +@@ -1201,8 +1256,38 @@ export interface HeaderBarButtonItemWithMenu extends SharedHeaderBarButtonItem { + export interface HeaderBarButtonItemSpacing { + type: 'spacing'; + spacing: number; ++ flexible?: boolean | undefined; ++} ++export interface HeaderBarButtonSearchBarPlacementItem { ++ type: 'searchBarPlacement'; ++ activatesSearchController?: boolean | undefined; ++ customView?: boolean | undefined; ++ index?: number | undefined; ++ width?: number | undefined; ++} ++export interface HeaderBarButtonSearchFieldItem { ++ type: 'searchField'; ++ placeholder?: string | undefined; ++ width?: number | undefined; ++} ++export interface HeaderBarButtonMailSearchToolbarItem { ++ type: 'mailSearchToolbar'; ++ composeButtonId?: string | undefined; ++ composeMenu?: HeaderBarButtonItemWithMenu['menu'] | undefined; ++ composeSystemImageName?: string | undefined; ++ filterButtonId?: string | undefined; ++ filterMenu?: HeaderBarButtonItemWithMenu['menu'] | undefined; ++ filterSystemImageName?: string | undefined; ++ onComposePress?: (() => void) | undefined; ++ onFilterPress?: (() => void) | undefined; ++ onSearchTextChange?: ((text: string) => void) | undefined; ++ placeholder?: string | undefined; ++ searchTextChangeId?: string | undefined; ++ showsSearchDismissButton?: boolean | undefined; ++ useFallbackSearchField?: boolean | undefined; ++ width?: number | undefined; + } +-export type HeaderBarButtonItem = HeaderBarButtonItemWithAction | HeaderBarButtonItemWithMenu | HeaderBarButtonItemSpacing; ++export type HeaderBarButtonItem = HeaderBarButtonItemWithAction | HeaderBarButtonItemWithMenu | HeaderBarButtonMailSearchToolbarItem | HeaderBarButtonSearchFieldItem | HeaderBarButtonSearchBarPlacementItem | HeaderBarButtonItemSpacing; + /** + * Custom Screen Transition + */ +diff --git a/src/components/ScreenStackHeaderConfig.tsx b/src/components/ScreenStackHeaderConfig.tsx +index 509d6cd..761e49b 100644 +--- a/src/components/ScreenStackHeaderConfig.tsx ++++ b/src/components/ScreenStackHeaderConfig.tsx +@@ -54,7 +54,12 @@ export const ScreenStackHeaderConfig = React.forwardRef< + props.disableBottomInsetApplication ?? false, + ); + +- const { headerLeftBarButtonItems, headerRightBarButtonItems } = props; ++ const { ++ headerLeftBarButtonItems, ++ headerRightBarButtonItems, ++ headerCenterBarButtonItems, ++ headerToolbarItems, ++ } = props; + + const preparedHeaderLeftBarButtonItems = + headerLeftBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform +@@ -64,22 +69,36 @@ export const ScreenStackHeaderConfig = React.forwardRef< + headerRightBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform + ? prepareHeaderBarButtonItems(headerRightBarButtonItems, 'right') + : undefined; ++ const preparedHeaderCenterBarButtonItems = ++ headerCenterBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform ++ ? prepareHeaderBarButtonItems(headerCenterBarButtonItems, 'center') ++ : undefined; ++ const preparedHeaderToolbarItems = ++ headerToolbarItems && isHeaderBarButtonsAvailableForCurrentPlatform ++ ? prepareHeaderBarButtonItems(headerToolbarItems, 'toolbar') ++ : undefined; + const hasHeaderBarButtonItems = + isHeaderBarButtonsAvailableForCurrentPlatform && + (preparedHeaderLeftBarButtonItems?.length || +- preparedHeaderRightBarButtonItems?.length); ++ preparedHeaderRightBarButtonItems?.length || ++ preparedHeaderCenterBarButtonItems?.length || ++ preparedHeaderToolbarItems?.length); + + // Handle bar button item presses + const onPressHeaderBarButtonItem = hasHeaderBarButtonItems + ? (event: NativeSyntheticEvent<{ buttonId: string }>) => { +- const pressedItem = [ ++ const buttonId = event.nativeEvent.buttonId; ++ const allItems = [ + ...(preparedHeaderLeftBarButtonItems ?? []), + ...(preparedHeaderRightBarButtonItems ?? []), +- ].find( ++ ...(preparedHeaderCenterBarButtonItems ?? []), ++ ...(preparedHeaderToolbarItems ?? []), ++ ]; ++ const pressedItem = allItems.find( + item => + item && + 'buttonId' in item && +- item.buttonId === event.nativeEvent.buttonId, ++ item.buttonId === buttonId, + ); + if ( + pressedItem && +@@ -87,6 +106,32 @@ export const ScreenStackHeaderConfig = React.forwardRef< + pressedItem.onPress + ) { + pressedItem.onPress(); ++ return; ++ } ++ for (const item of allItems) { ++ if (!item || item.type !== 'mailSearchToolbar') { ++ continue; ++ } ++ if (item.filterButtonId === buttonId) { ++ item.onFilterPress?.(); ++ return; ++ } ++ if (item.composeButtonId === buttonId) { ++ item.onComposePress?.(); ++ return; ++ } ++ const searchTextChangePrefix = item.searchTextChangeId ++ ? `${item.searchTextChangeId}:` ++ : undefined; ++ if ( ++ searchTextChangePrefix && ++ buttonId.startsWith(searchTextChangePrefix) ++ ) { ++ item.onSearchTextChange?.( ++ buttonId.slice(searchTextChangePrefix.length), ++ ); ++ return; ++ } + } + } + : undefined; +@@ -117,6 +162,8 @@ export const ScreenStackHeaderConfig = React.forwardRef< + const allItems = [ + ...(preparedHeaderLeftBarButtonItems ?? []), + ...(preparedHeaderRightBarButtonItems ?? []), ++ ...(preparedHeaderCenterBarButtonItems ?? []), ++ ...(preparedHeaderToolbarItems ?? []), + ]; + for (const item of allItems) { + if (item && item.type === 'menu' && item.menu) { +@@ -125,6 +172,17 @@ export const ScreenStackHeaderConfig = React.forwardRef< + action.onPress(); + return; + } ++ } else if (item && item.type === 'mailSearchToolbar') { ++ const toolbarMenus = [item.filterMenu, item.composeMenu].filter( ++ Boolean, ++ ); ++ for (const toolbarMenu of toolbarMenus) { ++ const action = findInMenu(toolbarMenu, event.nativeEvent.menuId); ++ if (action) { ++ action.onPress(); ++ return; ++ } ++ } + } + } + } +@@ -136,6 +194,8 @@ export const ScreenStackHeaderConfig = React.forwardRef< + userInterfaceStyle={props.experimental_userInterfaceStyle} + headerLeftBarButtonItems={preparedHeaderLeftBarButtonItems} + headerRightBarButtonItems={preparedHeaderRightBarButtonItems} ++ headerCenterBarButtonItems={preparedHeaderCenterBarButtonItems} ++ headerToolbarItems={preparedHeaderToolbarItems} + onPressHeaderBarButtonItem={onPressHeaderBarButtonItem} + onPressHeaderBarButtonMenuItem={onPressHeaderBarButtonMenuItem} + ref={ref} +diff --git a/src/components/helpers/prepareHeaderBarButtonItems.ts b/src/components/helpers/prepareHeaderBarButtonItems.ts +index 19ab7bc..9fd5ceb 100644 +--- a/src/components/helpers/prepareHeaderBarButtonItems.ts ++++ b/src/components/helpers/prepareHeaderBarButtonItems.ts +@@ -12,7 +12,7 @@ export interface ResolvedImageAsset extends ImageResolvedAssetSource {} + const prepareMenu = ( + menu: HeaderBarButtonItemWithMenu['menu'], + index: number, +- side: 'left' | 'right', ++ placement: 'left' | 'right' | 'center' | 'toolbar', + path: string = '', + ): HeaderBarButtonItemWithMenu['menu'] => { + return { +@@ -39,7 +39,7 @@ const prepareMenu = ( + xcassetName, + imageSource, + templateSource, +- ...prepareMenu(menuItem, index, side, currentPath), ++ ...prepareMenu(menuItem, index, placement, currentPath), + }; + } + return { +@@ -48,20 +48,53 @@ const prepareMenu = ( + xcassetName, + imageSource, + templateSource, +- menuId: `${currentPath}-${index}-${side}`, ++ menuId: `${currentPath}-${index}-${placement}`, + }; + }), + }; + }; + + export const prepareHeaderBarButtonItems = ( +- barButtonItems: HeaderBarButtonItem[], +- side: 'left' | 'right', ++ barButtonItems: ++ | HeaderBarButtonItem[] ++ | HeaderBarButtonItem ++ | null ++ | undefined, ++ placement: 'left' | 'right' | 'center' | 'toolbar', + ) => { +- return barButtonItems?.map((item, index) => { ++ const items = Array.isArray(barButtonItems) ++ ? barButtonItems ++ : barButtonItems && typeof barButtonItems === 'object' && 'type' in barButtonItems ++ ? [barButtonItems] ++ : undefined; ++ ++ return items?.map((item, index) => { + if (item.type === 'spacing') { + return item; + } ++ if (item.type === 'searchBarPlacement') { ++ if (placement !== 'toolbar') { ++ return null; ++ } ++ return { ++ ...item, ++ searchBarPlacement: true, ++ }; ++ } ++ if (item.type === 'searchField') { ++ return { ++ ...item, ++ searchField: true, ++ }; ++ } ++ if (item.type === 'mailSearchToolbar') { ++ return { ++ ...item, ++ mailSearchToolbar: true, ++ filterMenu: item.filterMenu ? prepareMenu(item.filterMenu, index, placement, 'filter') : undefined, ++ composeMenu: item.composeMenu ? prepareMenu(item.composeMenu, index, placement, 'compose') : undefined, ++ }; ++ } + let imageSource: ResolvedImageAsset | undefined, + templateSource: ResolvedImageAsset | undefined; + if (item.icon?.type === 'imageSource') { +@@ -97,15 +130,15 @@ export const prepareHeaderBarButtonItems = ( + if (item.type === 'button') { + return { + ...processedItem, +- buttonId: `${index}-${side}`, ++ buttonId: `${index}-${placement}`, + }; + } + if (item.type === 'menu') { + return { + ...processedItem, +- menu: prepareMenu(item.menu, index, side), ++ menu: prepareMenu(item.menu, index, placement), + }; + } + return null; +- }); ++ }).filter(item => item !== null); + }; +diff --git a/src/fabric/ScreenStackHeaderConfigNativeComponent.ts b/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +index da28c51..1136622 100644 +--- a/src/fabric/ScreenStackHeaderConfigNativeComponent.ts ++++ b/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +@@ -19,6 +19,7 @@ type OnPressHeaderBarButtonItemEvent = Readonly<{ buttonId: string }>; + type OnPressHeaderBarButtonMenuItemEvent = Readonly<{ menuId: string }>; + + type BackButtonDisplayMode = 'minimal' | 'default' | 'generic'; ++type NavigationItemStyle = 'navigator' | 'browser' | 'editor'; + + type BlurEffect = + | 'none' +@@ -66,12 +67,15 @@ export interface NativeProps extends ViewProps { + largeTitleColor?: ColorValue | undefined; + translucent?: boolean | undefined; + title?: string | undefined; ++ subtitle?: string | undefined; ++ largeSubtitle?: string | undefined; + titleFontFamily?: string | undefined; + titleFontSize?: CT.Int32 | undefined; + titleFontWeight?: string | undefined; + titleColor?: ColorValue | undefined; + disableBackButtonMenu?: boolean | undefined; + backButtonDisplayMode?: CT.WithDefault; ++ navigationItemStyle?: CT.WithDefault; + hideBackButton?: boolean | undefined; + backButtonInCustomView?: boolean | undefined; + blurEffect?: CT.WithDefault; +@@ -79,6 +83,8 @@ export interface NativeProps extends ViewProps { + topInsetEnabled?: boolean | undefined; + headerLeftBarButtonItems?: CT.UnsafeMixed[] | undefined; + headerRightBarButtonItems?: CT.UnsafeMixed[] | undefined; ++ headerCenterBarButtonItems?: CT.UnsafeMixed[] | undefined; ++ headerToolbarItems?: CT.UnsafeMixed[] | undefined; + onPressHeaderBarButtonItem?: + | CT.DirectEventHandler + | undefined; +diff --git a/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts b/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +index 9a6af57..03aa2b2 100644 +--- a/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts ++++ b/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +@@ -18,6 +18,7 @@ export type HeaderSubviewTypes = + export interface NativeProps extends ViewProps { + type?: CT.WithDefault; + hidesSharedBackground?: boolean | undefined; ++ identifier?: string | undefined; + synchronousShadowStateUpdatesEnabled?: CT.WithDefault; + } + +diff --git a/src/types.tsx b/src/types.tsx +index 8594b73..20c6e88 100644 +--- a/src/types.tsx ++++ b/src/types.tsx +@@ -35,6 +35,7 @@ export type SearchBarCommands = { + }; + + export type BackButtonDisplayMode = 'default' | 'generic' | 'minimal'; ++export type NavigationItemStyle = 'navigator' | 'browser' | 'editor'; + export type StackPresentationTypes = + | 'push' + | 'modal' +@@ -754,6 +755,14 @@ export interface ScreenStackHeaderConfigProps extends ViewProps { + * @platform ios + */ + backButtonDisplayMode?: BackButtonDisplayMode | undefined; ++ /** ++ * Controls the UIKit `UINavigationItem.style` used by native iOS headers. ++ * ++ * `editor` matches modern document/editor-style bars with leading-aligned compact titles and glass controls. ++ * ++ * @platform ios ++ */ ++ navigationItemStyle?: NavigationItemStyle | undefined; + /** + * Array of UIBarButtomItems to the left side of the header. + * +@@ -766,6 +775,26 @@ export interface ScreenStackHeaderConfigProps extends ViewProps { + * @platform ios + */ + headerRightBarButtonItems?: HeaderBarButtonItem[] | undefined; ++ /** ++ * Array of UIBarButtonItems to the centered item group in modern iOS headers. ++ * ++ * This maps to `UINavigationItem.centerItemGroups` on iOS 26+ and lets ++ * document/editor-style chrome keep primary actions visually centered while ++ * leaving trailing search separate. ++ * ++ * @platform ios ++ */ ++ headerCenterBarButtonItems?: HeaderBarButtonItem[] | undefined; ++ /** ++ * Array of UIBarButtonItems to display in the native toolbar attached to ++ * the current screen's navigation controller. ++ * ++ * On iOS 26+, this can contain a `searchBarPlacement` item to let UIKit ++ * render integrated Mail-style search chrome using the attached SearchBar. ++ * ++ * @platform ios ++ */ ++ headerToolbarItems?: HeaderBarButtonItem[] | undefined; + /** + * When set to true the header will be hidden while the parent Screen is on the top of the stack. The default value is false. + */ +@@ -827,6 +856,20 @@ export interface ScreenStackHeaderConfigProps extends ViewProps { + * String that can be displayed in the header as a fallback for `headerTitle`. + */ + title?: string | undefined; ++ /** ++ * String displayed below the compact navigation title on iOS 26+. ++ * ++ * @platform ios ++ */ ++ subtitle?: string | undefined; ++ /** ++ * String displayed below the large navigation title on iOS 26+. ++ * ++ * Falls back to `subtitle` when omitted. ++ * ++ * @platform ios ++ */ ++ largeSubtitle?: string | undefined; + /** + * Allows for setting text color of the title. + */ +@@ -1139,6 +1182,13 @@ export interface SearchBarProps { + } + + export interface ScreenStackHeaderSubviewProps { ++ /** ++ * An identifier used to match this item across navigation bar transitions. ++ * Only applicable to type="right" and type="left" subviews on iOS 26.0 and later. ++ * ++ * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/identifier ++ */ ++ identifier?: string | undefined; + /** + * A boolean value indicating whether the background this item may share with other items in the bar should be hidden. + * Only applicable to type="right" and type="left" subviews. +@@ -1180,6 +1230,11 @@ interface SharedHeaderBarButtonItem { + * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/style-swift.property + */ + variant?: 'plain' | 'done' | 'prominent' | undefined; ++ /** ++ * Render the item with UIButtonConfiguration.glassButtonConfiguration. ++ * Only available from iOS 26.0 and later. ++ */ ++ glassEffect?: boolean | undefined; + /** + * The tint color to apply to the item. + * +@@ -1335,11 +1390,47 @@ export interface HeaderBarButtonItemWithMenu extends SharedHeaderBarButtonItem { + export interface HeaderBarButtonItemSpacing { + type: 'spacing'; + spacing: number; ++ flexible?: boolean | undefined; ++} ++ ++export interface HeaderBarButtonSearchBarPlacementItem { ++ type: 'searchBarPlacement'; ++ activatesSearchController?: boolean | undefined; ++ customView?: boolean | undefined; ++ index?: number | undefined; ++ width?: number | undefined; ++} ++ ++export interface HeaderBarButtonSearchFieldItem { ++ type: 'searchField'; ++ placeholder?: string | undefined; ++ width?: number | undefined; ++} ++ ++export interface HeaderBarButtonMailSearchToolbarItem { ++ type: 'mailSearchToolbar'; ++ composeButtonId?: string | undefined; ++ composeMenu?: HeaderBarButtonItemWithMenu['menu'] | undefined; ++ composeSystemImageName?: string | undefined; ++ filterButtonId?: string | undefined; ++ filterMenu?: HeaderBarButtonItemWithMenu['menu'] | undefined; ++ filterSystemImageName?: string | undefined; ++ onComposePress?: (() => void) | undefined; ++ onFilterPress?: (() => void) | undefined; ++ onSearchTextChange?: ((text: string) => void) | undefined; ++ placeholder?: string | undefined; ++ searchTextChangeId?: string | undefined; ++ showsSearchDismissButton?: boolean | undefined; ++ useFallbackSearchField?: boolean | undefined; ++ width?: number | undefined; + } + + export type HeaderBarButtonItem = + | HeaderBarButtonItemWithAction + | HeaderBarButtonItemWithMenu ++ | HeaderBarButtonMailSearchToolbarItem ++ | HeaderBarButtonSearchFieldItem ++ | HeaderBarButtonSearchBarPlacementItem + | HeaderBarButtonItemSpacing; + + /** diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6ef065c7af83be0e7f08976e0a4fc8e0101d48c2..5da642b3b618ca5bc4ef1626077b849fb095072f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -69,52 +69,50 @@ overrides: '@effect/sql-pg': 4.0.0-rc.115 '@effect/vitest': 4.0.0-rc.115 '@effect/vitest>vitest': '-' - '@expo/dom-webview': 57.0.1 - '@expo/metro-config': 57.0.12 - expo-constants: 57.0.16 - expo-modules-core: 57.0.14 + '@expo/dom-webview': 58.0.2 + '@expo/metro-config': 58.0.6 + expo-constants: 58.0.9 + expo-router: 58.0.10 + expo-sharing>@expo/config-plugins: 58.0.4 + expo-sharing>@expo/config-types: 58.0.2 '@pierre/diffs>@shikijs/transformers': ^4.2.0 '@tailwindcss/node': 4.3.3 '@tailwindcss/oxide': 4.3.3 '@tailwindcss/vite': 4.3.3 '@types/node': 24.12.4 effect: 4.0.0-rc.115 - expo-router: 57.0.17 - expo-sharing>@expo/config-plugins: 57.0.9 - expo-sharing>@expo/config-types: 57.0.2 node-abi: 4.33.0 lightningcss: 1.33.0 tailwindcss: 4.3.3 vite: npm:@voidzero-dev/vite-plus-core@1.0.0 yaml: ^2.9.0 -packageExtensionsChecksum: sha256-k/dT9NFDl5hihRPaoFKeY11hzyutMFs5psfZLFiKJic= +packageExtensionsChecksum: sha256-34mvKz5PLlrn2Tt9jUJC1SbK5hRE+oxwqyC1J6r09oE= patchedDependencies: - '@clerk/expo@4.6.8': a82bb41039ee88a290a87d4ab58be7be4c49fa338603b17ea646e1ec140a1cfb + '@clerk/expo@4.6.8': b8b22ab733de5bea846ad9e88046c10582352fe9ad86f314f368b2a823f0f281 '@effect/vitest@4.0.0-rc.115': 172bd95ef73a13d322888984415d5d18d9d2aa8e13fa529eac235efac837e902 - '@expo/metro-config@57.0.12': 96f1a75347e6ea02dc4b7034ace815d8ee39e18b8166ebfb573d9e58328f0dc2 + '@expo/metro-config@58.0.6': 90fa980e8b6480631fb2fbb04559834e3c612db40c550cd828f11be297d8d760 '@ff-labs/fff-node@0.9.4': c4e3cc2420ceb9dc650f9d189e9c24baf7e83f342998bacda5f459a4ce7927a8 '@legendapp/list@3.3.5': 680cc6a5c5b4a4032e467e7b3fde22f89a84c0ee2e6eac6fda737d6277cc0806 '@pierre/diffs@1.3.0-beta.10': 0ccee155b93b63d810e2c1a40c1fd676fb6fbcfa72cf6430dcedf1a3ae475ab4 '@react-native-ai/apple@0.12.0': 2d09870c2848d185cb05b53ed823a46e12dba519324d8dd8e584e28731990f9d - '@react-native-menu/menu@2.0.0': f63d256bf6a97a873b5e628eb595bd6ef0075ddd5bdd890fc920f7a6024290dd + '@react-native-menu/menu@2.0.0': 1cc2d43fbd0281ca0dd1feb5ffcefee7d4419459c8daaa58effff10c657832fb '@react-navigation/native-stack@7.17.6': e667c3cef8c78bb9ff4882ee5bd23a432247b843060a9499eb5f07e9e2295552 alchemy@2.0.0-beta.79: d1a03d902083946ee58121cc2787d88d1da561e9e30a5bcfcb8654692a489fb8 dbus-next@0.10.2: cfff57561b0ee59b5addb3b2e6c6f20906e967507a530ab67e8db8108e520ba4 effect@4.0.0-rc.115: 0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5 - expo-audio@57.0.4: fa9a3e0442ed395d4071bb406e08c3a471c9a84700bdfa0b9ad7ff144c96041a - expo-modules-core@57.0.14: 6be7092f8c6f03a57b75c797d98b5f19ed62d2dd205bfc4c8adf4cef45655d7e - expo-notifications@57.0.15: f89252c2c08dc7b3acb8415f319ebbe15fff8c9f88a64ebe1830cd5ac5c9ac40 - expo-sharing@57.0.17: 8d2e3b10eb3f52036a9a086800180ec6cebf3b75bccc5b1775117a7244d4ac45 - expo-widgets@57.0.15: 319a9ded5db49c5b5215c511a138b33f44c7ea2972eb418192e8d5342fe75ce6 + expo-audio@58.0.3: c20cb927d6848c53e7bf6ec14fe12f19daae9210165d2dbaf4e0f97ce31e8742 + expo-blur@58.0.2: d0311b0c0b05bd94393bd9a84653cb42503d5f3c8a19eb2627c34ace08bedf18 + expo-glass-effect@58.0.3: f750041c45ab838a3530451dc7b50d6640a79141037a1b0499c5e3412a860c57 + expo-sharing@58.0.12: 5c85c709d951b5522b5bca897204b73ba7c17dec76e0dd155f41f8c2e833a7a8 + expo-widgets@58.0.9: 94de7964c5a67ab40e6b79d9bdf4b7bfc50ae97b70722ee8e5a35105ca83386b node-pty@1.2.0-beta.15: f2fe901c61cde17986240002d05c172d5d0272d83ffaab8d0ebeb922763be414 - react-native-gesture-handler@2.32.0: 0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2 - react-native-keyboard-controller@1.21.13: 6e4339347bc5bb3c9ea67d85ff5c814058b211c5750f247aba59d07869a2e787 + react-native-gesture-handler@3.2.1: d518a937e3cb2df5e7d67f1ab6b265c74a8639e4572d1b032b7b747e9b1c01a9 + react-native-keyboard-controller@1.22.4: a438114039aed2e280a81d95c25723132ad071e4768fe492bd92aa628ad74597 react-native-nitro-markdown@0.5.8: 642b47830730acff3761fe29cf54271d18b493c0070c750097850b7ea032e00c - react-native-nitro-modules@0.35.9: 825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675 - react-native-reanimated@4.5.5: bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d - react-native-screens@4.26.2: 595114f3f9ce8b9f0d99d1aafe5c12c997b7d75ca9add31d46cbedbfe347b8e0 + react-native-nitro-modules@0.35.9: daf4a639ce3f951af630a3711e4082d58e3a11e5a79f45efb0b59925327ebde2 + react-native-screens@4.28.0: cc1301436ee62c39860acc9ee1a1e60b7d47e6abd211c42effa62c056d165483 uniwind@1.11.0: a91f3953483cfd434436de6358ff5b63c49974ef148fad91246c26ba95332625 importers: @@ -144,7 +142,7 @@ importers: dependencies: '@clerk/electron': specifier: 0.0.44 - version: 0.0.44(@clerk/electron-passkeys@0.0.3)(electron-store@8.2.0)(electron@44.4.2)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 0.0.44(@clerk/electron-passkeys@0.0.3)(electron-store@8.2.0)(electron@44.4.2)(react-dom@19.3.0(react@19.3.0))(react@19.2.6) '@clerk/electron-passkeys': specifier: 0.0.3 version: 0.0.3 @@ -245,19 +243,22 @@ importers: dependencies: '@clerk/expo': specifier: 4.6.8 - version: 4.6.8(patch_hash=a82bb41039ee88a290a87d4ab58be7be4c49fa338603b17ea646e1ec140a1cfb)(dbc31631339ce74330e188d5d7a88158) + version: 4.6.8(patch_hash=b8b22ab733de5bea846ad9e88046c10582352fe9ad86f314f368b2a823f0f281)(950bb7335d61b76ffb649f136fc0d4df) '@effect/atom-react': specifier: 4.0.0-rc.115 - version: 4.0.0-rc.115(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(react@19.2.3)(scheduler@0.27.0) + version: 4.0.0-rc.115(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(react@19.3.0)(scheduler@0.27.0) '@expo-google-fonts/dm-sans': specifier: ^0.4.2 version: 0.4.2 + '@expo/metro-runtime': + specifier: ~58.0.9 + version: 58.0.9(@expo/log-box@58.0.7)(expo@58.0.0)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) '@expo/ui': - specifier: ~57.0.14 - version: 57.0.14(@babel/core@7.29.7)(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(expo@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: ~58.0.9 + version: 58.0.9(@babel/core@7.29.7)(expo@58.0.0)(react-dom@19.3.0(react@19.3.0))(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) '@legendapp/list': specifier: 'catalog:' - version: 3.3.5(patch_hash=680cc6a5c5b4a4032e467e7b3fde22f89a84c0ee2e6eac6fda737d6277cc0806)(react-dom@19.2.3(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + version: 3.3.5(patch_hash=680cc6a5c5b4a4032e467e7b3fde22f89a84c0ee2e6eac6fda737d6277cc0806)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) '@material/material-color-utilities': specifier: 0.3.0 version: 0.3.0 @@ -266,22 +267,22 @@ importers: version: 1.9.1 '@pierre/diffs': specifier: 'catalog:' - version: 1.3.0-beta.10(patch_hash=0ccee155b93b63d810e2c1a40c1fd676fb6fbcfa72cf6430dcedf1a3ae475ab4)(@shikijs/themes@4.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 1.3.0-beta.10(patch_hash=0ccee155b93b63d810e2c1a40c1fd676fb6fbcfa72cf6430dcedf1a3ae475ab4)(@shikijs/themes@4.2.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) '@react-native-ai/apple': specifier: 0.12.0 - version: 0.12.0(patch_hash=2d09870c2848d185cb05b53ed823a46e12dba519324d8dd8e584e28731990f9d)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) + version: 0.12.0(patch_hash=2d09870c2848d185cb05b53ed823a46e12dba519324d8dd8e584e28731990f9d)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)) '@react-native-menu/menu': specifier: ^2.0.0 - version: 2.0.0(patch_hash=f63d256bf6a97a873b5e628eb595bd6ef0075ddd5bdd890fc920f7a6024290dd)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + version: 2.0.0(patch_hash=1cc2d43fbd0281ca0dd1feb5ffcefee7d4419459c8daaa58effff10c657832fb)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) '@react-navigation/elements': specifier: 2.9.26 - version: 2.9.26(c10301b6e0c42fc6434d2b643197a81e) + version: 2.9.26(83de68753219ecf7f3321e065bd378be) '@react-navigation/native': specifier: 7.3.4 - version: 7.3.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + version: 7.3.4(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) '@react-navigation/native-stack': specifier: 7.17.6 - version: 7.17.6(patch_hash=e667c3cef8c78bb9ff4882ee5bd23a432247b843060a9499eb5f07e9e2295552)(f640afa6cd4b9a1dc5422cbafdc82f53) + version: 7.17.6(patch_hash=e667c3cef8c78bb9ff4882ee5bd23a432247b843060a9499eb5f07e9e2295552)(cdeee8948497d4b80ffe015e2a003650) '@shikijs/core': specifier: 4.2.0 version: 4.2.0 @@ -302,7 +303,7 @@ importers: version: link:../../packages/contracts '@t3tools/mobile-markdown-text': specifier: file:./modules/t3-markdown-text - version: file:apps/mobile/modules/t3-markdown-text(c883758f8793b29a89016166016b354e) + version: file:apps/mobile/modules/t3-markdown-text(5c46709ff7a3b3b481fcdaa30ae2beb2) '@t3tools/mobile-review-diff-native': specifier: file:./modules/t3-review-diff version: file:apps/mobile/modules/t3-review-diff @@ -314,7 +315,7 @@ importers: version: link:../../packages/shared '@tabler/icons-react-native': specifier: ^3.44.0 - version: 3.44.0(react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react@19.2.3) + version: 3.44.0(react-native-svg@15.15.5(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react@19.3.0) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -325,155 +326,155 @@ importers: specifier: 4.0.0-rc.115 version: 4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5) expo: - specifier: ~57.0.18 - version: 57.0.18(41fd11498a34454c91128cdad32f22f8) + specifier: 58.0.0 + version: 58.0.0(3abfa3879936d948a635873738556226) expo-asset: - specifier: ~57.0.15 - version: 57.0.15(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@7.0.2) + specifier: ~58.0.9 + version: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2) expo-audio: - specifier: 57.0.4 - version: 57.0.4(patch_hash=fa9a3e0442ed395d4071bb406e08c3a471c9a84700bdfa0b9ad7ff144c96041a)(expo-asset@57.0.15(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@7.0.2))(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: 58.0.3 + version: 58.0.3(patch_hash=c20cb927d6848c53e7bf6ec14fe12f19daae9210165d2dbaf4e0f97ce31e8742)(expo-asset@58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2))(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) expo-auth-session: - specifier: ~57.0.10 - version: 57.0.10(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: ~58.0.6 + version: 58.0.6(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2) expo-blur: - specifier: ~57.0.2 - version: 57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: 58.0.2 + version: 58.0.2(patch_hash=d0311b0c0b05bd94393bd9a84653cb42503d5f3c8a19eb2627c34ace08bedf18)(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) expo-build-properties: - specifier: ~57.0.15 - version: 57.0.15(expo@57.0.18) + specifier: ~58.0.9 + version: 58.0.9(expo@58.0.0) expo-camera: - specifier: ~57.0.4 - version: 57.0.4(@types/emscripten@1.41.5)(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: ~58.0.5 + version: 58.0.5(@types/emscripten@1.41.5)(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) expo-clipboard: - specifier: ~57.0.1 - version: 57.0.1(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: ~58.0.2 + version: 58.0.2(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) expo-constants: - specifier: 57.0.16 - version: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) + specifier: 58.0.9 + version: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(typescript@7.0.2) expo-crypto: - specifier: ~57.0.2 - version: 57.0.2(expo@57.0.18) + specifier: ~58.0.3 + version: 58.0.3(expo@58.0.0) expo-dev-client: - specifier: ~57.0.16 - version: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) + specifier: ~58.0.9 + version: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)) expo-device: - specifier: ~57.0.1 - version: 57.0.1(expo@57.0.18) + specifier: ~58.0.3 + version: 58.0.3(expo@58.0.0) expo-document-picker: - specifier: ~57.0.1 - version: 57.0.1(expo@57.0.18) + specifier: ~58.0.3 + version: 58.0.3(expo@58.0.0) expo-file-system: - specifier: ~57.0.6 - version: 57.0.6(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) + specifier: ~58.0.4 + version: 58.0.4(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)) expo-font: - specifier: ~57.0.2 - version: 57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: ~58.0.4 + version: 58.0.4(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) expo-glass-effect: - specifier: ~57.0.1 - version: 57.0.1(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: 58.0.3 + version: 58.0.3(patch_hash=f750041c45ab838a3530451dc7b50d6640a79141037a1b0499c5e3412a860c57)(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) expo-haptics: - specifier: ~57.0.2 - version: 57.0.2(expo@57.0.18) + specifier: ~58.0.3 + version: 58.0.3(expo@58.0.0) expo-image: - specifier: ~57.0.3 - version: 57.0.3(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: ~58.0.8 + version: 58.0.8(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) expo-image-manipulator: - specifier: ~57.0.17 - version: 57.0.17(expo@57.0.18) + specifier: ~58.0.10 + version: 58.0.10(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) expo-image-picker: - specifier: ~57.0.14 - version: 57.0.14(expo@57.0.18) + specifier: ~58.0.9 + version: 58.0.9(expo@58.0.0) expo-keep-awake: - specifier: ~57.0.2 - version: 57.0.2(expo@57.0.18)(react@19.2.3) + specifier: ~58.0.2 + version: 58.0.2(expo@58.0.0)(react@19.3.0) expo-linking: - specifier: ~57.0.8 - version: 57.0.8(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: ~58.0.9 + version: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2) expo-network: - specifier: ~57.0.1 - version: 57.0.1(expo@57.0.18)(react@19.2.3) + specifier: ~58.0.2 + version: 58.0.2(expo@58.0.0)(react@19.3.0) expo-notifications: - specifier: 57.0.15 - version: 57.0.15(patch_hash=f89252c2c08dc7b3acb8415f319ebbe15fff8c9f88a64ebe1830cd5ac5c9ac40)(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@7.0.2) + specifier: ~58.0.9 + version: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2) expo-paste-input: specifier: ^0.1.15 - version: 0.1.15(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + version: 0.1.15(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) expo-quick-actions: specifier: ^6.0.2 - version: 6.0.2(expo@57.0.18)(typescript@7.0.2) + version: 6.0.2(expo@58.0.0)(typescript@7.0.2) expo-secure-store: - specifier: ~57.0.2 - version: 57.0.2(expo@57.0.18) + specifier: ~58.0.1 + version: 58.0.1(expo@58.0.0) expo-sharing: - specifier: 57.0.17 - version: 57.0.17(patch_hash=8d2e3b10eb3f52036a9a086800180ec6cebf3b75bccc5b1775117a7244d4ac45)(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@7.0.2) + specifier: 58.0.12 + version: 58.0.12(patch_hash=5c85c709d951b5522b5bca897204b73ba7c17dec76e0dd155f41f8c2e833a7a8)(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2) expo-splash-screen: - specifier: ~57.0.8 - version: 57.0.8(expo@57.0.18)(typescript@7.0.2) + specifier: ~58.0.2 + version: 58.0.2(expo@58.0.0)(typescript@7.0.2) expo-sqlite: - specifier: ~57.0.2 - version: 57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: ~58.0.7 + version: 58.0.7(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) expo-symbols: - specifier: ~57.0.2 - version: 57.0.2(expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: ~58.0.3 + version: 58.0.3(expo-font@58.0.4(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) expo-updates: - specifier: ~57.0.19 - version: 57.0.19(expo-dev-client@57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)))(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: ~58.0.11 + version: 58.0.11(expo-dev-client@58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)))(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) expo-video: - specifier: ~57.0.3 - version: 57.0.3(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: ~58.0.5 + version: 58.0.5(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) expo-web-browser: - specifier: ~57.0.2 - version: 57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) + specifier: ~58.0.3 + version: 58.0.3(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)) expo-widgets: - specifier: 57.0.15 - version: 57.0.15(patch_hash=319a9ded5db49c5b5215c511a138b33f44c7ea2972eb418192e8d5342fe75ce6)(@babel/core@7.29.7)(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(expo@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: 58.0.9 + version: 58.0.9(patch_hash=94de7964c5a67ab40e6b79d9bdf4b7bfc50ae97b70722ee8e5a35105ca83386b)(@babel/core@7.29.7)(expo@58.0.0)(react-dom@19.3.0(react@19.3.0))(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) react: - specifier: 19.2.3 - version: 19.2.3 + specifier: 19.3.0 + version: 19.3.0 react-dom: - specifier: 19.2.3 - version: 19.2.3(react@19.2.3) + specifier: 19.3.0 + version: 19.3.0(react@19.3.0) react-native: - specifier: 0.86.3 - version: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + specifier: 0.88.0-rc.3 + version: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) react-native-gesture-handler: - specifier: ~2.32.0 - version: 2.32.0(patch_hash=0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: ~3.2.1 + version: 3.2.1(patch_hash=d518a937e3cb2df5e7d67f1ab6b265c74a8639e4572d1b032b7b747e9b1c01a9)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) react-native-image-viewing: specifier: ^0.2.2 - version: 0.2.2(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + version: 0.2.2(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) react-native-keyboard-controller: - specifier: 1.21.13 - version: 1.21.13(patch_hash=6e4339347bc5bb3c9ea67d85ff5c814058b211c5750f247aba59d07869a2e787)(react-native-reanimated@4.5.5(patch_hash=bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d)(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: 1.22.4 + version: 1.22.4(patch_hash=a438114039aed2e280a81d95c25723132ad071e4768fe492bd92aa628ad74597)(react-native-reanimated@4.7.0(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) react-native-nitro-markdown: specifier: ^0.5.0 - version: 0.5.8(patch_hash=642b47830730acff3761fe29cf54271d18b493c0070c750097850b7ea032e00c)(react-native-nitro-modules@0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + version: 0.5.8(patch_hash=642b47830730acff3761fe29cf54271d18b493c0070c750097850b7ea032e00c)(react-native-nitro-modules@0.35.9(patch_hash=daf4a639ce3f951af630a3711e4082d58e3a11e5a79f45efb0b59925327ebde2)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native-svg@15.15.5(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) react-native-nitro-modules: specifier: 0.35.9 - version: 0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + version: 0.35.9(patch_hash=daf4a639ce3f951af630a3711e4082d58e3a11e5a79f45efb0b59925327ebde2)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) react-native-reanimated: - specifier: 4.5.5 - version: 4.5.5(patch_hash=bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d)(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: 4.7.0 + version: 4.7.0(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) react-native-safe-area-context: - specifier: ~5.7.0 - version: 5.7.0(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: ~5.9.1 + version: 5.9.1(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) react-native-screens: - specifier: ~4.26.0 - version: 4.26.2(patch_hash=595114f3f9ce8b9f0d99d1aafe5c12c997b7d75ca9add31d46cbedbfe347b8e0)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: ~4.28.0 + version: 4.28.0(patch_hash=cc1301436ee62c39860acc9ee1a1e60b7d47e6abd211c42effa62c056d165483)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) react-native-shiki-engine: specifier: ^0.3.12 - version: 0.3.12(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + version: 0.3.12(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) react-native-svg: - specifier: 15.15.4 - version: 15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: 15.15.5 + version: 15.15.5(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) react-native-webview: - specifier: ^13.16.1 - version: 13.16.1(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: 14.0.1 + version: 14.0.1(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) react-native-worklets: - specifier: 0.11.4 - version: 0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: 0.13.0 + version: 0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) shiki: specifier: 4.2.0 version: 4.2.0 @@ -482,23 +483,23 @@ importers: version: 3.6.0 uniwind: specifier: 1.11.0 - version: 1.11.0(patch_hash=a91f3953483cfd434436de6358ff5b63c49974ef148fad91246c26ba95332625)(@expo/metro-config@57.0.12(patch_hash=96f1a75347e6ea02dc4b7034ace815d8ee39e18b8166ebfb573d9e58328f0dc2)(bufferutil@4.1.0)(expo@57.0.18)(typescript@7.0.2)(utf-8-validate@6.0.6))(metro-cache@0.84.5)(metro-transform-worker@0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6))(metro@0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(tailwindcss@4.3.3) + version: 1.11.0(patch_hash=a91f3953483cfd434436de6358ff5b63c49974ef148fad91246c26ba95332625)(@expo/metro-config@58.0.6(patch_hash=90fa980e8b6480631fb2fbb04559834e3c612db40c550cd828f11be297d8d760)(bufferutil@4.1.0)(expo@58.0.0)(typescript@7.0.2)(utf-8-validate@6.0.6))(metro-cache@0.87.1)(metro-transform-worker@0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(metro@0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(tailwindcss@4.3.3) devDependencies: '@effect/vitest': specifier: 4.0.0-rc.115 version: 4.0.0-rc.115(patch_hash=172bd95ef73a13d322888984415d5d18d9d2aa8e13fa529eac235efac837e902)(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5)) '@pierre/trees': specifier: 1.0.0-beta.4 - version: 1.0.0-beta.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 1.0.0-beta.4(react-dom@19.3.0(react@19.3.0))(react@19.3.0) '@types/react': - specifier: ~19.2.0 - version: 19.2.16 + specifier: ~19.3.0 + version: 19.3.0 '@types/react-dom': specifier: ~19.2.3 - version: 19.2.3(@types/react@19.2.16) + version: 19.2.3(@types/react@19.3.0) babel-preset-expo: - specifier: ~57.0.9 - version: 57.0.9(@babel/core@7.29.7)(@babel/runtime@7.29.7)(expo-widgets@57.0.15)(expo@57.0.18)(react-refresh@0.14.2) + specifier: ~58.0.6 + version: 58.0.6(@babel/core@7.29.7)(@babel/runtime@7.29.7)(expo-widgets@58.0.9)(expo@58.0.0)(react-refresh@0.14.2) tailwindcss: specifier: 4.3.3 version: 4.3.3 @@ -595,7 +596,7 @@ importers: dependencies: '@base-ui/react': specifier: ^1.4.1 - version: 1.5.0(@date-fns/tz@1.5.0)(@types/react@19.2.16)(date-fns@4.4.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 1.5.0(@date-fns/tz@1.5.0)(@types/react@19.3.0)(date-fns@4.4.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@clerk/electron': specifier: 0.0.44 version: 0.0.44(@clerk/electron-passkeys@0.0.3)(electron-store@8.2.0)(electron@44.4.2)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -604,7 +605,7 @@ importers: version: 6.16.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@daypicker/react': specifier: ^10.0.1 - version: 10.0.1(@types/react@19.2.16)(react@19.2.6) + version: 10.0.1(@types/react@19.3.0)(react@19.2.6) '@dnd-kit/core': specifier: ^6.3.1 version: 6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -667,7 +668,7 @@ importers: version: 3.31.3 '@tiptap/react': specifier: ^3.31.3 - version: 3.31.3(@floating-ui/dom@1.7.6)(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 3.31.3(@floating-ui/dom@1.7.6)(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)(@types/react-dom@19.2.3(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@tiptap/starter-kit': specifier: ^3.31.3 version: 3.31.3 @@ -709,7 +710,7 @@ importers: version: 19.2.6(react@19.2.6) react-markdown: specifier: ^10.1.0 - version: 10.1.0(@types/react@19.2.16)(react@19.2.6) + version: 10.1.0(@types/react@19.3.0)(react@19.2.6) rehype-raw: specifier: ^7.0.0 version: 7.0.0 @@ -727,7 +728,7 @@ importers: version: 3.6.0 zustand: specifier: ^5.0.11 - version: 5.0.14(@types/react@19.2.16)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)) + version: 5.0.14(@types/react@19.3.0)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)) devDependencies: '@effect/platform-node': specifier: 4.0.0-rc.115 @@ -757,11 +758,11 @@ importers: specifier: ^4.0.4 version: 4.0.4 '@types/react': - specifier: ~19.2.14 - version: 19.2.16 + specifier: ~19.3.0 + version: 19.3.0 '@types/react-dom': specifier: ~19.2.3 - version: 19.2.3(@types/react@19.2.16) + version: 19.2.3(@types/react@19.3.0) '@types/react-test-renderer': specifier: 19.1.0 version: 19.1.0 @@ -800,7 +801,7 @@ importers: dependencies: '@clerk/backend': specifier: 3.18.1 - version: 3.18.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 3.18.1(react-dom@19.3.0(react@19.3.0))(react@19.2.6) '@effect/sql-pg': specifier: 4.0.0-rc.115 version: 4.0.0-rc.115(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5)) @@ -821,10 +822,10 @@ importers: version: link:../../packages/shared alchemy: specifier: 2.0.0-beta.79 - version: 2.0.0-beta.79(patch_hash=d1a03d902083946ee58121cc2787d88d1da561e9e30a5bcfcb8654692a489fb8)(@effect/platform-node@4.0.0-rc.115(bufferutil@4.1.0)(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(redis@6.2.1)(utf-8-validate@6.0.6))(@effect/sql-pg@4.0.0-rc.115(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5)))(@types/node@24.12.4)(@types/react@19.2.16)(@voidzero-dev/vite-plus-core@1.0.0(@types/node@24.12.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.48.0)(typescript@7.0.2)(unrun@0.2.39)(yaml@2.9.0))(bufferutil@4.1.0)(drizzle-kit@1.0.0-rc.5-ab785fc)(drizzle-orm@1.0.0-rc.5-ab785fc(31bc26b129d6bba2f2e387113f50dba2))(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(mongodb@6.21.0(@aws-sdk/credential-providers@3.1062.0)(socks@2.8.9))(pg@8.23.0)(react-devtools-core@6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typescript@7.0.2)(utf-8-validate@6.0.6)(ws@8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + version: 2.0.0-beta.79(patch_hash=d1a03d902083946ee58121cc2787d88d1da561e9e30a5bcfcb8654692a489fb8)(@effect/platform-node@4.0.0-rc.115(bufferutil@4.1.0)(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(redis@6.2.1)(utf-8-validate@6.0.6))(@effect/sql-pg@4.0.0-rc.115(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5)))(@types/node@24.12.4)(@types/react@19.3.0)(@voidzero-dev/vite-plus-core@1.0.0(@types/node@24.12.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.48.0)(typescript@7.0.2)(unrun@0.2.39)(yaml@2.9.0))(bufferutil@4.1.0)(drizzle-kit@1.0.0-rc.5-ab785fc)(drizzle-orm@1.0.0-rc.5-ab785fc(7abae7c285f47308cc52e143cbe0c150))(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(mongodb@6.21.0(@aws-sdk/credential-providers@3.1062.0)(socks@2.8.9))(pg@8.23.0)(react-devtools-core@6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typescript@7.0.2)(utf-8-validate@6.0.6)(ws@8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6)) drizzle-orm: specifier: 1.0.0-rc.5-ab785fc - version: 1.0.0-rc.5-ab785fc(31bc26b129d6bba2f2e387113f50dba2) + version: 1.0.0-rc.5-ab785fc(7abae7c285f47308cc52e143cbe0c150) effect: specifier: 4.0.0-rc.115 version: 4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5) @@ -1096,6 +1097,15 @@ importers: packages: + 2g@0.4.4: + resolution: {integrity: sha512-ZwH02IRQicm+92YzJZMS8imSAJaqTPI+VASb1zMnisotnWcEP4e7nb57Mr8C2dGAA5G8ZmialbMmpkGLWgAY/w==} + hasBin: true + peerDependencies: + typescript: '>=5.8.0' + peerDependenciesMeta: + typescript: + optional: true + '@ai-sdk/provider-utils@4.0.49': resolution: {integrity: sha512-8e7pd+82bobqrFOaD5dG/PiEuvLYr5olaE3I56ch0jipR0H7sGD6ohwTUynv6k8O8QidWiyIbEsZCtr/2dyXIA==} engines: {node: '>=18.17'} @@ -1688,12 +1698,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx@7.28.6': - resolution: {integrity: sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx@7.29.7': resolution: {integrity: sha512-WsZulLVBUHXVj2cUcPVx6UE21TpalB6bHbSFErKT0Ib++ax24jjXe73FqlWvdylFOjiuPHYi6VCcgRad1ItN+A==} engines: {node: '>=6.9.0'} @@ -1921,7 +1925,7 @@ packages: expo: '>=54 <58' expo-apple-authentication: '>=7.0.0' expo-auth-session: '>=5' - expo-constants: 57.0.16 + expo-constants: 58.0.9 expo-crypto: '>=12' expo-local-authentication: '>=13.5.0' expo-secure-store: '>=12.4.0' @@ -2286,10 +2290,6 @@ packages: peerDependencies: effect: 4.0.0-rc.115 - '@egjs/hammerjs@2.0.17': - resolution: {integrity: sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==} - engines: {node: '>=0.8.0'} - '@electric-sql/pglite@0.3.15': resolution: {integrity: sha512-Cj++n1Mekf9ETfdc16TlDi+cDDQF0W7EcbyRHYOAeZdsAe8M/FJg18itDTSwyHfar2WIezawM9o0EKaRGVKygQ==} @@ -2732,12 +2732,12 @@ packages: '@expo-google-fonts/material-symbols@0.4.38': resolution: {integrity: sha512-IJkBtN1o8u9BW5fvSii1MyHPQ7Q0HxbWcVBvOrOzgMLpVtZw7R2w94wBTVR7kZwv3w1JNTESMmLA5Sqn1+Z36A==} - '@expo/cli@57.0.20': - resolution: {integrity: sha512-ZjWz7SA5TBTyKq4+aFRUPgMFxmqHtKkDMv6d85J2UAAjdRhkNRf+B80t+rr5IFo2ywuTvyrPRBth4ei4w08olA==} + '@expo/cli@58.0.9': + resolution: {integrity: sha512-qoCjBSbq8sFmhPHA0jgDvkRdGvVm9Wjti0U/zlrqYrH/lVolqT8++RvWebCLIGrT1WHQ9HWOmaL7szKqbhVgiA==} hasBin: true peerDependencies: expo: '*' - expo-router: 57.0.17 + expo-router: 58.0.10 react-native: '*' peerDependenciesMeta: expo-router: @@ -2748,85 +2748,91 @@ packages: '@expo/code-signing-certificates@0.0.6': resolution: {integrity: sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w==} - '@expo/config-plugins@57.0.9': - resolution: {integrity: sha512-hHgfL1avkCdEvDSw7IwlKwRYYNgcxzbNNMIk6W6lTkJpY0MajinAfeJUS0J+wPCsjUfGbVqOJM+XhPaO5ulUxg==} + '@expo/config-plugins@58.0.4': + resolution: {integrity: sha512-JlZSHqYPU7nrU1E68KGpoW9pcXYgHfKOeTnqXXOop/4yj9UarOe9Y26Wlp6fhXjZ28ZooBJxo3J0Z5SSuLfbDQ==} - '@expo/config-types@57.0.2': - resolution: {integrity: sha512-ewW08OonrcRIsRKIlFvvcmmafE5zemb1ocu3HkNwtVPyRtj2w42pZCAkMIROYpcVBaPnc3mDT9UZDzwXWC3i6g==} + '@expo/config-types@58.0.2': + resolution: {integrity: sha512-iXoMw0/8KVSrrGRxOnf69eB9k5iPomOH7RPJnYEErAMFCfl2QCkftkHVSUdZ3qxtpx9EjRm0MANyAoQj77U7qw==} - '@expo/config@57.0.9': - resolution: {integrity: sha512-dmzlKraIFxa7wLwV6K7WzI8jp6QZpW6Mc5mGjLimJUFjzh4uQdYaT3m3plEutM5yxBoBEwqzks7l+I/ljCbxAQ==} + '@expo/config@58.0.1': + resolution: {integrity: sha512-sFI8mxS2p3E08xOGk1fKTQiuF27EQj1evwT4fXeMoaD6RjDJJDVmwJ27FMb6d4a/NObwgieIlGtoCE0+mmfD4A==} '@expo/devcert@1.2.1': resolution: {integrity: sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==} - '@expo/devtools@57.0.1': - resolution: {integrity: sha512-GyUf+wFNkbttaX0jR7MZa9bm77U0IrLg6d2AjpxdyoXw/w4abHoXG0oFufwLMgP9zLTd5+Ct4X/ffNUTnlzZgg==} + '@expo/devtools@58.0.2': + resolution: {integrity: sha512-WBj/K+vv8JPSmY70ennL04YYOHkpEsGGkfuVY9lfv4XO7Qhbt5qz4q6W7maME194I5oGcimRMigUFfWNkBe90w==} peerDependencies: + expo: '*' react: '*' react-native: '*' peerDependenciesMeta: + expo: + optional: true react: optional: true react-native: optional: true - '@expo/dom-webview@57.0.1': - resolution: {integrity: sha512-lAKsME4SAq+8sf56oN0DX5TBYyruupoRxbWbD2xf9RnKY8y6x8eb9LCE5pxSN0qyWdqnp+0wmyWzDkKboThKAw==} + '@expo/dom-webview@58.0.2': + resolution: {integrity: sha512-bLkREoP7qL3rEuzxP60xG+TjdPoGjbnZfxkvYo5imJxGWfKMOf7x962W06Pu+WWAr4gcDRk16iA+Clg8D0zjCg==} peerDependencies: expo: '*' react: '*' react-native: '*' - '@expo/env@2.4.3': - resolution: {integrity: sha512-M1NXeZCA1mkMkYOyIe7PlyRX0/jqFtMoJgyblnlq/vpCRfmueFT7RnGSQG8uEFDF5WHOFGijAQ3fogPh3/n5Ng==} + '@expo/env@2.5.1': + resolution: {integrity: sha512-FXr7sJtusDKrrtfxenRdAwbqARTasYY1+3vL3FjnlvwiWzvItnSBRbcspF6AI45jIBLbi2GHDIAorzAXhmA1+Q==} engines: {node: '>=20.12.0'} - '@expo/expo-modules-macros-plugin@0.6.1': - resolution: {integrity: sha512-cpsLZE4rqkc1Y3eZTkxB98jrqY1YXgetmtxFt8q89jBRmk3quRuk1BZo+VcnCSObZardjg99r1k5xijEMONFGA==} - - '@expo/fingerprint@0.20.11': - resolution: {integrity: sha512-GC43EcjQwzpzNZISqmhvjKdi+6FTfxnC9ZxOeg6osCkYXJz94j107l0QpPLipg62khD5HAA5G5cUhevffbRC4w==} + '@expo/fingerprint@0.21.2': + resolution: {integrity: sha512-LlXmTyDMsTYL5gGIUbTZ9EOrGPTmykmI44tld6v/hU0aSQndbdoAtT+LHvKKy6oSMdm1yHgHd2YzuMU+9MwwZQ==} hasBin: true - '@expo/image-utils@0.11.5': - resolution: {integrity: sha512-KPQBTpmpAfy/Vu9y4wPW808/qtZxjYmyJg8cm2QCPAupp+qEWA3b5zmk0ulOwQ9OgeHxuCPgUqWgkwHFo7UsrQ==} + '@expo/image-utils@0.12.2': + resolution: {integrity: sha512-lz4ShWkci1UYI8JhBywQM15hamJ5YLG3kz9qjNNKS7cOq4EKkzf4ZZXLEzAPpQaN1j1wWpY2MtbPIYXFLNUHsA==} '@expo/image-utils@0.8.14': resolution: {integrity: sha512-5Sn+jG4Cw+shC2wDMXoqSAJnvERbiwzHn05FpWtD5IBflfTIs5gUmjzwiGVyjOdlMSQhgRrw/AymPbmO9h9mpQ==} - '@expo/inline-modules@0.1.7': - resolution: {integrity: sha512-Bz/khd1gIJqDkje7t5ejD5e9jFbm4xEJzWSwRKadRo6gruepbw1xJ3Eb+e58OS8fY1ZNQYjzZbspnuph67sN0g==} + '@expo/inline-modules@0.2.1': + resolution: {integrity: sha512-WvmG1vuVbd6Py6uwYw7NUHGlOSBdJTXU8X18qBhCYXMfV8MPic0QUuFuUZGTyIzs4xUB/Pk6qgCyUdxOlJStxg==} - '@expo/json-file@11.0.1': - resolution: {integrity: sha512-zxHWj4MKKMAL29ZQSY/Fssx4Thluk40JmuGNaeS078wy/NhlFhnVi+rHHunulE3xJAJ0CM73m8VK2+GkF9eRwQ==} + '@expo/json-file@11.2.1': + resolution: {integrity: sha512-UPhKoFCj8BcwgLB1rKQ1CuR/REITnZLiqxHEHOeH1tPsdXcHGtUDh0P5bLbr7oU0nKVdtJ5rzyKx8jniMQdESQ==} - '@expo/local-build-cache-provider@57.0.8': - resolution: {integrity: sha512-SEdE0pAQrr90bRh3MNR0ZuwoIBw390cYdFgbn7Vk0Mtm9EHaBfP7kYj+2hXnXZJgOEm3/JMtfoD3rV7rWA9FGg==} + '@expo/local-build-cache-provider@58.0.1': + resolution: {integrity: sha512-V7zXjGgivtiqLe1oa6PQUvamoTf2/HxyavUrQSmZyDDUV6/mLQoTBrslRnj41OSIlIUqah9lxrcl759vKgMxqw==} - '@expo/log-box@57.0.4': - resolution: {integrity: sha512-IxwS9s1L2muj8mj8AQSuiy7u8OFJdc02NRFo2me/Tj6DiaeG5SREqmpBE4rQpR2cadqSg5jl8Qab8Cjie616dg==} + '@expo/log-box-utils@58.0.1': + resolution: {integrity: sha512-BUDoo1BUsSNmGonRkVWBNI6moKsZxH/Tkt9a1pphOBJQMdr8/1HbhGEB84YOwaKMpMXMWAK6cwu3Ip8ax3J28g==} + + '@expo/log-box@58.0.7': + resolution: {integrity: sha512-V6KY7IoeRZ7GqMRXQDrBF5w53w+a3PWWrNXnjzzkDC1uiaf2RN8qSACDPbJRUxJloL7X8EXnA7Q29i/YozxYSQ==} peerDependencies: - '@expo/dom-webview': 57.0.1 + '@expo/dom-webview': 58.0.2 expo: '*' react: '*' react-native: '*' + peerDependenciesMeta: + expo: + optional: true - '@expo/metro-config@57.0.12': - resolution: {integrity: sha512-S62Lrq35HZqBFD55423pmWb8PjaiR/W02zQC1uECBmw1vTN8WZaFz4TJ0i21EeJzwfebMb9MLxL8JZ102Z6VbA==} + '@expo/metro-config@58.0.6': + resolution: {integrity: sha512-jznif78n3+oOjvhtvmSqBbnkOfabDvouAMIXQXC3FlGl75bygzRTYvB+L712fvZOJd+LSo1jcCg2Q3swUnJyBA==} peerDependencies: expo: '*' peerDependenciesMeta: expo: optional: true - '@expo/metro-file-map@57.0.2': - resolution: {integrity: sha512-tb50nSIWwKpRufSkGuivOK0FbUxv1Uwqptb0SzFTk0bkmYmcy3gIwnCbOHTfmrQDVndRhPEiu2SYgh9Z0PCvGg==} + '@expo/metro-file-map@58.0.3': + resolution: {integrity: sha512-BAYHbRc89uX/mfxkK7oPe+YUXrPKE0rn3rq/e0E/PimUBeTfQjs1Y6Y7A4gLPuDTtSczyiZzFFJiTyA4MlNl5w==} - '@expo/metro-runtime@57.0.14': - resolution: {integrity: sha512-LVpsfF0QOzlLSKlHYpxgW1cP1NKcYeaoalLO18jYHgqseSveEkb9VOffFpicTQ7AN03odZ4fgkUF+p5YpoY4yw==} + '@expo/metro-runtime@58.0.9': + resolution: {integrity: sha512-nWxcO3zFVIAMf9sw8n2meAy/pHlNQ1jbUe3aDYGun+slKx41sJ+xzd/Z2LFjuP2uzoyWE0v0zekEqzsA0fQ1AQ==} peerDependencies: - '@expo/log-box': ^57.0.4 + '@expo/log-box': ^58.0.7 expo: '*' react: '*' react-dom: '*' @@ -2835,21 +2841,21 @@ packages: react-dom: optional: true - '@expo/metro@56.0.2': - resolution: {integrity: sha512-Ld5AeYMCCDa8bLeWhfuLbZFFjlV3f6ORqyPz2glGh6RltIngMuLf9BTC2yvHFjkKuGxL5SynijmA8xmNNWn5iA==} + '@expo/metro@58.0.0-rc.0': + resolution: {integrity: sha512-9ZXNH/rppKQcoW0ycTSQqnKcjuYnutWf/6YkfAh1PBeWs+W1Nuc2uMTRM0qWNc9btbD4iHZKovru3gJqMgFzFQ==} - '@expo/osascript@2.7.1': - resolution: {integrity: sha512-Zn03EX6In7ts2lPUW2ESUSkEhEWQN1qqsiXjadtZMJOuZRkMiAg1ZQHuvz9DjByDWNJ2pBwAGyrts9lj9k389g==} + '@expo/osascript@2.8.1': + resolution: {integrity: sha512-SCi+6q6uOkGhiAn6AIP/OPFgaIq/iKD2oYpnAOg2rShHStJ8ey7wyT127RbOaZXmlcY/62rHOX1WiiMnD8u/BA==} engines: {node: '>=12'} - '@expo/package-manager@1.13.1': - resolution: {integrity: sha512-y/K+CaYYpZpNGZhSX4HyLT/vyIunFjNfyoxNysPBCefeLKI/VCx6f9LNPzrxayr3rCYO5bl9O8H+HRQK265Nkg==} + '@expo/package-manager@1.14.1': + resolution: {integrity: sha512-aw/VqeDaZsn2G5FxJUfWgWkdcl4u/JsNhlQakAEUhu5++4AitDprw4Uc0PwerH76V8Y34U/nVypL+YTVs/pi2g==} - '@expo/plist@0.8.1': - resolution: {integrity: sha512-3gTReGIUm0oRaMClsAJYxBnVPCl6fVpsl8HS+DTVxDhW4GyVyxg9E/Znm3BvcHtUJ51RJJI14pC1wvrNilCRHw==} + '@expo/plist@0.10.1': + resolution: {integrity: sha512-nuNOqj+r/hGJbZ1Ax3jUpZaOB8UAMHUrISALJEUKaCieTflYj7224EqFWmMpriCGk9wXS1gH+9GGVnSj0tWzuQ==} - '@expo/prebuild-config@57.0.15': - resolution: {integrity: sha512-xTbWHroj0PDmlbqvmU+zF9ZZxveJkiuyiPoeRJYRGruFHebRAWnoTdw5S7d/UCzDBI8ropGGu9g2eb2nMxtvAw==} + '@expo/prebuild-config@58.0.6': + resolution: {integrity: sha512-rnaPdJ+bSHRlJ2ElANH5P1QKtJSFSTxxR7FSh4qpwPfFJs6L3ozhOLP4R1z5oFCXq6MUQfYIDHb51rUfPAgDMg==} '@expo/require-utils@55.0.5': resolution: {integrity: sha512-U4K/CQ2VpXuwfNGsN+daKmYOt15hCP8v/pXaYH6eut7kdYZo6SfJ1yr67BIcJ+1Gzzs+QzTxswAZChKpXmceyw==} @@ -2859,26 +2865,26 @@ packages: typescript: optional: true - '@expo/require-utils@57.0.5': - resolution: {integrity: sha512-kTAXj9lDFEIPMsbAOGCGbjBbMF0oi7CqkYM79KOX0DDD9wSwXmlKL1z2h8OwsrBf7mbOo2DjlRvZu4BEjrIxGw==} + '@expo/require-utils@58.0.2': + resolution: {integrity: sha512-50w3h4s8eQze5L0PGfVAWGUWrT0ss9oHPa9INAIra43ScU+MP5s3b5qysvdv7mep9SgSX3+qdWIjcrOP5rNd+A==} peerDependencies: typescript: ^5.0.0 || ^5.0.0-0 || ^6.0.0 || ^7.0.0 peerDependenciesMeta: typescript: optional: true - '@expo/router-server@57.0.8': - resolution: {integrity: sha512-lEPGYoDmh97yyEcY/MFWQsfE7yIgMRnGDcnsBN7B6AiWBFSJIMEcGnO0aYPgY0ZjNWyJDi7Ee8QZRGqB+LhI6w==} + '@expo/router-server@58.0.4': + resolution: {integrity: sha512-zoHpJzp7ltEY5w9eCINlkeCZg0BvtXexj0SIg/B9YGgFIiGYQDbtrQYy6eDc1lUICQn6ntzql3lrunegdConvw==} peerDependencies: - '@expo/metro-runtime': ^57.0.14 + '@expo/metro-runtime': ^58.0.9 expo: '*' - expo-constants: 57.0.16 - expo-font: ^57.0.1 - expo-router: 57.0.17 - expo-server: ^57.0.3 + expo-constants: 58.0.9 + expo-font: ^58.0.4 + expo-router: 58.0.10 + expo-server: ^58.0.2 react: '*' react-dom: '*' - react-server-dom-webpack: ~19.0.1 || ~19.1.2 || ~19.2.1 + react-server-dom-webpack: ~19.0.1 || ~19.1.2 || ~19.2.1 || ~19.3.0 peerDependenciesMeta: '@expo/metro-runtime': optional: true @@ -2889,8 +2895,8 @@ packages: react-server-dom-webpack: optional: true - '@expo/schema-utils@57.0.2': - resolution: {integrity: sha512-fMu/jyN0l1Wzv7XkeWR4IYCx1M8ryui3FdBNGrWwbRgJ7EhxXxK8E2jxP2W3pbgUwUY0V3hG8+GyfCZwny+Lxw==} + '@expo/schema-utils@58.0.1': + resolution: {integrity: sha512-r5ox9st0g1IYC37tKD0WYiKH6RXout9FqjSwVv0nIhRYYTXhChJfzcMnJ90zkBznKO1lZVCqdO302YVYsm3qQA==} '@expo/sdk-runtime-versions@1.0.0': resolution: {integrity: sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==} @@ -2902,8 +2908,8 @@ packages: '@expo/sudo-prompt@9.3.2': resolution: {integrity: sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==} - '@expo/ui@57.0.14': - resolution: {integrity: sha512-m8Z5dCplkOOQ70lu/xfB67qhk00Muw4U1T9frHBIW3LxxJeJZQ+jOmV6vCk6O6zVgoG/ib1et7PeX6etxI4Rsw==} + '@expo/ui@58.0.9': + resolution: {integrity: sha512-uKwQb8zoDlbEw6jjHMA9OPzMVmo+sbnnKUhO/VNruaE3HF3swazCbrSRIomeznOVvyPP7EJsV5jXUrQgLAWzkg==} peerDependencies: '@babel/core': '*' expo: '*' @@ -3464,6 +3470,58 @@ packages: resolution: {integrity: sha512-ugvXJjwF5ldtUpa7D95kruNJ41yFQDEKyF5CW4TgKJnh+W/zmlBzXXeKTyqIgwMFrkePN2JqOBqcF0M0oOunow==} engines: {node: '>=0.3.0'} + '@noxcturnal/noxcturnal-darwin-arm64@0.1.1': + resolution: {integrity: sha512-Y0JXi8J4abYq88swQLqXOw0kSw0v6CfKp4tboyqPOWNVgQvUy14SMTKVyPLUpaKd0ZJGP8cvNTSQI9bZP7+5CQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@noxcturnal/noxcturnal-darwin-x64@0.1.1': + resolution: {integrity: sha512-lAaRd5TGFKydkYaPiDl/zGxg5hOZmJknEF0thMQHhe6s90fCcP/1t3XAaNH6czUbWV2dkhPggo9ua3Mm0KisGg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@noxcturnal/noxcturnal-linux-arm64-gnu@0.1.1': + resolution: {integrity: sha512-871HxfCyTzrMz/OKzG17M4OgWdPwns9a3yCo+HALvuBsed+mtY2CliJvzoQhoRw1bdICaXp6LqUsY4KhX1A+Yw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@noxcturnal/noxcturnal-linux-arm64-musl@0.1.1': + resolution: {integrity: sha512-ehEOT/CgdZUpfuGVQ32u/nJU80SQVNql3J/vVTglH30MbGQlMA5Sd1VAHtYgVMtpXsIo4rlNhcvHIJ0L9by9Cg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@noxcturnal/noxcturnal-linux-x64-gnu@0.1.1': + resolution: {integrity: sha512-psTHW5aDNc3PpWFzQOJLmOj4oP3NZRMjpc8H1Jvu8vAqtVWakdxhICG5/q0jMkgY9iyg+mqdtHaLMeAImmCeHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@noxcturnal/noxcturnal-linux-x64-musl@0.1.1': + resolution: {integrity: sha512-MSdZTx5GL6hdG0UVrL7PHbLqDoO0Mz9mf6vwkhBbVYJGM4NY0ptNHsd5j5B+0RGjQgSMQX52tC96g8e23oqi8w==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@noxcturnal/noxcturnal-win32-arm64-msvc@0.1.1': + resolution: {integrity: sha512-Bq/C94sV38ay57QS4EbwIOamGNVXRkPVDc5Wg+4gvBjhJbYs+nfH05CpwRkQBgb8SpV51FQCLQfXvk59Aab60Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@noxcturnal/noxcturnal-win32-x64-msvc@0.1.1': + resolution: {integrity: sha512-D5ZuKQyxJd/wvf9qcVSCD69spzhoHNbaib/dJGpHXQLomrDBwtzYbPVxUwEBWAaXnTqme6/TEZdl/6sG4tm4wA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@octokit/auth-token@6.0.0': resolution: {integrity: sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==} engines: {node: '>= 20'} @@ -3793,6 +3851,9 @@ packages: '@oxc-project/types@0.127.0': resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==} + '@oxc-project/types@0.141.0': + resolution: {integrity: sha512-S4as7z0j0xQkXcJlyY5ehntwK8/wRkQb9Cyqw+J/N2rkWGQGK0SxD6X6DhQTc7qsxVTBxXbxZtBJh3mr3PtIzQ==} + '@oxc-project/types@0.146.0': resolution: {integrity: sha512-XC0QsnnhVe7sLIWmYmdPw7x5P0h4W8vUU3Nv1ySgWXtvCz8NizoAEpGXA0sOYoJQV2Rl13LgURAHQ5cI5ILCSA==} @@ -4256,177 +4317,6 @@ packages: yauzl: optional: true - '@radix-ui/primitive@1.1.3': - resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} - - '@radix-ui/react-compose-refs@1.1.2': - resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-context@1.1.2': - resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-dialog@1.1.15': - resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-dismissable-layer@1.1.11': - resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-focus-guards@1.1.3': - resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-focus-scope@1.1.7': - resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-id@1.1.1': - resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-portal@1.1.9': - resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-presence@1.1.5': - resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-primitive@2.1.3': - resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-slot@1.2.3': - resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-callback-ref@1.1.1': - resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-controllable-state@1.2.2': - resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-effect-event@0.0.2': - resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-escape-keydown@1.1.1': - resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-layout-effect@1.1.1': - resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@react-grab/cli@0.1.44': resolution: {integrity: sha512-gMDYY2rw6OWajCcDlXSIgs2LC432YJXSb3Lm5yM187uhRgBYddoEVULi36h+IolX3r7jSb3ew7vn9FfI8NSo0A==} hasBin: true @@ -4448,78 +4338,78 @@ packages: react: '*' react-native: '*' - '@react-native/assets-registry@0.86.3': - resolution: {integrity: sha512-TDhgCZA4wjJg84d5A9swiOQYPIWSKEEVdg9IwMFZDupQzW/F3QoLUrfAJOcalgqTDA9/buTB8awhE3Whwg6u9Q==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + '@react-native/asset-utils@0.88.0-rc.3': + resolution: {integrity: sha512-G3P/3lF1bvZoT4Za87UiVJCpTNNF6c07sTNINXYiSxXDpPiM8piisgqdgueyy90cKH6ReL28y2S8glRiG+jkeQ==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - '@react-native/babel-plugin-codegen@0.86.3': - resolution: {integrity: sha512-O6Xza4JBGPIU8J7YbKTyBoYL4thpy8jMW/oaLDWdAyOwYHKIjK47pAL5HUEbOe2bWz2PEKjbYRF2ApkJv1ottQ==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + '@react-native/babel-plugin-codegen@0.88.0-rc.3': + resolution: {integrity: sha512-v68EZUjkcs2ZLL1ayA2aQ79imy7BGlc6uAteKMDhA8vf0QKT92YHkSFMGA1+df38d3/v3R+AB6X6XFhixQ1EEQ==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - '@react-native/babel-preset@0.86.3': - resolution: {integrity: sha512-/eqs/Hy9RZRcjdcs4wj3Cqmxvtb3NM5g+Uuh1RIvsjynMO8PRsrVWWLWgBcZL/jYUo+ogXd2NFB0W8L5Bg89xw==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + '@react-native/babel-preset@0.88.0-rc.3': + resolution: {integrity: sha512-xkAmd1gSQWjl5QnY0YFuMhjykdABljvuUY0McQHHLf4GJHEcpwuRPf3kM5lDq8p/y+Ui2iAbGgQsGExFY6FV0w==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} peerDependencies: '@babel/core': '*' - '@react-native/codegen@0.86.3': - resolution: {integrity: sha512-Ux4jHi0fh+bdtVEcL0gaPLbY56V+SvFUDl/8sRAE1jdb4k+o7fT/4Nc29yz4X+qfjstkSqObQTMBGhdzxH9JvA==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + '@react-native/codegen@0.88.0-rc.3': + resolution: {integrity: sha512-fjDCsaVPTlrYHelSogo/J9RbeeJ+dfokyw57VdtFa3HMWssCSqBmgnSoKKexQAO6U4fppAm91550DC8+02pL4A==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} peerDependencies: '@babel/core': '*' - '@react-native/community-cli-plugin@0.86.3': - resolution: {integrity: sha512-qSDL9LQc5mZSZPNczT95WU9YQuPzxBklgON9vLhhqfI0yWIwKInqFx88dQ/uiEXBtf0yossthaQIqA4Ml6bF6g==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + '@react-native/community-cli-plugin@0.88.0-rc.3': + resolution: {integrity: sha512-wfchdOOL4EM12jQuDY75uG9/pJ1dMckugJmAkLsyHY2akhjImdn7rq0Ea7q2nLK0talq56jTklpXQZVoVvyrAA==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} peerDependencies: '@react-native-community/cli': '*' - '@react-native/metro-config': 0.86.3 + '@react-native/metro-config': 0.88.0-rc.3 peerDependenciesMeta: '@react-native-community/cli': optional: true '@react-native/metro-config': optional: true - '@react-native/debugger-frontend@0.86.3': - resolution: {integrity: sha512-TQmeofQ0PcuylhhlleOeuzHYZfbrgm3gayXzowqUEzgRisTm1D40/J3ggqs7XkQi5HP5ZA3n8dHmKL9vIzPcsw==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + '@react-native/debugger-frontend@0.88.0-rc.3': + resolution: {integrity: sha512-tv3DAqm5oTjQ9sYkr99UMKqc+VfoCZo13ZobzKD7oDRl7b+RT9wtyUiQrTuRQLrmadJ+TfU11G8xnyVmjHC/Sw==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - '@react-native/debugger-shell@0.86.3': - resolution: {integrity: sha512-O4ds+J7xZfxkbih9T+cAGegBdvKSPKYJm/lDgC9CpEjFMkmzWTpVLU3Qsv9sqZuo58z+sGhIcJfPsCFFWHpqbQ==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + '@react-native/debugger-shell@0.88.0-rc.3': + resolution: {integrity: sha512-ECf/bl4c/eGd77tNQnCizoLqYiOTyOQ1pU7SzVGI4Nql+aZiNR+lGaz3CJB1ve4+g+00hXTyiBjPjOmfNfdEYg==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - '@react-native/dev-middleware@0.86.3': - resolution: {integrity: sha512-LiEPTqTg/63bYUnrPyHLfjTDCNhA/+CUqI1+DsA9tYyewtSbULd5awsva6SgE10I+2iMhgKXS3ymkhU/kSCrGA==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + '@react-native/dev-middleware@0.88.0-rc.3': + resolution: {integrity: sha512-lM7ZJ/SZJAEHtN+TUlA4onk2PxRAIFSM/9v6bxtk6jkeXQyNIxFhXkqAzkI2vXV2ImtRv7XXjs4pwKkZ1jxJxg==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - '@react-native/gradle-plugin@0.86.3': - resolution: {integrity: sha512-lxmx0GqLEWRIpZfpYFXlYVIs3ENQwaW6Vmp6oi29l2GoQJ1wZfFZRdMimDWlGEk8LKfHar3QH3iaPMkTcK9lEQ==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + '@react-native/gradle-plugin@0.88.0-rc.3': + resolution: {integrity: sha512-mH7obkxTQ2s/7hANYIaGmZWXNgVIobbZNuV1YpTvWRZrwtLsl57scHevP87c6+j9RDYjzMSLIfHvfqDFo7cqoA==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - '@react-native/js-polyfills@0.86.3': - resolution: {integrity: sha512-eYIJ0es967+tePBFQDnl/gidVFxLns3fnbiK6rxscQrGodvuUO6hwxpQnfNynJ8MjbbndImXihXjcnJdc7SzJg==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + '@react-native/js-polyfills@0.88.0-rc.3': + resolution: {integrity: sha512-KONuwN2lvrLopOWVgLTFNwx1cwdlS5NZbmR+fQY5r6RvkHHvzbN4JqnfP2oQB0IGLxjJZPN0ljfhhPiCZ7YMdw==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - '@react-native/metro-babel-transformer@0.86.3': - resolution: {integrity: sha512-0nlwVkG0uT9o72nrGTKUz/IqDnCkM4zE0ihe4r+OJcxH93yBdDm58AXJ3EXZeSjv3osHEFXU7ceajdZiS34mTw==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + '@react-native/metro-babel-transformer@0.88.0-rc.3': + resolution: {integrity: sha512-ekhRzsHa13fDZYTSfq5SWS88wcc+2Magy3g2oG0fup7beFrbpLxGzIm1bpBNg892htwvWHtLDuV4CUvFKka/EQ==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} peerDependencies: '@babel/core': '*' - '@react-native/metro-config@0.86.3': - resolution: {integrity: sha512-qdzDMepV2xdUhsO4XC7idnnbt8K6+Hd59AjeK9y4KS86fxSQq5oL0TAbqUuajDGR7beNQoYTuS6AowN/zP0oaQ==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + '@react-native/metro-config@0.88.0-rc.3': + resolution: {integrity: sha512-nyJSwizwYxZtwHAaL7PFJ+33FN9Ho9q/5h931VtLTQDr6OxrWu957K2il9Yzd/k5wAURpv+DDB3Oagl3hl2HhQ==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - '@react-native/normalize-colors@0.86.3': - resolution: {integrity: sha512-Cv3CDkprb67GrzuaS9BGbBJC/6G4lIw3nyKOHRKTqTTum4bn37y5+R0Z04L8mcbQN85eEohNrRwb7IOM4j6uvg==} + '@react-native/normalize-colors@0.88.0-rc.3': + resolution: {integrity: sha512-el4NZ16vfh2quo56hB5G8cD8Bbk8N2+hamMfeaSWE5XCQC4vyTWGrE4FORjTdLAjv4Uh8LMuX87iMgwt2adArg==} - '@react-native/virtualized-lists@0.86.3': - resolution: {integrity: sha512-1j44NEyNn05Ut40vHAmoSWbsIcybFkMAOBTwQt1PrESyfSS+qBoyU1LGIogNva0VIa0rQyEC5PzbA7R4/7Nhyw==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + '@react-native/virtualized-lists@0.88.0-rc.3': + resolution: {integrity: sha512-0vI4q0kjrS3HPn5pg5IXkVUAmNBS67ZqKzhaAKfuxvQ3Xrr5Q5LOH7u6DphTSQ+Dy2GYeQUxSN1XqCUbpbcxxg==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} peerDependencies: '@types/react': ^19.2.0 react: '*' - react-native: 0.86.3 + react-native: 0.88.0-rc.3 peerDependenciesMeta: '@types/react': optional: true @@ -5379,9 +5269,6 @@ packages: '@types/fs-extra@9.0.13': resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} - '@types/hammerjs@2.0.46': - resolution: {integrity: sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==} - '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} @@ -5441,8 +5328,8 @@ packages: '@types/react-test-renderer@19.1.0': resolution: {integrity: sha512-XD0WZrHqjNrxA/MaR9O22w/RNidWR9YZmBdRGI7wcnWGrv/3dA8wKCJ8m63Sn+tLJhcjmuhOi629N66W6kgWzQ==} - '@types/react@19.2.16': - resolution: {integrity: sha512-esJiCAnl0kfpNdE69f3So4WJUXy95dLZydX0KwK46riIHDzHM7O9Vtf9xCHW0PXIqvgqNrswl522kA/5yx+F4w==} + '@types/react@19.3.0': + resolution: {integrity: sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==} '@types/responselike@1.0.3': resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} @@ -6058,8 +5945,8 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} - agent-cli-detector@0.1.6: - resolution: {integrity: sha512-vKrPeEVN3upDF3GjWxsWBbwQgMtNJ8VB1cduPvK3svmmz4ENpS7yaPxbogsbe3w+xp9xp2Cu+0Ar41rjAR4+lA==} + agent-cli-detector@0.1.7: + resolution: {integrity: sha512-d8OWDVdZMgjhLUT9ZPgSv/BdFFF9pVuscC0JdUSz3bjwE15gcp6u/o0/JooM2yyAWC49KThFhXlgTXRa9B7yng==} engines: {node: '>=18.18'} hasBin: true @@ -6220,10 +6107,6 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - aria-hidden@1.2.6: - resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} - engines: {node: '>=10'} - aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} @@ -6307,21 +6190,18 @@ packages: babel-plugin-react-native-web@0.21.2: resolution: {integrity: sha512-SPD0J6qjJn8231i0HZhlAGH6NORe+QvRSQM2mwQEzJ2Fb3E4ruWTiiicPlHjmeWShDXLcvoorOCXjeR7k/lyWA==} - babel-plugin-syntax-hermes-parser@0.36.0: - resolution: {integrity: sha512-LhD0xdoedDw7ansQgXbB2DADLZIK/LRXuWNBPuVzMc5S2WK5GyT89tCM+cQzxFGO0mGyLK6D5TrVOJJzAoDy8Q==} - babel-plugin-syntax-hermes-parser@0.36.1: resolution: {integrity: sha512-ycduwJbvdvIMmVvlAZqGggS+pm5Eu4Bk9pcV9Sm2Z4PJNRVsKkv0g7vHj+LeuC1gHTeF67sJXFOq61IlqCa2hA==} babel-plugin-transform-flow-enums@0.0.2: resolution: {integrity: sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==} - babel-preset-expo@57.0.9: - resolution: {integrity: sha512-T19biGOBTnMp161PyBqWOoSIEeZug8/EjtuUdVob8JPQKZMTalHUQaQt+qtQQE7XsEkZJ6erb3k0CohneTFzQg==} + babel-preset-expo@58.0.6: + resolution: {integrity: sha512-e4PqE6comKx0CKZo2l1XlNoWE9mfabQvAHDk6CvqmDWMEh3vIJgBubZAbdBONsxaUqKON2SVnXKmmPD01iW1iA==} peerDependencies: '@babel/runtime': ^7.20.0 expo: '*' - expo-widgets: ^57.0.13 + expo-widgets: ^58.0.9 react-refresh: '>=0.14.0 <1.0.0' peerDependenciesMeta: '@babel/runtime': @@ -6537,20 +6417,9 @@ packages: resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} engines: {node: '>=18'} - chrome-launcher@0.15.2: - resolution: {integrity: sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==} - engines: {node: '>=12.13.0'} - hasBin: true - - chromium-edge-launcher@0.3.0: - resolution: {integrity: sha512-p03azHlGjtyRvFEee3cyvtsRYdniSkwjkzmM/KmVnqT5d7QkkwpJBhis/zCLMYdQMVJ5tt140TBNqqrZPaWeFA==} - chromium-pickle-js@0.2.0: resolution: {integrity: sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==} - ci-info@2.0.0: - resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} - ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} @@ -6873,6 +6742,10 @@ packages: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} @@ -6911,9 +6784,6 @@ packages: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} - detect-node-es@1.1.0: - resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} - detect-node@2.1.0: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} @@ -6937,8 +6807,8 @@ packages: dmg-builder@26.15.6: resolution: {integrity: sha512-nr5vQxEhM0REomp1qiHbc6V99yrfBZy+wUU56VXADfSOlLj8PdLqsHiRe7b+FbqKesiyv4ax+k1GVwGonYKuCg==} - dnssd-advertise@1.1.4: - resolution: {integrity: sha512-AmGyK9WpNf06WeP5TjHZq/wNzP76OuEeaiTlKr9E/EEelYLczywUKoqRz+DPRq/ErssjT4lU+/W7wzJW+7K/ZA==} + dnssd-advertise@1.1.6: + resolution: {integrity: sha512-Ndrrf6BMPalkQPd/zubL+4YghH2J9NspapQ09uDXwYbvOPkP0oaqf5CkcwJ0b50kS2O3ul6yVu+jz+RY62Cejg==} dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} @@ -7314,46 +7184,46 @@ packages: resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} engines: {node: '>=12.0.0'} - expo-application@57.0.2: - resolution: {integrity: sha512-q31YwcXyymviAmdrtDfAg3Dld4VMxLCNAfgMHip7vZpPX4lzF/AfwsywqBJUAjQnJknzaNAkzqvMVjO5XmKYDA==} + expo-application@58.0.2: + resolution: {integrity: sha512-N1ivhudcdS6KmEm8S9W14L3WVgFnCUv85MU1YX+AYauJcs9IZWRoM7Wl1JU+PUUYvbVGLHoXNpu0aE3jVTdkFg==} peerDependencies: expo: '*' - expo-asset@57.0.15: - resolution: {integrity: sha512-ZoiUftQb1Nn1jvL6l1kZoUXvgRCx57tMQYxSsp+g4ZvY+jgVWp/THruXOtPtZVdC/WWZxPUTct53bfAm2EPDAQ==} + expo-asset@58.0.9: + resolution: {integrity: sha512-31fMfET8PyoCNGKmyjOY6fBTyTO7du80EjtrzZ/TsT+9zincWMUGwBWeby/fTXPHMEVgWQAiU2sKEteWEw8+Tg==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-audio@57.0.4: - resolution: {integrity: sha512-TLP8rt1UvUDzgxGnyQ0TR9hV6tNP/UJQdDu7mSK+dgEydMFoptq55D3hcUoB1gF39f3/3AUuWfOtpGM+4N4X1A==} + expo-audio@58.0.3: + resolution: {integrity: sha512-BwH1calLvev1jfU/ZF3GIpW76LOhevLXk+nur0FZRZyiZJYxYvvg6scO0+XAt0d7pk6/kiPIirPHFlWgb79fpw==} peerDependencies: expo: '*' expo-asset: '*' react: '*' react-native: '*' - expo-auth-session@57.0.10: - resolution: {integrity: sha512-i1RY93LouEgal2e/Ly1r2Ytwed7/y6i4AUShVj4Gg49h/Okf8QpZO7XylwL43IHfKRrKkqapRDEN8mWe7z/HgA==} + expo-auth-session@58.0.6: + resolution: {integrity: sha512-kTTQcZ2WgFxJlV2XtlBJxikADl8zPk1T2tTcC5c2ZOpjfAXHPDF/4pC9tfyYxNe0fOjCq9+t6aVL5X0uzZdVmg==} peerDependencies: react: '*' react-native: '*' - expo-blur@57.0.2: - resolution: {integrity: sha512-Aoud8H8lmlNkbRufyvRLefmGFELdBf1n5Te/Xm+Zx8ORINH+aXL+gKb5mbftFSha860+I7pMArz77TBYz8HDVg==} + expo-blur@58.0.2: + resolution: {integrity: sha512-2WKeR2FCSwTjTm+D0YLoLy/6rR583LYxlnhkB04zVkzWBiQKYCnOaUaOSsjQO2Nr/6ZpECmwXDhw4yzIuHZARQ==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-build-properties@57.0.15: - resolution: {integrity: sha512-qZe9pnxlBpHT7SSNDR2a3C+P34xv67Ep9I0Erh+3xCczGlokyRd4pu9h0PrBdsVlr1d0QREQ1Do/+IgrIWkQQA==} + expo-build-properties@58.0.9: + resolution: {integrity: sha512-NJ2Zf1/ELtXVng9J8EH6F7zSA2tfjOyaq4itda3yaiSb5a5lgLjLg1+USwPo628HI/yGILGyOwmC8zxegEUyPQ==} peerDependencies: expo: '*' - expo-camera@57.0.4: - resolution: {integrity: sha512-MqbbQ63O+cA8JbK3lfFHiD0f2jv8jB+EG/ILK6f5xnOPV9IR37yaG5+lGtRZNoOeYBzGypyOi17USItleMyuGw==} + expo-camera@58.0.5: + resolution: {integrity: sha512-UMc27NClJ5xnu2m/6Kz5zynOxJ7LluY0lgbu/TdxDZgGccjfM/myfLcO5r1FXaW84Llf3vTveG7SvwuRsNWIlQ==} peerDependencies: expo: '*' react: '*' @@ -7363,101 +7233,103 @@ packages: react-native-web: optional: true - expo-clipboard@57.0.1: - resolution: {integrity: sha512-HWICri4+1ao7S6QEfcorxVumXDiDnx1guGGewjZgGJWLGxFYs0RgH8ujBs+lkTzBkMmlwADaWSlaesR+nDJt5Q==} + expo-clipboard@58.0.2: + resolution: {integrity: sha512-AiL1yU6iLX4sP8BZZyLzsSCo7XWysIBgVAck1vTqIkZm5PcVBeKiDgjXeJzG8nHBpti+ReeGhxbCaMQe7VbyMg==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-constants@57.0.16: - resolution: {integrity: sha512-HG3yJjGZo2BPTo2F1sBoxdJZRwX7d9C554EhKn8m12K62pxGolCsvPSoh/lQf95OEP9vO34wwXB2C3QFs0KG0g==} + expo-constants@58.0.9: + resolution: {integrity: sha512-+EaES5uHt3t3kY4VPsvM0uiOo0sjiMKuxGKqdfKaNbpCg3FI5D3qfQbgDHf5fbM09DIfXSbymKeiZx/JKQgzng==} peerDependencies: expo: '*' react-native: '*' - expo-crypto@57.0.2: - resolution: {integrity: sha512-OGLvHK7Hb7qsONMWGB9pJw3n+iY4OnZQmM/KwQEHRMrrOmNg0Lxj9+tp9bj46aAMMzXx0FTVA2jUKoplpXPnkA==} + expo-crypto@58.0.3: + resolution: {integrity: sha512-i6es/jfng4LDnmgVmHMCsFPA0ns3Iur9ypH+reRLVqH2Mgi9spYqZgpuhpX3gMyu0rKYylLz2YM8n5wxvhNp7w==} peerDependencies: expo: '*' - expo-dev-client@57.0.16: - resolution: {integrity: sha512-Txss9sgzEFI0E+4I34E76vPiukeVDHnqCj0ZXy8SDijVM31/P6MCNniVbEZk7MBPQclD0aopfuaCFtkV8+r1sw==} + expo-dev-client@58.0.9: + resolution: {integrity: sha512-JQPBDw0bZqZCqbOVxbphTaJXdlzuHcP7rXBxakWhotNy8nA5Ek4p6E8pIJu/OMWSLleoM0Dgtz05H/ShEHBItw==} peerDependencies: expo: '*' - expo-dev-launcher@57.0.16: - resolution: {integrity: sha512-jaBr6q4A5js/r465m2mRxN8A87YOi8I6PiIt8XIt4qfQWDgw6hqGovaF1AVFGT1Z5jxkjtgK8WNz/rAeypjqPQ==} + expo-dev-launcher@58.0.9: + resolution: {integrity: sha512-wf7MDFbPOoTBD+ZWcFKyhxw+g1jghPL5yl9/r3PZmTiprpoMIZQXUBGpmnAHifJbA1Fhlhzm978tGU/Njr2t5Q==} peerDependencies: expo: '*' react-native: '*' - expo-dev-menu-interface@57.0.0: - resolution: {integrity: sha512-F47VdzOHYc19FhI/jBgctpO8a5UskTIxG6a1E5t3W5gF8VImuvBQffdXXfLHhsuCl7dS3v3U0R45cleeVXO1Zg==} + expo-dev-menu-interface@58.0.1: + resolution: {integrity: sha512-XdjO3ZZhEq1dXm15GVtzQ0SXxSTPguJIDZib3Z8tAf2jLxfPUlQObgO/0hdnw7ssEBhTT2jQo2HAfnOSGUfj8w==} peerDependencies: expo: '*' - expo-dev-menu@57.0.16: - resolution: {integrity: sha512-KzMHtAmnr0GqyU6MCrKLzIo/AfOjcToGhzK+pFeXlcqSPOrPJbTGlZqQ3E1o2G2jZMs+M1XvXh/VgnRyJUaRGw==} + expo-dev-menu@58.0.9: + resolution: {integrity: sha512-+VJMHf6XeGgVhQsJY+9CqKP2JTAv6n8Ki5NJt70BF0iqM5LzWa+/vwRna+HcTVYPA1KfHErSfL2WlLJT9LDNyQ==} peerDependencies: expo: '*' react-native: '*' - expo-device@57.0.1: - resolution: {integrity: sha512-jyEMDUticH+dhcL3GHa2aiifOvGXJsmb3oVT2R2q4i8bN7Bddy61+NkpMmuS2VAZrvoLQwf0TJJ/1vi1ukvutA==} + expo-device@58.0.3: + resolution: {integrity: sha512-sK1xb02joE79KQ/c9c4oCaMhErjwUoL7IfInImRyxxmuEfKuzlNldBV61mahIrT3UyvYZBEwMM0Sx76Yqn7izg==} peerDependencies: expo: '*' - expo-document-picker@57.0.1: - resolution: {integrity: sha512-qBwM5oxDZ3I9kwFD3pUE1oK/WNv9artoEKO6UpqhQgNRr0XA1ALRVWYjkF4+ge9lUNDRehjTm/jenINkzqg84g==} + expo-document-picker@58.0.3: + resolution: {integrity: sha512-7oNPAhvzjGoF3Yhmkpw8GppXT05I0RC6qzskW4wbRgDFhuQRhE8eUvYU7T/Bq6NX1ERu5TUbTI0QS9zo3DO1SQ==} peerDependencies: expo: '*' - expo-eas-client@57.0.2: - resolution: {integrity: sha512-EfFiqUr0o9TvTOgMbqDiV1oIdG/d7kirhqtwa7roGmm9wF+CpXUz20d9YGzO6KzJWUYgdUgu4B6Ocv0jNJUdnQ==} + expo-eas-client@58.0.1: + resolution: {integrity: sha512-FkomAg1uLen36v8U7jyzMKbdrMjKRSufB9qSCnhWnJynYkeWK4qAb9UyJBD/afkbTFQfq+ARImjM7IAi3V+2NA==} - expo-file-system@57.0.6: - resolution: {integrity: sha512-pm8PMYEW6BnVOCBJ7df9FcDmQtE1tqImuYphlfYe1ipQRLYtdCayRczJcbKIsnB3mqEyp4gC2gWmMbsAsAOjVg==} + expo-file-system@58.0.4: + resolution: {integrity: sha512-w7Vuh1qA4fkZOSR4Zylvdr6bgOiH5p1hvfrnNlP+Xqb1x5h8Mu13yvQKUm4A1yc7BAeZ7CXu7//dw5hDEevFUg==} peerDependencies: expo: '*' react-native: '*' - expo-font@57.0.2: - resolution: {integrity: sha512-eWR0CAdysgVqg8VewJ8b5wKh1pa6C8YShIEU3SP0+hlSqOk4djUwuJjn3P04KHVzL3hws9FrUuPxCNmd4TGung==} + expo-font@58.0.4: + resolution: {integrity: sha512-AElYv+6hg7xgf8x7yL0zP8D2QrJuASU59iKC+yLd38SM6AvWFMlgBz0fkcgWtZFH7QI0Kz1WP+WsCQd06wYxBQ==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-glass-effect@57.0.1: - resolution: {integrity: sha512-m/n8maxqNcHk6ZDhuqXBfD5Kt1Iz3M8xykVgdB0iSCIXvF70IqWXmQhX8Psswhrp8eZ+3r0mAD0Jh/2gFA3QaA==} + expo-glass-effect@58.0.3: + resolution: {integrity: sha512-NoFT5j2uZecNsiDAd47z37PWYTxNJnJMrVYiAU+SggiV9K91Sc0IuIcMsuOM4sUuPBQdSTs8/I9KXk5M0Z2O/w==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-haptics@57.0.2: - resolution: {integrity: sha512-vPths6zTxxaGaemC7D1GKbw1iOnOAAL5oAcCFVSgVNWnuLCBefL1LkhRBaJsepiMXRh2y3vwPiXkPaf6d16blA==} + expo-haptics@58.0.3: + resolution: {integrity: sha512-5chRroIhYhB2CG6Ce7sE82q4EATF9O4G7oyeUlDumcVAZzpNWWJkCZ7ucajyHOj2Wc/rArg2h7jYmwI3sgxnNA==} peerDependencies: expo: '*' - expo-image-loader@57.0.1: - resolution: {integrity: sha512-uhrZKLT/cTl2mXyR28kPpVkS5O+PK9N1QA/07IFM4f5T4g0lTW1JHT3NEWwEEsGFldPmVX4j7LwUVVZxE+woug==} + expo-image-loader@58.0.2: + resolution: {integrity: sha512-anioFtqL5sl7556fw0vZOJBqICq0cpQAUUeQlFR40e9OJawCguWAs/FFpJYNX94DUYrp8YzlacThSWNyh0YPGw==} peerDependencies: expo: '*' - expo-image-manipulator@57.0.17: - resolution: {integrity: sha512-VpM8qAotTeSIobIAL8RAIDrZKL0jQBK/6O41NnwmdT96sd2wT263DlTbkvQ6RkcFrR9+NZiC5Um7FDBK+jFneg==} + expo-image-manipulator@58.0.10: + resolution: {integrity: sha512-JWapRwmOUq5RaePB1WKlEDgX/MewnRUeM6MKE0W7zEvbkyFYVn+4swUNOP3WDjDzu+To+878bqt7hcRcaqWzzA==} peerDependencies: expo: '*' + react: '*' + react-native: '*' - expo-image-picker@57.0.14: - resolution: {integrity: sha512-NK9XBQqOtscbB/uRts1Gm7Oki6odMN3FQPWD6fSKmNUfKM69O6kcgU25lEXFTSLZ7sLl+AopHa2X0uILd8rjaQ==} + expo-image-picker@58.0.9: + resolution: {integrity: sha512-irYps0kkD+t17jHhBbQfm5Y9NbWXxULGyZPP/y90td3LE5zlFvFzNCj8Qnfif+ZFtg0QaL0T2fb/p5NLbfFA0w==} peerDependencies: expo: '*' - expo-image@57.0.3: - resolution: {integrity: sha512-EYfV8tIQxXLQPHhgZxc+bESUn2NcVw1U0RM28qqFeFfHyD1sBpIYJC2JTy24OtfBowYVoUyTvgf2ykWydiZVCw==} + expo-image@58.0.8: + resolution: {integrity: sha512-kRzMdDK+Cp0Iunz/psYnFDvt2MGTYA2qsZrey+nkH3XrtjTJVRD9hhdnHh35vLO3LXJsUNXfEvGnNV+ghnk0Hw==} peerDependencies: expo: '*' react: '*' @@ -7467,32 +7339,33 @@ packages: react-native-web: optional: true - expo-json-utils@57.0.1: - resolution: {integrity: sha512-cgTe1NqzQdYs/WN+3nIY5IZg8s0pb0xaTUbhYvxQDn137GbwRfHoGM2se3m3Vsl4Qu+B9G4RPEK5WJDEU2Do7g==} + expo-json-utils@58.0.1: + resolution: {integrity: sha512-jNHNElOUPz2/vW3CbDKRn6tTF6eE9wwVbh/Isnqp5c/CdTcONzFVR3YHN3WQ05PnkmieyEqVfeOusOd1X9FDtQ==} - expo-keep-awake@57.0.2: - resolution: {integrity: sha512-GqgH746wtJImmsbyHmCQoi7cOslKuWQBbJHXr53S35Bpf5UvxCAztvnitUEd7D0QvFN2rvkOhylbZpgZZfBLlQ==} + expo-keep-awake@58.0.2: + resolution: {integrity: sha512-UIddpQTJrYq/qsiuFHRJQwb1z1jojQ44XV2o6+bSuxLFKwO4KXp21to2GD3RkRFYLKdrEm98FLbzD9KpALkdKQ==} peerDependencies: expo: '*' react: '*' - expo-linking@57.0.8: - resolution: {integrity: sha512-gv0ZNaF7tILbcvX8xinNbQr6GIGQStxeUAJseweP+LjC9ped7Wl6EeyIMBlDR83U6Da+8drVeqBQSMvwAXgytA==} + expo-linking@58.0.9: + resolution: {integrity: sha512-EhA4cClb/rB8idwcrg0zQvgPxAiB0rnjy/zF9DLxmxxkTjV1Y1X3XphfeDxmoWNNf1gL9E47K/R6wsfJcni8aA==} peerDependencies: + expo: '*' react: '*' react-native: '*' - expo-manifests@57.0.1: - resolution: {integrity: sha512-qB/mDG2dYdl+EvUeQuqP8KFYCFgFCQjJYdWIHo8SFBgDzMYmdF286DFY2M1M9Okr99wkb5M4tgA3aCcwv3aEQA==} + expo-manifests@58.0.1: + resolution: {integrity: sha512-fVeJJ71Fj8FJgcAUggn6QIsm7CTxsXFgekLl4pEPHgON6fmcxog63FGO0sisQ3F6yUWFR4nn8iJmgBp1Exs7ew==} peerDependencies: expo: '*' - expo-modules-autolinking@57.0.12: - resolution: {integrity: sha512-Q8KAlq37nLKsQ+HsS9NpQVpd5jCgqtu694TDUNHBUBpV9ViD82mRBh8Uug/h68RG9xnLS+kuL4nYaCuFRghHjg==} + expo-modules-autolinking@58.0.6: + resolution: {integrity: sha512-1O707KinH8UCUzi9JNeFqF87BJSh1fGgpwjdI/NzBhG2IoHAFQ1ngnpyqF6ikr/o01aGoBgjdCRRLfzEnop/IA==} hasBin: true - expo-modules-core@57.0.14: - resolution: {integrity: sha512-Cg3aQnVsQhZcMOF/RFgPGzMuhIak5W9eR9ecwmFSeQ813r4/49ut6RMA6PqUuUKuPCUIRqnBAHfSyTm1W9nfzg==} + expo-modules-core@58.0.9: + resolution: {integrity: sha512-0BD1t8aWXPGGA+222KzG4MA29iZVqBNJWCKoPKFwD9ab7x9wPkazLGifAp8m3VOYKLLMbzYD8uS9XTJdiplduA==} peerDependencies: react: '*' react-native: '*' @@ -7501,19 +7374,22 @@ packages: react-native-worklets: optional: true - expo-modules-jsi@57.0.6: - resolution: {integrity: sha512-WK0xFEe0FdZTCLCdfXK+HVNYfAmEbA6goecRxqjr0gh3XYRKAr9tikxqcM0ItLQoEPKntscPZhWcPLGvr97Tfw==} + expo-modules-jsi@58.0.5: + resolution: {integrity: sha512-5UMYPOEB1amqV7SCQKxJBvyZHycW4ZIeP3cwkv22pSE2nx3Hj6IymNz34TtIrCMcJAs6mO7MtG5OUsgwTp+iTQ==} peerDependencies: react-native: '*' - expo-network@57.0.1: - resolution: {integrity: sha512-ndg+FbDDlz6XTpQ6aVuVgyvrYQwMkpcUAvZIXbwrGBbLTSWNzYC/gawYu1BAeDN7O6JTGY98GBVJBov/JH7LgQ==} + expo-modules-macros@0.14.0: + resolution: {integrity: sha512-R6ODnfK0Za+pSZZjv0SuOTV2YkxczeavvrsLv40gueH3U7QJ8H5OlD3kkFqyT68UzDLRJhwF52D884egtNH7Rw==} + + expo-network@58.0.2: + resolution: {integrity: sha512-+Ek0nuLcZmW4f35L1lg4vo3lpotV0OUehFj8y5z0w/VEAw3WOeEzXh7Eo3TS6lIvsbyIJO7woWx8fYjMbGnhbA==} peerDependencies: expo: '*' react: '*' - expo-notifications@57.0.15: - resolution: {integrity: sha512-H91z4WSFukSQP3dThgh6PCPFrT6VHeR+J2f7CuCOE72JV7YEGcBCir103QY58ocKsdgkodQpnkTU2m8LTHkWLg==} + expo-notifications@58.0.9: + resolution: {integrity: sha512-Ygi1bvJKMiv6wP0r9b3WzDkZy28EbIeagNvxyQqcy6FoyuUpAIXbH0IgnaAjK3czPWin78jC3GsDJYeZbHFPDg==} peerDependencies: expo: '*' react: '*' @@ -7531,52 +7407,52 @@ packages: peerDependencies: expo: '*' - expo-secure-store@57.0.2: - resolution: {integrity: sha512-PhrPMKnI7YSObLEQZOoP9evB2ZOCv9kFuG2L7cZfNlOwWjGbir711PlppkXVoM3JE8vamDrTqzMLGv266FhJJg==} + expo-secure-store@58.0.1: + resolution: {integrity: sha512-jYKTkbXOlKrt3DiDw+f/EGc70UfyWNJgQiBEQ8ocyEpUehouyp9GcKza3gWixgLV8CWaCx4RtxiFQ5pFWaj0XQ==} peerDependencies: expo: '*' - expo-server@57.0.3: - resolution: {integrity: sha512-aK+LdKzauHSGmsOStZtyxdzv0zWssCkxTw3m4QuOhfDSJsZaMRTd9O41d8ixU/QfELTbaJ0oRNcF7JFV/7O9YQ==} - engines: {node: '>=20.16.0'} + expo-server@58.0.2: + resolution: {integrity: sha512-QOdIBRZ7hEhlKzDud99/4YPggg+rASCD901PuuDy/oHzSP+eQKs2B4PDwzwfYvtelDA45nOwJsyCKnBvwpuJZA==} + engines: {node: ^22.13.0 || ^24.3.0 || ^26.0.0 || >=27.0.0} - expo-sharing@57.0.17: - resolution: {integrity: sha512-p2B4SMeNsOv6hm1NkrxRlncjwu9mmLfi0drLaEyX13Rxn4DdDFPhuaezpOK7XLogTsmWGpfR46uq6oHMvSxbfA==} + expo-sharing@58.0.12: + resolution: {integrity: sha512-2uwxo2+9W6WzA87FnBiwCAWkrBAoNUrNY7mJHA5k3Q5i/je6tH2N65kl5pACpYEIOOShQkOAd4zz7DVc23JydA==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-splash-screen@57.0.8: - resolution: {integrity: sha512-BEsrKg4niYBZa5AFzWRyGqxA4ZemtBOPwbCy+C336iGYYPuZYLEgWJGmm2xD1gRfCdrM/TP+l2ONd86Zvk3KyA==} + expo-splash-screen@58.0.2: + resolution: {integrity: sha512-rYs8/d8GGFKBfj1cecr8/87nfUcdSmqQq/enm8Wmv1IuC3l1dxnxFRWlnz2KORCYLUw42M2vNRqlSU9ETHt8GQ==} peerDependencies: expo: '*' - expo-sqlite@57.0.2: - resolution: {integrity: sha512-5KVbT7BQFZlIcQBXKWvwBERK3ODF6PSqct27GQKukZzAjsx2B97R+mwtYqrTUtUbw71VJrQrdr9Yl2OWYC7UpA==} + expo-sqlite@58.0.7: + resolution: {integrity: sha512-0ge3jryvlzEDyT7mXPEpTaqIIT65+n2noQfxBrWMdmSmuqL4L6eAYw/81C8UrXmDM97Y7vmmdR3abkMdN/a2mg==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-structured-headers@57.0.0: - resolution: {integrity: sha512-//t9UNPbJSEysc2x4VKJG/u7Osvv5DYJWsET5bqt/B+qcD1by/JXvSQzX3Q/YAgA96xFPontrz6OAPLbO4JKEA==} + expo-structured-headers@58.0.1: + resolution: {integrity: sha512-wIduvAIUdGQk82osLjFiYYq3TFHUdG4RgmN+C//EySxn/2PTu0RsJsdgBtXrp/OT3YGeesNgfzb1mFxq5Zhp0g==} - expo-symbols@57.0.2: - resolution: {integrity: sha512-qZ0iqOflm5lZGwRsQ5Y8sDksw3GAUKwHSX1bJBoocXf7gu14vafIXXYWte+JT9VfXAUGyKodJhLHP/GoOrcNWg==} + expo-symbols@58.0.3: + resolution: {integrity: sha512-WmO6gAjvUlgS3gFgvuHN/JRPsfHaDPiPj31i28YBN5yjg/B/k2UiPHFgqfktm8Tyy+rVtUr4ttMp91sibnybRw==} peerDependencies: expo: '*' expo-font: '*' react: '*' react-native: '*' - expo-updates-interface@57.0.1: - resolution: {integrity: sha512-+LUWwJ0gf/TEKMVdQAw/Gjih4dvrk+URgy24X9qEGKuuMDZqjBRm9T4yQyBVALGL5TTdPUaB6ILxx3lshm3pwQ==} + expo-updates-interface@58.0.1: + resolution: {integrity: sha512-OF+3BtMXtUsXWDfpHVNus9yHpx7WjMwjxDfeeN9LQBYSq/UtYmNNHBSfzChYTuqljWFSOAHRfsDykV9EB73Wlg==} peerDependencies: expo: '*' - expo-updates@57.0.19: - resolution: {integrity: sha512-xX4KIUa8H2xKmiVDe/uEehD96MV6nyyF/OCrE+PBYfOEp6BbS8bYkHZfNFcoDCKMRuT6pg9JrCi8OmnoWlM/2A==} + expo-updates@58.0.11: + resolution: {integrity: sha512-7mijq0yyFhPExPO/IS/feFrmrbR6pZP3WOAYf07RkfW/3lacLBxWt5/rKG9QMe7ydbvjqMednhca1Rx48lB2mg==} hasBin: true peerDependencies: expo: '*' @@ -7587,31 +7463,32 @@ packages: expo-dev-client: optional: true - expo-video@57.0.3: - resolution: {integrity: sha512-Z+rLdBSzICwoHm/HUxND5fm5nfgqiB+QPWAOKxmA8ScYwvxG1UGjZ6OaayvPc3GkT4aucsbycmFO0uUv/qnIhg==} + expo-video@58.0.5: + resolution: {integrity: sha512-iJM0z/HR7Gocywq5Z4ou1CvTMaoGrXVNb1HzzENpqF+endoJcOGZFgV5uq+OGbiLtm7S/LSm/CCtcPwvVsdcCw==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo-web-browser@57.0.2: - resolution: {integrity: sha512-3vl5kvd7PB48ub6PpNIJUuPxO8xVa6D8RnIgNba6SXRwqFprOfeEZgwTgtm41kz0AAtvMOztUVNEUkwrHKjqMQ==} + expo-web-browser@58.0.3: + resolution: {integrity: sha512-SEPI0pphJ6rCTtJ01OWNRDTxvEqCTl3TkVRC3erUC1CGUrz5UWCzK+ejUx4F1WEayfj4j9tQAw0JDc+dzDq26g==} peerDependencies: expo: '*' react-native: '*' - expo-widgets@57.0.15: - resolution: {integrity: sha512-dlwbUCLaxOZFcIejxtOo95NyqJMa4Sop4NPzJEvvD2MwXERBqxkp8RExxVDAEiBRIdAYqC1u02SnIJWT/27f7g==} + expo-widgets@58.0.9: + resolution: {integrity: sha512-wGmI39qtJ6965rJA1bgAuKA2rEHfecoL939wxnBsSz3mvAAnSsjUNytP1rsVc0cBooPCssxqJST9EXGzee5Hfg==} peerDependencies: expo: '*' react: '*' react-native: '*' - expo@57.0.18: - resolution: {integrity: sha512-6nax9hJPhf9dWrstliXUABTJXDNIJrfJKcCtjSxuYVs2Yf127GIhKf3wsEYSFUl+LFdRbPPTNaweJePH159wZA==} + expo@58.0.0: + resolution: {integrity: sha512-/KiC8tFY0hHl/mm49AFgNUFEQbnPthVh9o7EuDCSnTVpor8Cm/x1oqRyE97dxPT640lwuHO55xFO6OXopzjKXA==} + engines: {node: ^22.13.0 || ^24.3.0 || ^26.0.0 || >=27.0.0} hasBin: true peerDependencies: - '@expo/dom-webview': 57.0.1 + '@expo/dom-webview': 58.0.2 '@expo/metro-runtime': '*' react: '*' react-dom: '*' @@ -7755,12 +7632,25 @@ packages: flow-enums-runtime@0.0.6: resolution: {integrity: sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==} + flow-estree@0.327.0: + resolution: {integrity: sha512-f9vK751YUzD0qaHSpKc5/qQM6gqOlgGS+4ZRqTNcZOpVqn3mC55yEQ6dUG2K1eaVm5FbKkz9CFWe6XNvrkQFQg==} + engines: {node: '>=18'} + + flow-estree@0.331.0: + resolution: {integrity: sha512-FVLYkSL/ITb/QXBEQvNWPjPooRGswuUtGOwrH+puSlMDneNkxy640+FZsk/TfKL+b7Wbw/Fg9FTUv2bMQDpj2w==} + engines: {node: '>=18'} + + flow-parser@0.327.0: + resolution: {integrity: sha512-/MYZ5hXWf5ozpbdfUDmazMgQXviLxWEiRLH3MppEGDdW0itRVqmB5UaU7QX+SBCDNiq+gEesSVn8nlxmPDyDkw==} + engines: {node: '>=0.4.0'} + + flow-parser@0.331.0: + resolution: {integrity: sha512-vEZcHIlnKeN8JSVtYFczj8sWJfHIJOkz+YG00O/oul/Bete+t1ZhTi+O6JRRLFYvGW+yJkZ0YgL16iStnbkUqQ==} + engines: {node: '>=0.4.0'} + fontace@0.4.1: resolution: {integrity: sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==} - fontfaceobserver@2.3.0: - resolution: {integrity: sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg==} - fontkitten@1.0.3: resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==} engines: {node: '>=20'} @@ -7840,10 +7730,6 @@ packages: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} - get-nonce@1.0.1: - resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} - engines: {node: '>=6'} - get-proto@1.0.1: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} @@ -7963,24 +7849,12 @@ packages: heic-to@1.5.2: resolution: {integrity: sha512-8Fns+lZHAWmz5U5IUxDeXKwIf3foBoKNPLxxFY4B0MkLjNuomEIHCoDbDE+x/llFK3NCEO1cu4+n3iUKY+Svmw==} - hermes-compiler@250829098.0.17: - resolution: {integrity: sha512-qG1PXzTEtriF6oQLZF3vyHhSMxOdW5h2TqqLri0rdpstPustd2fSvRZQMVAPdlhgFwBfYnj3OUZtiO6LjYsEFw==} - - hermes-estree@0.35.0: - resolution: {integrity: sha512-xVx5Opwy8Oo1I5yGpVRhCvWL/iV3M+ylksSKVNlxxD90cpDpR/AR1jLYqK8HWihm065a6UI3HeyAmYzwS8NOOg==} - - hermes-estree@0.36.0: - resolution: {integrity: sha512-A1+8zn5oss2CFP7pKsOaxorQG6FNIz1WU1VDqruLPPZl3LVgeE2C5xfFg8Ow6/Ow4mSslLLtYP1J3n38eKyW9w==} + hermes-compiler@260318099.0.4: + resolution: {integrity: sha512-8odcPFkPC82HlqCl0C5QI9mBN4rEAT+IAo55sJhzwKw//K3qZloiv3ex6J2O8CuBbhdmkJozfidNsset2KH25w==} hermes-estree@0.36.1: resolution: {integrity: sha512-guv1nQ6IJ7S83NRFPWc3SA7IBZrdNC9kapwOq6uXvF4wP+sDCgjzQbKPCoyYmoyZRzztF/n/c36l/rccCZSiCw==} - hermes-parser@0.35.0: - resolution: {integrity: sha512-9JLjeHxBx8T4CAsydZR49PNZUaix+WpQJwu9p2010lu+7Kwl6D/7wYFFJxoz+aXkaaClp9Zfg6W6/zVlSJORaA==} - - hermes-parser@0.36.0: - resolution: {integrity: sha512-GdpwMmH5x6IpC1cijvcvYnlPB60Mh6kTSF/NFdYV/j56gYdi+0RIakYs+eqOV+bbO0SW7mgVVGSsTJxyPQfo3w==} - hermes-parser@0.36.1: resolution: {integrity: sha512-GApNk4zLHi2UWoWZZkx7LNCOSzLSc5lB55pZ/PhK7ycFeg7u5LcF88p/WbpIi1XUDtE0MpHE3uRR3u3KB7TjSQ==} @@ -7988,9 +7862,6 @@ packages: resolution: {integrity: sha512-ciq6hFsSG/Bpt2DmrZJtv+56zpPdnq+NQ4ijEFrveKN0ZG1mhl/LdT1NQZ9se6ty1fACcI4d4vYqC9v8EYpH2A==} hasBin: true - hoist-non-react-statics@3.3.2: - resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} - hono@4.13.7: resolution: {integrity: sha512-c8/gF9ac8Y78/agExVocyLevgR+JlpNB444Py0FSX8pJoPdYUfUzRcXtYEYGwt6l19qIlVZPN5Mfsw9jFShmQQ==} engines: {node: '>=16.9.0'} @@ -8057,11 +7928,6 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} - image-size@1.2.1: - resolution: {integrity: sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==} - engines: {node: '>=16.x'} - hasBin: true - immediate@3.0.6: resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} @@ -8347,9 +8213,6 @@ packages: lie@3.3.0: resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} - lighthouse-logger@1.4.2: - resolution: {integrity: sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==} - lightningcss-android-arm64@1.33.0: resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} engines: {node: '>= 12.0.0'} @@ -8517,9 +8380,6 @@ packages: markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} - marky@1.3.0: - resolution: {integrity: sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==} - matcher@3.0.0: resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==} engines: {node: '>=10'} @@ -8608,120 +8468,62 @@ packages: meshoptimizer@0.22.0: resolution: {integrity: sha512-IebiK79sqIy+E4EgOr+CAw+Ke8hAspXKzBd0JdgEmPHiAwmvEj2S4h1rfvo+o/BnfEYd/jAOg5IeeIjzlzSnDg==} - metro-babel-transformer@0.84.4: - resolution: {integrity: sha512-rvCfz8snl9h20VcvpOHxZuHP1SlAkv4HXbzw7nyyVwu6Eqo5PRerbakQ9XmUCOsRy70spJ37O+G1TK8oMzo48g==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + metro-babel-transformer@0.87.1: + resolution: {integrity: sha512-orvRIGpb0yK1yMbk5YP3dhVKjmoxUkRB9fdltGJxNppEqus/1tFpNuf9KnGFR3Qjg0izoUrJ4z6WgoBvdkXPrA==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - metro-babel-transformer@0.84.5: - resolution: {integrity: sha512-2WbHILKMiJUzfdjmGOQOqU1bWi9//gqiclc/tkk/AIsrrVw3efhZ1uhkOwMTxUEPOzqoo091H0olLmVZH5FHGQ==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + metro-cache-key@0.87.1: + resolution: {integrity: sha512-scqVVPMA2c+RVO12I3wyMDp5xCkRPLsyrcG4Qc3xfU5JR0EW/0sz2tjty+5UjMUtG09uiM1KYQ8HjWg7OQXHtw==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - metro-cache-key@0.84.4: - resolution: {integrity: sha512-wVO79aGrkYImpnaVS4+d5RrRBRPX31QtvKB3wKGBuiNSznduZTQHzsrJZRroFJSwnygrzdsGUtDQPuqqFjFdvw==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + metro-cache@0.87.1: + resolution: {integrity: sha512-juNPaj0Xi5tkLp8imXqvbSnEIijwKG36m7OiFFVJMqEkiURwAjkMFVek3/xpix1+LVQqO7kjVp3PvuvIM61mKQ==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - metro-cache-key@0.84.5: - resolution: {integrity: sha512-3dPB2TnvGjjf0/9O7AXVQURKXuQNauTZE7WpTGTlR017Gh/B5y0m/2wcqxfveUguHSpu89KhVxCAlr2k/H7uhQ==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + metro-config@0.87.1: + resolution: {integrity: sha512-NmkDlc/qZAdo5gTkVTuO2AKE/khemRKRH5IA+SKfqUBJigI5GqZ5TOXhmEokhlkAqzjt8dyzKhzI6FHvXoXaTQ==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - metro-cache@0.84.4: - resolution: {integrity: sha512-gpcFQdSLUwUCk71saKoE64jLFbx2nwTfVCcPSULMNT8QYq0p1eZZE29Jvd0HtT/UlhC3ZOutLxJME5xqD2JUZg==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + metro-core@0.87.1: + resolution: {integrity: sha512-xizzky/4+c/Mkznege8OW05j7bSdM39VPoEps61Se4+hf32UQujmbvLvIE9+UnP6kNEPVomk0Fw8NsBK9iRQmw==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - metro-cache@0.84.5: - resolution: {integrity: sha512-WHS0n2OxQqtwEjSeQFPePNrMvEFhmQcUQM9cRJMHByWoi/GMWFBEWOf7hVkAM/0KRutAXNbDlSu/cZB6CyxgQQ==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + metro-file-map@0.87.1: + resolution: {integrity: sha512-9sPuNCojC3pS4vj+ZPY7FXmHGpdJeckXuKXQrDAfJvZc60AF8owRFTkI8XdwlwrmPIB2w++KraK9FMEXvC4wJw==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - metro-config@0.84.4: - resolution: {integrity: sha512-PMotGDjXcXLWo2TMRH+VR99phFNgYTwqh4OoieIKK3yTJa1Jmkl+fZJxDO0jfBvNF+WESHciHvpNuBtXaF3B0Q==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + metro-minify-terser@0.87.1: + resolution: {integrity: sha512-YK4k1oO1wV48hfE+Nbw2rJCnAgeabzrgT/xH5ha5n9gbK4p3HYFC898cERUiyTl9vRh58CNTiXRc88f7y6PfKg==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - metro-config@0.84.5: - resolution: {integrity: sha512-zie+uN6oohscowi2S7ByU+wUw6CrT4ZxW9uAbONOObSxx86RGmnIAmjXHLkfmcdYoY7jzOPEbqcI6oeVmqyBQA==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + metro-resolver@0.87.1: + resolution: {integrity: sha512-FXH/brY69wT6sPxaSW8BhMmDGD/6irmBr/cL4rUi+VWwqR3pbvdcfUOfyjcHucgQ7pe5IW3xJY21eHKLVKNumQ==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - metro-core@0.84.4: - resolution: {integrity: sha512-HONpWC5LGXZn3ffkd4Hu6AIrfE7j4Z0g0wMo/goV24WOB3lhuFZ40KgvaDiSw8iyQHloMYay5N/wPX+z8oN/PQ==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + metro-runtime@0.87.1: + resolution: {integrity: sha512-kjeuSvInsM6OzBjkCQsWxnkrKZFMKtnkCl38oXWRI9lDGs2L9hGs9Tak9sQYJ9h3gtDujneB7wZio+irgqJKDw==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - metro-core@0.84.5: - resolution: {integrity: sha512-xwm605hCi5Y6eJTTb8ZWo6pkUcoBEIyiQOfkZh5GwtDwUrP9SNhTQZhzJHrBCwwxlf3Ptl/pxWJgQ1rsNYMnrA==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + metro-source-map@0.87.1: + resolution: {integrity: sha512-Bqpm0PBGdy53pigIJb4HRF7QxD2pUOdgSmVh/4AWbP635kSCv+Y6ltVxUZgSnzS/QbSmzyCGijmRPlXMj2/qHw==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - metro-file-map@0.84.4: - resolution: {integrity: sha512-KSVDi/u60hKPx++NLu3MTIvyjzNoJnFAF8PQFxaj1jiSka/wjw+Ua6sNuJ0TDHQv+7AAoFQxeMgaRAe8Yic5wQ==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - - metro-file-map@0.84.5: - resolution: {integrity: sha512-mlm/JL8toSbSc2akpKIGmzvrVRSCgZ5vkbycI34oMLoOnLGuLyC8WTyVJ6P0hZG/usDaGwZSl/s9BCRriqjGJA==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - - metro-minify-terser@0.84.4: - resolution: {integrity: sha512-5qpbaVOMC7CPitIpuewzVeGw7E+C3ykbv2mqTjQLl85Z3annSVGlSCTcsZjqXZzjupfK4Ztj3dDc4kc44NZwtQ==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - - metro-minify-terser@0.84.5: - resolution: {integrity: sha512-BJoFwCEDsYnagPqarayInv2+diCDNDdLlaof/p6s9w4gh+gc9HXYM+pDvsKGKKUumpZswNF3Z/ftTMqKl/5IBg==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - - metro-resolver@0.84.4: - resolution: {integrity: sha512-1qLgbxQ5ZGhhutuPot1Yp348ofDsATL2WkrHF65TobqTT9K3P9qJXw38bomk7ncp5B7OYMfWwtyBZo1lCV792A==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - - metro-resolver@0.84.5: - resolution: {integrity: sha512-VSSnepg1k6LyCwtb6eirWdAWlpKwBG8Rdtsr1mU38rMelFyWgh3/QuMSiZIZAIjwg/fsa8GhW5/FO54CAUPCEA==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - - metro-runtime@0.84.4: - resolution: {integrity: sha512-Jibypds4g7AhzdRKY+kDoj51s5EXMwgyp5ddtlreDAsWefMdOx+agWqgm0H2XSZ/ueanHHVM89fnf5OJnlxa8Q==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - - metro-runtime@0.84.5: - resolution: {integrity: sha512-U1m2+d1Pr+JO2/iVXBB2OfXXityz7tqwIorxfrT15IEgaHvpJBq/OHiqnOWPKJbUl3JcxjcdviZZOKk85oK4Qg==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - - metro-source-map@0.84.4: - resolution: {integrity: sha512-jbWkPxIesVuo1IWkvezmMJld6iu8nD62GsrZiV6jP37AOdbo4OBq1FJ+qkOg8sV05wAHB//jAbziuW0SlJfW4g==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - - metro-source-map@0.84.5: - resolution: {integrity: sha512-2BtV5L9uPc49F13Gn5wiP6bX/EncqzqTIk2VL/0F/96Vo0YEOjluT/qktQjFODfqGFsucwnh5mPEAl/2jVEfeg==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - - metro-symbolicate@0.84.4: - resolution: {integrity: sha512-OnfpacxUqGPZQ27t8qK9mFa7uqHIlVWeqRqkCbvMvreEBiamEeOn8krKtcwgP5M4cYDPwuSmCTopHMVthqG4zA==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - hasBin: true - - metro-symbolicate@0.84.5: - resolution: {integrity: sha512-rQ40zYDAkaWBN9yvjUuAD0ZpzBMZSoKyGYXnb5JrfbKjun7fTvfoLHL3KXFYenBTYZkQtlp4cKSCv/1utxFyOw==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + metro-symbolicate@0.87.1: + resolution: {integrity: sha512-rcGvwabrg0lbXGRGRKl14PY3My3+dkno2jZYhdJEuH2DmjTtTkV5bYwgto4JtV/Lbe+sXE6GO1UGg654430uow==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} hasBin: true - metro-transform-plugins@0.84.4: - resolution: {integrity: sha512-kehr6HbAecqD0/a3xLXobELdPaAmRAl8bel0qagPF4vhZtux93nS8S4eq2kgKt6J2GnQpVjSoW1PXdst04mwow==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + metro-transform-plugins@0.87.1: + resolution: {integrity: sha512-qMiJ/x+VfqumFJJSefKS6nj8uojzC29b2/aK8vlMuFABIqGjDucICEOXd2Yt6k/XMFAgAcaJvShUOT0HLyYaPw==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - metro-transform-plugins@0.84.5: - resolution: {integrity: sha512-+InaSVGaOyt0DyRo4Y/zIdPI6CZwnbNho5LAL23tgmuGwv7fyfkF7kKfPjZcfxXBcoYdTLLFnCfCH/dHSiCqNg==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - - metro-transform-worker@0.84.4: - resolution: {integrity: sha512-W1IYMvvXTu4MxYr7d9h7CeG2vpIr3bmLLIavkPY4O1ilzDrvS8z/NEe6y+pC44Ff7raMXQgYSfdqDUwN/i39gg==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - - metro-transform-worker@0.84.5: - resolution: {integrity: sha512-ui1Z8x4s5RL36gMmKLaMMO7O9NNDHNdthEZSCDQHAau3JcAsTaFOK6I+2q4I/kW5u8hSEjJk9L45TXSVJw6g1A==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - - metro@0.84.4: - resolution: {integrity: sha512-8ETTubqfD6ornDy2zYDvRcKnVDOXdFJsjetYDBsY4oAsb6NJkiwFR+FaMESyGppFmQUyBQA4H4sFGxzcQSGtFA==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - hasBin: true + metro-transform-worker@0.87.1: + resolution: {integrity: sha512-VOzs3OV405FuOLYdAhqA2wsn1F9lvueDVxMDLvCKaQ44U+yknIqphJ9eMjjsGwLDZiJq9sW3DMLhjD27JxQgqQ==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} - metro@0.84.5: - resolution: {integrity: sha512-r1liLkyFZMVSEMNjU1CJU5pRzs3NdkxHqXS60O25c0rCIqAR+cGk7rPydw/g0WAIKVXojIBIF45yYBPagJGcgw==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + metro@0.87.1: + resolution: {integrity: sha512-1oyLU9elM7hPAsKIqKooEekwxiuWr27+MZBhUROPhzcbXhMDxK64GPF/hCXwBZVp1F89ODavCrBmJtLx9WtBoQ==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} hasBin: true micromark-core-commonmark@2.0.3: @@ -8900,11 +8702,6 @@ packages: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true - mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - modern-tar@0.8.5: resolution: {integrity: sha512-snEhs+6G5Tjd4I7tLCDOaoln2RgE0bD19RzEKgvgK2hZ5VKy3MpLhLTZ2fWpXSTg4K2cyPwp+VHATFJhxfnOeA==} engines: {node: '>=18.0.0'} @@ -9061,6 +8858,10 @@ packages: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} + noxcturnal@0.1.1: + resolution: {integrity: sha512-Fa9SvpVNi+2AVr9CI6mkxqIIeGQNlVRLZsXdinOx1xrvV5ZvCsyBff9QRJdwnzlVnn1AIpksFe9SW9sDfzYKLw==} + engines: {node: '>=18'} + npm-package-arg@11.0.3: resolution: {integrity: sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==} engines: {node: ^16.14.0 || >=18.0.0} @@ -9087,13 +8888,9 @@ packages: oas-validator@5.0.8: resolution: {integrity: sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==} - ob1@0.84.4: - resolution: {integrity: sha512-eJXMpz4aQHXF/YBB9ddqZDIS+ooO91hObo9FoW/xBkr54/zCwYYCDqT/O54vNo8kOkWs5Ou/y28NgdrV0edQNA==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} - - ob1@0.84.5: - resolution: {integrity: sha512-aH9RkoZc7w/90HBamFxTw8ZLFr05wXS+iOnvmrgo53Ep8Pyrm5FieQSaPIVROkfFVQISeD/zo92fes26TOwe+A==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + ob1@0.87.1: + resolution: {integrity: sha512-i8iA8uij0g1YQzS8uOJPSRCgwDjO9warIHUAu1Fqj877Wc3wlfxDYBioYWgKTBF2+URVJttyDWSEpmd99nlvtQ==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} @@ -9150,9 +8947,9 @@ packages: oniguruma-to-es@4.3.6: resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==} - open@7.4.2: - resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} - engines: {node: '>=8'} + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} ora@3.4.0: resolution: {integrity: sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==} @@ -9558,9 +9355,6 @@ packages: resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} engines: {node: '>=6'} - queue@6.0.2: - resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==} - quick-lru@5.1.1: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} @@ -9589,16 +9383,16 @@ packages: react-devtools-core@6.1.5: resolution: {integrity: sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==} - react-dom@19.2.3: - resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} - peerDependencies: - react: ^19.2.3 - react-dom@19.2.6: resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} peerDependencies: react: ^19.2.6 + react-dom@19.3.0: + resolution: {integrity: sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==} + peerDependencies: + react: ^19.3.0 + react-freeze@1.0.4: resolution: {integrity: sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==} engines: {node: '>=10'} @@ -9614,9 +9408,6 @@ packages: react: optional: true - react-is@16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} @@ -9632,8 +9423,8 @@ packages: '@types/react': '>=18' react: '>=18' - react-native-gesture-handler@2.32.0: - resolution: {integrity: sha512-uYIMOKlKENORq2SABE+jIjbPU+h5I/sQKcq2v16zRq848nwEp1fWRVwML4QWqijc8UcXJC25o54S8GQd4Mf2OA==} + react-native-gesture-handler@3.2.1: + resolution: {integrity: sha512-VEWscxUN29aeccbD2McF0LSXrwOhSdisaSRFiEWg0O/3WrVghNJp/tOtLrCgzb9gfcZ3xdA+K2Sp8F5G3iHx/Q==} peerDependencies: react: '*' react-native: '*' @@ -9650,8 +9441,8 @@ packages: react: '*' react-native: '*' - react-native-keyboard-controller@1.21.13: - resolution: {integrity: sha512-FLr0MucraPyCGykRAcPM8Bv0JT5TcG1juQGMI+GLDuuaoOUKUY3SMUnRhHn7IgSM8KlxpcNQmMPNDmGpOw1OcA==} + react-native-keyboard-controller@1.22.4: + resolution: {integrity: sha512-2by3oJBQqKH9UAydlBeiEpivxIyTbt345bmverLym7vbEp4NXckWQLF0STnVuXYccRak5/sd3wMYDJPhv/9+3g==} peerDependencies: react: '*' react-native: '*' @@ -9677,21 +9468,21 @@ packages: react: '*' react-native: '*' - react-native-reanimated@4.5.5: - resolution: {integrity: sha512-xtJXZRZ1vkec1AIUVG02St2sbyZS5jc7227TlDu/HonqUYPeZAfiC4RI2jqL1dVMNBu1+7oBx/c9QkjF2kg6Lg==} + react-native-reanimated@4.7.0: + resolution: {integrity: sha512-8TyTrPisqz7WzmbhCz8F60Uw7NI2QeYWrY5Hk58/kurCA5L5KuHmhyQjxeq5k2YalpXUAKbdkn/mAMZWm/fU0g==} peerDependencies: react: '*' - react-native: 0.83 - 0.86 - react-native-worklets: 0.10.x - 0.11.x + react-native: 0.86 - 0.88 + react-native-worklets: 0.13.x - react-native-safe-area-context@5.7.0: - resolution: {integrity: sha512-/9/MtQz8ODphjsLdZ+GZAIcC/RtoqW9EeShf7Uvnfgm/pzYrJ75y3PV/J1wuAV1T5Dye5ygq4EAW20RoBq0ABQ==} + react-native-safe-area-context@5.9.1: + resolution: {integrity: sha512-Zpx9Iwg6VhgNarWFpcIM61xK2lUbSfSXemQUmcvOVRpux49lJsUompY1S3E5jKUJbLq233qEpj28DgmXVsgZMQ==} peerDependencies: react: '*' react-native: '*' - react-native-screens@4.26.2: - resolution: {integrity: sha512-2XnWsZToKj76trGtEZzx5ELD/qOICFEprEeUntImmitQFVUkea27fiWdUSITArI356Y1qynpXZINW+Unbhky/A==} + react-native-screens@4.28.0: + resolution: {integrity: sha512-0/79Z8RCibuaAHti+DJ2Dq0m6UFWh4+p1bH58K3cjiQ7IDWs5kU9tCAj4lXcJMHHonbF2mIE2BeaPSEvOpIiFg==} peerDependencies: react: '*' react-native: '*' @@ -9702,8 +9493,8 @@ packages: react: '*' react-native: '*' - react-native-svg@15.15.4: - resolution: {integrity: sha512-boT/vIRgj6zZKBpfTPJJiYWMbZE9duBMOwPK6kCSTgxsS947IFMOq9OgIFkpWZTB7t229H24pDRkh3W9ZK/J1A==} + react-native-svg@15.15.5: + resolution: {integrity: sha512-L4go5jA+GWutdJ/JucuN20cjAbMg1HmMtAP+wZ+3JLCf6Jd0bhXQHxciRP/AQm/FlrIEZwkMcHNZP+FXAiic0w==} peerDependencies: react: '*' react-native: '*' @@ -9713,39 +9504,28 @@ packages: peerDependencies: react-native: '*' - react-native-webview@13.16.1: - resolution: {integrity: sha512-If0eHhoEdOYDcHsX+xBFwHMbWBGK1BvGDQDQdVkwtSIXiq1uiqjkpWVP2uQ1as94J0CzvFE9PUNDuhiX0Z6ubw==} + react-native-webview@14.0.1: + resolution: {integrity: sha512-lBUuvFk459Mo+5vUNqwzGvn+I8rDJE6zvOulG2hWWudeEOJfWTsQwOfuYnRu+27djUIXrESFfC+EQE3PGu+FWA==} peerDependencies: react: '*' react-native: '*' - react-native-worklets@0.10.1: - resolution: {integrity: sha512-62mRM19bDpfpdI8HLkEErcdOsrAPDtE9lA/sw+5lLRpzBHNhxaoj9QyY2KjXqUmirelxkX4zuPGTC3VdA0feJA==} + react-native-worklets@0.13.0: + resolution: {integrity: sha512-1OrhAeAKaZF4XrBa4YbPQbKzNOpjh52HDlId8e6ete1OCHNdAlrQHzG4gznJ225EAj3dgQXHViJvK51M9B52jQ==} peerDependencies: '@babel/core': '*' '@react-native/metro-config': '*' react: '*' - react-native: 0.83 - 0.86 + react-native: 0.86 - 0.88 - react-native-worklets@0.11.4: - resolution: {integrity: sha512-yNiDDQAVvt1wacBhnrEMTBlQzZ8Y8Rg7Dbdxs/r595EXw4REsZGE5sY1Ug8SmlQUT+0L+fX7oY0SuCs0mjiA4w==} - peerDependencies: - '@babel/core': '*' - '@react-native/metro-config': '*' - react: '*' - react-native: 0.83 - 0.86 - - react-native@0.86.3: - resolution: {integrity: sha512-JR5s3bM9ezud+Mw24GlNXNfthqPIKwrQgPPJcam+L97t2sKjjEavhCzBn+fyqZZRcM5+XlhYxpTxVkK7e1n38Q==} - engines: {node: ^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0} + react-native@0.88.0-rc.3: + resolution: {integrity: sha512-8gTeprAQP1j3B8lUJGZNmo33jH41Hmrd1Jm9PoOr7D/uImnifPqkagpFSKyK9fPJTWtwAK2TLDqTo+eFxlUcvA==} + engines: {node: ^22.13.0 || ^24.3.0 || >= 26.0.0} hasBin: true peerDependencies: - '@react-native/jest-preset': 0.86.3 '@types/react': ^19.1.1 - react: ^19.2.3 + react: ^19.3.0 peerDependenciesMeta: - '@react-native/jest-preset': - optional: true '@types/react': optional: true @@ -9753,49 +9533,19 @@ packages: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} - react-remove-scroll-bar@2.3.8: - resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - react-remove-scroll@2.7.2: - resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - react-style-singleton@2.2.3: - resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - react-test-renderer@19.2.6: resolution: {integrity: sha512-GbS6V23YduFTPiWJ5xICbKEjRcqx1Z90js/V5miqhz7qp/d6xSe9Dd6NjSQODFRdzdsqRMPW82E/sFpPRbY5Mw==} peerDependencies: react: ^19.2.6 - react@19.2.3: - resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} - engines: {node: '>=0.10.0'} - react@19.2.6: resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} engines: {node: '>=0.10.0'} + react@19.3.0: + resolution: {integrity: sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==} + engines: {node: '>=0.10.0'} + read-binary-file-arch@1.0.6: resolution: {integrity: sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==} hasBin: true @@ -9994,6 +9744,9 @@ packages: scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + scheduler@0.28.0: + resolution: {integrity: sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==} + schema-utils@4.3.3: resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} engines: {node: '>= 10.13.0'} @@ -10615,7 +10368,7 @@ packages: resolution: {integrity: sha512-e2mYlHrZzAQtZUf3STrfVDTetspv7p5vm/cu6p8kjLRQaL9r6QFG+MlwZ3hrI2LHnzgzjbSo+MwvoE380zz2JQ==} hasBin: true peerDependencies: - '@expo/metro-config': 57.0.12 + '@expo/metro-config': 58.0.6 metro: '*' metro-cache: '*' metro-transform-worker: '*' @@ -10723,31 +10476,11 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - use-callback-ref@1.3.3: - resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - use-latest-callback@0.2.6: resolution: {integrity: sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg==} peerDependencies: react: '>=16.8' - use-sidecar@1.1.3: - resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - use-sync-external-store@1.6.0: resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} peerDependencies: @@ -10788,12 +10521,6 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - vaul@1.1.2: - resolution: {integrity: sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==} - peerDependencies: - react: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc - vfile-location@5.0.3: resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} @@ -11007,8 +10734,8 @@ packages: resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} engines: {node: '>=20'} - whatwg-url-minimum@0.1.2: - resolution: {integrity: sha512-XPEm0XFQWNVG292lII1PrRRJl3sItrs7CettZ4ncYxuDVpLyy+NwlGyut2hXI0JswcJUxeCH+CyOJK0ZzAXD6A==} + whatwg-url-minimum@0.2.0: + resolution: {integrity: sha512-BtjXU1caNcCFfETP2DhqSeVPfRDl2MTUitI107RE34rJXjR/izfUtR5IoTFOK1WqjNLXbbeqaCH/mQAOLjpc8g==} whatwg-url@14.2.0: resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} @@ -11241,6 +10968,10 @@ packages: snapshots: + 2g@0.4.4(typescript@7.0.2): + optionalDependencies: + typescript: 7.0.2 + '@ai-sdk/provider-utils@4.0.49(zod@4.4.3)': dependencies: '@ai-sdk/provider': 3.0.15 @@ -11285,9 +11016,9 @@ snapshots: chokidar: 5.0.0 rolldown: 1.2.5 - '@alchemy.run/sigil@0.0.0-alpha.11(@types/react@19.2.16)(react-devtools-core@6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + '@alchemy.run/sigil@0.0.0-alpha.11(@types/react@19.3.0)(react-devtools-core@6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6))': optionalDependencies: - '@types/react': 19.2.16 + '@types/react': 19.3.0 react-devtools-core: 6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@anthropic-ai/claude-agent-sdk@0.3.276(@anthropic-ai/sdk@0.93.0(zod@4.6.5))(@modelcontextprotocol/sdk@1.29.0(zod@4.6.5))(zod@4.6.5)': @@ -11745,7 +11476,7 @@ snapshots: '@babel/helper-module-imports@7.29.7': dependencies: '@babel/traverse': 7.29.7 - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 transitivePeerDependencies: - supports-color @@ -11810,7 +11541,7 @@ snapshots: '@babel/parser@7.29.7': dependencies: - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 '@babel/parser@7.29.8': dependencies: @@ -12045,17 +11776,6 @@ snapshots: '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.7)': - dependencies: - '@babel/core': 7.29.7 - '@babel/helper-annotate-as-pure': 7.29.7 - '@babel/helper-module-imports': 7.29.7 - '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7) - '@babel/types': 7.29.7 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-react-jsx@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -12063,7 +11783,7 @@ snapshots: '@babel/helper-module-imports': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7) - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 transitivePeerDependencies: - supports-color @@ -12158,10 +11878,10 @@ snapshots: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 - '@base-ui/react@1.5.0(@date-fns/tz@1.5.0)(@types/react@19.2.16)(date-fns@4.4.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@base-ui/react@1.5.0(@date-fns/tz@1.5.0)(@types/react@19.3.0)(date-fns@4.4.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@babel/runtime': 7.29.7 - '@base-ui/utils': 0.2.9(@types/react@19.2.16)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@base-ui/utils': 0.2.9(@types/react@19.3.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@floating-ui/react-dom': 2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@floating-ui/utils': 0.2.11 react: 19.2.6 @@ -12169,10 +11889,10 @@ snapshots: use-sync-external-store: 1.6.0(react@19.2.6) optionalDependencies: '@date-fns/tz': 1.5.0 - '@types/react': 19.2.16 + '@types/react': 19.3.0 date-fns: 4.4.0 - '@base-ui/utils@0.2.9(@types/react@19.2.16)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@base-ui/utils@0.2.9(@types/react@19.3.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@babel/runtime': 7.29.7 '@floating-ui/utils': 0.2.11 @@ -12181,7 +11901,7 @@ snapshots: reselect: 5.2.0 use-sync-external-store: 1.6.0(react@19.2.6) optionalDependencies: - '@types/react': 19.2.16 + '@types/react': 19.3.0 '@blazediff/core@1.10.0': {} @@ -12236,32 +11956,15 @@ snapshots: fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 - '@clerk/backend@3.18.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@clerk/backend@3.18.1(react-dom@19.3.0(react@19.3.0))(react@19.2.6)': dependencies: - '@clerk/shared': 4.33.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@clerk/shared': 4.33.0(react-dom@19.3.0(react@19.3.0))(react@19.2.6) standardwebhooks: 1.0.0 tslib: 2.8.1 transitivePeerDependencies: - react - react-dom - '@clerk/clerk-js@6.32.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@clerk/shared': 4.33.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@stripe/stripe-js': 5.6.0 - '@swc/helpers': 0.5.21 - '@tanstack/query-core': 5.102.8 - '@zxcvbn-ts/core': 3.0.4 - '@zxcvbn-ts/language-common': 3.0.4 - alien-signals: 2.0.6 - browser-tabs-lock: 1.3.0 - core-js: 3.47.0 - crypto-js: 4.2.0 - dequal: 2.0.3 - transitivePeerDependencies: - - react - - react-dom - '@clerk/clerk-js@6.32.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@clerk/shared': 4.33.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -12279,6 +11982,40 @@ snapshots: - react - react-dom + '@clerk/clerk-js@6.32.1(react-dom@19.3.0(react@19.3.0))(react@19.2.6)': + dependencies: + '@clerk/shared': 4.33.0(react-dom@19.3.0(react@19.3.0))(react@19.2.6) + '@stripe/stripe-js': 5.6.0 + '@swc/helpers': 0.5.21 + '@tanstack/query-core': 5.102.8 + '@zxcvbn-ts/core': 3.0.4 + '@zxcvbn-ts/language-common': 3.0.4 + alien-signals: 2.0.6 + browser-tabs-lock: 1.3.0 + core-js: 3.47.0 + crypto-js: 4.2.0 + dequal: 2.0.3 + transitivePeerDependencies: + - react + - react-dom + + '@clerk/clerk-js@6.32.1(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@clerk/shared': 4.33.0(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@stripe/stripe-js': 5.6.0 + '@swc/helpers': 0.5.21 + '@tanstack/query-core': 5.102.8 + '@zxcvbn-ts/core': 3.0.4 + '@zxcvbn-ts/language-common': 3.0.4 + alien-signals: 2.0.6 + browser-tabs-lock: 1.3.0 + core-js: 3.47.0 + crypto-js: 4.2.0 + dequal: 2.0.3 + transitivePeerDependencies: + - react + - react-dom + '@clerk/electron-passkeys-darwin-arm64@0.0.3': optional: true @@ -12311,36 +12048,42 @@ snapshots: electron-store: 8.2.0 react-dom: 19.2.6(react@19.2.6) - '@clerk/expo@4.6.8(patch_hash=a82bb41039ee88a290a87d4ab58be7be4c49fa338603b17ea646e1ec140a1cfb)(dbc31631339ce74330e188d5d7a88158)': + '@clerk/electron@0.0.44(@clerk/electron-passkeys@0.0.3)(electron-store@8.2.0)(electron@44.4.2)(react-dom@19.3.0(react@19.3.0))(react@19.2.6)': dependencies: - '@clerk/clerk-js': 6.32.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@clerk/react': 6.16.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@clerk/shared': 4.33.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@expo/config-plugins': 57.0.9(typescript@7.0.2) + '@clerk/clerk-js': 6.32.1(react-dom@19.3.0(react@19.3.0))(react@19.2.6) + '@clerk/react': 6.16.1(react-dom@19.3.0(react@19.3.0))(react@19.2.6) + '@clerk/shared': 4.33.0(react-dom@19.3.0(react@19.3.0))(react@19.2.6) + electron: 44.4.2 + react: 19.2.6 + tslib: 2.8.1 + optionalDependencies: + '@clerk/electron-passkeys': 0.0.3 + electron-store: 8.2.0 + react-dom: 19.3.0(react@19.3.0) + + '@clerk/expo@4.6.8(patch_hash=b8b22ab733de5bea846ad9e88046c10582352fe9ad86f314f368b2a823f0f281)(950bb7335d61b76ffb649f136fc0d4df)': + dependencies: + '@clerk/clerk-js': 6.32.1(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@clerk/react': 6.16.1(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@clerk/shared': 4.33.0(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@expo/config-plugins': 58.0.4(typescript@7.0.2) base-64: 1.0.0 - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - react-native-url-polyfill: 4.0.0(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) + react-native-url-polyfill: 4.0.0(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)) tslib: 2.8.1 optionalDependencies: - expo-auth-session: 57.0.10(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - expo-constants: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) - expo-crypto: 57.0.2(expo@57.0.18) - expo-secure-store: 57.0.2(expo@57.0.18) - expo-web-browser: 57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) - react-dom: 19.2.3(react@19.2.3) + expo-auth-session: 58.0.6(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2) + expo-constants: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(typescript@7.0.2) + expo-crypto: 58.0.3(expo@58.0.0) + expo-secure-store: 58.0.1(expo@58.0.0) + expo-web-browser: 58.0.3(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)) + react-dom: 19.3.0(react@19.3.0) transitivePeerDependencies: - supports-color - typescript - '@clerk/react@6.16.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@clerk/shared': 4.33.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - tslib: 2.8.1 - '@clerk/react@6.16.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@clerk/shared': 4.33.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -12348,15 +12091,19 @@ snapshots: react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 - '@clerk/shared@4.33.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@clerk/react@6.16.1(react-dom@19.3.0(react@19.3.0))(react@19.2.6)': dependencies: - '@tanstack/query-core': 5.102.8 - dequal: 2.0.3 - glob-to-regexp: 0.4.1 - js-cookie: 3.0.8 - optionalDependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + '@clerk/shared': 4.33.0(react-dom@19.3.0(react@19.3.0))(react@19.2.6) + react: 19.2.6 + react-dom: 19.3.0(react@19.3.0) + tslib: 2.8.1 + + '@clerk/react@6.16.1(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@clerk/shared': 4.33.0(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + tslib: 2.8.1 '@clerk/shared@4.33.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: @@ -12368,6 +12115,26 @@ snapshots: react: 19.2.6 react-dom: 19.2.6(react@19.2.6) + '@clerk/shared@4.33.0(react-dom@19.3.0(react@19.3.0))(react@19.2.6)': + dependencies: + '@tanstack/query-core': 5.102.8 + dequal: 2.0.3 + glob-to-regexp: 0.4.1 + js-cookie: 3.0.8 + optionalDependencies: + react: 19.2.6 + react-dom: 19.3.0(react@19.3.0) + + '@clerk/shared@4.33.0(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@tanstack/query-core': 5.102.8 + dequal: 2.0.3 + glob-to-regexp: 0.4.1 + js-cookie: 3.0.8 + optionalDependencies: + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + '@cloudflare/unenv-preset@2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260901.1)': dependencies: unenv: 2.0.0-rc.24 @@ -12446,12 +12213,12 @@ snapshots: '@date-fns/tz@1.5.0': {} - '@daypicker/react@10.0.1(@types/react@19.2.16)(react@19.2.6)': + '@daypicker/react@10.0.1(@types/react@19.3.0)(react@19.2.6)': dependencies: react: 19.2.6 - react-day-picker: 10.0.1(@types/react@19.2.16)(react@19.2.6) + react-day-picker: 10.0.1(@types/react@19.3.0)(react@19.2.6) optionalDependencies: - '@types/react': 19.2.16 + '@types/react': 19.3.0 '@dimforge/rapier3d-compat@0.12.0': {} @@ -12549,18 +12316,18 @@ snapshots: '@drizzle-team/brocli@0.12.0': {} - '@effect/atom-react@4.0.0-rc.115(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(react@19.2.3)(scheduler@0.27.0)': - dependencies: - effect: 4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5) - react: 19.2.3 - scheduler: 0.27.0 - '@effect/atom-react@4.0.0-rc.115(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(react@19.2.6)(scheduler@0.27.0)': dependencies: effect: 4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5) react: 19.2.6 scheduler: 0.27.0 + '@effect/atom-react@4.0.0-rc.115(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(react@19.3.0)(scheduler@0.27.0)': + dependencies: + effect: 4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5) + react: 19.3.0 + scheduler: 0.27.0 + '@effect/openapi-generator@4.0.0-rc.115(@effect/platform-node@4.0.0-rc.115(bufferutil@4.1.0)(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(redis@6.2.1)(utf-8-validate@6.0.6))(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(encoding@0.1.13)': dependencies: '@effect/platform-node': 4.0.0-rc.115(bufferutil@4.1.0)(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(redis@6.2.1)(utf-8-validate@6.0.6) @@ -12641,10 +12408,6 @@ snapshots: dependencies: effect: 4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5) - '@egjs/hammerjs@2.0.17': - dependencies: - '@types/hammerjs': 2.0.46 - '@electric-sql/pglite@0.3.15': optional: true @@ -12999,33 +12762,36 @@ snapshots: '@expo-google-fonts/material-symbols@0.4.38': {} - '@expo/cli@57.0.20(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.14)(bufferutil@4.1.0)(expo-constants@57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)))(expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(expo@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@7.0.2)(utf-8-validate@6.0.6)': + '@expo/cli@58.0.9(@expo/dom-webview@58.0.2)(@expo/metro-runtime@58.0.9)(bufferutil@4.1.0)(expo-constants@58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(typescript@7.0.2))(expo-font@58.0.4(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(expo@58.0.0)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2)(utf-8-validate@6.0.6)': dependencies: + 2g: 0.4.4(typescript@7.0.2) '@expo/code-signing-certificates': 0.0.6 - '@expo/config': 57.0.9(typescript@7.0.2) - '@expo/config-plugins': 57.0.9(typescript@7.0.2) + '@expo/config': 58.0.1(typescript@7.0.2) + '@expo/config-plugins': 58.0.4(typescript@7.0.2) '@expo/devcert': 1.2.1 - '@expo/env': 2.4.3 - '@expo/image-utils': 0.11.5(typescript@7.0.2) - '@expo/inline-modules': 0.1.7(typescript@7.0.2) - '@expo/json-file': 11.0.1 - '@expo/log-box': 57.0.4(@expo/dom-webview@57.0.1)(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - '@expo/metro': 56.0.2(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@expo/metro-config': 57.0.12(patch_hash=96f1a75347e6ea02dc4b7034ace815d8ee39e18b8166ebfb573d9e58328f0dc2)(bufferutil@4.1.0)(expo@57.0.18)(typescript@7.0.2)(utf-8-validate@6.0.6) - '@expo/metro-file-map': 57.0.2 - '@expo/osascript': 2.7.1 - '@expo/package-manager': 1.13.1 - '@expo/plist': 0.8.1 - '@expo/prebuild-config': 57.0.15(typescript@7.0.2) - '@expo/require-utils': 57.0.5(typescript@7.0.2) - '@expo/router-server': 57.0.8(@expo/metro-runtime@57.0.14)(expo-constants@57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)))(expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(expo-server@57.0.3)(expo@57.0.18)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@expo/schema-utils': 57.0.2 + '@expo/env': 2.5.1 + '@expo/image-utils': 0.12.2(typescript@7.0.2) + '@expo/inline-modules': 0.2.1(typescript@7.0.2) + '@expo/json-file': 11.2.1 + '@expo/log-box': 58.0.7(@expo/dom-webview@58.0.2)(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + '@expo/log-box-utils': 58.0.1 + '@expo/metro': 58.0.0-rc.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@expo/metro-config': 58.0.6(patch_hash=90fa980e8b6480631fb2fbb04559834e3c612db40c550cd828f11be297d8d760)(bufferutil@4.1.0)(expo@58.0.0)(typescript@7.0.2)(utf-8-validate@6.0.6) + '@expo/metro-file-map': 58.0.3(typescript@7.0.2) + '@expo/osascript': 2.8.1 + '@expo/package-manager': 1.14.1 + '@expo/plist': 0.10.1 + '@expo/prebuild-config': 58.0.6(typescript@7.0.2) + '@expo/require-utils': 58.0.2(typescript@7.0.2) + '@expo/router-server': 58.0.4(@expo/metro-runtime@58.0.9)(expo-constants@58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(typescript@7.0.2))(expo-font@58.0.4(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(expo-server@58.0.2)(expo@58.0.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@expo/schema-utils': 58.0.1 '@expo/spawn-async': 1.8.0 '@expo/ws-tunnel': 2.0.0(ws@8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6)) '@expo/xcpretty': 4.4.4 - '@react-native/dev-middleware': 0.86.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@react-native/dev-middleware': 0.88.0-rc.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@react-native/js-polyfills': 0.88.0-rc.3 accepts: 1.3.8 - agent-cli-detector: 0.1.6 + agent-cli-detector: 0.1.7 arg: 5.0.2 bplist-creator: 0.1.0 bplist-parser: 0.3.2 @@ -13033,10 +12799,9 @@ snapshots: ci-info: 3.9.0 compression: 1.8.1 connect: 3.7.0 - debug: 4.4.3 - dnssd-advertise: 1.1.4 - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-server: 57.0.3 + dnssd-advertise: 1.1.6 + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-server: 58.0.2 fetch-nodeshim: 0.4.10 getenv: 2.0.0 glob: 13.0.6 @@ -13062,7 +12827,7 @@ snapshots: ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) zod: 3.25.76 optionalDependencies: - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - '@expo/dom-webview' - '@expo/metro-runtime' @@ -13076,94 +12841,16 @@ snapshots: - typescript - utf-8-validate - '@expo/cli@57.0.20(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.14)(bufferutil@4.1.0)(expo-constants@57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6)))(expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6))(expo@57.0.18)(react-dom@19.2.6(react@19.2.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6)(typescript@7.0.2)(utf-8-validate@6.0.6)': - dependencies: - '@expo/code-signing-certificates': 0.0.6 - '@expo/config': 57.0.9(typescript@7.0.2) - '@expo/config-plugins': 57.0.9(typescript@7.0.2) - '@expo/devcert': 1.2.1 - '@expo/env': 2.4.3 - '@expo/image-utils': 0.11.5(typescript@7.0.2) - '@expo/inline-modules': 0.1.7(typescript@7.0.2) - '@expo/json-file': 11.0.1 - '@expo/log-box': 57.0.4(@expo/dom-webview@57.0.1)(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6) - '@expo/metro': 56.0.2(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@expo/metro-config': 57.0.12(patch_hash=96f1a75347e6ea02dc4b7034ace815d8ee39e18b8166ebfb573d9e58328f0dc2)(bufferutil@4.1.0)(expo@57.0.18)(typescript@7.0.2)(utf-8-validate@6.0.6) - '@expo/metro-file-map': 57.0.2 - '@expo/osascript': 2.7.1 - '@expo/package-manager': 1.13.1 - '@expo/plist': 0.8.1 - '@expo/prebuild-config': 57.0.15(typescript@7.0.2) - '@expo/require-utils': 57.0.5(typescript@7.0.2) - '@expo/router-server': 57.0.8(@expo/metro-runtime@57.0.14)(expo-constants@57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6)))(expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6))(expo-server@57.0.3)(expo@57.0.18)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@expo/schema-utils': 57.0.2 - '@expo/spawn-async': 1.8.0 - '@expo/ws-tunnel': 2.0.0(ws@8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6)) - '@expo/xcpretty': 4.4.4 - '@react-native/dev-middleware': 0.86.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) - accepts: 1.3.8 - agent-cli-detector: 0.1.6 - arg: 5.0.2 - bplist-creator: 0.1.0 - bplist-parser: 0.3.2 - chalk: 4.1.2 - ci-info: 3.9.0 - compression: 1.8.1 - connect: 3.7.0 - debug: 4.4.3 - dnssd-advertise: 1.1.4 - expo: 57.0.18(0bf40d5ad6281d8f1e92517b24812edb) - expo-server: 57.0.3 - fetch-nodeshim: 0.4.10 - getenv: 2.0.0 - glob: 13.0.6 - lan-network: 0.2.1 - multitars: 1.0.2 - node-forge: 1.4.0 - npm-package-arg: 11.0.3 - ora: 3.4.0 - picomatch: 4.0.7 - pretty-format: 29.7.0 - progress: 2.0.3 - prompts: 2.4.2 - resolve-from: 5.0.0 - sandbox-cli-detector: 0.2.0 - semver: 7.8.5 - send: 0.19.2 - slugify: 1.6.9 - stacktrace-parser: 0.1.11 - structured-headers: 0.4.1 - terminal-link: 2.1.1 - toqr: 0.1.1 - wrap-ansi: 7.0.0 - ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) - zod: 3.25.76 - optionalDependencies: - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) - transitivePeerDependencies: - - '@expo/dom-webview' - - '@expo/metro-runtime' - - bufferutil - - expo-constants - - expo-font - - react - - react-dom - - react-server-dom-webpack - - supports-color - - typescript - - utf-8-validate - optional: true - '@expo/code-signing-certificates@0.0.6': dependencies: node-forge: 1.4.0 - '@expo/config-plugins@57.0.9(typescript@7.0.2)': + '@expo/config-plugins@58.0.4(typescript@7.0.2)': dependencies: - '@expo/config-types': 57.0.2 - '@expo/json-file': 11.0.1 - '@expo/plist': 0.8.1 - '@expo/require-utils': 57.0.5(typescript@7.0.2) + '@expo/config-types': 58.0.2 + '@expo/json-file': 11.2.1 + '@expo/plist': 0.10.1 + '@expo/require-utils': 58.0.2(typescript@7.0.2) '@expo/sdk-runtime-versions': 1.0.0 chalk: 4.1.2 debug: 4.4.3 @@ -13177,14 +12864,14 @@ snapshots: - supports-color - typescript - '@expo/config-types@57.0.2': {} + '@expo/config-types@58.0.2': {} - '@expo/config@57.0.9(typescript@7.0.2)': + '@expo/config@58.0.1(typescript@7.0.2)': dependencies: - '@expo/config-plugins': 57.0.9(typescript@7.0.2) - '@expo/config-types': 57.0.2 - '@expo/json-file': 11.0.1 - '@expo/require-utils': 57.0.5(typescript@7.0.2) + '@expo/config-plugins': 58.0.4(typescript@7.0.2) + '@expo/config-types': 58.0.2 + '@expo/json-file': 11.2.1 + '@expo/require-utils': 58.0.2(typescript@7.0.2) deepmerge: 4.3.1 getenv: 2.0.0 glob: 13.0.6 @@ -13202,35 +12889,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/devtools@57.0.1(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)': + '@expo/devtools@58.0.2(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)': dependencies: chalk: 4.1.2 optionalDependencies: - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - '@expo/devtools@57.0.1(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6)': + '@expo/dom-webview@58.0.2(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)': dependencies: - chalk: 4.1.2 - optionalDependencies: - react: 19.2.6 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) - optional: true - - '@expo/dom-webview@57.0.1(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)': - dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - - '@expo/dom-webview@57.0.1(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6)': - dependencies: - expo: 57.0.18(0bf40d5ad6281d8f1e92517b24812edb) - react: 19.2.6 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) - optional: true + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - '@expo/env@2.4.3': + '@expo/env@2.5.1': dependencies: chalk: 4.1.2 debug: 4.4.3 @@ -13238,11 +12911,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/expo-modules-macros-plugin@0.6.1': {} - - '@expo/fingerprint@0.20.11': + '@expo/fingerprint@0.21.2': dependencies: - '@expo/env': 2.4.3 + '@expo/env': 2.5.1 '@expo/spawn-async': 1.8.0 arg: 5.0.2 chalk: 4.1.2 @@ -13256,9 +12927,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/image-utils@0.11.5(typescript@7.0.2)': + '@expo/image-utils@0.12.2(typescript@7.0.2)': dependencies: - '@expo/require-utils': 57.0.5(typescript@7.0.2) + '@expo/require-utils': 58.0.2(typescript@7.0.2) '@expo/spawn-async': 1.8.0 chalk: 4.1.2 getenv: 2.0.0 @@ -13282,59 +12953,56 @@ snapshots: - supports-color - typescript - '@expo/inline-modules@0.1.7(typescript@7.0.2)': + '@expo/inline-modules@0.2.1(typescript@7.0.2)': dependencies: - '@expo/config-plugins': 57.0.9(typescript@7.0.2) + '@expo/config-plugins': 58.0.4(typescript@7.0.2) transitivePeerDependencies: - supports-color - typescript - '@expo/json-file@11.0.1': + '@expo/json-file@11.2.1': dependencies: '@babel/code-frame': 7.29.7 json5: 2.2.3 - '@expo/local-build-cache-provider@57.0.8(typescript@7.0.2)': + '@expo/local-build-cache-provider@58.0.1(typescript@7.0.2)': dependencies: - '@expo/config': 57.0.9(typescript@7.0.2) + '@expo/config': 58.0.1(typescript@7.0.2) chalk: 4.1.2 transitivePeerDependencies: - supports-color - typescript - '@expo/log-box@57.0.4(@expo/dom-webview@57.0.1)(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)': - dependencies: - '@expo/dom-webview': 57.0.1(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - anser: 1.4.10 - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - stacktrace-parser: 0.1.11 + '@expo/log-box-utils@58.0.1': {} - '@expo/log-box@57.0.4(@expo/dom-webview@57.0.1)(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6)': + '@expo/log-box@58.0.7(@expo/dom-webview@58.0.2)(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)': dependencies: - '@expo/dom-webview': 57.0.1(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6) + '@expo/dom-webview': 58.0.2(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + '@expo/log-box-utils': 58.0.1 anser: 1.4.10 - expo: 57.0.18(0bf40d5ad6281d8f1e92517b24812edb) - react: 19.2.6 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) stacktrace-parser: 0.1.11 - optional: true + optionalDependencies: + expo: 58.0.0(3abfa3879936d948a635873738556226) - '@expo/metro-config@57.0.12(patch_hash=96f1a75347e6ea02dc4b7034ace815d8ee39e18b8166ebfb573d9e58328f0dc2)(bufferutil@4.1.0)(expo@57.0.18)(typescript@7.0.2)(utf-8-validate@6.0.6)': + '@expo/metro-config@58.0.6(patch_hash=90fa980e8b6480631fb2fbb04559834e3c612db40c550cd828f11be297d8d760)(bufferutil@4.1.0)(expo@58.0.0)(typescript@7.0.2)(utf-8-validate@6.0.6)': dependencies: + 2g: 0.4.4(typescript@7.0.2) '@babel/code-frame': 7.29.7 '@babel/core': 7.29.7 '@babel/generator': 7.29.7 - '@expo/config': 57.0.9(typescript@7.0.2) - '@expo/env': 2.4.3 - '@expo/json-file': 11.0.1 - '@expo/metro': 56.0.2(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@expo/require-utils': 57.0.5(typescript@7.0.2) + '@expo/config': 58.0.1(typescript@7.0.2) + '@expo/env': 2.5.1 + '@expo/json-file': 11.2.1 + '@expo/metro': 58.0.0-rc.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@expo/require-utils': 58.0.2(typescript@7.0.2) '@expo/spawn-async': 1.8.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.6.0 + '@jridgewell/trace-mapping': 0.3.31 + '@react-native/js-polyfills': 0.88.0-rc.3 browserslist: 4.29.0 chalk: 4.1.2 debug: 4.4.3 @@ -13343,19 +13011,21 @@ snapshots: hermes-parser: 0.36.1 jsc-safe-url: 0.2.4 lightningcss: 1.33.0 + noxcturnal: 0.1.1 picomatch: 4.0.7 postcss: 8.5.28 resolve-from: 5.0.0 optionalDependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) + expo: 58.0.0(3abfa3879936d948a635873738556226) transitivePeerDependencies: - bufferutil - supports-color - typescript - utf-8-validate - '@expo/metro-file-map@57.0.2': + '@expo/metro-file-map@58.0.3(typescript@7.0.2)': dependencies: + 2g: 0.4.4(typescript@7.0.2) debug: 4.4.3 fb-watchman: 2.0.2 invariant: 2.2.4 @@ -13364,85 +13034,71 @@ snapshots: walker: 1.0.8 transitivePeerDependencies: - supports-color + - typescript - '@expo/metro-runtime@57.0.14(@expo/log-box@57.0.4)(expo@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)': + '@expo/metro-runtime@58.0.9(@expo/log-box@58.0.7)(expo@58.0.0)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)': dependencies: - '@expo/log-box': 57.0.4(@expo/dom-webview@57.0.1)(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + '@expo/log-box': 58.0.7(@expo/dom-webview@58.0.2)(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) anser: 1.4.10 - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) + expo: 58.0.0(3abfa3879936d948a635873738556226) pretty-format: 29.7.0 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) stacktrace-parser: 0.1.11 whatwg-fetch: 3.6.20 optionalDependencies: - react-dom: 19.2.3(react@19.2.3) - optional: true + react-dom: 19.3.0(react@19.3.0) - '@expo/metro-runtime@57.0.14(@expo/log-box@57.0.4)(expo@57.0.18)(react-dom@19.2.6(react@19.2.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6)': + '@expo/metro@58.0.0-rc.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: - '@expo/log-box': 57.0.4(@expo/dom-webview@57.0.1)(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6) - anser: 1.4.10 - expo: 57.0.18(0bf40d5ad6281d8f1e92517b24812edb) - pretty-format: 29.7.0 - react: 19.2.6 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) - stacktrace-parser: 0.1.11 - whatwg-fetch: 3.6.20 - optionalDependencies: - react-dom: 19.2.6(react@19.2.6) - optional: true - - '@expo/metro@56.0.2(bufferutil@4.1.0)(utf-8-validate@6.0.6)': - dependencies: - metro: 0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-babel-transformer: 0.84.5 - metro-cache: 0.84.5 - metro-cache-key: 0.84.5 - metro-config: 0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-core: 0.84.5 - metro-file-map: 0.84.5 - metro-minify-terser: 0.84.5 - metro-resolver: 0.84.5 - metro-runtime: 0.84.5 - metro-source-map: 0.84.5 - metro-symbolicate: 0.84.5 - metro-transform-plugins: 0.84.5 - metro-transform-worker: 0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro: 0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-babel-transformer: 0.87.1 + metro-cache: 0.87.1 + metro-cache-key: 0.87.1 + metro-config: 0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-core: 0.87.1 + metro-file-map: 0.87.1 + metro-minify-terser: 0.87.1 + metro-resolver: 0.87.1 + metro-runtime: 0.87.1 + metro-source-map: 0.87.1 + metro-symbolicate: 0.87.1 + metro-transform-plugins: 0.87.1 + metro-transform-worker: 0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - '@expo/osascript@2.7.1': + '@expo/osascript@2.8.1': dependencies: '@expo/spawn-async': 1.8.0 - '@expo/package-manager@1.13.1': + '@expo/package-manager@1.14.1': dependencies: - '@expo/json-file': 11.0.1 + '@expo/json-file': 11.2.1 '@expo/spawn-async': 1.8.0 chalk: 4.1.2 npm-package-arg: 11.0.3 ora: 3.4.0 resolve-workspace-root: 2.0.1 - '@expo/plist@0.8.1': + '@expo/plist@0.10.1': dependencies: '@xmldom/xmldom': 0.8.15 base64-js: 1.5.1 xmlbuilder: 15.1.1 - '@expo/prebuild-config@57.0.15(typescript@7.0.2)': + '@expo/prebuild-config@58.0.6(typescript@7.0.2)': dependencies: - '@expo/config': 57.0.9(typescript@7.0.2) - '@expo/config-plugins': 57.0.9(typescript@7.0.2) - '@expo/config-types': 57.0.2 - '@expo/image-utils': 0.11.5(typescript@7.0.2) - '@expo/json-file': 11.0.1 - '@react-native/normalize-colors': 0.86.3 + '@expo/config': 58.0.1(typescript@7.0.2) + '@expo/config-plugins': 58.0.4(typescript@7.0.2) + '@expo/config-types': 58.0.2 + '@expo/image-utils': 0.12.2(typescript@7.0.2) + '@expo/json-file': 11.2.1 + '@react-native/normalize-colors': 0.88.0-rc.3 debug: 4.4.3 - expo-modules-autolinking: 57.0.12(typescript@7.0.2) + expo-modules-autolinking: 58.0.6(typescript@7.0.2) resolve-from: 5.0.0 semver: 7.8.5 transitivePeerDependencies: @@ -13459,7 +13115,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/require-utils@57.0.5(typescript@7.0.2)': + '@expo/require-utils@58.0.2(typescript@7.0.2)': dependencies: '@babel/code-frame': 7.29.7 '@babel/core': 7.29.7 @@ -13469,36 +13125,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/router-server@57.0.8(@expo/metro-runtime@57.0.14)(expo-constants@57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)))(expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(expo-server@57.0.3)(expo@57.0.18)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@expo/router-server@58.0.4(@expo/metro-runtime@58.0.9)(expo-constants@58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(typescript@7.0.2))(expo-font@58.0.4(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(expo-server@58.0.2)(expo@58.0.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': dependencies: debug: 4.4.3 - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-constants: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) - expo-font: 57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - expo-server: 57.0.3 - react: 19.2.3 + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-constants: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(typescript@7.0.2) + expo-font: 58.0.4(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + expo-server: 58.0.2 + react: 19.3.0 optionalDependencies: - '@expo/metro-runtime': 57.0.14(@expo/log-box@57.0.4)(expo@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - react-dom: 19.2.3(react@19.2.3) + '@expo/metro-runtime': 58.0.9(@expo/log-box@58.0.7)(expo@58.0.0)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + react-dom: 19.3.0(react@19.3.0) transitivePeerDependencies: - supports-color - '@expo/router-server@57.0.8(@expo/metro-runtime@57.0.14)(expo-constants@57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6)))(expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6))(expo-server@57.0.3)(expo@57.0.18)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - debug: 4.4.3 - expo: 57.0.18(0bf40d5ad6281d8f1e92517b24812edb) - expo-constants: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6)) - expo-font: 57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6) - expo-server: 57.0.3 - react: 19.2.6 - optionalDependencies: - '@expo/metro-runtime': 57.0.14(@expo/log-box@57.0.4)(expo@57.0.18)(react-dom@19.2.6(react@19.2.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6) - react-dom: 19.2.6(react@19.2.6) - transitivePeerDependencies: - - supports-color - optional: true - - '@expo/schema-utils@57.0.2': {} + '@expo/schema-utils@58.0.1': {} '@expo/sdk-runtime-versions@1.0.0': {} @@ -13508,20 +13149,16 @@ snapshots: '@expo/sudo-prompt@9.3.2': {} - '@expo/ui@57.0.14(@babel/core@7.29.7)(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(expo@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)': + '@expo/ui@58.0.9(@babel/core@7.29.7)(expo@58.0.0)(react-dom@19.3.0(react@19.3.0))(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)': dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) sf-symbols-typescript: 2.2.0 - vaul: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) optionalDependencies: '@babel/core': 7.29.7 - react-dom: 19.2.3(react@19.2.3) - react-native-worklets: 0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - transitivePeerDependencies: - - '@types/react' - - '@types/react-dom' + react-dom: 19.3.0(react@19.3.0) + react-native-worklets: 0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) '@expo/ws-tunnel@2.0.0(ws@8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: @@ -13784,14 +13421,6 @@ snapshots: dependencies: jsbi: 4.3.2 - '@legendapp/list@3.3.5(patch_hash=680cc6a5c5b4a4032e467e7b3fde22f89a84c0ee2e6eac6fda737d6277cc0806)(react-dom@19.2.3(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)': - dependencies: - react: 19.2.3 - use-sync-external-store: 1.6.0(react@19.2.3) - optionalDependencies: - react-dom: 19.2.3(react@19.2.3) - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - '@legendapp/list@3.3.5(patch_hash=680cc6a5c5b4a4032e467e7b3fde22f89a84c0ee2e6eac6fda737d6277cc0806)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: react: 19.2.6 @@ -13799,6 +13428,14 @@ snapshots: optionalDependencies: react-dom: 19.2.6(react@19.2.6) + '@legendapp/list@3.3.5(patch_hash=680cc6a5c5b4a4032e467e7b3fde22f89a84c0ee2e6eac6fda737d6277cc0806)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)': + dependencies: + react: 19.3.0 + use-sync-external-store: 1.6.0(react@19.3.0) + optionalDependencies: + react-dom: 19.3.0(react@19.3.0) + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) + '@libsql/client@0.17.3(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@libsql/core': 0.17.3 @@ -14006,6 +13643,30 @@ snapshots: '@nornagon/put@0.0.8': {} + '@noxcturnal/noxcturnal-darwin-arm64@0.1.1': + optional: true + + '@noxcturnal/noxcturnal-darwin-x64@0.1.1': + optional: true + + '@noxcturnal/noxcturnal-linux-arm64-gnu@0.1.1': + optional: true + + '@noxcturnal/noxcturnal-linux-arm64-musl@0.1.1': + optional: true + + '@noxcturnal/noxcturnal-linux-x64-gnu@0.1.1': + optional: true + + '@noxcturnal/noxcturnal-linux-x64-musl@0.1.1': + optional: true + + '@noxcturnal/noxcturnal-win32-arm64-msvc@0.1.1': + optional: true + + '@noxcturnal/noxcturnal-win32-x64-msvc@0.1.1': + optional: true + '@octokit/auth-token@6.0.0': {} '@octokit/core@7.0.6': @@ -14216,6 +13877,8 @@ snapshots: '@oxc-project/types@0.127.0': optional: true + '@oxc-project/types@0.141.0': {} + '@oxc-project/types@0.146.0': {} '@oxc-project/types@0.147.0': {} @@ -14444,16 +14107,16 @@ snapshots: tslib: 2.8.1 webcrypto-core: 1.9.2 - '@pierre/diffs@1.3.0-beta.10(patch_hash=0ccee155b93b63d810e2c1a40c1fd676fb6fbcfa72cf6430dcedf1a3ae475ab4)(@shikijs/themes@4.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@pierre/diffs@1.3.0-beta.10(patch_hash=0ccee155b93b63d810e2c1a40c1fd676fb6fbcfa72cf6430dcedf1a3ae475ab4)(@shikijs/themes@4.2.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': dependencies: '@pierre/theme': 1.1.0 - '@pierre/theming': 0.0.2(@pierre/theme@1.1.0)(@shikijs/themes@4.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(shiki@4.2.0) + '@pierre/theming': 0.0.2(@pierre/theme@1.1.0)(@shikijs/themes@4.2.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(shiki@4.2.0) '@shikijs/transformers': 4.2.0 diff: 9.0.0 hast-util-to-html: 9.0.5 lru_map: 0.4.1 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) shiki: 4.2.0 transitivePeerDependencies: - '@shikijs/themes' @@ -14474,12 +14137,12 @@ snapshots: '@pierre/theme@1.1.0': {} - '@pierre/theming@0.0.2(@pierre/theme@1.1.0)(@shikijs/themes@4.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(shiki@4.2.0)': + '@pierre/theming@0.0.2(@pierre/theme@1.1.0)(@shikijs/themes@4.2.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(shiki@4.2.0)': optionalDependencies: '@pierre/theme': 1.1.0 '@shikijs/themes': 4.2.0 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) shiki: 4.2.0 '@pierre/theming@0.0.2(@pierre/theme@1.1.0)(@shikijs/themes@4.3.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(shiki@4.2.0)': @@ -14490,13 +14153,6 @@ snapshots: react-dom: 19.2.6(react@19.2.6) shiki: 4.2.0 - '@pierre/trees@1.0.0-beta.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - preact: 11.0.0-beta.0 - preact-render-to-string: 6.6.5(preact@11.0.0-beta.0) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - '@pierre/trees@1.0.0-beta.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: preact: 11.0.0-beta.0 @@ -14504,6 +14160,13 @@ snapshots: react: 19.2.6 react-dom: 19.2.6(react@19.2.6) + '@pierre/trees@1.0.0-beta.4(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + preact: 11.0.0-beta.0 + preact-render-to-string: 6.6.5(preact@11.0.0-beta.0) + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + '@polka/url@1.0.0-next.29': {} '@puppeteer/browsers@3.2.2(yauzl@3.4.0)': @@ -14513,149 +14176,6 @@ snapshots: optionalDependencies: yauzl: 3.4.0 - '@radix-ui/primitive@1.1.3': {} - - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.16)(react@19.2.3)': - dependencies: - react: 19.2.3 - optionalDependencies: - '@types/react': 19.2.16 - - '@radix-ui/react-context@1.1.2(@types/react@19.2.16)(react@19.2.3)': - dependencies: - react: 19.2.3 - optionalDependencies: - '@types/react': 19.2.16 - - '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.16)(react@19.2.3) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.16)(react@19.2.3) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.16)(react@19.2.3) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.16)(react@19.2.3) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.16)(react@19.2.3) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.16)(react@19.2.3) - aria-hidden: 1.2.6 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - react-remove-scroll: 2.7.2(@types/react@19.2.16)(react@19.2.3) - optionalDependencies: - '@types/react': 19.2.16 - '@types/react-dom': 19.2.3(@types/react@19.2.16) - - '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.16)(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.16)(react@19.2.3) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.16)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - optionalDependencies: - '@types/react': 19.2.16 - '@types/react-dom': 19.2.3(@types/react@19.2.16) - - '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.16)(react@19.2.3)': - dependencies: - react: 19.2.3 - optionalDependencies: - '@types/react': 19.2.16 - - '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.16)(react@19.2.3) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.16)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - optionalDependencies: - '@types/react': 19.2.16 - '@types/react-dom': 19.2.3(@types/react@19.2.16) - - '@radix-ui/react-id@1.1.1(@types/react@19.2.16)(react@19.2.3)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.16)(react@19.2.3) - react: 19.2.3 - optionalDependencies: - '@types/react': 19.2.16 - - '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.16)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - optionalDependencies: - '@types/react': 19.2.16 - '@types/react-dom': 19.2.3(@types/react@19.2.16) - - '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.16)(react@19.2.3) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.16)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - optionalDependencies: - '@types/react': 19.2.16 - '@types/react-dom': 19.2.3(@types/react@19.2.16) - - '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.16)(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - optionalDependencies: - '@types/react': 19.2.16 - '@types/react-dom': 19.2.3(@types/react@19.2.16) - - '@radix-ui/react-slot@1.2.3(@types/react@19.2.16)(react@19.2.3)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.16)(react@19.2.3) - react: 19.2.3 - optionalDependencies: - '@types/react': 19.2.16 - - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.16)(react@19.2.3)': - dependencies: - react: 19.2.3 - optionalDependencies: - '@types/react': 19.2.16 - - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.16)(react@19.2.3)': - dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.16)(react@19.2.3) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.16)(react@19.2.3) - react: 19.2.3 - optionalDependencies: - '@types/react': 19.2.16 - - '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.16)(react@19.2.3)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.16)(react@19.2.3) - react: 19.2.3 - optionalDependencies: - '@types/react': 19.2.16 - - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.16)(react@19.2.3)': - dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.16)(react@19.2.3) - react: 19.2.3 - optionalDependencies: - '@types/react': 19.2.16 - - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.16)(react@19.2.3)': - dependencies: - react: 19.2.3 - optionalDependencies: - '@types/react': 19.2.16 - '@react-grab/cli@0.1.44': dependencies: agent-install: 0.0.5 @@ -14667,35 +14187,35 @@ snapshots: prompts: 2.4.2 tinyexec: 1.2.4 - '@react-native-ai/apple@0.12.0(patch_hash=2d09870c2848d185cb05b53ed823a46e12dba519324d8dd8e584e28731990f9d)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))': + '@react-native-ai/apple@0.12.0(patch_hash=2d09870c2848d185cb05b53ed823a46e12dba519324d8dd8e584e28731990f9d)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))': dependencies: '@ai-sdk/provider': 3.0.15 '@ai-sdk/provider-utils': 4.0.49(zod@4.4.3) - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) zod: 4.4.3 - '@react-native-masked-view/masked-view@0.3.2(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)': + '@react-native-masked-view/masked-view@0.3.2(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)': dependencies: - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) optional: true - '@react-native-menu/menu@2.0.0(patch_hash=f63d256bf6a97a873b5e628eb595bd6ef0075ddd5bdd890fc920f7a6024290dd)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)': + '@react-native-menu/menu@2.0.0(patch_hash=1cc2d43fbd0281ca0dd1feb5ffcefee7d4419459c8daaa58effff10c657832fb)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)': dependencies: - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - '@react-native/assets-registry@0.86.3': {} + '@react-native/asset-utils@0.88.0-rc.3': {} - '@react-native/babel-plugin-codegen@0.86.3(@babel/core@7.29.7)': + '@react-native/babel-plugin-codegen@0.88.0-rc.3(@babel/core@7.29.7)': dependencies: '@babel/traverse': 7.29.7 - '@react-native/codegen': 0.86.3(@babel/core@7.29.7) + '@react-native/codegen': 0.88.0-rc.3(@babel/core@7.29.7) transitivePeerDependencies: - '@babel/core' - supports-color - '@react-native/babel-preset@0.86.3(@babel/core@7.29.7)': + '@react-native/babel-preset@0.88.0-rc.3(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 '@babel/plugin-proposal-export-default-from': 7.29.7(@babel/core@7.29.7) @@ -14726,42 +14246,42 @@ snapshots: '@babel/plugin-transform-runtime': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-typescript': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-unicode-regex': 7.29.7(@babel/core@7.29.7) - '@react-native/babel-plugin-codegen': 0.86.3(@babel/core@7.29.7) - babel-plugin-syntax-hermes-parser: 0.36.0 + '@react-native/babel-plugin-codegen': 0.88.0-rc.3(@babel/core@7.29.7) babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.29.7) + flow-parser: 0.327.0 react-refresh: 0.14.2 transitivePeerDependencies: - supports-color - '@react-native/codegen@0.86.3(@babel/core@7.29.7)': + '@react-native/codegen@0.88.0-rc.3(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 - '@babel/parser': 7.29.7 - hermes-parser: 0.36.0 + '@babel/parser': 7.29.8 + flow-parser: 0.327.0 invariant: 2.2.4 nullthrows: 1.1.1 tinyglobby: 0.2.17 yargs: 17.7.2 - '@react-native/community-cli-plugin@0.86.3(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + '@react-native/community-cli-plugin@0.88.0-rc.3(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: - '@react-native/dev-middleware': 0.86.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@react-native/asset-utils': 0.88.0-rc.3 + '@react-native/dev-middleware': 0.88.0-rc.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) + commander: 12.1.0 debug: 4.4.3 invariant: 2.2.4 - metro: 0.84.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-config: 0.84.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-core: 0.84.4 + metro: 0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) semver: 7.8.5 optionalDependencies: - '@react-native/metro-config': 0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@react-native/metro-config': 0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - '@react-native/debugger-frontend@0.86.3': {} + '@react-native/debugger-frontend@0.88.0-rc.3': {} - '@react-native/debugger-shell@0.86.3': + '@react-native/debugger-shell@0.88.0-rc.3': dependencies: cross-spawn: 7.0.6 debug: 4.4.3 @@ -14769,18 +14289,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@react-native/dev-middleware@0.86.3(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + '@react-native/dev-middleware@0.88.0-rc.3(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@isaacs/ttlcache': 1.4.1 - '@react-native/debugger-frontend': 0.86.3 - '@react-native/debugger-shell': 0.86.3 - chrome-launcher: 0.15.2 - chromium-edge-launcher: 0.3.0 + '@react-native/debugger-frontend': 0.88.0-rc.3 + '@react-native/debugger-shell': 0.88.0-rc.3 connect: 3.7.0 debug: 4.4.3 invariant: 2.2.4 nullthrows: 1.1.1 - open: 7.4.2 + open: 8.4.2 serve-static: 1.16.3 ws: 7.5.11(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: @@ -14788,100 +14306,90 @@ snapshots: - supports-color - utf-8-validate - '@react-native/gradle-plugin@0.86.3': {} + '@react-native/gradle-plugin@0.88.0-rc.3': {} - '@react-native/js-polyfills@0.86.3': {} + '@react-native/js-polyfills@0.88.0-rc.3': {} - '@react-native/metro-babel-transformer@0.86.3(@babel/core@7.29.7)': + '@react-native/metro-babel-transformer@0.88.0-rc.3(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 - '@react-native/babel-preset': 0.86.3(@babel/core@7.29.7) - hermes-parser: 0.36.0 + '@react-native/babel-preset': 0.88.0-rc.3(@babel/core@7.29.7) + flow-parser: 0.327.0 nullthrows: 1.1.1 transitivePeerDependencies: - supports-color - '@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + '@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: - '@react-native/js-polyfills': 0.86.3 - '@react-native/metro-babel-transformer': 0.86.3(@babel/core@7.29.7) - metro-config: 0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-runtime: 0.84.5 + '@react-native/js-polyfills': 0.88.0-rc.3 + '@react-native/metro-babel-transformer': 0.88.0-rc.3(@babel/core@7.29.7) + metro-config: 0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-runtime: 0.87.1 transitivePeerDependencies: - '@babel/core' - bufferutil - supports-color - utf-8-validate - '@react-native/normalize-colors@0.86.3': {} + '@react-native/normalize-colors@0.88.0-rc.3': {} - '@react-native/virtualized-lists@0.86.3(@types/react@19.2.16)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)': + '@react-native/virtualized-lists@0.88.0-rc.3(@types/react@19.3.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)': dependencies: invariant: 2.2.4 nullthrows: 1.1.1 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) optionalDependencies: - '@types/react': 19.2.16 + '@types/react': 19.3.0 - '@react-native/virtualized-lists@0.86.3(@types/react@19.2.16)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6)': - dependencies: - invariant: 2.2.4 - nullthrows: 1.1.1 - react: 19.2.6 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) - optionalDependencies: - '@types/react': 19.2.16 - optional: true - - '@react-navigation/core@7.21.13(react@19.2.3)': + '@react-navigation/core@7.21.13(react@19.3.0)': dependencies: '@react-navigation/routers': 7.6.4 escape-string-regexp: 4.0.0 fast-deep-equal: 3.1.3 nanoid: 3.3.19 query-string: 7.1.3 - react: 19.2.3 + react: 19.3.0 react-is: 19.2.7 - use-latest-callback: 0.2.6(react@19.2.3) - use-sync-external-store: 1.6.0(react@19.2.3) + use-latest-callback: 0.2.6(react@19.3.0) + use-sync-external-store: 1.6.0(react@19.3.0) - '@react-navigation/elements@2.9.26(c10301b6e0c42fc6434d2b643197a81e)': + '@react-navigation/elements@2.9.26(83de68753219ecf7f3321e065bd378be)': dependencies: - '@react-navigation/native': 7.3.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + '@react-navigation/native': 7.3.4(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) color: 4.2.3 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - react-native-safe-area-context: 5.7.0(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - use-latest-callback: 0.2.6(react@19.2.3) - use-sync-external-store: 1.6.0(react@19.2.3) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) + react-native-safe-area-context: 5.9.1(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + use-latest-callback: 0.2.6(react@19.3.0) + use-sync-external-store: 1.6.0(react@19.3.0) optionalDependencies: - '@react-native-masked-view/masked-view': 0.3.2(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + '@react-native-masked-view/masked-view': 0.3.2(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) - '@react-navigation/native-stack@7.17.6(patch_hash=e667c3cef8c78bb9ff4882ee5bd23a432247b843060a9499eb5f07e9e2295552)(f640afa6cd4b9a1dc5422cbafdc82f53)': + '@react-navigation/native-stack@7.17.6(patch_hash=e667c3cef8c78bb9ff4882ee5bd23a432247b843060a9499eb5f07e9e2295552)(cdeee8948497d4b80ffe015e2a003650)': dependencies: - '@react-navigation/elements': 2.9.26(c10301b6e0c42fc6434d2b643197a81e) - '@react-navigation/native': 7.3.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + '@react-navigation/elements': 2.9.26(83de68753219ecf7f3321e065bd378be) + '@react-navigation/native': 7.3.4(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) color: 4.2.3 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - react-native-safe-area-context: 5.7.0(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - react-native-screens: 4.26.2(patch_hash=595114f3f9ce8b9f0d99d1aafe5c12c997b7d75ca9add31d46cbedbfe347b8e0)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) + react-native-safe-area-context: 5.9.1(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + react-native-screens: 4.28.0(patch_hash=cc1301436ee62c39860acc9ee1a1e60b7d47e6abd211c42effa62c056d165483)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) sf-symbols-typescript: 2.2.0 warn-once: 0.1.1 transitivePeerDependencies: - '@react-native-masked-view/masked-view' - '@react-navigation/native@7.3.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)': + '@react-navigation/native@7.3.4(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)': dependencies: - '@react-navigation/core': 7.21.13(react@19.2.3) + '@react-navigation/core': 7.21.13(react@19.3.0) escape-string-regexp: 4.0.0 fast-deep-equal: 3.1.3 nanoid: 3.3.19 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) standard-navigation: 0.0.7 - use-latest-callback: 0.2.6(react@19.2.3) + use-latest-callback: 0.2.6(react@19.3.0) '@react-navigation/routers@7.6.4': dependencies: @@ -15153,28 +14661,28 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@t3tools/mobile-markdown-text@file:apps/mobile/modules/t3-markdown-text(c883758f8793b29a89016166016b354e)': + '@t3tools/mobile-markdown-text@file:apps/mobile/modules/t3-markdown-text(5c46709ff7a3b3b481fcdaa30ae2beb2)': dependencies: '@t3tools/client-runtime': link:packages/client-runtime '@t3tools/shared': link:packages/shared - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-asset: 57.0.15(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@7.0.2) - expo-clipboard: 57.0.1(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - expo-haptics: 57.0.2(expo@57.0.18) - expo-symbols: 57.0.2(expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - react-native-nitro-markdown: 0.5.8(patch_hash=642b47830730acff3761fe29cf54271d18b493c0070c750097850b7ea032e00c)(react-native-nitro-modules@0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-asset: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2) + expo-clipboard: 58.0.2(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + expo-haptics: 58.0.3(expo@58.0.0) + expo-symbols: 58.0.3(expo-font@58.0.4(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) + react-native-nitro-markdown: 0.5.8(patch_hash=642b47830730acff3761fe29cf54271d18b493c0070c750097850b7ea032e00c)(react-native-nitro-modules@0.35.9(patch_hash=daf4a639ce3f951af630a3711e4082d58e3a11e5a79f45efb0b59925327ebde2)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native-svg@15.15.5(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) '@t3tools/mobile-review-diff-native@file:apps/mobile/modules/t3-review-diff': {} '@t3tools/mobile-terminal-native@file:apps/mobile/modules/t3-terminal': {} - '@tabler/icons-react-native@3.44.0(react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react@19.2.3)': + '@tabler/icons-react-native@3.44.0(react-native-svg@15.15.5(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react@19.3.0)': dependencies: '@tabler/icons': 3.44.0 - react: 19.2.3 - react-native-svg: 15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + react: 19.3.0 + react-native-svg: 15.15.5(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) '@tabler/icons@3.44.0': {} @@ -15296,7 +14804,7 @@ snapshots: '@tanstack/router-generator@1.167.12': dependencies: - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 '@tanstack/router-core': 1.171.8 '@tanstack/router-utils': 1.162.1 '@tanstack/virtual-file-routes': 1.162.0 @@ -15333,7 +14841,7 @@ snapshots: '@babel/core': 7.29.7 '@babel/generator': 7.29.7 '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 ansis: 4.3.1 babel-dead-code-elimination: 1.0.12 diff: 8.0.3 @@ -15500,12 +15008,12 @@ snapshots: prosemirror-transform: 1.12.1 prosemirror-view: 1.42.3 - '@tiptap/react@3.31.3(@floating-ui/dom@1.7.6)(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@tiptap/react@3.31.3(@floating-ui/dom@1.7.6)(@tiptap/core@3.31.3(@tiptap/pm@3.31.3))(@tiptap/pm@3.31.3)(@types/react-dom@19.2.3(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@tiptap/core': 3.31.3(@tiptap/pm@3.31.3) '@tiptap/pm': 3.31.3 - '@types/react': 19.2.16 - '@types/react-dom': 19.2.3(@types/react@19.2.16) + '@types/react': 19.3.0 + '@types/react-dom': 19.2.3(@types/react@19.3.0) '@types/use-sync-external-store': 0.0.6 fast-equals: 5.4.2 react: 19.2.6 @@ -15570,16 +15078,16 @@ snapshots: '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 '@types/babel__template@7.4.4': dependencies: '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 '@types/babel__traverse@7.28.0': dependencies: - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 '@types/body-parser@1.19.6': dependencies: @@ -15640,8 +15148,6 @@ snapshots: dependencies: '@types/node': 24.12.4 - '@types/hammerjs@2.0.46': {} - '@types/hast@3.0.4': dependencies: '@types/unist': 3.0.3 @@ -15696,15 +15202,15 @@ snapshots: '@types/range-parser@1.2.7': {} - '@types/react-dom@19.2.3(@types/react@19.2.16)': + '@types/react-dom@19.2.3(@types/react@19.3.0)': dependencies: - '@types/react': 19.2.16 + '@types/react': 19.3.0 '@types/react-test-renderer@19.1.0': dependencies: - '@types/react': 19.2.16 + '@types/react': 19.3.0 - '@types/react@19.2.16': + '@types/react@19.3.0': dependencies: csstype: 3.2.3 @@ -16185,7 +15691,7 @@ snapshots: agent-base@7.1.4: {} - agent-cli-detector@0.1.6: {} + agent-cli-detector@0.1.7: {} agent-install@0.0.5: dependencies: @@ -16228,12 +15734,12 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - ? alchemy@2.0.0-beta.79(patch_hash=d1a03d902083946ee58121cc2787d88d1da561e9e30a5bcfcb8654692a489fb8)(@effect/platform-node@4.0.0-rc.115(bufferutil@4.1.0)(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(redis@6.2.1)(utf-8-validate@6.0.6))(@effect/sql-pg@4.0.0-rc.115(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5)))(@types/node@24.12.4)(@types/react@19.2.16)(@voidzero-dev/vite-plus-core@1.0.0(@types/node@24.12.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.48.0)(typescript@7.0.2)(unrun@0.2.39)(yaml@2.9.0))(bufferutil@4.1.0)(drizzle-kit@1.0.0-rc.5-ab785fc)(drizzle-orm@1.0.0-rc.5-ab785fc(31bc26b129d6bba2f2e387113f50dba2))(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(mongodb@6.21.0(@aws-sdk/credential-providers@3.1062.0)(socks@2.8.9))(pg@8.23.0)(react-devtools-core@6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typescript@7.0.2)(utf-8-validate@6.0.6)(ws@8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + ? alchemy@2.0.0-beta.79(patch_hash=d1a03d902083946ee58121cc2787d88d1da561e9e30a5bcfcb8654692a489fb8)(@effect/platform-node@4.0.0-rc.115(bufferutil@4.1.0)(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(redis@6.2.1)(utf-8-validate@6.0.6))(@effect/sql-pg@4.0.0-rc.115(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5)))(@types/node@24.12.4)(@types/react@19.3.0)(@voidzero-dev/vite-plus-core@1.0.0(@types/node@24.12.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.48.0)(typescript@7.0.2)(unrun@0.2.39)(yaml@2.9.0))(bufferutil@4.1.0)(drizzle-kit@1.0.0-rc.5-ab785fc)(drizzle-orm@1.0.0-rc.5-ab785fc(7abae7c285f47308cc52e143cbe0c150))(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(mongodb@6.21.0(@aws-sdk/credential-providers@3.1062.0)(socks@2.8.9))(pg@8.23.0)(react-devtools-core@6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typescript@7.0.2)(utf-8-validate@6.0.6)(ws@8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6)) : dependencies: '@alchemy.run/cloudflare-runtime': 2.0.0-beta.79(@distilled.cloud/cloudflare@1.0.0-rc.12(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5)))(@effect/platform-node@4.0.0-rc.115(bufferutil@4.1.0)(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(redis@6.2.1)(utf-8-validate@6.0.6))(@types/node@24.12.4)(@voidzero-dev/vite-plus-core@1.0.0(@types/node@24.12.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.48.0)(typescript@7.0.2)(unrun@0.2.39)(yaml@2.9.0))(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(rolldown@1.2.5)(typescript@7.0.2) '@alchemy.run/floci': 2.0.0-beta.79(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5)) '@alchemy.run/node-utils': 2.0.0-beta.79 - '@alchemy.run/sigil': 0.0.0-alpha.11(@types/react@19.2.16)(react-devtools-core@6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@alchemy.run/sigil': 0.0.0-alpha.11(@types/react@19.3.0)(react-devtools-core@6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6)) '@aws-sdk/credential-providers': 3.1062.0 '@distilled.cloud/aws': 1.0.0-rc.12(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5)) '@distilled.cloud/axiom': 1.0.0-rc.12(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5)) @@ -16268,7 +15774,7 @@ snapshots: '@effect/platform-node': 4.0.0-rc.115(bufferutil@4.1.0)(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5))(redis@6.2.1)(utf-8-validate@6.0.6) '@effect/sql-pg': 4.0.0-rc.115(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5)) drizzle-kit: 1.0.0-rc.5-ab785fc - drizzle-orm: 1.0.0-rc.5-ab785fc(31bc26b129d6bba2f2e387113f50dba2) + drizzle-orm: 1.0.0-rc.5-ab785fc(7abae7c285f47308cc52e143cbe0c150) mongodb: 6.21.0(@aws-sdk/credential-providers@3.1062.0)(socks@2.8.9) pg: 8.23.0 vite: '@voidzero-dev/vite-plus-core@1.0.0(@types/node@24.12.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.48.0)(typescript@7.0.2)(unrun@0.2.39)(yaml@2.9.0)' @@ -16375,10 +15881,6 @@ snapshots: argparse@2.0.1: {} - aria-hidden@1.2.6: - dependencies: - tslib: 2.8.1 - aria-query@5.3.0: dependencies: dequal: 2.0.3 @@ -16512,9 +16014,9 @@ snapshots: babel-dead-code-elimination@1.0.12: dependencies: '@babel/core': 7.29.7 - '@babel/parser': 7.29.7 + '@babel/parser': 7.29.8 '@babel/traverse': 7.29.7 - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 transitivePeerDependencies: - supports-color @@ -16548,10 +16050,6 @@ snapshots: babel-plugin-react-native-web@0.21.2: {} - babel-plugin-syntax-hermes-parser@0.36.0: - dependencies: - hermes-parser: 0.36.0 - babel-plugin-syntax-hermes-parser@0.36.1: dependencies: hermes-parser: 0.36.1 @@ -16562,7 +16060,7 @@ snapshots: transitivePeerDependencies: - '@babel/core' - babel-preset-expo@57.0.9(@babel/core@7.29.7)(@babel/runtime@7.29.7)(expo-widgets@57.0.15)(expo@57.0.18)(react-refresh@0.14.2): + babel-preset-expo@58.0.6(@babel/core@7.29.7)(@babel/runtime@7.29.7)(expo-widgets@58.0.9)(expo@58.0.0)(react-refresh@0.14.2): dependencies: '@babel/generator': 7.29.7 '@babel/helper-module-imports': 7.29.7 @@ -16593,14 +16091,14 @@ snapshots: '@babel/plugin-transform-private-methods': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-private-property-in-object': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-react-display-name': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.7) + '@babel/plugin-transform-react-jsx': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-react-jsx-development': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-react-pure-annotations': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-runtime': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-typescript': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-unicode-regex': 7.29.7(@babel/core@7.29.7) '@babel/preset-typescript': 7.29.7(@babel/core@7.29.7) - '@react-native/babel-plugin-codegen': 0.86.3(@babel/core@7.29.7) + '@react-native/babel-plugin-codegen': 0.88.0-rc.3(@babel/core@7.29.7) babel-plugin-react-compiler: 1.0.0 babel-plugin-react-native-web: 0.21.2 babel-plugin-syntax-hermes-parser: 0.36.1 @@ -16609,8 +16107,8 @@ snapshots: react-refresh: 0.14.2 optionalDependencies: '@babel/runtime': 7.29.7 - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-widgets: 57.0.15(patch_hash=319a9ded5db49c5b5215c511a138b33f44c7ea2972eb418192e8d5342fe75ce6)(@babel/core@7.29.7)(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(expo@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-widgets: 58.0.9(patch_hash=94de7964c5a67ab40e6b79d9bdf4b7bfc50ae97b70722ee8e5a35105ca83386b)(@babel/core@7.29.7)(expo@58.0.0)(react-dom@19.3.0(react@19.3.0))(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) transitivePeerDependencies: - '@babel/core' - supports-color @@ -16829,29 +16327,8 @@ snapshots: chownr@3.0.0: {} - chrome-launcher@0.15.2: - dependencies: - '@types/node': 24.12.4 - escape-string-regexp: 4.0.0 - is-wsl: 2.2.0 - lighthouse-logger: 1.4.2 - transitivePeerDependencies: - - supports-color - - chromium-edge-launcher@0.3.0: - dependencies: - '@types/node': 24.12.4 - escape-string-regexp: 4.0.0 - is-wsl: 2.2.0 - lighthouse-logger: 1.4.2 - mkdirp: 1.0.4 - transitivePeerDependencies: - - supports-color - chromium-pickle-js@0.2.0: {} - ci-info@2.0.0: {} - ci-info@3.9.0: {} ci-info@4.3.1: {} @@ -17150,6 +16627,8 @@ snapshots: gopd: 1.2.0 optional: true + define-lazy-prop@2.0.0: {} + define-properties@1.2.1: dependencies: define-data-property: 1.1.4 @@ -17176,8 +16655,6 @@ snapshots: detect-libc@2.1.2: {} - detect-node-es@1.1.0: {} - detect-node@2.1.0: optional: true @@ -17206,7 +16683,7 @@ snapshots: - electron-builder-squirrel-windows - supports-color - dnssd-advertise@1.1.4: {} + dnssd-advertise@1.1.6: {} dom-accessibility-api@0.5.16: {} @@ -17246,7 +16723,7 @@ snapshots: get-tsconfig: 4.14.3 jiti: 2.7.0 - drizzle-orm@1.0.0-rc.5-ab785fc(31bc26b129d6bba2f2e387113f50dba2): + drizzle-orm@1.0.0-rc.5-ab785fc(7abae7c285f47308cc52e143cbe0c150): optionalDependencies: '@cloudflare/workers-types': 4.20260604.1 '@effect/sql-d1': 4.0.0-rc.115(effect@4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5)) @@ -17257,7 +16734,7 @@ snapshots: '@libsql/client': 0.17.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) bun-types: 1.3.14 effect: 4.0.0-rc.115(patch_hash=0dfc4bb8ebd80fb3e06b91ef61346f5259517ab0f2437644fe95ae531084b1f5) - expo-sqlite: 57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6) + expo-sqlite: 58.0.7(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) pg: 8.23.0 valibot: 1.2.0(typescript@7.0.2) zod: 4.4.3 @@ -17526,231 +17003,195 @@ snapshots: expect-type@1.4.0: {} - expo-application@57.0.2(expo@57.0.18): + expo-application@58.0.2(expo@58.0.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) + expo: 58.0.0(3abfa3879936d948a635873738556226) - expo-asset@57.0.15(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@7.0.2): + expo-asset@58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2): dependencies: - '@expo/image-utils': 0.11.5(typescript@7.0.2) - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-constants: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + '@expo/image-utils': 0.12.2(typescript@7.0.2) + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-constants: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(typescript@7.0.2) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color - typescript - expo-asset@57.0.15(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6)(typescript@7.0.2): + expo-audio@58.0.3(patch_hash=c20cb927d6848c53e7bf6ec14fe12f19daae9210165d2dbaf4e0f97ce31e8742)(expo-asset@58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2))(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - '@expo/image-utils': 0.11.5(typescript@7.0.2) - expo: 57.0.18(0bf40d5ad6281d8f1e92517b24812edb) - expo-constants: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6)) - react: 19.2.6 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) - transitivePeerDependencies: - - supports-color - - typescript - optional: true - - expo-audio@57.0.4(patch_hash=fa9a3e0442ed395d4071bb406e08c3a471c9a84700bdfa0b9ad7ff144c96041a)(expo-asset@57.0.15(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@7.0.2))(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): - dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-asset: 57.0.15(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@7.0.2) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-asset: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - expo-auth-session@57.0.10(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + expo-auth-session@58.0.6(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2): dependencies: - expo-application: 57.0.2(expo@57.0.18) - expo-constants: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) - expo-crypto: 57.0.2(expo@57.0.18) - expo-linking: 57.0.8(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - expo-web-browser: 57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) + expo-application: 58.0.2(expo@58.0.0) + expo-constants: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(typescript@7.0.2) + expo-crypto: 58.0.3(expo@58.0.0) + expo-linking: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2) + expo-web-browser: 58.0.3(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)) invariant: 2.2.4 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - expo - supports-color + - typescript - expo-blur@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + expo-blur@58.0.2(patch_hash=d0311b0c0b05bd94393bd9a84653cb42503d5f3c8a19eb2627c34ace08bedf18)(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - expo-build-properties@57.0.15(expo@57.0.18): + expo-build-properties@58.0.9(expo@58.0.0): dependencies: - '@expo/schema-utils': 57.0.2 - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) + '@expo/schema-utils': 58.0.1 + expo: 58.0.0(3abfa3879936d948a635873738556226) resolve-from: 5.0.0 semver: 7.8.5 - expo-camera@57.0.4(@types/emscripten@1.41.5)(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + expo-camera@58.0.5(@types/emscripten@1.41.5)(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: barcode-detector: 3.2.0(@types/emscripten@1.41.5) - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - '@types/emscripten' - expo-clipboard@57.0.1(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + expo-clipboard@58.0.2(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - expo-constants@57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)): + expo-constants@58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(typescript@7.0.2): dependencies: - '@expo/env': 2.4.3 - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + '@expo/env': 2.5.1 + '@expo/require-utils': 58.0.2(typescript@7.0.2) + expo: 58.0.0(3abfa3879936d948a635873738556226) + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color + - typescript - expo-constants@57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6)): + expo-crypto@58.0.3(expo@58.0.0): dependencies: - '@expo/env': 2.4.3 - expo: 57.0.18(0bf40d5ad6281d8f1e92517b24812edb) - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) - transitivePeerDependencies: - - supports-color - optional: true - - expo-crypto@57.0.2(expo@57.0.18): - dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) + expo: 58.0.0(3abfa3879936d948a635873738556226) - expo-dev-client@57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)): + expo-dev-client@58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-dev-launcher: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) - expo-dev-menu: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) - expo-dev-menu-interface: 57.0.0(expo@57.0.18) - expo-manifests: 57.0.1(expo@57.0.18) - expo-updates-interface: 57.0.1(expo@57.0.18) + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-dev-launcher: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)) + expo-dev-menu: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)) + expo-dev-menu-interface: 58.0.1(expo@58.0.0) + expo-manifests: 58.0.1(expo@58.0.0) + expo-updates-interface: 58.0.1(expo@58.0.0) transitivePeerDependencies: - react-native - expo-dev-launcher@57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)): + expo-dev-launcher@58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)): dependencies: - '@expo/schema-utils': 57.0.2 - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-dev-menu: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) - expo-manifests: 57.0.1(expo@57.0.18) - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + '@expo/schema-utils': 58.0.1 + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-dev-menu: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)) + expo-manifests: 58.0.1(expo@58.0.0) + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - expo-dev-menu-interface@57.0.0(expo@57.0.18): + expo-dev-menu-interface@58.0.1(expo@58.0.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) + expo: 58.0.0(3abfa3879936d948a635873738556226) - expo-dev-menu@57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)): + expo-dev-menu@58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-dev-menu-interface: 57.0.0(expo@57.0.18) - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-dev-menu-interface: 58.0.1(expo@58.0.0) + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - expo-device@57.0.1(expo@57.0.18): + expo-device@58.0.3(expo@58.0.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) + expo: 58.0.0(3abfa3879936d948a635873738556226) ua-parser-js: 0.7.41 - expo-document-picker@57.0.1(expo@57.0.18): + expo-document-picker@58.0.3(expo@58.0.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) + expo: 58.0.0(3abfa3879936d948a635873738556226) - expo-eas-client@57.0.2: {} + expo-eas-client@58.0.1: {} - expo-file-system@57.0.6(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)): + expo-file-system@58.0.4(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - expo-file-system@57.0.6(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6)): + expo-font@58.0.4(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - expo: 57.0.18(0bf40d5ad6281d8f1e92517b24812edb) - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) - optional: true + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + expo-glass-effect@58.0.3(patch_hash=f750041c45ab838a3530451dc7b50d6640a79141037a1b0499c5e3412a860c57)(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - fontfaceobserver: 2.3.0 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6): + expo-haptics@58.0.3(expo@58.0.0): dependencies: - expo: 57.0.18(0bf40d5ad6281d8f1e92517b24812edb) - fontfaceobserver: 2.3.0 - react: 19.2.6 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) - optional: true + expo: 58.0.0(3abfa3879936d948a635873738556226) - expo-glass-effect@57.0.1(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + expo-image-loader@58.0.2(expo@58.0.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) - expo-haptics@57.0.2(expo@57.0.18): + expo-image-manipulator@58.0.10(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-image-loader: 58.0.2(expo@58.0.0) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - expo-image-loader@57.0.1(expo@57.0.18): + expo-image-picker@58.0.9(expo@58.0.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-image-loader: 58.0.2(expo@58.0.0) - expo-image-manipulator@57.0.17(expo@57.0.18): + expo-image@58.0.8(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-image-loader: 57.0.1(expo@57.0.18) - - expo-image-picker@57.0.14(expo@57.0.18): - dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-image-loader: 57.0.1(expo@57.0.18) - - expo-image@57.0.3(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): - dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) sf-symbols-typescript: 2.2.0 - expo-json-utils@57.0.1: {} + expo-json-utils@58.0.1: {} - expo-keep-awake@57.0.2(expo@57.0.18)(react@19.2.3): + expo-keep-awake@58.0.2(expo@58.0.0)(react@19.3.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 - expo-keep-awake@57.0.2(expo@57.0.18)(react@19.2.6): + expo-linking@58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2): dependencies: - expo: 57.0.18(0bf40d5ad6281d8f1e92517b24812edb) - react: 19.2.6 - optional: true - - expo-linking@57.0.8(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): - dependencies: - expo-constants: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-constants: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(typescript@7.0.2) invariant: 2.2.4 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - - expo - supports-color + - typescript - expo-manifests@57.0.1(expo@57.0.18): + expo-manifests@58.0.1(expo@58.0.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-json-utils: 57.0.1 + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-json-utils: 58.0.1 - expo-modules-autolinking@57.0.12(typescript@7.0.2): + expo-modules-autolinking@58.0.6(typescript@7.0.2): dependencies: - '@expo/require-utils': 57.0.5(typescript@7.0.2) + '@expo/require-utils': 58.0.2(typescript@7.0.2) '@expo/spawn-async': 1.8.0 chalk: 4.1.2 commander: 7.2.0 @@ -17758,253 +17199,187 @@ snapshots: - supports-color - typescript - expo-modules-core@57.0.14(patch_hash=6be7092f8c6f03a57b75c797d98b5f19ed62d2dd205bfc4c8adf4cef45655d7e)(react-native-worklets@0.10.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6): + expo-modules-core@58.0.9(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - '@expo/expo-modules-macros-plugin': 0.6.1 - expo-modules-jsi: 57.0.6(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6)) + expo-modules-jsi: 58.0.5(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)) + expo-modules-macros: 0.14.0 invariant: 2.2.4 - react: 19.2.6 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) optionalDependencies: - react-native-worklets: 0.10.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6) - optional: true + react-native-worklets: 0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) - expo-modules-core@57.0.14(patch_hash=6be7092f8c6f03a57b75c797d98b5f19ed62d2dd205bfc4c8adf4cef45655d7e)(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + expo-modules-jsi@58.0.5(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)): dependencies: - '@expo/expo-modules-macros-plugin': 0.6.1 - expo-modules-jsi: 57.0.6(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) - invariant: 2.2.4 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - optionalDependencies: - react-native-worklets: 0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - expo-modules-jsi@57.0.6(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)): - dependencies: - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - - expo-modules-jsi@57.0.6(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6)): - dependencies: - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) - optional: true + expo-modules-macros@0.14.0: {} - expo-network@57.0.1(expo@57.0.18)(react@19.2.3): + expo-network@58.0.2(expo@58.0.0)(react@19.3.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 - expo-notifications@57.0.15(patch_hash=f89252c2c08dc7b3acb8415f319ebbe15fff8c9f88a64ebe1830cd5ac5c9ac40)(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@7.0.2): + expo-notifications@58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2): dependencies: - '@expo/image-utils': 0.11.5(typescript@7.0.2) + '@expo/image-utils': 0.12.2(typescript@7.0.2) abort-controller: 3.0.0 badgin: 1.2.3 - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-application: 57.0.2(expo@57.0.18) - expo-constants: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-application: 58.0.2(expo@58.0.0) + expo-constants: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(typescript@7.0.2) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color - typescript - expo-paste-input@0.1.15(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + expo-paste-input@0.1.15(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - expo-quick-actions@6.0.2(expo@57.0.18)(typescript@7.0.2): + expo-quick-actions@6.0.2(expo@58.0.0)(typescript@7.0.2): dependencies: '@expo/image-utils': 0.8.14(typescript@7.0.2) - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) + expo: 58.0.0(3abfa3879936d948a635873738556226) schema-utils: 4.3.3 sf-symbols-typescript: 2.2.0 transitivePeerDependencies: - supports-color - typescript - expo-secure-store@57.0.2(expo@57.0.18): + expo-secure-store@58.0.1(expo@58.0.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) + expo: 58.0.0(3abfa3879936d948a635873738556226) - expo-server@57.0.3: {} + expo-server@58.0.2: {} - expo-sharing@57.0.17(patch_hash=8d2e3b10eb3f52036a9a086800180ec6cebf3b75bccc5b1775117a7244d4ac45)(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@7.0.2): + expo-sharing@58.0.12(patch_hash=5c85c709d951b5522b5bca897204b73ba7c17dec76e0dd155f41f8c2e833a7a8)(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2): dependencies: - '@expo/config-plugins': 57.0.9(typescript@7.0.2) - '@expo/config-types': 57.0.2 - '@expo/plist': 0.8.1 - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + '@expo/config-plugins': 58.0.4(typescript@7.0.2) + '@expo/config-types': 58.0.2 + '@expo/plist': 0.10.1 + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color - typescript - expo-splash-screen@57.0.8(expo@57.0.18)(typescript@7.0.2): + expo-splash-screen@58.0.2(expo@58.0.0)(typescript@7.0.2): dependencies: - '@expo/config-plugins': 57.0.9(typescript@7.0.2) - '@expo/image-utils': 0.11.5(typescript@7.0.2) - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) + '@expo/config-plugins': 58.0.4(typescript@7.0.2) + '@expo/image-utils': 0.12.2(typescript@7.0.2) + expo: 58.0.0(3abfa3879936d948a635873738556226) xml2js: 0.6.0 transitivePeerDependencies: - supports-color - typescript - expo-sqlite@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + expo-sqlite@58.0.7(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: await-lock: 2.2.2 - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - expo-sqlite@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6): - dependencies: - await-lock: 2.2.2 - expo: 57.0.18(0bf40d5ad6281d8f1e92517b24812edb) - react: 19.2.6 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) - optional: true - - expo-structured-headers@57.0.0: {} + expo-structured-headers@58.0.1: {} - expo-symbols@57.0.2(expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + expo-symbols@58.0.3(expo-font@58.0.4(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: '@expo-google-fonts/material-symbols': 0.4.38 - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-font: 57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-font: 58.0.4(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) sf-symbols-typescript: 2.2.0 - expo-updates-interface@57.0.1(expo@57.0.18): + expo-updates-interface@58.0.1(expo@58.0.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) + expo: 58.0.0(3abfa3879936d948a635873738556226) - expo-updates@57.0.19(expo-dev-client@57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)))(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + expo-updates@58.0.11(expo-dev-client@58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)))(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: '@expo/code-signing-certificates': 0.0.6 - '@expo/plist': 0.8.1 + '@expo/plist': 0.10.1 '@expo/spawn-async': 1.8.0 arg: 4.1.3 chalk: 4.1.2 debug: 4.4.3 - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-eas-client: 57.0.2 - expo-manifests: 57.0.1(expo@57.0.18) - expo-structured-headers: 57.0.0 - expo-updates-interface: 57.0.1(expo@57.0.18) + expo: 58.0.0(3abfa3879936d948a635873738556226) + expo-eas-client: 58.0.1 + expo-manifests: 58.0.1(expo@58.0.0) + expo-structured-headers: 58.0.1 + expo-updates-interface: 58.0.1(expo@58.0.0) getenv: 2.0.0 glob: 13.0.6 ignore: 5.3.2 nullthrows: 1.1.1 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) resolve-from: 5.0.0 optionalDependencies: - expo-dev-client: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) + expo-dev-client: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)) transitivePeerDependencies: - supports-color - expo-video@57.0.3(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + expo-video@58.0.5(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - expo-web-browser@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)): + expo-web-browser@58.0.3(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)): dependencies: - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + expo: 58.0.0(3abfa3879936d948a635873738556226) + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - expo-widgets@57.0.15(patch_hash=319a9ded5db49c5b5215c511a138b33f44c7ea2972eb418192e8d5342fe75ce6)(@babel/core@7.29.7)(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(expo@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + expo-widgets@58.0.9(patch_hash=94de7964c5a67ab40e6b79d9bdf4b7bfc50ae97b70722ee8e5a35105ca83386b)(@babel/core@7.29.7)(expo@58.0.0)(react-dom@19.3.0(react@19.3.0))(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - '@expo/plist': 0.8.1 - '@expo/ui': 57.0.14(@babel/core@7.29.7)(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(expo@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + '@expo/plist': 0.10.1 + '@expo/ui': 58.0.9(@babel/core@7.29.7)(expo@58.0.0)(react-dom@19.3.0(react@19.3.0))(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + expo: 58.0.0(3abfa3879936d948a635873738556226) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - '@babel/core' - - '@types/react' - - '@types/react-dom' - react-dom - react-native-worklets - expo@57.0.18(0bf40d5ad6281d8f1e92517b24812edb): + expo@58.0.0(3abfa3879936d948a635873738556226): dependencies: '@babel/runtime': 7.29.7 - '@expo/cli': 57.0.20(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.14)(bufferutil@4.1.0)(expo-constants@57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6)))(expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6))(expo@57.0.18)(react-dom@19.2.6(react@19.2.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6)(typescript@7.0.2)(utf-8-validate@6.0.6) - '@expo/config': 57.0.9(typescript@7.0.2) - '@expo/config-plugins': 57.0.9(typescript@7.0.2) - '@expo/devtools': 57.0.1(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6) - '@expo/fingerprint': 0.20.11 - '@expo/local-build-cache-provider': 57.0.8(typescript@7.0.2) - '@expo/log-box': 57.0.4(@expo/dom-webview@57.0.1)(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6) - '@expo/metro': 56.0.2(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@expo/metro-config': 57.0.12(patch_hash=96f1a75347e6ea02dc4b7034ace815d8ee39e18b8166ebfb573d9e58328f0dc2)(bufferutil@4.1.0)(expo@57.0.18)(typescript@7.0.2)(utf-8-validate@6.0.6) + '@expo/cli': 58.0.9(@expo/dom-webview@58.0.2)(@expo/metro-runtime@58.0.9)(bufferutil@4.1.0)(expo-constants@58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(typescript@7.0.2))(expo-font@58.0.4(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(expo@58.0.0)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2)(utf-8-validate@6.0.6) + '@expo/config': 58.0.1(typescript@7.0.2) + '@expo/config-plugins': 58.0.4(typescript@7.0.2) + '@expo/devtools': 58.0.2(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + '@expo/fingerprint': 0.21.2 + '@expo/local-build-cache-provider': 58.0.1(typescript@7.0.2) + '@expo/log-box': 58.0.7(@expo/dom-webview@58.0.2)(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + '@expo/log-box-utils': 58.0.1 + '@expo/metro': 58.0.0-rc.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@expo/metro-config': 58.0.6(patch_hash=90fa980e8b6480631fb2fbb04559834e3c612db40c550cd828f11be297d8d760)(bufferutil@4.1.0)(expo@58.0.0)(typescript@7.0.2)(utf-8-validate@6.0.6) '@ungap/structured-clone': 1.3.1 - babel-preset-expo: 57.0.9(@babel/core@7.29.7)(@babel/runtime@7.29.7)(expo-widgets@57.0.15)(expo@57.0.18)(react-refresh@0.14.2) - expo-asset: 57.0.15(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6)(typescript@7.0.2) - expo-constants: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6)) - expo-file-system: 57.0.6(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6)) - expo-font: 57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6) - expo-keep-awake: 57.0.2(expo@57.0.18)(react@19.2.6) - expo-modules-autolinking: 57.0.12(typescript@7.0.2) - expo-modules-core: 57.0.14(patch_hash=6be7092f8c6f03a57b75c797d98b5f19ed62d2dd205bfc4c8adf4cef45655d7e)(react-native-worklets@0.10.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6) + babel-preset-expo: 58.0.6(@babel/core@7.29.7)(@babel/runtime@7.29.7)(expo-widgets@58.0.9)(expo@58.0.0)(react-refresh@0.14.2) + expo-asset: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(typescript@7.0.2) + expo-constants: 58.0.9(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(typescript@7.0.2) + expo-file-system: 58.0.4(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)) + expo-font: 58.0.4(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + expo-keep-awake: 58.0.2(expo@58.0.0)(react@19.3.0) + expo-modules-autolinking: 58.0.6(typescript@7.0.2) + expo-modules-core: 58.0.9(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) pretty-format: 29.7.0 - react: 19.2.6 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) react-refresh: 0.14.2 - whatwg-url-minimum: 0.1.2 + whatwg-url-minimum: 0.2.0 optionalDependencies: - '@expo/dom-webview': 57.0.1(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6) - '@expo/metro-runtime': 57.0.14(@expo/log-box@57.0.4)(expo@57.0.18)(react-dom@19.2.6(react@19.2.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6) - react-dom: 19.2.6(react@19.2.6) - react-native-webview: 13.16.1(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6) - transitivePeerDependencies: - - '@babel/core' - - bufferutil - - expo-router - - expo-widgets - - react-native-worklets - - react-server-dom-webpack - - supports-color - - typescript - - utf-8-validate - optional: true - - expo@57.0.18(41fd11498a34454c91128cdad32f22f8): - dependencies: - '@babel/runtime': 7.29.7 - '@expo/cli': 57.0.20(@expo/dom-webview@57.0.1)(@expo/metro-runtime@57.0.14)(bufferutil@4.1.0)(expo-constants@57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)))(expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(expo@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@7.0.2)(utf-8-validate@6.0.6) - '@expo/config': 57.0.9(typescript@7.0.2) - '@expo/config-plugins': 57.0.9(typescript@7.0.2) - '@expo/devtools': 57.0.1(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - '@expo/fingerprint': 0.20.11 - '@expo/local-build-cache-provider': 57.0.8(typescript@7.0.2) - '@expo/log-box': 57.0.4(@expo/dom-webview@57.0.1)(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - '@expo/metro': 56.0.2(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@expo/metro-config': 57.0.12(patch_hash=96f1a75347e6ea02dc4b7034ace815d8ee39e18b8166ebfb573d9e58328f0dc2)(bufferutil@4.1.0)(expo@57.0.18)(typescript@7.0.2)(utf-8-validate@6.0.6) - '@ungap/structured-clone': 1.3.1 - babel-preset-expo: 57.0.9(@babel/core@7.29.7)(@babel/runtime@7.29.7)(expo-widgets@57.0.15)(expo@57.0.18)(react-refresh@0.14.2) - expo-asset: 57.0.15(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@7.0.2) - expo-constants: 57.0.16(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) - expo-file-system: 57.0.6(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)) - expo-font: 57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - expo-keep-awake: 57.0.2(expo@57.0.18)(react@19.2.3) - expo-modules-autolinking: 57.0.12(typescript@7.0.2) - expo-modules-core: 57.0.14(patch_hash=6be7092f8c6f03a57b75c797d98b5f19ed62d2dd205bfc4c8adf4cef45655d7e)(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - pretty-format: 29.7.0 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - react-refresh: 0.14.2 - whatwg-url-minimum: 0.1.2 - optionalDependencies: - '@expo/dom-webview': 57.0.1(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - '@expo/metro-runtime': 57.0.14(@expo/log-box@57.0.4)(expo@57.0.18)(react-dom@19.2.3(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - react-dom: 19.2.3(react@19.2.3) - react-native-webview: 13.16.1(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + '@expo/dom-webview': 58.0.2(expo@58.0.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + '@expo/metro-runtime': 58.0.9(@expo/log-box@58.0.7)(expo@58.0.0)(react-dom@19.3.0(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + react-dom: 19.3.0(react@19.3.0) + react-native-webview: 14.0.1(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) transitivePeerDependencies: - '@babel/core' - bufferutil @@ -18185,12 +17560,22 @@ snapshots: flow-enums-runtime@0.0.6: {} + flow-estree@0.327.0: {} + + flow-estree@0.331.0: {} + + flow-parser@0.327.0: + dependencies: + flow-estree: 0.327.0 + + flow-parser@0.331.0: + dependencies: + flow-estree: 0.331.0 + fontace@0.4.1: dependencies: fontkitten: 1.0.3 - fontfaceobserver@2.3.0: {} - fontkitten@1.0.3: dependencies: tiny-inflate: 1.0.3 @@ -18279,8 +17664,6 @@ snapshots: hasown: 2.0.4 math-intrinsics: 1.1.0 - get-nonce@1.0.1: {} - get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 @@ -18487,32 +17870,16 @@ snapshots: heic-to@1.5.2: {} - hermes-compiler@250829098.0.17: {} - - hermes-estree@0.35.0: {} - - hermes-estree@0.36.0: {} + hermes-compiler@260318099.0.4: {} hermes-estree@0.36.1: {} - hermes-parser@0.35.0: - dependencies: - hermes-estree: 0.35.0 - - hermes-parser@0.36.0: - dependencies: - hermes-estree: 0.36.0 - hermes-parser@0.36.1: dependencies: hermes-estree: 0.36.1 hexy@0.2.11: {} - hoist-non-react-statics@3.3.2: - dependencies: - react-is: 16.13.1 - hono@4.13.7: {} hosted-git-info@4.1.0: @@ -18582,10 +17949,6 @@ snapshots: ignore@7.0.5: {} - image-size@1.2.1: - dependencies: - queue: 6.0.2 - immediate@3.0.6: {} inflight@1.0.6: @@ -18865,13 +18228,6 @@ snapshots: dependencies: immediate: 3.0.6 - lighthouse-logger@1.4.2: - dependencies: - debug: 2.6.9 - marky: 1.3.0 - transitivePeerDependencies: - - supports-color - lightningcss-android-arm64@1.33.0: optional: true @@ -19001,8 +18357,6 @@ snapshots: markdown-table@3.0.4: {} - marky@1.3.0: {} - matcher@3.0.0: dependencies: escape-string-regexp: 4.0.0 @@ -19201,95 +18555,50 @@ snapshots: meshoptimizer@0.22.0: {} - metro-babel-transformer@0.84.4: + metro-babel-transformer@0.87.1: dependencies: '@babel/core': 7.29.7 flow-enums-runtime: 0.0.6 - hermes-parser: 0.35.0 - metro-cache-key: 0.84.4 + flow-parser: 0.331.0 + metro-cache-key: 0.87.1 nullthrows: 1.1.1 transitivePeerDependencies: - supports-color - metro-babel-transformer@0.84.5: - dependencies: - '@babel/core': 7.29.7 - flow-enums-runtime: 0.0.6 - hermes-parser: 0.35.0 - metro-cache-key: 0.84.5 - nullthrows: 1.1.1 - transitivePeerDependencies: - - supports-color - - metro-cache-key@0.84.4: + metro-cache-key@0.87.1: dependencies: flow-enums-runtime: 0.0.6 - metro-cache-key@0.84.5: - dependencies: - flow-enums-runtime: 0.0.6 - - metro-cache@0.84.4: - dependencies: - exponential-backoff: 3.1.3 - flow-enums-runtime: 0.0.6 - https-proxy-agent: 7.0.6 - metro-core: 0.84.4 - transitivePeerDependencies: - - supports-color - - metro-cache@0.84.5: + metro-cache@0.87.1: dependencies: exponential-backoff: 3.1.3 flow-enums-runtime: 0.0.6 https-proxy-agent: 7.0.6 - metro-core: 0.84.5 + metro-core: 0.87.1 transitivePeerDependencies: - supports-color - metro-config@0.84.4(bufferutil@4.1.0)(utf-8-validate@6.0.6): + metro-config@0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: connect: 3.7.0 flow-enums-runtime: 0.0.6 jest-validate: 29.7.0 - metro: 0.84.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-cache: 0.84.4 - metro-core: 0.84.4 - metro-runtime: 0.84.4 - yaml: 2.9.0 + metro: 0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-cache: 0.87.1 + metro-core: 0.87.1 + metro-runtime: 0.87.1 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - metro-config@0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6): - dependencies: - connect: 3.7.0 - flow-enums-runtime: 0.0.6 - jest-validate: 29.7.0 - metro: 0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-cache: 0.84.5 - metro-core: 0.84.5 - metro-runtime: 0.84.5 - yaml: 2.9.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - metro-core@0.84.4: - dependencies: - flow-enums-runtime: 0.0.6 - lodash.throttle: 4.1.1 - metro-resolver: 0.84.4 - - metro-core@0.84.5: + metro-core@0.87.1: dependencies: flow-enums-runtime: 0.0.6 lodash.throttle: 4.1.1 - metro-resolver: 0.84.5 + metro-resolver: 0.87.1 - metro-file-map@0.84.4: + metro-file-map@0.87.1: dependencies: debug: 4.4.3 fb-watchman: 2.0.2 @@ -19299,103 +18608,49 @@ snapshots: jest-worker: 29.7.0 micromatch: 4.0.8 nullthrows: 1.1.1 - walker: 1.0.8 transitivePeerDependencies: - supports-color - metro-file-map@0.84.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.84.4: + metro-minify-terser@0.87.1: dependencies: flow-enums-runtime: 0.0.6 terser: 5.48.0 - metro-minify-terser@0.84.5: + metro-resolver@0.87.1: dependencies: flow-enums-runtime: 0.0.6 - terser: 5.48.0 - metro-resolver@0.84.4: - dependencies: - flow-enums-runtime: 0.0.6 - - metro-resolver@0.84.5: - dependencies: - flow-enums-runtime: 0.0.6 - - metro-runtime@0.84.4: - dependencies: - '@babel/runtime': 7.29.7 - flow-enums-runtime: 0.0.6 - - metro-runtime@0.84.5: + metro-runtime@0.87.1: dependencies: '@babel/runtime': 7.29.7 flow-enums-runtime: 0.0.6 - metro-source-map@0.84.4: - dependencies: - '@babel/traverse': 7.29.7 - '@babel/types': 7.29.7 - flow-enums-runtime: 0.0.6 - invariant: 2.2.4 - metro-symbolicate: 0.84.4 - nullthrows: 1.1.1 - ob1: 0.84.4 - source-map: 0.5.7 - vlq: 1.0.1 - transitivePeerDependencies: - - supports-color - - metro-source-map@0.84.5: + metro-source-map@0.87.1: dependencies: '@babel/traverse': 7.29.7 '@babel/types': 7.29.8 flow-enums-runtime: 0.0.6 invariant: 2.2.4 - metro-symbolicate: 0.84.5 + metro-symbolicate: 0.87.1 nullthrows: 1.1.1 - ob1: 0.84.5 + ob1: 0.87.1 source-map: 0.5.7 vlq: 1.0.1 transitivePeerDependencies: - supports-color - metro-symbolicate@0.84.4: + metro-symbolicate@0.87.1: dependencies: flow-enums-runtime: 0.0.6 invariant: 2.2.4 - metro-source-map: 0.84.4 + metro-source-map: 0.87.1 nullthrows: 1.1.1 source-map: 0.5.7 vlq: 1.0.1 transitivePeerDependencies: - supports-color - metro-symbolicate@0.84.5: - dependencies: - flow-enums-runtime: 0.0.6 - invariant: 2.2.4 - metro-source-map: 0.84.5 - nullthrows: 1.1.1 - source-map: 0.5.7 - vlq: 1.0.1 - transitivePeerDependencies: - - supports-color - - metro-transform-plugins@0.84.4: + metro-transform-plugins@0.87.1: dependencies: '@babel/core': 7.29.7 '@babel/generator': 7.29.7 @@ -19406,104 +18661,27 @@ snapshots: transitivePeerDependencies: - supports-color - metro-transform-plugins@0.84.5: - dependencies: - '@babel/core': 7.29.7 - '@babel/generator': 7.29.7 - '@babel/template': 7.29.7 - '@babel/traverse': 7.29.7 - flow-enums-runtime: 0.0.6 - nullthrows: 1.1.1 - transitivePeerDependencies: - - supports-color - - metro-transform-worker@0.84.4(bufferutil@4.1.0)(utf-8-validate@6.0.6): - dependencies: - '@babel/core': 7.29.7 - '@babel/generator': 7.29.7 - '@babel/parser': 7.29.8 - '@babel/types': 7.29.8 - flow-enums-runtime: 0.0.6 - metro: 0.84.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-babel-transformer: 0.84.4 - metro-cache: 0.84.4 - metro-cache-key: 0.84.4 - metro-minify-terser: 0.84.4 - metro-source-map: 0.84.4 - metro-transform-plugins: 0.84.4 - nullthrows: 1.1.1 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - metro-transform-worker@0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6): + metro-transform-worker@0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@babel/core': 7.29.7 '@babel/generator': 7.29.7 '@babel/parser': 7.29.8 '@babel/types': 7.29.8 flow-enums-runtime: 0.0.6 - metro: 0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-babel-transformer: 0.84.5 - metro-cache: 0.84.5 - metro-cache-key: 0.84.5 - metro-minify-terser: 0.84.5 - metro-source-map: 0.84.5 - metro-transform-plugins: 0.84.5 + metro: 0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-babel-transformer: 0.87.1 + metro-cache: 0.87.1 + metro-cache-key: 0.87.1 + metro-minify-terser: 0.87.1 + metro-source-map: 0.87.1 + metro-transform-plugins: 0.87.1 nullthrows: 1.1.1 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - metro@0.84.4(bufferutil@4.1.0)(utf-8-validate@6.0.6): - dependencies: - '@babel/code-frame': 7.29.7 - '@babel/core': 7.29.7 - '@babel/generator': 7.29.7 - '@babel/parser': 7.29.7 - '@babel/template': 7.29.7 - '@babel/traverse': 7.29.7 - '@babel/types': 7.29.7 - accepts: 2.0.0 - 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.35.0 - 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.84.4 - metro-cache: 0.84.4 - metro-cache-key: 0.84.4 - metro-config: 0.84.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-core: 0.84.4 - metro-file-map: 0.84.4 - metro-resolver: 0.84.4 - metro-runtime: 0.84.4 - metro-source-map: 0.84.4 - metro-symbolicate: 0.84.4 - metro-transform-plugins: 0.84.4 - metro-transform-worker: 0.84.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) - 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.11(bufferutil@4.1.0)(utf-8-validate@6.0.6) - yargs: 17.7.2 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - metro@0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6): + metro@0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@babel/code-frame': 7.29.7 '@babel/core': 7.29.7 @@ -19513,29 +18691,28 @@ snapshots: '@babel/traverse': 7.29.7 '@babel/types': 7.29.8 accepts: 2.0.0 - 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 + flow-parser: 0.331.0 graceful-fs: 4.2.11 - hermes-parser: 0.35.0 invariant: 2.2.4 jest-worker: 29.7.0 jsc-safe-url: 0.2.4 lodash.throttle: 4.1.1 - metro-babel-transformer: 0.84.5 - metro-cache: 0.84.5 - metro-cache-key: 0.84.5 - metro-config: 0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-core: 0.84.5 - metro-file-map: 0.84.5 - metro-resolver: 0.84.5 - metro-runtime: 0.84.5 - metro-source-map: 0.84.5 - metro-symbolicate: 0.84.5 - metro-transform-plugins: 0.84.5 - metro-transform-worker: 0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-babel-transformer: 0.87.1 + metro-cache: 0.87.1 + metro-cache-key: 0.87.1 + metro-config: 0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-core: 0.87.1 + metro-file-map: 0.87.1 + metro-resolver: 0.87.1 + metro-runtime: 0.87.1 + metro-source-map: 0.87.1 + metro-symbolicate: 0.87.1 + metro-transform-plugins: 0.87.1 + metro-transform-worker: 0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) mime-types: 3.0.2 nullthrows: 1.1.1 serialize-error: 2.1.0 @@ -19812,8 +18989,6 @@ snapshots: dependencies: minimist: 1.2.8 - mkdirp@1.0.4: {} - modern-tar@0.8.5: {} mongodb-connection-string-url@3.0.2: @@ -19947,6 +19122,20 @@ snapshots: normalize-url@6.1.0: {} + noxcturnal@0.1.1: + dependencies: + '@babel/code-frame': 7.29.7 + '@oxc-project/types': 0.141.0 + optionalDependencies: + '@noxcturnal/noxcturnal-darwin-arm64': 0.1.1 + '@noxcturnal/noxcturnal-darwin-x64': 0.1.1 + '@noxcturnal/noxcturnal-linux-arm64-gnu': 0.1.1 + '@noxcturnal/noxcturnal-linux-arm64-musl': 0.1.1 + '@noxcturnal/noxcturnal-linux-x64-gnu': 0.1.1 + '@noxcturnal/noxcturnal-linux-x64-musl': 0.1.1 + '@noxcturnal/noxcturnal-win32-arm64-msvc': 0.1.1 + '@noxcturnal/noxcturnal-win32-x64-msvc': 0.1.1 + npm-package-arg@11.0.3: dependencies: hosted-git-info: 7.0.2 @@ -19991,11 +19180,7 @@ snapshots: should: 13.2.3 yaml: 2.9.0 - ob1@0.84.4: - dependencies: - flow-enums-runtime: 0.0.6 - - ob1@0.84.5: + ob1@0.87.1: dependencies: flow-enums-runtime: 0.0.6 @@ -20050,8 +19235,9 @@ snapshots: regex: 6.1.0 regex-recursion: 6.0.2 - open@7.4.2: + open@8.4.2: dependencies: + define-lazy-prop: 2.0.0 is-docker: 2.2.1 is-wsl: 2.2.0 @@ -20573,10 +19759,6 @@ snapshots: split-on-first: 1.1.0 strict-uri-encode: 2.0.0 - queue@6.0.2: - dependencies: - inherits: 2.0.4 - quick-lru@5.1.1: {} radix3@1.1.2: {} @@ -20590,13 +19772,13 @@ snapshots: iconv-lite: 0.7.2 unpipe: 1.0.0 - react-day-picker@10.0.1(@types/react@19.2.16)(react@19.2.6): + react-day-picker@10.0.1(@types/react@19.3.0)(react@19.2.6): dependencies: '@date-fns/tz': 1.5.0 date-fns: 4.4.0 react: 19.2.6 optionalDependencies: - '@types/react': 19.2.16 + '@types/react': 19.3.0 react-devtools-core@6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: @@ -20606,19 +19788,19 @@ snapshots: - bufferutil - utf-8-validate - react-dom@19.2.3(react@19.2.3): - dependencies: - react: 19.2.3 - scheduler: 0.27.0 - react-dom@19.2.6(react@19.2.6): dependencies: react: 19.2.6 scheduler: 0.27.0 - react-freeze@1.0.4(react@19.2.3): + react-dom@19.3.0(react@19.3.0): dependencies: - react: 19.2.3 + react: 19.3.0 + scheduler: 0.28.0 + + react-freeze@1.0.4(react@19.3.0): + dependencies: + react: 19.3.0 react-grab@0.1.44(react@19.2.6): dependencies: @@ -20627,19 +19809,17 @@ snapshots: optionalDependencies: react: 19.2.6 - react-is@16.13.1: {} - react-is@17.0.2: {} react-is@18.3.1: {} react-is@19.2.7: {} - react-markdown@10.1.0(@types/react@19.2.16)(react@19.2.6): + react-markdown@10.1.0(@types/react@19.3.0)(react@19.2.6): dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 - '@types/react': 19.2.16 + '@types/react': 19.3.0 devlop: 1.1.0 hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 @@ -20653,122 +19833,89 @@ snapshots: transitivePeerDependencies: - supports-color - react-native-gesture-handler@2.32.0(patch_hash=0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-gesture-handler@3.2.1(patch_hash=d518a937e3cb2df5e7d67f1ab6b265c74a8639e4572d1b032b7b747e9b1c01a9)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - '@egjs/hammerjs': 2.0.17 '@types/react-test-renderer': 19.1.0 - hoist-non-react-statics: 3.3.2 invariant: 2.2.4 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - react-native-image-viewing@0.2.2(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-image-viewing@0.2.2(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - react-native-is-edge-to-edge@1.3.1(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-is-edge-to-edge@1.3.1(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - ? react-native-keyboard-controller@1.21.13(patch_hash=6e4339347bc5bb3c9ea67d85ff5c814058b211c5750f247aba59d07869a2e787)(react-native-reanimated@4.5.5(patch_hash=bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d)(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - : dependencies: - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - react-native-is-edge-to-edge: 1.3.1(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - react-native-reanimated: 4.5.5(patch_hash=bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d)(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + react-native-keyboard-controller@1.22.4(patch_hash=a438114039aed2e280a81d95c25723132ad071e4768fe492bd92aa628ad74597)(react-native-reanimated@4.7.0(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): + dependencies: + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) + react-native-is-edge-to-edge: 1.3.1(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + react-native-reanimated: 4.7.0(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) - react-native-nitro-markdown@0.5.8(patch_hash=642b47830730acff3761fe29cf54271d18b493c0070c750097850b7ea032e00c)(react-native-nitro-modules@0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-nitro-markdown@0.5.8(patch_hash=642b47830730acff3761fe29cf54271d18b493c0070c750097850b7ea032e00c)(react-native-nitro-modules@0.35.9(patch_hash=daf4a639ce3f951af630a3711e4082d58e3a11e5a79f45efb0b59925327ebde2)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native-svg@15.15.5(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - react-native-nitro-modules: 0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) + react-native-nitro-modules: 0.35.9(patch_hash=daf4a639ce3f951af630a3711e4082d58e3a11e5a79f45efb0b59925327ebde2)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) optionalDependencies: - react-native-svg: 15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + react-native-svg: 15.15.5(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) - react-native-nitro-modules@0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-nitro-modules@0.35.9(patch_hash=daf4a639ce3f951af630a3711e4082d58e3a11e5a79f45efb0b59925327ebde2)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - react-native-reanimated@4.5.5(patch_hash=bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d)(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-reanimated@4.7.0(react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - react-native-is-edge-to-edge: 1.3.1(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - react-native-worklets: 0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) + react-native-is-edge-to-edge: 1.3.1(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) + react-native-worklets: 0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) semver: 7.8.5 - react-native-safe-area-context@5.7.0(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-safe-area-context@5.9.1(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - react-native-screens@4.26.2(patch_hash=595114f3f9ce8b9f0d99d1aafe5c12c997b7d75ca9add31d46cbedbfe347b8e0)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-screens@4.28.0(patch_hash=cc1301436ee62c39860acc9ee1a1e60b7d47e6abd211c42effa62c056d165483)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: - react: 19.2.3 - react-freeze: 1.0.4(react@19.2.3) - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-freeze: 1.0.4(react@19.3.0) + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) warn-once: 0.1.1 - react-native-shiki-engine@0.3.12(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-shiki-engine@0.3.12(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: '@shikijs/types': 4.3.0 '@shikijs/vscode-textmate': 10.0.2 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-svg@15.15.5(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: css-select: 5.2.2 css-tree: 1.1.3 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - warn-once: 0.1.1 + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - react-native-url-polyfill@4.0.0(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)): + react-native-url-polyfill@4.0.0(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6)): dependencies: - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - react-native-webview@13.16.1(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-webview@14.0.1(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: escape-string-regexp: 4.0.0 invariant: 2.2.4 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) - react-native-webview@13.16.1(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6): - dependencies: - escape-string-regexp: 4.0.0 - invariant: 2.2.4 - react: 19.2.6 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) - optional: true - - react-native-worklets@0.10.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6): - dependencies: - '@babel/core': 7.29.7 - '@babel/plugin-transform-arrow-functions': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-class-properties': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-classes': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-nullish-coalescing-operator': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-optional-chaining': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-shorthand-properties': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-template-literals': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-unicode-regex': 7.29.7(@babel/core@7.29.7) - '@babel/preset-typescript': 7.29.7(@babel/core@7.29.7) - '@babel/types': 7.29.8 - '@react-native/metro-config': 0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6) - convert-source-map: 2.0.0 - react: 19.2.6 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6) - semver: 7.8.5 - transitivePeerDependencies: - - supports-color - optional: true - - react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-worklets@0.13.0(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0): dependencies: '@babel/core': 7.29.7 '@babel/generator': 7.29.7 @@ -20782,89 +19929,43 @@ snapshots: '@babel/plugin-transform-unicode-regex': 7.29.7(@babel/core@7.29.7) '@babel/preset-typescript': 7.29.7(@babel/core@7.29.7) '@babel/traverse': 7.29.7 - '@babel/types': 7.29.7 - '@react-native/metro-config': 0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@babel/types': 7.29.8 + '@jridgewell/remapping': 2.3.5 + '@react-native/metro-config': 0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6) convert-source-map: 2.0.0 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) semver: 7.8.5 - transitivePeerDependencies: - - supports-color - - react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6): - dependencies: - '@react-native/assets-registry': 0.86.3 - '@react-native/codegen': 0.86.3(@babel/core@7.29.7) - '@react-native/community-cli-plugin': 0.86.3(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@react-native/gradle-plugin': 0.86.3 - '@react-native/js-polyfills': 0.86.3 - '@react-native/normalize-colors': 0.86.3 - '@react-native/virtualized-lists': 0.86.3(@types/react@19.2.16)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - abort-controller: 3.0.0 - anser: 1.4.10 - ansi-regex: 5.0.1 - babel-plugin-syntax-hermes-parser: 0.36.0 - base64-js: 1.5.1 - commander: 12.1.0 - flow-enums-runtime: 0.0.6 - hermes-compiler: 250829098.0.17 - invariant: 2.2.4 - memoize-one: 5.2.1 - metro-runtime: 0.84.4 - metro-source-map: 0.84.4 - nullthrows: 1.1.1 - pretty-format: 29.7.0 - promise: 8.3.0 - react: 19.2.3 - react-devtools-core: 6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - react-refresh: 0.14.2 - regenerator-runtime: 0.13.11 - scheduler: 0.27.0 - semver: 7.8.5 - stacktrace-parser: 0.1.11 - tinyglobby: 0.2.17 whatwg-fetch: 3.6.20 - ws: 7.5.11(bufferutil@4.1.0)(utf-8-validate@6.0.6) - yargs: 17.7.2 - optionalDependencies: - '@types/react': 19.2.16 transitivePeerDependencies: - - '@babel/core' - - '@react-native-community/cli' - - '@react-native/metro-config' - - bufferutil - supports-color - - utf-8-validate - react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6): + react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6): dependencies: - '@react-native/assets-registry': 0.86.3 - '@react-native/codegen': 0.86.3(@babel/core@7.29.7) - '@react-native/community-cli-plugin': 0.86.3(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@react-native/gradle-plugin': 0.86.3 - '@react-native/js-polyfills': 0.86.3 - '@react-native/normalize-colors': 0.86.3 - '@react-native/virtualized-lists': 0.86.3(@types/react@19.2.16)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.6)(utf-8-validate@6.0.6))(react@19.2.6) - abort-controller: 3.0.0 + '@react-native/asset-utils': 0.88.0-rc.3 + '@react-native/codegen': 0.88.0-rc.3(@babel/core@7.29.7) + '@react-native/community-cli-plugin': 0.88.0-rc.3(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@react-native/gradle-plugin': 0.88.0-rc.3 + '@react-native/normalize-colors': 0.88.0-rc.3 + '@react-native/virtualized-lists': 0.88.0-rc.3(@types/react@19.3.0)(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0) anser: 1.4.10 ansi-regex: 5.0.1 - babel-plugin-syntax-hermes-parser: 0.36.0 base64-js: 1.5.1 - commander: 12.1.0 flow-enums-runtime: 0.0.6 - hermes-compiler: 250829098.0.17 + flow-parser: 0.327.0 + hermes-compiler: 260318099.0.4 invariant: 2.2.4 memoize-one: 5.2.1 - metro-runtime: 0.84.4 - metro-source-map: 0.84.4 + metro-runtime: 0.87.1 + metro-source-map: 0.87.1 nullthrows: 1.1.1 pretty-format: 29.7.0 promise: 8.3.0 - react: 19.2.6 + react: 19.3.0 react-devtools-core: 6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) react-refresh: 0.14.2 regenerator-runtime: 0.13.11 - scheduler: 0.27.0 + scheduler: 0.28.0 semver: 7.8.5 stacktrace-parser: 0.1.11 tinyglobby: 0.2.17 @@ -20872,7 +19973,7 @@ snapshots: ws: 7.5.11(bufferutil@4.1.0)(utf-8-validate@6.0.6) yargs: 17.7.2 optionalDependencies: - '@types/react': 19.2.16 + '@types/react': 19.3.0 transitivePeerDependencies: - '@babel/core' - '@react-native-community/cli' @@ -20880,47 +19981,19 @@ snapshots: - bufferutil - supports-color - utf-8-validate - optional: true react-refresh@0.14.2: {} - react-remove-scroll-bar@2.3.8(@types/react@19.2.16)(react@19.2.3): - dependencies: - react: 19.2.3 - react-style-singleton: 2.2.3(@types/react@19.2.16)(react@19.2.3) - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.16 - - react-remove-scroll@2.7.2(@types/react@19.2.16)(react@19.2.3): - dependencies: - react: 19.2.3 - react-remove-scroll-bar: 2.3.8(@types/react@19.2.16)(react@19.2.3) - react-style-singleton: 2.2.3(@types/react@19.2.16)(react@19.2.3) - tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.2.16)(react@19.2.3) - use-sidecar: 1.1.3(@types/react@19.2.16)(react@19.2.3) - optionalDependencies: - '@types/react': 19.2.16 - - react-style-singleton@2.2.3(@types/react@19.2.16)(react@19.2.3): - dependencies: - get-nonce: 1.0.1 - react: 19.2.3 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.16 - react-test-renderer@19.2.6(react@19.2.6): dependencies: react: 19.2.6 react-is: 19.2.7 scheduler: 0.27.0 - react@19.2.3: {} - react@19.2.6: {} + react@19.3.0: {} + read-binary-file-arch@1.0.6: dependencies: debug: 4.4.3 @@ -21206,6 +20279,8 @@ snapshots: scheduler@0.27.0: {} + scheduler@0.28.0: {} + schema-utils@4.3.3: dependencies: '@types/json-schema': 7.0.15 @@ -21874,20 +20949,20 @@ snapshots: universalify@2.0.1: {} - uniwind@1.11.0(patch_hash=a91f3953483cfd434436de6358ff5b63c49974ef148fad91246c26ba95332625)(@expo/metro-config@57.0.12(patch_hash=96f1a75347e6ea02dc4b7034ace815d8ee39e18b8166ebfb573d9e58328f0dc2)(bufferutil@4.1.0)(expo@57.0.18)(typescript@7.0.2)(utf-8-validate@6.0.6))(metro-cache@0.84.5)(metro-transform-worker@0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6))(metro@0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(tailwindcss@4.3.3): + uniwind@1.11.0(patch_hash=a91f3953483cfd434436de6358ff5b63c49974ef148fad91246c26ba95332625)(@expo/metro-config@58.0.6(patch_hash=90fa980e8b6480631fb2fbb04559834e3c612db40c550cd828f11be297d8d760)(bufferutil@4.1.0)(expo@58.0.0)(typescript@7.0.2)(utf-8-validate@6.0.6))(metro-cache@0.87.1)(metro-transform-worker@0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(metro@0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6))(react@19.3.0)(tailwindcss@4.3.3): dependencies: '@tailwindcss/node': 4.3.3 '@tailwindcss/oxide': 4.3.3 culori: 4.0.2 lightningcss: 1.33.0 - metro: 0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - metro-cache: 0.84.5 - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + metro: 0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-cache: 0.87.1 + react: 19.3.0 + react-native: 0.88.0-rc.3(@babel/core@7.29.7)(@react-native/metro-config@0.88.0-rc.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(utf-8-validate@6.0.6) tailwindcss: 4.3.3 optionalDependencies: - '@expo/metro-config': 57.0.12(patch_hash=96f1a75347e6ea02dc4b7034ace815d8ee39e18b8166ebfb573d9e58328f0dc2)(bufferutil@4.1.0)(expo@57.0.18)(typescript@7.0.2)(utf-8-validate@6.0.6) - metro-transform-worker: 0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@expo/metro-config': 58.0.6(patch_hash=90fa980e8b6480631fb2fbb04559834e3c612db40c550cd828f11be297d8d760)(bufferutil@4.1.0)(expo@58.0.0)(typescript@7.0.2)(utf-8-validate@6.0.6) + metro-transform-worker: 0.87.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) unpipe@1.0.0: {} @@ -21939,33 +21014,18 @@ snapshots: punycode: 2.3.1 optional: true - use-callback-ref@1.3.3(@types/react@19.2.16)(react@19.2.3): + use-latest-callback@0.2.6(react@19.3.0): dependencies: - react: 19.2.3 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.16 - - use-latest-callback@0.2.6(react@19.2.3): - dependencies: - react: 19.2.3 - - use-sidecar@1.1.3(@types/react@19.2.16)(react@19.2.3): - dependencies: - detect-node-es: 1.1.0 - react: 19.2.3 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.16 - - use-sync-external-store@1.6.0(react@19.2.3): - dependencies: - react: 19.2.3 + react: 19.3.0 use-sync-external-store@1.6.0(react@19.2.6): dependencies: react: 19.2.6 + use-sync-external-store@1.6.0(react@19.3.0): + dependencies: + react: 19.3.0 + utf-8-validate@6.0.6: dependencies: node-gyp-build: 4.8.4 @@ -21988,15 +21048,6 @@ snapshots: vary@1.1.2: {} - vaul@1.1.2(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): - dependencies: - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.16))(@types/react@19.2.16)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - transitivePeerDependencies: - - '@types/react' - - '@types/react-dom' - vfile-location@5.0.3: dependencies: '@types/unist': 3.0.3 @@ -22235,7 +21286,7 @@ snapshots: whatwg-mimetype@5.0.0: {} - whatwg-url-minimum@0.1.2: {} + whatwg-url-minimum@0.2.0: {} whatwg-url@14.2.0: dependencies: @@ -22461,9 +21512,9 @@ snapshots: zod@4.6.5: {} - zustand@5.0.14(@types/react@19.2.16)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)): + zustand@5.0.14(@types/react@19.3.0)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)): optionalDependencies: - '@types/react': 19.2.16 + '@types/react': 19.3.0 react: 19.2.6 use-sync-external-store: 1.6.0(react@19.2.6) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 590d808e2da0a9848c017deb23fc8fe0568a52d4..9a887cb060453a540dabe02f6f079d4605372073 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -54,6 +54,9 @@ catalog: yaml: ^2.9.0 minimumReleaseAgeExclude: + - expo-glass-effect@58.0.3 + - expo-blur@58.0.2 + - expo-audio@58.0.3 - "@clerk/backend@3.18.1" - "@clerk/clerk-js@6.32.1" - "@clerk/electron@0.0.44" @@ -75,15 +78,40 @@ minimumReleaseAgeExclude: - alchemy@2.0.0-beta.79 - effect@4.0.0-rc.115 - "@legendapp/list@3.3.5" - - "@expo/cli@57.0.20" - - "@expo/env@2.4.3" - - "@expo/fingerprint@0.20.11" - - "@expo/metro-config@57.0.12" - - expo-constants@57.0.16 - - expo-font@57.0.2 - - expo-updates@57.0.19 - - expo@57.0.18 - - expo-widgets@57.0.15 + - "@expo/cli@58.0.9" + - "@expo/env@2.5.1" + - "@expo/fingerprint@0.21.2" + - "@expo/metro-config@58.0.6" + - expo-constants@58.0.9 + - expo-font@58.0.4 + - expo-updates@58.0.11 + - expo@58.0.0 + - expo-widgets@58.0.9 + - "@expo/config-plugins@58.0.4" + - "@expo/log-box@58.0.7" + - "@expo/metro-file-map@58.0.3" + - "@expo/metro-runtime@58.0.9" + - "@expo/metro@58.0.0-rc.0" + - "@expo/prebuild-config@58.0.6" + - "@expo/router-server@58.0.4" + - "@expo/ui@58.0.9" + - babel-preset-expo@58.0.6 + - expo-asset@58.0.9 + - expo-build-properties@58.0.9 + - expo-dev-client@58.0.9 + - expo-dev-launcher@58.0.9 + - expo-dev-menu@58.0.9 + - expo-image-manipulator@58.0.10 + - expo-image-picker@58.0.9 + - expo-image@58.0.8 + - expo-linking@58.0.9 + - expo-modules-autolinking@58.0.6 + - expo-modules-core@58.0.9 + - expo-modules-jsi@58.0.5 + - expo-notifications@58.0.9 + - expo-sharing@58.0.12 + - expo-sqlite@58.0.7 + - expo-symbols@58.0.3 - electron@44.4.2 - "@anthropic-ai/claude-agent-sdk@0.3.276" - "@alchemy.run/cloudflare-runtime@2.0.0-beta.79" @@ -96,6 +124,29 @@ minimumReleaseAgeExclude: - "@distilled.cloud/stripe@1.0.0-rc.12" - "@shadcn/lint@0.1.5" - cn@0.3.2 + - "@expo/dom-webview@58.0.2" + - "expo-auth-session@58.0.6" + - "expo-camera@58.0.5" + - "expo-clipboard@58.0.2" + - "expo-crypto@58.0.3" + - "expo-device@58.0.3" + - "expo-document-picker@58.0.3" + - "expo-file-system@58.0.4" + - "expo-haptics@58.0.3" + - "expo-keep-awake@58.0.2" + - "expo-network@58.0.2" + - "expo-secure-store@58.0.1" + - "expo-splash-screen@58.0.2" + - "expo-video@58.0.5" + - "expo-web-browser@58.0.3" + - "react@19.3.0" + - "react-dom@19.3.0" + - "react-native@0.88.0-rc.3" + - "react-native-keyboard-controller@1.22.4" + - "react-native-worklets@0.13.0" + - "react-native-reanimated@4.7.0" + - "react-native-screens@4.28.0" + - "@expo/config-types@58.0.2" overrides: # Keep jsdom's optional peer consistent so Vite+ has one test-runner instance. @@ -143,11 +194,12 @@ overrides: "@effect/sql-pg": "catalog:" "@effect/vitest": "catalog:" "@effect/vitest>vitest": "-" - "@expo/dom-webview": 57.0.1 - "@expo/metro-config": 57.0.12 - expo-constants: 57.0.16 - # Keep fresh resolution on the version carrying the permissions registry fix. - expo-modules-core: 57.0.14 + "@expo/dom-webview": 58.0.2 + "@expo/metro-config": 58.0.6 + expo-constants: 58.0.9 + expo-router: 58.0.10 + "expo-sharing>@expo/config-plugins": 58.0.4 + "expo-sharing>@expo/config-types": 58.0.2 "@pierre/diffs>@shikijs/transformers": ^4.2.0 # Keep one copy of these native-binary packages. lightningcss ships 11 platform binaries per # version, and the workspaces' tailwindcss ^4 ranges drift into two 4.3.x copies of the family. @@ -156,9 +208,6 @@ overrides: "@tailwindcss/vite": "catalog:" "@types/node": "catalog:" effect: "catalog:" - expo-router: 57.0.17 - "expo-sharing>@expo/config-plugins": 57.0.9 - "expo-sharing>@expo/config-types": 57.0.2 node-abi: 4.33.0 lightningcss: "catalog:" tailwindcss: "catalog:" @@ -168,7 +217,7 @@ overrides: packageExtensions: "@clerk/expo@*": dependencies: - "@expo/config-plugins": 57.0.9 + "@expo/config-plugins": 58.0.4 "@effect/vitest@*": dependencies: vite-plus: "catalog:" @@ -181,9 +230,14 @@ packageExtensions: patchedDependencies: alchemy@2.0.0-beta.79: patches/alchemy@2.0.0-beta.79.patch + expo-glass-effect@58.0.3: patches/expo-glass-effect@58.0.3.patch + expo-blur@58.0.2: patches/expo-blur@58.0.2.patch + expo-audio@58.0.3: patches/expo-audio@58.0.3.patch "@clerk/expo@4.6.8": patches/@clerk__expo@4.6.8.patch "@effect/vitest@4.0.0-rc.115": patches/@effect__vitest@4.0.0-rc.115.patch - "@expo/metro-config@57.0.12": patches/@expo__metro-config@57.0.12.patch + "@expo/metro-config@58.0.6": patches/@expo__metro-config@58.0.6.patch + expo-sharing@58.0.12: patches/expo-sharing@58.0.12.patch + expo-widgets@58.0.9: patches/expo-widgets@58.0.9.patch "@ff-labs/fff-node@0.9.4": patches/@ff-labs__fff-node@0.9.4.patch "@legendapp/list@3.3.5": patches/@legendapp__list@3.3.5.patch "@pierre/diffs@1.3.0-beta.10": patches/@pierre%2Fdiffs@1.3.0-beta.10.patch @@ -192,20 +246,13 @@ patchedDependencies: "@react-navigation/native-stack@7.17.6": patches/@react-navigation%2Fnative-stack@7.17.6.patch dbus-next@0.10.2: patches/dbus-next@0.10.2.patch effect@4.0.0-rc.115: patches/effect@4.0.0-rc.115.patch - expo-audio@57.0.4: patches/expo-audio@57.0.4.patch - expo-modules-core@57.0.14: patches/expo-modules-core@57.0.14.patch - expo-notifications@57.0.15: patches/expo-notifications@57.0.15.patch - expo-sharing@57.0.17: patches/expo-sharing@57.0.17.patch - expo-widgets@57.0.15: patches/expo-widgets@57.0.15.patch node-pty@1.2.0-beta.15: patches/node-pty@1.2.0-beta.15.patch - react-native-gesture-handler@2.32.0: patches/react-native-gesture-handler@2.32.0.patch - react-native-keyboard-controller@1.21.13: patches/react-native-keyboard-controller@1.21.13.patch - react-native-nitro-modules@0.35.9: patches/react-native-nitro-modules@0.35.9.patch # Link http(s) URLs with a port or a single-label host. md4c otherwise requires a dotted host and stops at ':'. react-native-nitro-markdown@0.5.8: patches/react-native-nitro-markdown@0.5.8.patch - # Preserve the final layout frame. Backport of [#10171](https://github.com/software-mansion/react-native-reanimated/pull/10171). - react-native-reanimated@4.5.5: patches/react-native-reanimated@4.5.5.patch - react-native-screens@4.26.2: patches/react-native-screens@4.26.2.patch + react-native-gesture-handler@3.2.1: patches/react-native-gesture-handler@3.2.1.patch + react-native-keyboard-controller@1.22.4: patches/react-native-keyboard-controller@1.22.4.patch + react-native-nitro-modules@0.35.9: patches/react-native-nitro-modules@0.35.9.patch + react-native-screens@4.28.0: patches/react-native-screens@4.28.0.patch uniwind@1.11.0: patches/uniwind@1.11.0.patch peerDependencyRules: diff --git a/third-party-licenses.config.json b/third-party-licenses.config.json index 5c7c35f13b4688e15c7cb3db9d42a3076b5b3284..aaa5413c3aceb2688804edcb07bfc041b7e684a5 100644 --- a/third-party-licenses.config.json +++ b/third-party-licenses.config.json @@ -473,6 +473,87 @@ "licenseId": "MIT", "copyrights": ["Copyright (c) 2025 opencode"] } + }, + { + "license": "MIT", + "name": "noxcturnal", + "sourceUrl": "https://github.com/expo/noxcturnal", + "generatedNotice": { + "licenseId": "MIT", + "copyrights": ["Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)"] + } + }, + { + "license": "MIT", + "name": "@noxcturnal/noxcturnal-linux-x64-gnu", + "sourceUrl": "https://github.com/expo/noxcturnal", + "generatedNotice": { + "licenseId": "MIT", + "copyrights": ["Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)"] + } + }, + { + "license": "MIT", + "name": "@noxcturnal/noxcturnal-darwin-x64", + "sourceUrl": "https://github.com/expo/noxcturnal", + "generatedNotice": { + "licenseId": "MIT", + "copyrights": ["Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)"] + } + }, + { + "license": "MIT", + "name": "@noxcturnal/noxcturnal-linux-arm64-gnu", + "sourceUrl": "https://github.com/expo/noxcturnal", + "generatedNotice": { + "licenseId": "MIT", + "copyrights": ["Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)"] + } + }, + { + "license": "MIT", + "name": "@noxcturnal/noxcturnal-darwin-arm64", + "sourceUrl": "https://github.com/expo/noxcturnal", + "generatedNotice": { + "licenseId": "MIT", + "copyrights": ["Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)"] + } + }, + { + "license": "MIT", + "name": "@noxcturnal/noxcturnal-linux-arm64-musl", + "sourceUrl": "https://github.com/expo/noxcturnal", + "generatedNotice": { + "licenseId": "MIT", + "copyrights": ["Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)"] + } + }, + { + "license": "MIT", + "name": "@noxcturnal/noxcturnal-linux-x64-musl", + "sourceUrl": "https://github.com/expo/noxcturnal", + "generatedNotice": { + "licenseId": "MIT", + "copyrights": ["Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)"] + } + }, + { + "license": "MIT", + "name": "@noxcturnal/noxcturnal-win32-arm64-msvc", + "sourceUrl": "https://github.com/expo/noxcturnal", + "generatedNotice": { + "licenseId": "MIT", + "copyrights": ["Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)"] + } + }, + { + "license": "MIT", + "name": "@noxcturnal/noxcturnal-win32-x64-msvc", + "sourceUrl": "https://github.com/expo/noxcturnal", + "generatedNotice": { + "licenseId": "MIT", + "copyrights": ["Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)"] + } } ] }