feat(mobile): build native in-app QR Stand Generator with theme switcher & A5 PDF / PNG exporter

This commit is contained in:
AyrisAI
2026-08-20 18:25:20 +03:00
parent bf44bf3e9d
commit 3a15dd15b9
3 changed files with 590 additions and 107 deletions
+4 -1
View File
@@ -25,7 +25,9 @@
"expo-haptics": "^14.0.1",
"expo-image-picker": "~16.0.6",
"expo-linking": "~7.0.5",
"expo-print": "^57.0.1",
"expo-router": "~4.0.0",
"expo-sharing": "^57.0.13",
"expo-splash-screen": "~0.29.24",
"expo-status-bar": "~2.0.0",
"react": "18.3.1",
@@ -33,7 +35,8 @@
"react-native-purchases": "^8.2.0",
"react-native-safe-area-context": "4.12.0",
"react-native-screens": "~4.4.0",
"react-native-url-polyfill": "^2.0.0"
"react-native-url-polyfill": "^2.0.0",
"react-native-view-shot": "^5.1.1"
},
"devDependencies": {
"@babel/core": "^7.25.2",
+401 -81
View File
@@ -1,10 +1,9 @@
import { useEffect, useState } from "react";
import { useEffect, useRef, useState } from "react";
import { router } from "expo-router";
import {
ActivityIndicator,
Alert,
Image,
Linking,
Pressable,
ScrollView,
Share,
@@ -13,6 +12,10 @@ import {
} from "react-native";
import { Ionicons } from "@expo/vector-icons";
import * as Clipboard from "expo-clipboard";
import ViewShot from "react-native-view-shot";
import * as Sharing from "expo-sharing";
import * as Print from "expo-print";
import { QR_STAND_PRESETS, type QrStandPreset } from "@menulio/shared";
import { api } from "@/lib/api";
import { getActiveRestaurant, type ActiveRestaurant } from "@/lib/active-restaurant";
@@ -25,10 +28,20 @@ interface QrResponse {
export default function QrScreen() {
const [active, setActive] = useState<ActiveRestaurant | null>(null);
const [restaurantName, setRestaurantName] = useState<string>("RESTORAN");
const [qr, setQr] = useState<QrResponse | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [copied, setCopied] = useState(false);
const [selectedKey, setSelectedKey] = useState<string>("urban");
const [categories, setCategories] = useState<string[]>([]);
const [exportingPng, setExportingPng] = useState(false);
const [exportingPdf, setExportingPdf] = useState(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const viewShotRef = useRef<any>(null);
const activePreset: QrStandPreset = (QR_STAND_PRESETS[selectedKey] || QR_STAND_PRESETS.urban)!;
useEffect(() => {
(async () => {
@@ -39,6 +52,28 @@ export default function QrScreen() {
try {
const data = await api.post<QrResponse>(`/restaurants/${activeRest.restaurantId}/qr`);
setQr(data);
// Fetch detailed restaurant name
try {
const restDetail = await api.get<{ name?: string }>(`/restaurants/${activeRest.restaurantId}`);
if (restDetail?.name) {
setRestaurantName(restDetail.name);
}
} catch {
// fallback
}
// Fetch categories for preview
if (activeRest.menuId) {
try {
const menuRes = await api.get<{ categories: { name: string }[] }>(`/menus/${activeRest.menuId}`);
if (menuRes?.categories?.length) {
setCategories(menuRes.categories.map((c) => c.name));
}
} catch {
// ignore fallback
}
}
} catch (err) {
setError(err instanceof Error ? err.message : "QR oluşturulamadı");
} finally {
@@ -47,6 +82,8 @@ export default function QrScreen() {
})();
}, []);
const displayCategories = categories.length > 0 ? categories.slice(0, 4) : activePreset.categories;
async function handleCopy() {
if (!qr?.targetUrl) return;
await Clipboard.setStringAsync(qr.targetUrl);
@@ -54,7 +91,7 @@ export default function QrScreen() {
setTimeout(() => setCopied(false), 2000);
}
async function handleShare() {
async function handleShareQuick() {
if (!qr?.targetUrl) return;
await Share.share({
title: "Dijital QR Menü",
@@ -63,11 +100,124 @@ export default function QrScreen() {
});
}
async function handleExportPng() {
if (!viewShotRef.current) return;
setExportingPng(true);
try {
const uri = await viewShotRef.current.capture?.();
if (uri) {
await Sharing.shareAsync(uri, {
mimeType: "image/png",
dialogTitle: "Masa Stant QR Görselini Paylaş / Kaydet",
});
}
} catch {
Alert.alert("Hata", "Görsel oluşturulamadı.");
} finally {
setExportingPng(false);
}
}
async function handleExportPdf() {
if (!qr || !active) return;
setExportingPdf(true);
try {
const restTitle = restaurantName.toUpperCase();
const qrImageUri = `data:image/png;base64,${qr.pngBase64}`;
const catsHtml = displayCategories
.map(
(c, i) =>
`<div style="padding: 4px 0;">${c}</div>${
i < displayCategories.length - 1
? '<div style="height: 1px; background: ' + activePreset.dividerColor + '; margin: 2px 0;"></div>'
: ""
}`,
)
.join("");
const htmlContent = `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<style>
@page { size: A5 portrait; margin: 0; }
body {
margin: 0; padding: 0; width: 148mm; height: 210mm;
box-sizing: border-box;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
background: ${activePreset.bgGradient};
display: flex; align-items: center; justify-content: center;
-webkit-print-color-adjust: exact;
}
.plaque {
width: 120mm; height: 180mm;
background: ${activePreset.plaqueBg};
border: 3px solid ${activePreset.borderAccent};
border-radius: 24px;
padding: 20px; box-sizing: border-box;
display: flex; flex-direction: column; align-items: center; text-align: center;
color: ${activePreset.headerText};
position: relative;
}
.badge {
border: 2px solid ${activePreset.logoBorder};
background: ${activePreset.logoBg};
color: ${activePreset.accentText};
padding: 6px 16px; border-radius: 12px;
font-weight: 900; font-size: 16px; letter-spacing: 2px;
margin-bottom: 12px;
}
.title {
font-size: 20px; font-weight: 900; letter-spacing: 1px;
line-height: 1.1; margin-bottom: 16px;
}
.qr-box {
background: ${activePreset.qrBg};
padding: 14px; border-radius: 20px;
display: inline-block; margin-bottom: 16px;
}
.qr-img { width: 150px; height: 150px; display: block; }
.sub { font-size: 11px; opacity: 0.8; margin-bottom: 12px; color: ${activePreset.subText}; }
.cats { font-size: 13px; font-weight: 800; letter-spacing: 2px; width: 80%; margin: 0 auto; }
</style>
</head>
<body>
<div class="plaque">
<div class="badge">${restTitle}</div>
<div class="title">DİJİTAL MENÜ<br><span style="letter-spacing:2px;">KAMERANIZLA TARATIN</span></div>
<div class="qr-box">
<img class="qr-img" src="${qrImageUri}" />
</div>
<div class="sub">Telefonunuzun kamerasını doğrultun</div>
<div class="cats">${catsHtml}</div>
</div>
</body>
</html>
`;
const { uri } = await Print.printToFileAsync({
html: htmlContent,
width: 420,
height: 595,
});
await Sharing.shareAsync(uri, {
mimeType: "application/pdf",
dialogTitle: "A5 Baskıya Hazır PDF İndir / Paylaş",
});
} catch {
Alert.alert("Hata", "PDF oluşturulamadı.");
} finally {
setExportingPdf(false);
}
}
if (loading) {
return (
<View style={{ flex: 1, backgroundColor: "#FAF8F5", alignItems: "center", justifyContent: "center" }}>
<ActivityIndicator size="large" color="#C8A96B" />
<Text style={{ marginTop: 12, color: "#78716C", fontSize: 14 }}>QR Kod Hazırlanıyor...</Text>
<Text style={{ marginTop: 12, color: "#78716C", fontSize: 14 }}>QR Kod ve Şablonlar Hazırlanıyor...</Text>
</View>
);
}
@@ -89,25 +239,18 @@ export default function QrScreen() {
);
}
function handleOpenStandGenerator() {
if (!active?.slug) return;
const standUrl = `https://menul.io/qr/${active.slug}`;
Linking.openURL(standUrl).catch(() => {
Alert.alert("Bilgi", `Stant Jeneratörü adresi: ${standUrl}`);
});
}
return (
<ScrollView contentContainerStyle={{ flexGrow: 1, backgroundColor: "#FAF8F5", padding: 24, justifyContent: "center" }}>
<View style={{ maxWidth: 440, width: "100%", alignSelf: "center", alignItems: "center" }}>
<ScrollView contentContainerStyle={{ flexGrow: 1, backgroundColor: "#FAF8F5", paddingVertical: 20 }}>
<View style={{ width: "100%", maxWidth: 440, alignSelf: "center", paddingHorizontal: 20 }}>
{/* Header Badge */}
<View
style={{
alignSelf: "center",
backgroundColor: "#F3EDE2",
paddingHorizontal: 14,
paddingVertical: 6,
borderRadius: 99,
marginBottom: 16,
marginBottom: 12,
flexDirection: "row",
alignItems: "center",
gap: 6,
@@ -115,62 +258,208 @@ export default function QrScreen() {
>
<Ionicons name="qr-code-outline" size={15} color="#926E27" />
<Text style={{ color: "#926E27", fontSize: 12, fontWeight: "700" }}>
DİJİTAL RESTORAN QR KODU
MASA QR STANT JENERATÖRÜ
</Text>
</View>
<Text style={{ fontSize: 26, fontWeight: "800", color: "#1C1917", marginBottom: 6, textAlign: "center" }}>
Masanıza Özel QR Kod
<Text style={{ fontSize: 24, fontWeight: "800", color: "#1C1917", marginBottom: 4, textAlign: "center" }}>
Masa Stant Tasarımları
</Text>
<Text style={{ fontSize: 14, color: "#78716C", textAlign: "center", marginBottom: 28, lineHeight: 20 }}>
Müşterileriniz bu QR kodu telefon kameralarıyla taratarak saniyeler içinde menünüzü inceleyebilir.
<Text style={{ fontSize: 13, color: "#78716C", textAlign: "center", marginBottom: 20, lineHeight: 18 }}>
Şablon seçin; QR kodunuz otomatik yerleşsin. Baskıya hazır A5 PDF veya PNG olarak indirin.
</Text>
{/* QR Code Container Card */}
{/* Horizontal Theme Selector */}
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={{ gap: 10, paddingHorizontal: 4, marginBottom: 20 }}
>
{Object.values(QR_STAND_PRESETS).map((preset) => {
const isSelected = preset.key === selectedKey;
return (
<Pressable
key={preset.key}
onPress={() => setSelectedKey(preset.key)}
style={{
backgroundColor: isSelected ? "#1C1917" : "#FFFFFF",
borderWidth: 1.5,
borderColor: isSelected ? "#1C1917" : "#E7E5E4",
borderRadius: 14,
paddingHorizontal: 16,
paddingVertical: 10,
flexDirection: "row",
alignItems: "center",
gap: 8,
}}
>
<View
style={{
backgroundColor: "#FFFFFF",
width: 14,
height: 14,
borderRadius: 7,
backgroundColor: preset.qrColor,
borderWidth: 1,
borderColor: "rgba(255,255,255,0.4)",
}}
/>
<Text
style={{
fontSize: 13,
fontWeight: "700",
color: isSelected ? "#FFFFFF" : "#1C1917",
}}
>
{preset.name}
</Text>
</Pressable>
);
})}
</ScrollView>
{/* Live Stand Preview Wrapped in ViewShot */}
<View
style={{
alignItems: "center",
justifyContent: "center",
padding: 16,
borderRadius: 24,
backgroundColor: "#18181B",
marginBottom: 20,
shadowColor: "#000",
shadowOffset: { width: 0, height: 6 },
shadowOpacity: 0.15,
shadowRadius: 16,
elevation: 6,
}}
>
<ViewShot ref={viewShotRef} options={{ format: "png", quality: 1.0 }}>
<View
style={{
width: 300,
minHeight: 480,
borderRadius: 28,
padding: 24,
alignItems: "center",
backgroundColor: activePreset.qrColor === "#ffffff" ? "#18181b" : activePreset.qrColor,
borderWidth: 2,
borderColor: activePreset.borderAccent,
position: "relative",
}}
>
{/* Top Restaurant Badge */}
<View
style={{
borderWidth: 1.5,
borderColor: activePreset.logoBorder,
backgroundColor: activePreset.logoBg,
paddingHorizontal: 14,
paddingVertical: 6,
borderRadius: 10,
marginBottom: 14,
alignItems: "center",
}}
>
<Text
style={{
color: activePreset.accentText,
fontSize: 15,
fontWeight: "900",
letterSpacing: 1,
textAlign: "center",
}}
>
{restaurantName.toUpperCase()}
</Text>
</View>
{/* Title Callout */}
<Text
style={{
color: activePreset.headerText,
fontSize: 18,
fontWeight: "900",
textAlign: "center",
lineHeight: 22,
marginBottom: 16,
}}
>
DİJİTAL MENÜ{"\n"}
<Text style={{ letterSpacing: 1 }}>KAMERANIZLA TARATIN</Text>
</Text>
{/* Auto Placed QR Code Container */}
<View
style={{
backgroundColor: activePreset.qrBg,
padding: 12,
borderRadius: 20,
marginBottom: 14,
shadowColor: "#000",
shadowOffset: { width: 0, height: 8 },
shadowOpacity: 0.08,
shadowRadius: 24,
elevation: 8,
borderWidth: 1,
borderColor: "rgba(200, 169, 107, 0.25)",
marginBottom: 24,
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.15,
shadowRadius: 8,
elevation: 4,
}}
>
<Image
source={{ uri: `data:image/png;base64,${qr.pngBase64}` }}
style={{ width: 220, height: 220, borderRadius: 12 }}
style={{ width: 170, height: 170, borderRadius: 8 }}
resizeMode="contain"
/>
</View>
<View
{/* Instructional Subtext */}
<Text
style={{
marginTop: 16,
paddingVertical: 6,
paddingHorizontal: 14,
backgroundColor: "#FAF8F5",
borderRadius: 8,
borderWidth: 1,
borderColor: "#E7E5E4",
color: activePreset.subText,
fontSize: 11,
fontWeight: "600",
marginBottom: 14,
textAlign: "center",
}}
>
<Text style={{ fontSize: 13, fontWeight: "600", color: "#1C1917" }}>
{qr.targetUrl}
Telefonunuzun kamerasını doğrultun
</Text>
{/* Category Quick Preview List */}
<View style={{ width: "85%", alignItems: "center", gap: 3 }}>
{displayCategories.map((cat, idx) => (
<View key={idx} style={{ width: "100%", alignItems: "center" }}>
<Text
style={{
color: activePreset.headerText,
fontSize: 12,
fontWeight: "800",
letterSpacing: 1.5,
textTransform: "uppercase",
}}
>
{cat}
</Text>
{idx < displayCategories.length - 1 && (
<View
style={{
width: "100%",
height: 1,
backgroundColor: activePreset.dividerColor,
marginVertical: 2,
}}
/>
)}
</View>
))}
</View>
</View>
</ViewShot>
</View>
{/* Action Buttons */}
<View style={{ width: "100%", gap: 12 }}>
{/* Stand Generator PDF / PNG Button */}
{/* Output Action Buttons */}
<View style={{ width: "100%", gap: 10 }}>
{/* PDF Download Button */}
<Pressable
onPress={handleOpenStandGenerator}
onPress={handleExportPdf}
disabled={exportingPdf}
style={({ pressed }) => ({
backgroundColor: "#C8A96B",
borderRadius: 14,
@@ -178,8 +467,8 @@ export default function QrScreen() {
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
gap: 10,
opacity: pressed ? 0.9 : 1,
gap: 8,
opacity: pressed || exportingPdf ? 0.85 : 1,
shadowColor: "#C8A96B",
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.2,
@@ -187,64 +476,95 @@ export default function QrScreen() {
elevation: 4,
})}
>
<Ionicons name="color-palette-outline" size={18} color="#FFFFFF" />
{exportingPdf ? (
<ActivityIndicator color="#FFFFFF" />
) : (
<>
<Ionicons name="document-text-outline" size={18} color="#FFFFFF" />
<Text style={{ color: "#FFFFFF", fontSize: 15, fontWeight: "800" }}>
Masa Stant Tasarımları & İndir (PDF / PNG)
A5 Baskı PDF Dosyası İndir / Paylaş
</Text>
</>
)}
</Pressable>
{/* Share Button */}
{/* PNG Export Button */}
<Pressable
onPress={handleShare}
onPress={handleExportPng}
disabled={exportingPng}
style={({ pressed }) => ({
backgroundColor: "#1C1917",
borderRadius: 14,
padding: 16,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
gap: 10,
opacity: pressed ? 0.9 : 1,
shadowColor: "#000",
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.1,
shadowRadius: 10,
elevation: 4,
})}
>
<Ionicons name="share-social-outline" size={18} color="#FFFFFF" />
<Text style={{ color: "#FFFFFF", fontSize: 15, fontWeight: "700" }}>
QR Kodu ve Linki Paylaş
</Text>
</Pressable>
{/* Copy Link Button */}
<Pressable
onPress={handleCopy}
style={({ pressed }) => ({
backgroundColor: "#FFFFFF",
borderWidth: 1.5,
borderColor: "#E7E5E4",
borderRadius: 14,
padding: 15,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
gap: 8,
opacity: pressed || exportingPng ? 0.85 : 1,
})}
>
{exportingPng ? (
<ActivityIndicator color="#FFFFFF" />
) : (
<>
<Ionicons name="image-outline" size={18} color="#FFFFFF" />
<Text style={{ color: "#FFFFFF", fontSize: 15, fontWeight: "700" }}>
PNG Görsel Olarak Kaydet / Paylaş
</Text>
</>
)}
</Pressable>
{/* Secondary Quick Share & Copy */}
<View style={{ flexDirection: "row", gap: 10, marginTop: 4 }}>
<Pressable
onPress={handleShareQuick}
style={({ pressed }) => ({
flex: 1,
backgroundColor: "#FFFFFF",
borderWidth: 1,
borderColor: "#E7E5E4",
borderRadius: 12,
padding: 12,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
gap: 6,
opacity: pressed ? 0.85 : 1,
})}
>
<Ionicons name="share-social-outline" size={16} color="#1C1917" />
<Text style={{ color: "#1C1917", fontSize: 13, fontWeight: "600" }}>Linki Paylaş</Text>
</Pressable>
<Pressable
onPress={handleCopy}
style={({ pressed }) => ({
flex: 1,
backgroundColor: "#FFFFFF",
borderWidth: 1,
borderColor: "#E7E5E4",
borderRadius: 12,
padding: 12,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
gap: 6,
opacity: pressed ? 0.85 : 1,
})}
>
<Ionicons
name={copied ? "checkmark-circle-outline" : "copy-outline"}
size={18}
size={16}
color={copied ? "#10B981" : "#1C1917"}
/>
<Text style={{ color: copied ? "#10B981" : "#1C1917", fontSize: 14, fontWeight: "600" }}>
{copied ? "Link Kopyalandı!" : "Menü Linkini Kopyala"}
<Text style={{ color: copied ? "#10B981" : "#1C1917", fontSize: 13, fontWeight: "600" }}>
{copied ? "Kopyalandı!" : "Linki Kopyala"}
</Text>
</Pressable>
</View>
{/* Back to Menu Editor */}
{/* Back button */}
<Pressable
onPress={() => router.back()}
style={{ padding: 12, alignItems: "center", flexDirection: "row", justifyContent: "center", gap: 6 }}
+166 -6
View File
@@ -89,9 +89,15 @@ importers:
expo-linking:
specifier: ~7.0.5
version: 7.0.5(expo@52.0.49(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@expo/metro-runtime@4.0.1(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1)))(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))(react@18.3.1)(supports-color@8.1.1))(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))(react@18.3.1)(supports-color@8.1.1)
expo-print:
specifier: ^57.0.1
version: 57.0.1(expo@52.0.49(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@expo/metro-runtime@4.0.1(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1)))(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))(react@18.3.1)(supports-color@8.1.1))(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))
expo-router:
specifier: ~4.0.0
version: 4.0.22(1482d1318244a89f06fcfc2b6da7d585)
expo-sharing:
specifier: ^57.0.13
version: 57.0.13(expo@52.0.49(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@expo/metro-runtime@4.0.1(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1)))(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))(react@18.3.1)(supports-color@8.1.1))(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.9.3)
expo-splash-screen:
specifier: ~0.29.24
version: 0.29.24(expo@52.0.49(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@expo/metro-runtime@4.0.1(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1)))(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))(react@18.3.1)(supports-color@8.1.1))(supports-color@8.1.1)
@@ -116,6 +122,9 @@ importers:
react-native-url-polyfill:
specifier: ^2.0.0
version: 2.0.0(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))
react-native-view-shot:
specifier: ^5.1.1
version: 5.1.1(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))(react@18.3.1)
devDependencies:
'@babel/core':
specifier: ^7.25.2
@@ -1262,12 +1271,18 @@ packages:
'@expo/code-signing-certificates@0.0.6':
resolution: {integrity: sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w==}
'@expo/config-plugins@57.0.8':
resolution: {integrity: sha512-x6lx4s/19i39/+1dMPwb9tFCc4WR843dG5Yi+C64lhKL3YHX+6oKrT2Kv72PCEalnUY+usQDkB3NrLSrYOWtDg==}
'@expo/config-plugins@9.0.17':
resolution: {integrity: sha512-m24F1COquwOm7PBl5wRbkT9P9DviCXe0D7S7nQsolfbhdCWuvMkfXeoWmgjtdhy7sDlOyIgBrAdnB6MfsWKqIg==}
'@expo/config-types@52.0.5':
resolution: {integrity: sha512-AMDeuDLHXXqd8W+0zSjIt7f37vUd/BP8p43k68NHpyAvQO+z8mbQZm3cNQVAMySeayK2XoPigAFB1JF2NFajaA==}
'@expo/config-types@57.0.2':
resolution: {integrity: sha512-ewW08OonrcRIsRKIlFvvcmmafE5zemb1ocu3HkNwtVPyRtj2w42pZCAkMIROYpcVBaPnc3mDT9UZDzwXWC3i6g==}
'@expo/config@10.0.11':
resolution: {integrity: sha512-nociJ4zr/NmbVfMNe9j/+zRlt7wz/siISu7PjdWE4WE+elEGxWWxsGzltdJG0llzrM+khx8qUiFK5aiVcdMBww==}
@@ -1311,9 +1326,20 @@ packages:
'@expo/plist@0.2.2':
resolution: {integrity: sha512-ZZGvTO6vEWq02UAPs3LIdja+HRO18+LRI5QuDl6Hs3Ps7KX7xU6Y6kjahWKY37Rx2YjNpX07dGpBFzzC+vKa2g==}
'@expo/plist@0.8.1':
resolution: {integrity: sha512-3gTReGIUm0oRaMClsAJYxBnVPCl6fVpsl8HS+DTVxDhW4GyVyxg9E/Znm3BvcHtUJ51RJJI14pC1wvrNilCRHw==}
'@expo/prebuild-config@8.2.0':
resolution: {integrity: sha512-CxiPpd980s0jyxi7eyN3i/7YKu3XL+8qPjBZUCYtc0+axpGweqIkq2CslyLSKHyqVyH/zlPkbVgWdyiYavFS5Q==}
'@expo/require-utils@57.0.4':
resolution: {integrity: sha512-e7xbg/9BTQcsZE/oErafZXtI7kh5IgfasLJ97J5sFSzX2cA74pDvdlhW1KHVSaDkQyQv6h1LSLhsY7dEeOk7hw==}
peerDependencies:
typescript: ^5.0.0 || ^5.0.0-0 || ^6.0.0 || ^7.0.0
peerDependenciesMeta:
typescript:
optional: true
'@expo/rudder-sdk-node@1.1.1':
resolution: {integrity: sha512-uy/hS/awclDJ1S88w9UGpc6Nm9XnNUjzOAAib1A3PVAnGQIwebg8DpFqOthFBTlZxeuV/BKbZ5jmTbtNZkp1WQ==}
engines: {node: '>=12'}
@@ -2055,6 +2081,10 @@ packages:
engines: {node: '>=10.0.0'}
deprecated: this version has critical issues, please update to the latest version
'@xmldom/xmldom@0.8.14':
resolution: {integrity: sha512-T4EDRUBVZYRldYApjEJiU0e1stYWaRAX7CuSnKzrpwdZKo53zGV8/pqfzV6FfwNl9YThD2OumQYvqtvjvgG7aQ==}
engines: {node: '>=10.0.0'}
'@xmldom/xmldom@0.9.11':
resolution: {integrity: sha512-tW8bcK3hsG0/uqSnNz6TK4BkcuZSezoU7DlnYssILmZDktPnSHHuDJJFM0AJv+13gz2r0iGdrj6qqKeUnxXEDg==}
engines: {node: '>=14.6'}
@@ -2265,6 +2295,10 @@ packages:
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
balanced-match@4.0.4:
resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
engines: {node: 18 || 20 || >=22}
base64-arraybuffer@1.0.2:
resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==}
engines: {node: '>= 0.6.0'}
@@ -2309,6 +2343,10 @@ packages:
brace-expansion@2.1.4:
resolution: {integrity: sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==}
brace-expansion@5.0.9:
resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==}
engines: {node: 20 || >=22}
braces@3.0.3:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
engines: {node: '>=8'}
@@ -2856,6 +2894,12 @@ packages:
expo-modules-core@2.2.3:
resolution: {integrity: sha512-01QqZzpP/wWlxnNly4G06MsOBUTbMDj02DQigZoXfDh80vd/rk3/uVXqnZgOdLSggTs6DnvOgAUy0H2q30XdUg==}
expo-print@57.0.1:
resolution: {integrity: sha512-cEfxM+sV5suZyqbXsOmDGRHD+UmfAh2GWabbakdkl1s70L4MFiObPtC73ATXNjeUe+mlzxLhudoTxsuyJxk8Mg==}
peerDependencies:
expo: '*'
react-native: '*'
expo-router@4.0.22:
resolution: {integrity: sha512-cbl6pWUMMZl5sZaHSMmxhQi+kTC6Yzj0ATaD2j6MiLF6VQyr5IcWes3V0UxPtI08boTX0i+76/fnP5fZ3eGQYQ==}
peerDependencies:
@@ -2875,6 +2919,13 @@ packages:
react-native-reanimated:
optional: true
expo-sharing@57.0.13:
resolution: {integrity: sha512-8kRUBikuR+c90++PF4PaP8pj+McUNi7AIZkwmn0iXcA8QobkJDSAjSB3fP8qoFm8bzHDhyibHIlODTAsxrMYMw==}
peerDependencies:
expo: '*'
react: '*'
react-native: '*'
expo-splash-screen@0.29.24:
resolution: {integrity: sha512-k2rdjbb3Qeg4g104Sdz6+qXXYba8QgiuZRSxHX8IpsSYiiTU48BmCCGy12sN+O1B+sD1/+WPL4duCa1Fy6+Y4g==}
peerDependencies:
@@ -3101,6 +3152,10 @@ packages:
resolution: {integrity: sha512-7yetJWqbS9sbn0vIfliPsFgoXMKn/YMF+Wuiog97x+urnSRRRZ7xB+uVkwGKzRgq9CDFfMQnE9ruL5DHv9c6Xg==}
engines: {node: '>=6'}
getenv@2.0.0:
resolution: {integrity: sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==}
engines: {node: '>=6'}
glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@@ -3114,6 +3169,10 @@ packages:
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
hasBin: true
glob@13.0.6:
resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==}
engines: {node: 18 || 20 || >=22}
glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
@@ -3555,6 +3614,10 @@ packages:
lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
lru-cache@11.5.2:
resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==}
engines: {node: 20 || >=22}
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
@@ -3684,6 +3747,10 @@ packages:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
minimatch@10.2.6:
resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==}
engines: {node: 18 || 20 || >=22}
minimatch@3.1.5:
resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
@@ -3963,6 +4030,10 @@ packages:
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
engines: {node: '>=16 || 14 >=14.18'}
path-scurry@2.0.2:
resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==}
engines: {node: 18 || 20 || >=22}
path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
@@ -4226,6 +4297,13 @@ packages:
peerDependencies:
react-native: '*'
react-native-view-shot@5.1.1:
resolution: {integrity: sha512-jOTLQrMGNBgv/nRA81VR2x2AdiCGoCjc63c9a5P4A0gStCbh9oDeJ6W+GtRxxQmxXXf6LDSrvG+mmWYulIrOkg==}
engines: {node: '>=20.19.4', npm: '>=10'}
peerDependencies:
react: '>=18.0.0'
react-native: '>=0.76.0'
react-native@0.76.9:
resolution: {integrity: sha512-+LRwecWmTDco7OweGsrECIqJu0iyrREd6CTCgC/uLLYipiHvk+MH9nd6drFtCw/6Blz6eoKTcH9YTTJusNtrWg==}
engines: {node: '>=18'}
@@ -6224,6 +6302,25 @@ snapshots:
dependencies:
node-forge: 1.4.0
'@expo/config-plugins@57.0.8(supports-color@8.1.1)(typescript@5.9.3)':
dependencies:
'@expo/config-types': 57.0.2
'@expo/json-file': 11.0.1
'@expo/plist': 0.8.1
'@expo/require-utils': 57.0.4(supports-color@8.1.1)(typescript@5.9.3)
'@expo/sdk-runtime-versions': 1.0.0
chalk: 4.1.2
debug: 4.4.3(supports-color@8.1.1)
getenv: 2.0.0
glob: 13.0.6
semver: 7.8.5
slugify: 1.6.9
xcode: 3.0.1
xml2js: 0.6.0
transitivePeerDependencies:
- supports-color
- typescript
'@expo/config-plugins@9.0.17(supports-color@8.1.1)':
dependencies:
'@expo/config-types': 52.0.5
@@ -6245,6 +6342,8 @@ snapshots:
'@expo/config-types@52.0.5': {}
'@expo/config-types@57.0.2': {}
'@expo/config@10.0.11(supports-color@8.1.1)':
dependencies:
'@babel/code-frame': 7.10.4
@@ -6370,6 +6469,12 @@ snapshots:
base64-js: 1.5.1
xmlbuilder: 14.0.0
'@expo/plist@0.8.1':
dependencies:
'@xmldom/xmldom': 0.8.14
base64-js: 1.5.1
xmlbuilder: 15.1.1
'@expo/prebuild-config@8.2.0(supports-color@8.1.1)':
dependencies:
'@expo/config': 10.0.11(supports-color@8.1.1)
@@ -6386,6 +6491,16 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@expo/require-utils@57.0.4(supports-color@8.1.1)(typescript@5.9.3)':
dependencies:
'@babel/code-frame': 7.29.7
'@babel/core': 7.29.7(supports-color@8.1.1)
'@babel/plugin-transform-modules-commonjs': 7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1)
optionalDependencies:
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@expo/rudder-sdk-node@1.1.1':
dependencies:
'@expo/bunyan': 4.0.1
@@ -7145,6 +7260,8 @@ snapshots:
'@xmldom/xmldom@0.7.13': {}
'@xmldom/xmldom@0.8.14': {}
'@xmldom/xmldom@0.9.11': {}
abort-controller@3.0.0:
@@ -7379,8 +7496,9 @@ snapshots:
balanced-match@1.0.2: {}
base64-arraybuffer@1.0.2:
optional: true
balanced-match@4.0.4: {}
base64-arraybuffer@1.0.2: {}
base64-js@1.5.1: {}
@@ -7419,6 +7537,10 @@ snapshots:
dependencies:
balanced-match: 1.0.2
brace-expansion@5.0.9:
dependencies:
balanced-match: 4.0.4
braces@3.0.3:
dependencies:
fill-range: 7.1.1
@@ -7709,7 +7831,6 @@ snapshots:
css-line-break@2.1.0:
dependencies:
utrie: 1.0.2
optional: true
cssesc@3.0.0: {}
@@ -8028,6 +8149,11 @@ snapshots:
dependencies:
invariant: 2.2.4
expo-print@57.0.1(expo@52.0.49(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@expo/metro-runtime@4.0.1(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1)))(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))(react@18.3.1)(supports-color@8.1.1))(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1)):
dependencies:
expo: 52.0.49(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@expo/metro-runtime@4.0.1(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1)))(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))(react@18.3.1)(supports-color@8.1.1)
react-native: 0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1)
expo-router@4.0.22(1482d1318244a89f06fcfc2b6da7d585):
dependencies:
'@expo/metro-runtime': 4.0.1(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))
@@ -8055,6 +8181,18 @@ snapshots:
- react-native
- supports-color
expo-sharing@57.0.13(expo@52.0.49(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@expo/metro-runtime@4.0.1(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1)))(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))(react@18.3.1)(supports-color@8.1.1))(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.9.3):
dependencies:
'@expo/config-plugins': 57.0.8(supports-color@8.1.1)(typescript@5.9.3)
'@expo/config-types': 57.0.2
'@expo/plist': 0.8.1
expo: 52.0.49(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@expo/metro-runtime@4.0.1(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1)))(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))(react@18.3.1)(supports-color@8.1.1)
react: 18.3.1
react-native: 0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1)
transitivePeerDependencies:
- supports-color
- typescript
expo-splash-screen@0.29.24(expo@52.0.49(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@expo/metro-runtime@4.0.1(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1)))(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))(react@18.3.1)(supports-color@8.1.1))(supports-color@8.1.1):
dependencies:
'@expo/prebuild-config': 8.2.0(supports-color@8.1.1)
@@ -8343,6 +8481,8 @@ snapshots:
getenv@1.0.0: {}
getenv@2.0.0: {}
glob-parent@5.1.2:
dependencies:
is-glob: 4.0.3
@@ -8360,6 +8500,12 @@ snapshots:
package-json-from-dist: 1.0.1
path-scurry: 1.11.1
glob@13.0.6:
dependencies:
minimatch: 10.2.6
minipass: 7.1.3
path-scurry: 2.0.2
glob@7.2.3:
dependencies:
fs.realpath: 1.0.0
@@ -8418,7 +8564,6 @@ snapshots:
dependencies:
css-line-break: 2.1.0
text-segmentation: 1.0.3
optional: true
http-errors@2.0.1:
dependencies:
@@ -8793,6 +8938,8 @@ snapshots:
lru-cache@10.4.3: {}
lru-cache@11.5.2: {}
lru-cache@5.1.1:
dependencies:
yallist: 3.1.1
@@ -9025,6 +9172,10 @@ snapshots:
mimic-fn@2.1.0: {}
minimatch@10.2.6:
dependencies:
brace-expansion: 5.0.9
minimatch@3.1.5:
dependencies:
brace-expansion: 1.1.18
@@ -9269,6 +9420,11 @@ snapshots:
lru-cache: 10.4.3
minipass: 7.1.3
path-scurry@2.0.2:
dependencies:
lru-cache: 11.5.2
minipass: 7.1.3
path-type@4.0.0: {}
pathe@2.0.3: {}
@@ -9528,6 +9684,12 @@ snapshots:
react-native: 0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1)
whatwg-url-without-unicode: 8.0.0-3
react-native-view-shot@5.1.1(react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1))(react@18.3.1):
dependencies:
html2canvas: 1.4.1
react: 18.3.1
react-native: 0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1)
react-native@0.76.9(@babel/core@7.29.7(supports-color@8.1.1))(@babel/preset-env@7.29.7(@babel/core@7.29.7(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@18.3.31)(react@18.3.1)(supports-color@8.1.1):
dependencies:
'@jest/create-cache-key-function': 29.7.0
@@ -10071,7 +10233,6 @@ snapshots:
text-segmentation@1.0.3:
dependencies:
utrie: 1.0.2
optional: true
thenify-all@1.6.0:
dependencies:
@@ -10216,7 +10377,6 @@ snapshots:
utrie@1.0.2:
dependencies:
base64-arraybuffer: 1.0.2
optional: true
uuid@7.0.3: {}