diff --git a/expo-app/@types/CreatingItinerary.ts b/expo-app/@types/CreatingItinerary.ts index d0ca3a5..7334fe0 100644 --- a/expo-app/@types/CreatingItinerary.ts +++ b/expo-app/@types/CreatingItinerary.ts @@ -26,6 +26,9 @@ import { VisaModelTypes } from "./VisaModelTypes"; * @property specialWish - Special wishes or requests for the trip. * @property visitPreferences - Optional list of visit preferences. * @property itinerary - Optional object representing the detailed itinerary. + * @property status - Status of the itinerary ("Planejado", "Rascunho", or "Passado"). + * @property coverImage - Optional cover image URI for the itinerary. + * @property isNew - Optional flag to indicate if this is a newly created itinerary. */ export type CreatingItinerary = { title: string, @@ -48,5 +51,8 @@ export type CreatingItinerary = { visitPreferences?: Array, itinerary?: Object, pixabayTags?: string, - images?: Object + images?: Object, + status?: "Planejado" | "Rascunho" | "Passado", + coverImage?: string, + isNew?: boolean } \ No newline at end of file diff --git a/expo-app/@types/ExpenseControlTypes.ts b/expo-app/@types/ExpenseControlTypes.ts new file mode 100644 index 0000000..d25aafe --- /dev/null +++ b/expo-app/@types/ExpenseControlTypes.ts @@ -0,0 +1,36 @@ +export type ExpenseCategory = + | "Transporte" + | "Hospedagem" + | "Alimentação" + | "Atividades" + | "Compras" + | "Emergência" + | "Outros"; + +export type Expense = { + id: string; + title: string; + amount: number; + category: ExpenseCategory; + description?: string; + date: string; + itineraryTitle: string; + activityTitle?: string; + location?: string; + createdAt: string; +}; + +export type ExpensesByCategory = { + [key in ExpenseCategory]: number; +}; + +export type ExpenseControlContextType = { + expenses: Expense[]; + addExpense: (expense: Expense) => Promise; + removeExpense: (expenseId: string) => Promise; + updateExpense: (expenseId: string, updatedExpense: Partial) => Promise; + getTotalExpenses: () => number; + getExpensesByCategory: () => ExpensesByCategory; + getExpensesByItinerary: (itineraryTitle: string) => Expense[]; + clearAllExpenses: () => Promise; +} \ No newline at end of file diff --git a/expo-app/@types/FavoritePlacesTypes.ts b/expo-app/@types/FavoritePlacesTypes.ts new file mode 100644 index 0000000..9805077 --- /dev/null +++ b/expo-app/@types/FavoritePlacesTypes.ts @@ -0,0 +1,20 @@ +export type FavoritePlace = { + id: string; + title: string; + description: string; + coordinates: string; + category: string; + location: string; + date: string; + itineraryTitle: string; + favoritedAt: string; + images?: string[]; +} + +export type FavoritePlacesContextType = { + favoritePlaces: FavoritePlace[]; + addFavoritePlace: (place: FavoritePlace) => Promise; + removeFavoritePlace: (placeId: string) => Promise; + isFavorite: (placeId: string) => boolean; + clearAllFavorites: () => Promise; +} diff --git a/expo-app/docs/utils/gpt-requests.md b/expo-app/docs/utils/gpt-requests.md index a2d5400..fe71f66 100644 --- a/expo-app/docs/utils/gpt-requests.md +++ b/expo-app/docs/utils/gpt-requests.md @@ -1,28 +1,95 @@ # GPT Requests -Helpers para acessar endpoints do backend que intermediam chamadas à OpenAI. +Helpers para acessar os endpoints do backend que intermediam chamadas à OpenAI. -- Arquivo: `src/utils/gptRequests.ts` -- Endpoints: `http://SEU-IP-AQUI:3000/api/generateItinerary` e `http://SEU-IP-AQUI:3000/api/justchat` +Este arquivo documenta a API cliente localizada em `src/utils/gptRequests.ts` e traz exemplos, recomendações de uso e tratamento de erros. -## API +## API (assinaturas) - `generateItinerary(prompt: string): Promise` - - Envia `{ prompt }` e retorna `data.message` com o itinerário gerado. + - Envia `{ prompt }` para o endpoint e retorna `data.message` com o itinerário (texto). - `generateChatAnswers(prompt: string): Promise` - - Envia `{ prompt }` e retorna `data.message` com a resposta do chat. + - Envia `{ prompt }` e retorna `data.message` com a resposta do chat (texto). -## Exemplo +> Observação: a forma exata do `data` retornado depende do backend; adapte os parsers caso o formato seja diferente (ex.: `data.result` ou `data.choices[0].text`). + +## Exemplo de implementação (TypeScript) + +Arquivo sugerido: `src/utils/gptRequests.ts` + +```ts +import { API_URL } from "@config"; // ou './config' + +type ApiResponse = { + ok: boolean; + message?: string; + error?: string; +}; + +async function postJson(path: string, body: object, signal?: AbortSignal) { + const res = await fetch(`${API_URL}${path}`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(body), + signal, + }); + + const data: ApiResponse = await res.json().catch(() => ({ ok: false, error: "invalid_json" })); + + if (!res.ok) { + const errMsg = data?.error || `HTTP ${res.status}`; + const error: any = new Error(errMsg); + error.status = res.status; + throw error; + } + + return data; +} + +export async function generateItinerary(prompt: string, signal?: AbortSignal): Promise { + const data = await postJson("/api/generateItinerary", { prompt }, signal); + if (!data.message) throw new Error("Resposta inválida do servidor"); + return data.message; +} + +export async function generateChatAnswers(prompt: string, signal?: AbortSignal): Promise { + const data = await postJson("/api/justchat", { prompt }, signal); + if (!data.message) throw new Error("Resposta inválida do servidor"); + return data.message; +} +``` + +## Exemplo de uso ```ts import { generateItinerary, generateChatAnswers } from "@utils/gptRequests"; -const itinerary = await generateItinerary("3 dias em Salvador focando em cultura e gastronomia"); -const answer = await generateChatAnswers("Quais os melhores meses para visitar Floripa?"); +async function run() { + try { + const itinerary = await generateItinerary("3 dias em Salvador focando em cultura e gastronomia"); + console.log(itinerary); + + const answer = await generateChatAnswers("Quais os melhores meses para visitar Floripa?"); + console.log(answer); + } catch (err) { + console.error("Erro na chamada GPT:", err); + } +} ``` -## Dicas e erros comuns +## Boas práticas e dicas + +- centralize a URL da API em `src/config.ts` (exportar `API_URL`) e use-a em `gptRequests.ts`. +- trate `response.ok` e `data` com validação — não confie apenas no `res.json()`. +- HTTP 429: indique ao usuário que a cota foi atingida e ofereça retry exponencial ou uma mensagem amigável. +- timeouts: use `AbortController` para cancelar requisições longas (ex.: timeout em 15s). +- retries: em erros transientes (timeout, 502, 503), implemente retry com backoff. +- logs: registre `status` e `body` em ambiente de desenvolvimento para debug. +- CORS: se o backend estiver em domínio diferente, verifique as configurações CORS do servidor. + +## Erros comuns e how-to debug -- Substitua `SEU-IP-AQUI` pelo host da sua API (veja também `src/config.ts` onde há `API_URL` para outros módulos). -- HTTP 429: indica cota da OpenAI atingida; exponha mensagem ao usuário. -- Trate `response.ok` falso como erro de fluxo. +- URL inválida/hardcode: troque por `API_URL` — verifique `src/config.ts`. +- 429 (rate limit): exiba mensagem e desabilite ação temporariamente; registre para investigar. +- 500 / 502 / 503: retry com backoff e alertar manutenção. +- resposta sem `message`: confirme o contrato da API e ajuste o parser. \ No newline at end of file diff --git a/expo-app/package-lock.json b/expo-app/package-lock.json index bcb4b3d..86b2d5d 100644 --- a/expo-app/package-lock.json +++ b/expo-app/package-lock.json @@ -53,6 +53,7 @@ "react": "19.1.0", "react-dom": "19.1.0", "react-native": "0.81.4", + "react-native-calendars": "^1.1313.0", "react-native-country-flag": "^2.0.2", "react-native-dotenv": "^3.4.11", "react-native-drawer-layout": "^4.2.0", @@ -10619,6 +10620,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", @@ -11370,6 +11376,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "optional": true, + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -12252,6 +12267,21 @@ "node": ">= 6" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/protobufjs": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", @@ -12483,6 +12513,36 @@ } } }, + "node_modules/react-native-calendars": { + "version": "1.1313.0", + "resolved": "https://registry.npmjs.org/react-native-calendars/-/react-native-calendars-1.1313.0.tgz", + "integrity": "sha512-YQ7Vg57rBRVymolamYDTxZ0lPOELTDHQbTukTWdxR47aRBYJwKI6ocRbwcY5gYgyDwNgJS4uLGu5AvmYS74LYQ==", + "dependencies": { + "hoist-non-react-statics": "^3.3.1", + "lodash": "^4.17.15", + "memoize-one": "^5.2.1", + "prop-types": "^15.5.10", + "react-native-safe-area-context": "4.5.0", + "react-native-swipe-gestures": "^1.0.5", + "recyclerlistview": "^4.0.0", + "xdate": "^0.8.0" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "moment": "^2.29.4" + } + }, + "node_modules/react-native-calendars/node_modules/react-native-safe-area-context": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.5.0.tgz", + "integrity": "sha512-0WORnk9SkREGUg2V7jHZbuN5x4vcxj/1B0QOcXJjdYWrzZHgLcUzYWWIUecUPJh747Mwjt/42RZDOaFn3L8kPQ==", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-country-flag": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/react-native-country-flag/-/react-native-country-flag-2.0.2.tgz", @@ -12682,6 +12742,11 @@ "react-native-svg": ">=12.0.0" } }, + "node_modules/react-native-swipe-gestures": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/react-native-swipe-gestures/-/react-native-swipe-gestures-1.0.5.tgz", + "integrity": "sha512-Ns7Bn9H/Tyw278+5SQx9oAblDZ7JixyzeOczcBK8dipQk2pD7Djkcfnf1nB/8RErAmMLL9iXgW0QHqiII8AhKw==" + }, "node_modules/react-native-timeline-flatlist": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/react-native-timeline-flatlist/-/react-native-timeline-flatlist-0.8.0.tgz", @@ -12897,6 +12962,20 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, + "node_modules/recyclerlistview": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/recyclerlistview/-/recyclerlistview-4.2.3.tgz", + "integrity": "sha512-STR/wj/FyT8EMsBzzhZ1l2goYirMkIgfV3gYEPxI3Kf3lOnu6f7Dryhyw7/IkQrgX5xtTcDrZMqytvteH9rL3g==", + "dependencies": { + "lodash.debounce": "4.0.8", + "prop-types": "15.8.1", + "ts-object-utils": "0.0.5" + }, + "peerDependencies": { + "react": ">= 15.2.1", + "react-native": ">= 0.30.0" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -14052,6 +14131,11 @@ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, + "node_modules/ts-object-utils": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/ts-object-utils/-/ts-object-utils-0.0.5.tgz", + "integrity": "sha512-iV0GvHqOmilbIKJsfyfJY9/dNHCs969z3so90dQWsO1eMMozvTpnB1MEaUbb3FYtZTGjv5sIy/xmslEz0Rg2TA==" + }, "node_modules/tsconfig": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", @@ -14560,6 +14644,11 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/xdate": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/xdate/-/xdate-0.8.3.tgz", + "integrity": "sha512-1NhJWPJwN+VjbkACT9XHbQK4o6exeSVtS2CxhMPwUE7xQakoEFTlwra9YcqV/uHQVyeEUYoYC46VGDJ+etnIiw==" + }, "node_modules/xml2js": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.0.tgz", diff --git a/expo-app/package.json b/expo-app/package.json index 20cbfa9..a1af0dc 100644 --- a/expo-app/package.json +++ b/expo-app/package.json @@ -54,6 +54,7 @@ "react": "19.1.0", "react-dom": "19.1.0", "react-native": "0.81.4", + "react-native-calendars": "^1.1313.0", "react-native-country-flag": "^2.0.2", "react-native-dotenv": "^3.4.11", "react-native-drawer-layout": "^4.2.0", diff --git a/expo-app/src/components/Cards/ItineraryCard.tsx b/expo-app/src/components/Cards/ItineraryCard.tsx new file mode 100644 index 0000000..9b77383 --- /dev/null +++ b/expo-app/src/components/Cards/ItineraryCard.tsx @@ -0,0 +1,104 @@ +import { TouchableOpacity, Image as RNImage } from "react-native"; +import { Text, View, Button, ButtonIcon } from "@gluestack-ui/themed"; + +import DefaultImage from '@assets/adaptive-icon.png'; +import { MoreVertical } from "lucide-react-native"; + +type ItineraryCardProps = { + title: string; + dateBegin: string; + dateEnd: string; + imageUri?: string; + daysUntil: number; + onPress: () => void; + onOptionsPress?: () => void; +}; + +export function ItineraryCard({ + title, + dateBegin, + dateEnd, + imageUri, + daysUntil, + onPress, + onOptionsPress +}: ItineraryCardProps) { + + const formatDaysText = () => { + if (daysUntil < 0) { + return `Há ${Math.abs(daysUntil)} dias`; + } else if (daysUntil === 0) { + return "Hoje"; + } else { + return `Em ${daysUntil} dias`; + } + }; + + return ( + + + + + + + + {title} + + + {formatDaysText()} + + + + {dateBegin} - {dateEnd} + + + + + + {onOptionsPress && ( + + )} + + ); +} diff --git a/expo-app/src/components/Dialogs/ItineraryActionsDialog.tsx b/expo-app/src/components/Dialogs/ItineraryActionsDialog.tsx new file mode 100644 index 0000000..644fd8f --- /dev/null +++ b/expo-app/src/components/Dialogs/ItineraryActionsDialog.tsx @@ -0,0 +1,266 @@ +import { + AlertDialog, + AlertDialogBackdrop, + AlertDialogBody, + AlertDialogContent, + AlertDialogHeader, + Button, + ButtonIcon, + ButtonText, + Text, + View, + Pressable +} from "@gluestack-ui/themed"; + +import { X, Edit, Trash2, ArrowRightLeft } from "lucide-react-native"; + +type ItineraryActionsDialogProps = { + showAlertDialog: boolean; + currentStatus: "Planejado" | "Rascunho" | "Passado"; + handleClose: () => void; + onEdit: () => void; + onDelete: () => void; + onMove: () => void; +}; + +export function ItineraryActionsDialog({ + showAlertDialog, + currentStatus, + handleClose, + onEdit, + onDelete, + onMove +}: ItineraryActionsDialogProps) { + + const getMoveText = () => { + if (currentStatus === "Planejado") { + return "Mover para Rascunhos"; + } else if (currentStatus === "Rascunho") { + return "Mover para Planejados"; + } + return "Mover"; + }; + + const getMoveDescription = () => { + if (currentStatus === "Planejado") { + return "Salvar como rascunho para edição posterior"; + } else if (currentStatus === "Rascunho") { + return "Confirmar planejamento do roteiro"; + } + return "Alterar status"; + }; + + return ( + + + + {/* Header */} + + + + Gerenciar Roteiro + + + Escolha uma ação para continuar + + + + + + + + + + {/* Botão Editar */} + { + onEdit(); + handleClose(); + }} + > + {({ pressed }) => ( + + + + + + + Editar Roteiro + + + Modificar detalhes, datas e atividades + + + + )} + + + {/* Botão Mover */} + {currentStatus !== "Passado" && ( + { + onMove(); + handleClose(); + }} + > + {({ pressed }) => ( + + + + + + + {getMoveText()} + + + {getMoveDescription()} + + + + )} + + )} + + {/* Separador visual */} + + + {/* Botão Excluir */} + { + onDelete(); + handleClose(); + }} + > + {({ pressed }) => ( + + + + + + + Excluir Roteiro + + + Ação permanente e irreversível + + + + )} + + + + + + ); +} diff --git a/expo-app/src/components/Dialogs/SaveItineraryDialog.tsx b/expo-app/src/components/Dialogs/SaveItineraryDialog.tsx new file mode 100644 index 0000000..9f38d81 --- /dev/null +++ b/expo-app/src/components/Dialogs/SaveItineraryDialog.tsx @@ -0,0 +1,155 @@ +import { useState } from "react"; +import { TouchableOpacity, Image, Alert } from "react-native"; +import * as ImagePicker from 'expo-image-picker'; + +import { + AlertDialog, + AlertDialogBackdrop, + AlertDialogBody, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + Button, + ButtonIcon, + ButtonText, + Text, + View +} from "@gluestack-ui/themed"; + +import { X, ImagePlus } from "lucide-react-native"; + +type SaveItineraryDialogTypes = { + showAlertDialog: boolean, + onSave: (status: "Planejado" | "Rascunho", imageUri?: string) => void, + handleClose: () => void +} + +export function SaveItineraryDialog({ showAlertDialog, handleClose, onSave }: SaveItineraryDialogTypes){ + const [selectedImage, setSelectedImage] = useState(""); + const [selectedStatus, setSelectedStatus] = useState<"Planejado" | "Rascunho" | null>(null); + + const pickImage = async () => { + const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync(); + + if (permissionResult.granted === false) { + Alert.alert("Permissão Necessária", "É necessário permitir acesso à galeria para adicionar uma imagem"); + return; + } + + const result = await ImagePicker.launchImageLibraryAsync({ + mediaTypes: ImagePicker.MediaTypeOptions.Images, + allowsEditing: true, + aspect: [16, 9], + quality: 0.8, + }); + + if (!result.canceled && result.assets[0]) { + setSelectedImage(result.assets[0].uri); + } + }; + + const handleSave = () => { + if (!selectedStatus) { + Alert.alert("Atenção", "Por favor, selecione se deseja salvar como Planejado ou Rascunho"); + return; + } + + onSave(selectedStatus, selectedImage || undefined); + handleClose(); + }; + + return( + + + + + Salvar Roteiro + + + + + + Como deseja salvar este roteiro? + + + + + + + + + Adicionar uma foto (opcional) + + + + { + selectedImage ? ( + + ) : ( + + + + Toque para adicionar uma foto + + + ) + } + + + + + + + + + + ) +} diff --git a/expo-app/src/components/Errors/PastItinerariesError.tsx b/expo-app/src/components/Errors/PastItinerariesError.tsx new file mode 100644 index 0000000..e5c6e4f --- /dev/null +++ b/expo-app/src/components/Errors/PastItinerariesError.tsx @@ -0,0 +1,14 @@ +import { Box, Text } from "@gluestack-ui/themed"; + +import { CalendarCheck } from "lucide-react-native"; + +export function PastItinerariesError(){ + return ( + + + + Você não tem nenhum roteiro expirado aqui ainda. + + + ) +} diff --git a/expo-app/src/components/Home/Destinations.tsx b/expo-app/src/components/Home/Destinations.tsx index e7d2959..53e8bdc 100644 --- a/expo-app/src/components/Home/Destinations.tsx +++ b/expo-app/src/components/Home/Destinations.tsx @@ -28,7 +28,7 @@ export function HomeDestinations({ item, userLocation, currentScreen }: Destinat const [isHovered, setIsHovered] = useState(false); const photoUrl = item.photos?.[0] - ? `http://SEU-IP-AQUI:3000/api/googlePhotoProxy?photo_reference=${item.photos[0].photo_reference}` + ? `https://guiaturisticoeztripai.vercel.app/api/googlePhotoProxy?photo_reference=${item.photos[0].photo_reference}` : null; const calculateDistance = () => { diff --git a/expo-app/src/components/Itinerary/ItineraryCreateDialog.tsx b/expo-app/src/components/Itinerary/ItineraryCreateDialog.tsx index 218b0e8..f9e3611 100644 --- a/expo-app/src/components/Itinerary/ItineraryCreateDialog.tsx +++ b/expo-app/src/components/Itinerary/ItineraryCreateDialog.tsx @@ -7,14 +7,15 @@ import { TextInput, TouchableOpacity, Dimensions, - Image + Image, + Alert } from "react-native"; import { useNavigation } from "@react-navigation/native"; import * as Contacts from 'expo-contacts'; import { Contact } from "expo-contacts"; -import RNDateTimePicker from "@react-native-community/datetimepicker"; +import { Calendar, DateData } from 'react-native-calendars'; import { FormControl, @@ -44,6 +45,7 @@ export function ItineraryCreateDialog({ showAlertDialog, setShowAlertDialog }: s const [startDate, setStartDate] = useState(new Date()); const [endDate, setEndDate] = useState(new Date(new Date().getTime() + 24 * 60 * 60 * 1000)); const [showDatePickers, setShowDatePickers] = useState(false); + const [activeCalendar, setActiveCalendar] = useState<'start' | 'end' | null>(null); const [days, setDays] = useState(1); const [selectedContinent, setSelectedContinent] = useState(""); const [selectedCountries, setSelectedCountries] = useState([]); @@ -107,25 +109,61 @@ export function ItineraryCreateDialog({ showAlertDialog, setShowAlertDialog }: s return diffDays; }; - const handleStartDateChange = (event: any, selectedDate?: Date) => { - if (selectedDate) { - setStartDate(selectedDate); + const handleStartDateChange = (day: DateData) => { + const selectedDate = new Date(day.year, day.month - 1, day.day); + setStartDate(selectedDate); + if (selectedDate > endDate) { + const newEndDate = new Date(selectedDate.getTime() + 24 * 60 * 60 * 1000); + setEndDate(newEndDate); + setDays(1); + } else { const newDays = calculateDays(selectedDate, endDate); - setDays(newDays); - setTimeout(() => setShowDatePickers(false), 300); + if (newDays > 45) { + Alert.alert( + 'Limite de dias excedido', + 'O itinerário não pode ultrapassar 45 dias. Ajustando automaticamente para 45 dias.', + [{ text: 'OK' }] + ); + const adjustedEndDate = new Date(selectedDate.getTime() + 44 * 24 * 60 * 60 * 1000); + setEndDate(adjustedEndDate); + setDays(45); + } else { + setDays(newDays); + } } + setActiveCalendar(null); }; - const handleEndDateChange = (event: any, selectedDate?: Date) => { - if (selectedDate) { - setEndDate(selectedDate); + const handleEndDateChange = (day: DateData) => { + const selectedDate = new Date(day.year, day.month - 1, day.day); + if (selectedDate >= startDate) { const newDays = calculateDays(startDate, selectedDate); - setDays(newDays); - setTimeout(() => setShowDatePickers(false), 300); + if (newDays > 45) { + Alert.alert( + 'Limite de dias excedido', + 'O itinerário não pode ultrapassar 45 dias. Ajustando automaticamente para 45 dias.', + [{ text: 'OK' }] + ); + const adjustedEndDate = new Date(startDate.getTime() + 44 * 24 * 60 * 60 * 1000); + setEndDate(adjustedEndDate); + setDays(45); + } else { + setEndDate(selectedDate); + setDays(newDays); + } } + setActiveCalendar(null); }; const incrementDays = () => { + if (days >= 45) { + Alert.alert( + 'Limite de dias excedido', + 'O itinerário não pode ultrapassar 45 dias. Por favor, ajuste as datas.', + [{ text: 'OK' }] + ); + return; + } const newDays = days + 1; setDays(newDays); const newEndDate = new Date(startDate.getTime() + (newDays - 1) * 24 * 60 * 60 * 1000); @@ -284,9 +322,8 @@ export function ItineraryCreateDialog({ showAlertDialog, setShowAlertDialog }: s Início da viagem setShowDatePickers(!showDatePickers)} + onPress={() => setActiveCalendar(activeCalendar === 'start' ? null : 'start')} > - Definir Datas {formatDate(startDate)} @@ -301,9 +338,8 @@ export function ItineraryCreateDialog({ showAlertDialog, setShowAlertDialog }: s Fim da viagem setShowDatePickers(!showDatePickers)} + onPress={() => setActiveCalendar(activeCalendar === 'end' ? null : 'end')} > - Definir Datas {formatDate(endDate)} @@ -311,30 +347,35 @@ export function ItineraryCreateDialog({ showAlertDialog, setShowAlertDialog }: s - {showDatePickers && ( - - - - Data de Início - - - - Data de Fim - - - + {activeCalendar && ( + + )} @@ -355,12 +396,20 @@ export function ItineraryCreateDialog({ showAlertDialog, setShowAlertDialog }: s = 45 && { opacity: 0.5 }]} onPress={incrementDays} + disabled={days >= 45} > + {days >= 45 && ( + + + Limite máximo de 45 dias atingido! + + + )} diff --git a/expo-app/src/components/Itinerary/ItineraryPreferencesModal.tsx b/expo-app/src/components/Itinerary/ItineraryPreferencesModal.tsx index 58285c4..86a681c 100644 --- a/expo-app/src/components/Itinerary/ItineraryPreferencesModal.tsx +++ b/expo-app/src/components/Itinerary/ItineraryPreferencesModal.tsx @@ -7,14 +7,15 @@ import { TextInput, TouchableOpacity, Dimensions, - Image + Image, + Alert } from "react-native"; import { useNavigation } from "@react-navigation/native"; import * as Contacts from 'expo-contacts'; import { Contact } from "expo-contacts"; -import RNDateTimePicker from "@react-native-community/datetimepicker"; +import { Calendar, DateData } from 'react-native-calendars'; import { FormControl, @@ -56,6 +57,7 @@ export function ItineraryPreferencesModal({ showAlertDialog, setShowAlertDialog const [startDate, setStartDate] = useState(new Date()); const [endDate, setEndDate] = useState(new Date(new Date().getTime() + 24 * 60 * 60 * 1000)); const [showDatePickers, setShowDatePickers] = useState(false); + const [activeCalendar, setActiveCalendar] = useState<'start' | 'end' | null>(null); const [days, setDays] = useState(1); const [originCountry, setOriginCountry] = useState(""); const [showOriginCountrySelector, setShowOriginCountrySelector] = useState(false); @@ -134,25 +136,61 @@ export function ItineraryPreferencesModal({ showAlertDialog, setShowAlertDialog return diffDays; }; - const handleStartDateChange = (event: any, selectedDate?: Date) => { - if (selectedDate) { - setStartDate(selectedDate); + const handleStartDateChange = (day: DateData) => { + const selectedDate = new Date(day.year, day.month - 1, day.day); + setStartDate(selectedDate); + if (selectedDate > endDate) { + const newEndDate = new Date(selectedDate.getTime() + 24 * 60 * 60 * 1000); + setEndDate(newEndDate); + setDays(1); + } else { const newDays = calculateDays(selectedDate, endDate); - setDays(newDays); - setTimeout(() => setShowDatePickers(false), 300); + if (newDays > 45) { + Alert.alert( + 'Limite de dias excedido', + 'O itinerário não pode ultrapassar 45 dias. Ajustando automaticamente para 45 dias.', + [{ text: 'OK' }] + ); + const adjustedEndDate = new Date(selectedDate.getTime() + 44 * 24 * 60 * 60 * 1000); + setEndDate(adjustedEndDate); + setDays(45); + } else { + setDays(newDays); + } } + setActiveCalendar(null); }; - const handleEndDateChange = (event: any, selectedDate?: Date) => { - if (selectedDate) { - setEndDate(selectedDate); + const handleEndDateChange = (day: DateData) => { + const selectedDate = new Date(day.year, day.month - 1, day.day); + if (selectedDate >= startDate) { const newDays = calculateDays(startDate, selectedDate); - setDays(newDays); - setTimeout(() => setShowDatePickers(false), 300); + if (newDays > 45) { + Alert.alert( + 'Limite de dias excedido', + 'O itinerário não pode ultrapassar 45 dias. Ajustando automaticamente para 45 dias.', + [{ text: 'OK' }] + ); + const adjustedEndDate = new Date(startDate.getTime() + 44 * 24 * 60 * 60 * 1000); + setEndDate(adjustedEndDate); + setDays(45); + } else { + setEndDate(selectedDate); + setDays(newDays); + } } + setActiveCalendar(null); }; const incrementDays = () => { + if (days >= 45) { + Alert.alert( + 'Limite de dias excedido', + 'O itinerário não pode ultrapassar 45 dias. Por favor, ajuste as datas.', + [{ text: 'OK' }] + ); + return; + } const newDays = days + 1; setDays(newDays); const newEndDate = new Date(startDate.getTime() + (newDays - 1) * 24 * 60 * 60 * 1000); @@ -373,23 +411,91 @@ export function ItineraryPreferencesModal({ showAlertDialog, setShowAlertDialog Data de Início - + setActiveCalendar(activeCalendar === 'start' ? null : 'start')} + style={{ + backgroundColor: '#F8F8F8', + padding: 12, + borderRadius: 10, + borderWidth: 1, + borderColor: activeCalendar === 'start' ? '#2752B7' : '#E5E5E5', + marginBottom: 10 + }} + > + + {formatDate(startDate)} + + + {activeCalendar === 'start' && ( + + )} Data de Fim - + setActiveCalendar(activeCalendar === 'end' ? null : 'end')} + style={{ + backgroundColor: '#F8F8F8', + padding: 12, + borderRadius: 10, + borderWidth: 1, + borderColor: activeCalendar === 'end' ? '#2752B7' : '#E5E5E5', + marginBottom: 10 + }} + > + + {formatDate(endDate)} + + + {activeCalendar === 'end' && ( + + )} @@ -412,12 +518,20 @@ export function ItineraryPreferencesModal({ showAlertDialog, setShowAlertDialog = 45 && { opacity: 0.5 }]} onPress={incrementDays} + disabled={days >= 45} > + {days >= 45 && ( + + + Limite máximo de 45 dias atingido + + + )} diff --git a/expo-app/src/components/Maps/Maps.tsx b/expo-app/src/components/Maps/Maps.tsx index 5769c94..32cfef3 100644 --- a/expo-app/src/components/Maps/Maps.tsx +++ b/expo-app/src/components/Maps/Maps.tsx @@ -59,7 +59,7 @@ export const Maps = forwardRef((props, ref) => { try { const response = await fetch( - `http://SEU-IP-AQUI:3000/api/googlePlacesApi?latitude=${location.coords.latitude}&longitude=${location.coords.longitude}` + `https://guiaturisticoeztripai.vercel.app/api/googlePlacesApi?latitude=${location.coords.latitude}&longitude=${location.coords.longitude}` ); if (!response.ok) { diff --git a/expo-app/src/components/Modals/AddExpenseModal.tsx b/expo-app/src/components/Modals/AddExpenseModal.tsx new file mode 100644 index 0000000..40caa13 --- /dev/null +++ b/expo-app/src/components/Modals/AddExpenseModal.tsx @@ -0,0 +1,341 @@ +import { useState, useEffect } from "react"; +import { Modal, TouchableOpacity, TextInput, KeyboardAvoidingView, Platform, ScrollView as RNScrollView } from "react-native"; + +import { Calendar } from 'react-native-calendars'; + +import { View, Text, Button, ButtonText } from "@gluestack-ui/themed"; + +import { ExpenseCategory } from "../../../@types/ExpenseControlTypes"; + +import { X, DollarSign, FileText, Calendar as CalendarIcon, Tag } from "lucide-react-native"; + +type AddExpenseModalProps = { + visible: boolean; + onClose: () => void; + onAdd: (expense: { + title: string; + amount: number; + category: ExpenseCategory; + description: string; + date: string; + }) => void; + defaultTitle?: string; + defaultDescription?: string; + defaultDate?: string; + defaultLocation?: string; + itineraryTitle: string; +}; + +export function AddExpenseModal({ + visible, + onClose, + onAdd, + defaultTitle = "", + defaultDescription = "", + defaultDate = "", + defaultLocation = "", + itineraryTitle +}: AddExpenseModalProps) { + const [title, setTitle] = useState(defaultTitle); + const [amount, setAmount] = useState(""); + const [category, setCategory] = useState("Outros"); + const [description, setDescription] = useState(""); + const [date, setDate] = useState(defaultDate); + const [showDatePicker, setShowDatePicker] = useState(false); + + useEffect(() => { + if (visible) { + setTitle(defaultTitle); + setDescription(defaultDescription); + setDate(defaultDate); + } + }, [visible, defaultTitle, defaultDescription, defaultDate]); + + const categories: ExpenseCategory[] = [ + "Transporte", + "Hospedagem", + "Alimentação", + "Atividades", + "Compras", + "Emergência", + "Outros" + ]; + + const handleAdd = () => { + if (!title.trim() || !amount || parseFloat(amount) <= 0) { + return; + } + + onAdd({ + title: title.trim(), + amount: parseFloat(amount), + category, + description: description.trim(), + date: date || new Date().toISOString().split('T')[0] + }); + + setTitle(""); + setAmount(""); + setCategory("Outros"); + setDescription(""); + setDate(""); + onClose(); + }; + + const handleCancel = () => { + setTitle(""); + setAmount(""); + setCategory("Outros"); + setDescription(""); + setDate(""); + onClose(); + }; + + return ( + + + + + + + Adicionar Gasto + + + + + + + + + + + + + Título do Gasto + + + + + + + + + + Valor + + + { + const numericValue = text.replace(/[^0-9.]/g, ''); + setAmount(numericValue); + }} + placeholder="0.00" + placeholderTextColor="#999" + keyboardType="decimal-pad" + style={{ + backgroundColor: "#F8F8F8", + borderRadius: 12, + padding: 14, + fontSize: 15, + color: "#000", + borderWidth: 1, + borderColor: "#E5E5E5" + }} + /> + + + + + + + Categoria + + + + {categories.map((cat) => ( + setCategory(cat)} + style={{ marginRight: 8 }} + > + + + {cat} + + + + ))} + + + + + + + + Descrição (Opcional) + + + + + + + + + + Data + + + setShowDatePicker(!showDatePicker)}> + + + {date ? (() => { + const [year, month, day] = date.split('-').map(Number); + const dateObj = new Date(year, month - 1, day); + return dateObj.toLocaleDateString('pt-BR'); + })() : 'Selecione a data'} + + + + {showDatePicker && ( + + { + setDate(day.dateString); + setShowDatePicker(false); + }} + markedDates={{ + [date || '']: { selected: true, selectedColor: '#2752B7' } + }} + theme={{ + backgroundColor: '#F8F8F8', + calendarBackground: '#F8F8F8', + textSectionTitleColor: '#2752B7', + selectedDayBackgroundColor: '#2752B7', + selectedDayTextColor: '#ffffff', + todayTextColor: '#2752B7', + dayTextColor: '#2d4150', + textDisabledColor: '#d9e1e8', + monthTextColor: '#2752B7', + textMonthFontWeight: 'bold', + textDayFontSize: 14, + textMonthFontSize: 16, + textDayHeaderFontSize: 12 + }} + /> + + )} + + + {defaultLocation && ( + + + Local: {defaultLocation} + + + )} + + + + + + + + + + + + ); +} diff --git a/expo-app/src/components/Modals/ExpenseAddedModal.tsx b/expo-app/src/components/Modals/ExpenseAddedModal.tsx new file mode 100644 index 0000000..79a7f4d --- /dev/null +++ b/expo-app/src/components/Modals/ExpenseAddedModal.tsx @@ -0,0 +1,94 @@ +import { Modal, TouchableOpacity } from "react-native"; + +import { View, Text, Button, ButtonText } from "@gluestack-ui/themed"; + +import { CheckCircle2, X, Eye } from "lucide-react-native"; + +type ExpenseAddedModalProps = { + visible: boolean; + onClose: () => void; + onViewExpenses: () => void; + expenseTitle: string; + expenseAmount: number; +}; + +export function ExpenseAddedModal({ + visible, + onClose, + onViewExpenses, + expenseTitle, + expenseAmount +}: ExpenseAddedModalProps) { + const formatCurrency = (value: number) => { + return new Intl.NumberFormat('pt-BR', { + style: 'currency', + currency: 'BRL' + }).format(value); + }; + + return ( + + + + + + + + + + + + + Gasto Adicionado + + + + + + { expenseTitle } + + + { formatCurrency(expenseAmount) } + + + + + + + + + + + + ); +} \ No newline at end of file diff --git a/expo-app/src/components/Sliders/SlideUpItinerary.tsx b/expo-app/src/components/Sliders/SlideUpItinerary.tsx index 6d3cbce..052842e 100644 --- a/expo-app/src/components/Sliders/SlideUpItinerary.tsx +++ b/expo-app/src/components/Sliders/SlideUpItinerary.tsx @@ -1,6 +1,7 @@ import { useEffect, useState, useCallback } from "react"; -import { StyleSheet, Dimensions, FlatList } from "react-native"; +import { StyleSheet, Dimensions, FlatList, Alert, ScrollView as RNScrollView, TouchableOpacity, KeyboardAvoidingView, Platform, Modal, TextInput as RNTextInput } from "react-native"; import { RouteProp, useNavigation, useRoute } from "@react-navigation/native"; +import MapView, { Marker, PROVIDER_GOOGLE } from 'react-native-maps'; import { Gesture, @@ -20,10 +21,15 @@ import Timeline from 'react-native-timeline-flatlist'; import { ItineraryCategoriesDefine } from "@components/Itinerary/ItineraryCategoriesDefine"; import { ItinerarySliderDateShow } from "@components/Itinerary/ItinerarySliderDateShow"; +import { AddExpenseModal } from "@components/Modals/AddExpenseModal"; +import { ExpenseAddedModal } from "@components/Modals/ExpenseAddedModal"; + +import { useFavoritePlaces } from "../../hooks/useFavoritePlaces"; +import { useExpenseControl } from "../../hooks/useExpenseControl"; import { AuthNavigationProp } from "@routes/auth.routes"; -import { ArrowDown, ArrowUp, CalendarX, ChevronRight, Compass, HandCoins, MessageCircle, Pen, SquarePlus, UtensilsCrossed, Bed, PartyPopper, TreePine, ShoppingBag, Landmark, Plane, Heart } from "lucide-react-native"; +import { ArrowDown, ArrowUp, CalendarX, ChevronRight, Compass, HandCoins, MessageCircle, Pen, SquarePlus, UtensilsCrossed, Bed, PartyPopper, TreePine, ShoppingBag, Landmark, Plane, Heart, Clock, FileText, Tag, MapPin, Move, X } from "lucide-react-native"; import { CreatingItinerary } from "../../../@types/CreatingItinerary"; import { CategoriesCounterTypes } from "../../../@types/CategoriesCounterTypes"; @@ -71,12 +77,24 @@ export function SlideUpItinerary({ isLoading, hideBackButton, setFirstLatitude, itinerary, } = route.params.itineraryData; + const { addFavoritePlace, isFavorite } = useFavoritePlaces(); + const { addExpense, expenses } = useExpenseControl(); + const [allTripDays, setAllTripDays] = useState([]); const [selectedDayIndex, setSelectedDayIndex] = useState(0); const [isEditing, setIsEditing] = useState(false); const [showCategories, setShowCategories] = useState(false); + const [showExpenseModal, setShowExpenseModal] = useState(false); + const [showExpenseAddedModal, setShowExpenseAddedModal] = useState(false); + const [lastAddedExpense, setLastAddedExpense] = useState<{ title: string; amount: number } | null>(null); + const [currentExpenseContext, setCurrentExpenseContext] = useState<{ title: string, description: string, date: string, location: string } | null>(null); const [editingTimelineIndex, setEditingTimelineIndex] = useState(null); const [itineraryState, setItineraryState] = useState(Array.isArray(itinerary) ? itinerary : []); + const [showAddActivityModal, setShowAddActivityModal] = useState(false); + const [addActivityPosition, setAddActivityPosition] = useState<'before' | 'after' | 'move' | null>(null); + const [newActivityData, setNewActivityData] = useState<{ time: string, title: string, description: string, category: string, coordinates: string }>({ time: '', title: '', description: '', category: '', coordinates: '0.0000,0.0000' }); + const [showMapPicker, setShowMapPicker] = useState(false); + const [selectedCoordinates, setSelectedCoordinates] = useState<{ latitude: number, longitude: number } | null>(null); const { height: screenHeight } = Dimensions.get('window'); @@ -125,6 +143,31 @@ export function SlideUpItinerary({ isLoading, hideBackButton, setFirstLatitude, }; }); + // Função para gerar horários disponíveis (agora de 00:00 a 23:59) + const generateAvailableTimes = (beforeTime?: string, afterTime?: string): string[] => { + const times: string[] = []; + const startHour = beforeTime ? parseInt(beforeTime.split(':')[0]) : 0; + const startMinute = beforeTime ? parseInt(beforeTime.split(':')[1]) : 0; + const endHour = afterTime ? parseInt(afterTime.split(':')[0]) : 23; + const endMinute = afterTime ? parseInt(afterTime.split(':')[1]) : 59; + + let currentHour = beforeTime ? startHour : 0; + let currentMinute = beforeTime ? startMinute + 15 : 0; + + while (currentHour < endHour || (currentHour === endHour && currentMinute <= endMinute)) { + if (currentMinute >= 60) { + currentHour++; + currentMinute = 0; + } + if (currentHour < endHour || (currentHour === endHour && currentMinute < endMinute)) { + times.push(`${String(currentHour).padStart(2, '0')}:${String(currentMinute).padStart(2, '0')}`); + } + currentMinute += 15; + } + + return times; + }; + const handleSelectCategory = (category: string) => { if (editingTimelineIndex === null) return; @@ -215,6 +258,275 @@ export function SlideUpItinerary({ isLoading, hideBackButton, setFirstLatitude, setEditingTimelineIndex(null); }; + // Função para abrir modal de adicionar antes + const handleAddBefore = (index: number) => { + setEditingTimelineIndex(index); + setAddActivityPosition('before'); + setNewActivityData({ time: '', title: '', description: '', category: '', coordinates: '0.0000,0.0000' }); + setSelectedCoordinates(null); + setShowAddActivityModal(true); + }; + + // Função para abrir modal de adicionar depois + const handleAddAfter = (index: number) => { + setEditingTimelineIndex(index); + setAddActivityPosition('after'); + setNewActivityData({ time: '', title: '', description: '', category: '', coordinates: '0.0000,0.0000' }); + setSelectedCoordinates(null); + setShowAddActivityModal(true); + }; + + // Função para mover/editar atividade + const handleMoveActivity = (index: number) => { + const activity = itineraryState[selectedDayIndex]?.timeline[index]; + if (!activity) return; + + setEditingTimelineIndex(index); + setAddActivityPosition('move'); + setNewActivityData({ + time: activity.time, + title: activity.title, + description: activity.description, + category: activity.category, + coordinates: activity.coordinates || '0.0000,0.0000' + }); + + // Converte coordenadas string para objeto (suporta ; e ,) + if (activity.coordinates && activity.coordinates !== '0.0000,0.0000') { + const coordString = activity.coordinates.replace(/\s+/g, ''); + const [lat, lng] = coordString.split(/[;,]/).map(Number); + if (!isNaN(lat) && !isNaN(lng)) { + setSelectedCoordinates({ latitude: lat, longitude: lng }); + } else { + setSelectedCoordinates(null); + } + } else { + setSelectedCoordinates(null); + } + + setShowAddActivityModal(true); + }; + + // Função para salvar nova atividade ou edição + const handleSaveNewActivity = () => { + if (editingTimelineIndex === null || !addActivityPosition) return; + if (!newActivityData.time || !newActivityData.title) { + Alert.alert('Erro', 'Por favor, preencha pelo menos o horário e o título da atividade.'); + return; + } + + const coordinates = selectedCoordinates + ? `${selectedCoordinates.latitude.toFixed(4)}; ${selectedCoordinates.longitude.toFixed(4)}` + : newActivityData.coordinates || '0.0000,0.0000'; + + const activityData: TimelineItemTypes = { + time: newActivityData.time, + title: newActivityData.title, + description: newActivityData.description || newActivityData.title, + coordinates: coordinates, + category: newActivityData.category + }; + + setItineraryState((prevState) => { + const newState = [...prevState]; + const dayData = newState[selectedDayIndex]; + + if (dayData && dayData.timeline) { + const newTimeline = [...dayData.timeline]; + + if (addActivityPosition === 'move') { + // Modo edição: substitui a atividade existente + newTimeline[editingTimelineIndex] = activityData; + } else { + // Modo adicionar: insere nova atividade + const insertIndex = addActivityPosition === 'before' ? editingTimelineIndex : editingTimelineIndex + 1; + newTimeline.splice(insertIndex, 0, activityData); + } + + dayData.timeline = newTimeline; + } + + return newState; + }); + + setShowAddActivityModal(false); + setEditingTimelineIndex(null); + setAddActivityPosition(null); + setNewActivityData({ time: '', title: '', description: '', category: '', coordinates: '0.0000,0.0000' }); + setSelectedCoordinates(null); + }; + + // Função para excluir visita + const handleDeleteActivity = (index: number) => { + const activity = itineraryState[selectedDayIndex]?.timeline[index]; + if (!activity) return; + + Alert.alert( + 'Confirmar exclusão', + 'Tem certeza que deseja excluir esta atividade?', + [ + { text: 'Cancelar', style: 'cancel' }, + { + text: 'Excluir', + style: 'destructive', + onPress: () => { + const oldCategory = activity.category; + + // Atualiza o estado do itinerário + setItineraryState((prevState) => { + const newState = [...prevState]; + const dayData = { ...newState[selectedDayIndex] }; + + if (dayData && dayData.timeline) { + dayData.timeline = dayData.timeline.filter((_, i) => i !== index); + newState[selectedDayIndex] = dayData; + } + + return newState; + }); + + // Atualiza contador de categorias de forma isolada + if (oldCategory) { + setCategoriesCounter((prev) => { + const newCounter = { ...prev }; + switch (oldCategory) { + case "Ponto Turístico": + newCounter.touristAttractions = Math.max(0, newCounter.touristAttractions - 1); + break; + case "Gastronomia": + newCounter.restaurant = Math.max(0, newCounter.restaurant - 1); + break; + case "Hospedagem": + newCounter.accomodation = Math.max(0, newCounter.accomodation - 1); + break; + case "Vida Noturna": + newCounter.nightLife = Math.max(0, newCounter.nightLife - 1); + break; + case "Parques": + newCounter.parks = Math.max(0, newCounter.parks - 1); + break; + case "Shopping": + newCounter.shopping = Math.max(0, newCounter.shopping - 1); + break; + case "Cultura": + newCounter.culture = Math.max(0, newCounter.culture - 1); + break; + case "Viagens": + newCounter.travel = Math.max(0, newCounter.travel - 1); + break; + } + return newCounter; + }); + } + } + } + ] + ); + }; + + const handleAddToFavorites = async (rowData: TimelineItemTypes, index: number) => { + const currentDay = itineraryState[selectedDayIndex]; + + if (!currentDay) return; + + // Gera um ID único para o local favorito + const placeId = `${title}-${currentDay.day}-${index}-${rowData.time}`; + + // Verifica se já está nos favoritos + if (isFavorite(placeId)) { + Alert.alert( + "Já está nos favoritos", + `"${rowData.title}" já foi adicionado aos seus locais favoritos.`, + [{ text: "OK" }] + ); + return; + } + + try { + await addFavoritePlace({ + id: placeId, + title: rowData.title, + description: rowData.description, + coordinates: rowData.coordinates || "0.0000,0.0000", + category: rowData.category || "", + location: currentDay.location, + date: currentDay.date, + itineraryTitle: title, + favoritedAt: new Date().toISOString(), + images: currentDay.images || [] + }); + + Alert.alert( + "Adicionado aos Favoritos!", + `"${rowData.title}" foi adicionado à sua lista de locais favoritos.`, + [{ text: "OK" }] + ); + } catch (error) { + // DEBUG: console.error('Erro ao adicionar aos favoritos:', error); + Alert.alert( + "Erro", + "Não foi possível adicionar este local aos favoritos. Tente novamente.", + [{ text: "OK" }] + ); + } + }; + + const handleOpenExpenseModal = (rowData: TimelineItemTypes, index: number) => { + const currentDay = itineraryState[selectedDayIndex]; + + if (!currentDay) return; + + setCurrentExpenseContext({ + title: rowData.title, + description: rowData.description, + date: currentDay.date, + location: currentDay.location + }); + setShowExpenseModal(true); + }; + + const handleAddExpense = async (expense: { title: string; amount: number; category: any; description: string; date: string }) => { + if (!currentExpenseContext) return; + + const expenseId = `${title}-${Date.now()}`; + + await addExpense({ + id: expenseId, + title: expense.title, + amount: expense.amount, + category: expense.category, + description: expense.description, + date: expense.date, + itineraryTitle: title, + activityTitle: currentExpenseContext.title, + location: currentExpenseContext.location, + createdAt: new Date().toISOString() + }); + + setShowExpenseModal(false); + setCurrentExpenseContext(null); + setLastAddedExpense({ title: expense.title, amount: expense.amount }); + setShowExpenseAddedModal(true); + }; + + // Função auxiliar para verificar se uma atividade está favoritada + const checkIfFavorited = (rowData: TimelineItemTypes, index: number): boolean => { + const currentDay = itineraryState[selectedDayIndex]; + if (!currentDay) return false; + + const placeId = `${title}-${currentDay.day}-${index}-${rowData.time}`; + return isFavorite(placeId); + }; + + // Função auxiliar para obter total de gastos de uma atividade + const getActivityExpenses = (rowData: TimelineItemTypes): number => { + const activityExpenses = expenses.filter( + expense => expense.itineraryTitle === title && expense.activityTitle === rowData.title + ); + + return activityExpenses.reduce((total, expense) => total + expense.amount, 0); + }; + const getCategoryIcon = (category: string) => { switch (category) { case "Ponto Turístico": @@ -425,17 +737,39 @@ export function SlideUpItinerary({ isLoading, hideBackButton, setFirstLatitude, - - @@ -443,33 +777,72 @@ export function SlideUpItinerary({ isLoading, hideBackButton, setFirstLatitude, isEditing ? - - - + : null } ); - }, [isEditing]); + }, [isEditing, itineraryState, selectedDayIndex, title, expenses, isFavorite]); const getTimelineDataForDay = (dayIndex: number) => { if (!itineraryState || !Array.isArray(itineraryState)) { @@ -658,6 +1031,327 @@ export function SlideUpItinerary({ isLoading, hideBackButton, setFirstLatitude, setShowModal={ () => setShowCategories(false) } onSelectCategory={ handleSelectCategory } /> + + {/* Modal de Adicionar/Editar Atividade */} + {showAddActivityModal && ( + { + setShowAddActivityModal(false); + setShowMapPicker(false); + }} + > + + + + {/* Header */} + + + {addActivityPosition === 'before' + ? 'Adicionar Atividade Antes' + : addActivityPosition === 'after' + ? 'Adicionar Atividade Depois' + : 'Mover Atividade'} + + { + setShowAddActivityModal(false); + setShowMapPicker(false); + }}> + + + + + {/* Body */} + + + {/* Horário */} + + + + + Horário * + + + + + {generateAvailableTimes( + editingTimelineIndex !== null && editingTimelineIndex > 0 && addActivityPosition !== 'move' + ? itineraryState[selectedDayIndex]?.timeline[editingTimelineIndex - 1]?.time + : undefined, + editingTimelineIndex !== null && itineraryState[selectedDayIndex]?.timeline[editingTimelineIndex + 1] && addActivityPosition !== 'move' + ? itineraryState[selectedDayIndex]?.timeline[editingTimelineIndex + 1]?.time + : undefined + ).map((time) => ( + setNewActivityData({ ...newActivityData, time })} + style={{ marginRight: 8 }} + > + + + {time} + + + + ))} + + + + + {/* Título */} + + + + + Título da Atividade * + + + setNewActivityData({ ...newActivityData, title: text })} + placeholder="Ex: Visita à Torre Eiffel" + placeholderTextColor="#999" + style={{ + backgroundColor: "#F8F8F8", + borderRadius: 12, + padding: 14, + fontSize: 15, + color: "#000", + borderWidth: 1, + borderColor: "#E5E5E5" + }} + /> + + + {/* Descrição */} + + + + + Descrição (Opcional) + + + setNewActivityData({ ...newActivityData, description: text })} + placeholder="Detalhes adicionais sobre a atividade" + placeholderTextColor="#999" + multiline + numberOfLines={3} + style={{ + backgroundColor: "#F8F8F8", + borderRadius: 12, + padding: 14, + fontSize: 15, + color: "#000", + borderWidth: 1, + borderColor: "#E5E5E5", + minHeight: 80, + textAlignVertical: "top" + }} + /> + + + {/* Categoria */} + + + + + Categoria + + + + {["Ponto Turístico", "Gastronomia", "Hospedagem", "Vida Noturna", "Parques", "Shopping", "Cultura", "Viagens"].map((cat) => ( + setNewActivityData({ ...newActivityData, category: cat })} + style={{ marginRight: 8 }} + > + + + {cat} + + + + ))} + + + + {/* Localização no Mapa */} + + + + + Localização no Mapa (Opcional) + + + setShowMapPicker(!showMapPicker)}> + + + {selectedCoordinates + ? `${selectedCoordinates.latitude.toFixed(4)}; ${selectedCoordinates.longitude.toFixed(4)}` + : 'Toque para selecionar no mapa'} + + + + {showMapPicker && ( + + + + Clique duas vezes no mapa para selecionar a nova localização! + + + + { + setSelectedCoordinates(e.nativeEvent.coordinate); + }} + > + {selectedCoordinates && ( + + )} + + + + )} + + + + + {/* Footer */} + + + + + + + + + )} + + { + setShowExpenseModal(false); + setCurrentExpenseContext(null); + }} + onAdd={handleAddExpense} + defaultTitle={currentExpenseContext?.title || ""} + defaultDescription={currentExpenseContext?.description || ""} + defaultDate={currentExpenseContext?.date || ""} + defaultLocation={currentExpenseContext?.location || ""} + itineraryTitle={title} + /> + + setShowExpenseAddedModal(false)} + onViewExpenses={() => { + setShowExpenseAddedModal(false); + navigation.navigate("ExpenseControl"); + }} + expenseTitle={lastAddedExpense?.title || ""} + expenseAmount={lastAddedExpense?.amount || 0} + /> ); diff --git a/expo-app/src/config.ts b/expo-app/src/config.ts index ca4b36e..23dd708 100644 --- a/expo-app/src/config.ts +++ b/expo-app/src/config.ts @@ -1 +1 @@ -export const API_URL = "http://SEU-IP-AQUI:3000/api"; \ No newline at end of file +export const API_URL = "https://guiaturisticoeztripai.vercel.app/api"; \ No newline at end of file diff --git a/expo-app/src/data/itineraries.ts b/expo-app/src/data/itineraries.ts index 9ecffdf..3fe4789 100644 --- a/expo-app/src/data/itineraries.ts +++ b/expo-app/src/data/itineraries.ts @@ -3,8 +3,8 @@ import { CreatingItinerary } from "../../@types/CreatingItinerary"; export let userTrips: CreatingItinerary[] = [ { title: "Vive la France (Demo)", - dateBegin: new Date("2025-12-01"), - dateEnd: new Date("2025-12-06"), + dateBegin: new Date("2026-01-20"), + dateEnd: new Date("2026-01-26"), days: 6, continent: "Europe", countries: [ @@ -25,6 +25,7 @@ export let userTrips: CreatingItinerary[] = [ visitPreferences: [ "Museums", "Monuments", "Parks", "Culture", "Food" ], + status: "Rascunho", itinerary: [ { day: 1, diff --git a/expo-app/src/hooks/useExpenseControl.ts b/expo-app/src/hooks/useExpenseControl.ts new file mode 100644 index 0000000..08ba346 --- /dev/null +++ b/expo-app/src/hooks/useExpenseControl.ts @@ -0,0 +1,141 @@ +import { useState, useEffect, useCallback } from 'react'; + +import AsyncStorage from '@react-native-async-storage/async-storage'; + +import { Expense, ExpensesByCategory, ExpenseCategory } from '../../@types/ExpenseControlTypes'; + +const EXPENSES_STORAGE_KEY = '@eztripai_userExpenses'; +const BUDGET_LIMIT_STORAGE_KEY = '@eztripai_userBudgetLimit'; + +export function useExpenseControl() { + const [expenses, setExpenses] = useState([]); + const [budgetLimit, setBudgetLimit] = useState(null); + const [isLoading, setIsLoading] = useState(true); + + const loadExpenses = useCallback(async () => { + try { + setIsLoading(true); + const jsonValue = await AsyncStorage.getItem(EXPENSES_STORAGE_KEY); + if (jsonValue) { + const loadedExpenses = JSON.parse(jsonValue); + setExpenses(loadedExpenses); + } + + const budgetValue = await AsyncStorage.getItem(BUDGET_LIMIT_STORAGE_KEY); + if (budgetValue) { + setBudgetLimit(parseFloat(budgetValue)); + } + } catch (error) { + // DEBUG: console.error('Erro ao carregar gastos:', error); + } finally { + setIsLoading(false); + } + }, []); + + const addExpense = useCallback(async (expense: Expense) => { + try { + const newExpenses = [...expenses, expense]; + setExpenses(newExpenses); + await AsyncStorage.setItem(EXPENSES_STORAGE_KEY, JSON.stringify(newExpenses)); + } catch (error) { + // DEBUG: console.error('Erro ao adicionar gasto:', error); + } + }, [expenses]); + + const removeExpense = useCallback(async (expenseId: string) => { + try { + const updatedExpenses = expenses.filter(expense => expense.id !== expenseId); + setExpenses(updatedExpenses); + await AsyncStorage.setItem(EXPENSES_STORAGE_KEY, JSON.stringify(updatedExpenses)); + } catch (error) { + // DEBUG: console.error('Erro ao remover gasto:', error); + } + }, [expenses]); + + const updateExpense = useCallback(async (expenseId: string, updatedExpense: Partial) => { + try { + const updatedExpenses = expenses.map(expense => + expense.id === expenseId ? { ...expense, ...updatedExpense } : expense + ); + setExpenses(updatedExpenses); + await AsyncStorage.setItem(EXPENSES_STORAGE_KEY, JSON.stringify(updatedExpenses)); + } catch (error) { + // DEBUG: console.error('Erro ao atualizar gasto:', error); + } + }, [expenses]); + + const getTotalExpenses = useCallback(() => { + return expenses.reduce((total, expense) => total + expense.amount, 0); + }, [expenses]); + + const getExpensesByCategory = useCallback((): ExpensesByCategory => { + const categories: ExpensesByCategory = { + "Transporte": 0, + "Hospedagem": 0, + "Alimentação": 0, + "Atividades": 0, + "Compras": 0, + "Emergência": 0, + "Outros": 0 + }; + + expenses.forEach(expense => { + categories[expense.category] += expense.amount; + }); + + return categories; + }, [expenses]); + + const getExpensesByItinerary = useCallback((itineraryTitle: string) => { + return expenses.filter(expense => expense.itineraryTitle === itineraryTitle); + }, [expenses]); + + const clearAllExpenses = useCallback(async () => { + try { + setExpenses([]); + await AsyncStorage.removeItem(EXPENSES_STORAGE_KEY); + } catch (error) { + // DEBUG: console.error('Erro ao limpar gastos:', error); + } + }, []); + + const setBudgetLimitValue = useCallback(async (limit: number | null) => { + try { + if (limit === null) { + setBudgetLimit(null); + await AsyncStorage.removeItem(BUDGET_LIMIT_STORAGE_KEY); + } else { + setBudgetLimit(limit); + await AsyncStorage.setItem(BUDGET_LIMIT_STORAGE_KEY, limit.toString()); + } + } catch (error) { + // DEBUG: console.error('Erro ao definir limite de orçamento:', error); + } + }, []); + + const getBudgetProgress = useCallback(() => { + if (!budgetLimit || budgetLimit === 0) return 0; + const total = getTotalExpenses(); + return Math.min((total / budgetLimit) * 100, 100); + }, [budgetLimit, getTotalExpenses]); + + useEffect(() => { + loadExpenses(); + }, [loadExpenses]); + + return { + expenses, + isLoading, + budgetLimit, + addExpense, + removeExpense, + updateExpense, + getTotalExpenses, + getExpensesByCategory, + getExpensesByItinerary, + clearAllExpenses, + setBudgetLimitValue, + getBudgetProgress, + reloadExpenses: loadExpenses + }; +} \ No newline at end of file diff --git a/expo-app/src/hooks/useFavoritePlaces.ts b/expo-app/src/hooks/useFavoritePlaces.ts new file mode 100644 index 0000000..38ea794 --- /dev/null +++ b/expo-app/src/hooks/useFavoritePlaces.ts @@ -0,0 +1,84 @@ +import { useState, useEffect, useCallback } from 'react'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { FavoritePlace } from '../../@types/FavoritePlacesTypes'; + +const FAVORITE_PLACES_STORAGE_KEY = '@eztripai_userFavoritePlaces'; + +export function useFavoritePlaces() { + const [favoritePlaces, setFavoritePlaces] = useState([]); + const [isLoading, setIsLoading] = useState(true); + + // Carrega os favoritos do AsyncStorage + const loadFavoritePlaces = useCallback(async () => { + try { + setIsLoading(true); + const jsonValue = await AsyncStorage.getItem(FAVORITE_PLACES_STORAGE_KEY); + if (jsonValue) { + const places = JSON.parse(jsonValue); + setFavoritePlaces(places); + } + } catch (error) { + // DEBUG: console.error('Erro ao carregar locais favoritos:', error); + } finally { + setIsLoading(false); + } + }, []); + + // Adiciona um novo local aos favoritos + const addFavoritePlace = useCallback(async (place: FavoritePlace) => { + try { + const currentFavorites = [...favoritePlaces]; + + // Verifica se o local já está nos favoritos + const alreadyExists = currentFavorites.some(fav => fav.id === place.id); + + if (!alreadyExists) { + const newFavorites = [...currentFavorites, place]; + setFavoritePlaces(newFavorites); + await AsyncStorage.setItem(FAVORITE_PLACES_STORAGE_KEY, JSON.stringify(newFavorites)); + } + } catch (error) { + // DEBUG: console.error('Erro ao adicionar local aos favoritos:', error); + } + }, [favoritePlaces]); + + // Remove um local dos favoritos + const removeFavoritePlace = useCallback(async (placeId: string) => { + try { + const updatedFavorites = favoritePlaces.filter(place => place.id !== placeId); + setFavoritePlaces(updatedFavorites); + await AsyncStorage.setItem(FAVORITE_PLACES_STORAGE_KEY, JSON.stringify(updatedFavorites)); + } catch (error) { + // DEBUG: console.error('Erro ao remover local dos favoritos:', error); + } + }, [favoritePlaces]); + + // Verifica se um local está nos favoritos + const isFavorite = useCallback((placeId: string) => { + return favoritePlaces.some(place => place.id === placeId); + }, [favoritePlaces]); + + // Limpa todos os favoritos + const clearAllFavorites = useCallback(async () => { + try { + setFavoritePlaces([]); + await AsyncStorage.removeItem(FAVORITE_PLACES_STORAGE_KEY); + } catch (error) { + // DEBUG: console.error('Erro ao limpar favoritos:', error); + } + }, []); + + useEffect(() => { + loadFavoritePlaces(); + }, [loadFavoritePlaces]); + + return { + favoritePlaces, + isLoading, + addFavoritePlace, + removeFavoritePlace, + isFavorite, + clearAllFavorites, + reloadFavorites: loadFavoritePlaces + }; +} \ No newline at end of file diff --git a/expo-app/src/routes/auth.routes.tsx b/expo-app/src/routes/auth.routes.tsx index 6f342b4..8953a89 100644 --- a/expo-app/src/routes/auth.routes.tsx +++ b/expo-app/src/routes/auth.routes.tsx @@ -9,6 +9,8 @@ import { GenerateItineraryMenu } from "@screens/Itinerary/GenerateItineraryMenu" import { GenerateItineraryFeaturesIntroduction } from "@screens/Itinerary/GenerateItineraryFeaturesIntroduction"; import { GenerateItineraryPreferences } from "@screens/Itinerary/GenerateItineraryPreferences"; import { ItineraryMapMenu } from "@screens/Itinerary/ItineraryMapMenu"; +import { FavoritePlaces } from "@screens/Itinerary/FavoritePlaces"; +import { ExpenseControl } from "@screens/Itinerary/ExpenseControl"; import { AIChat } from "@screens/AIChat/AIChat"; import { AIVoiceChat } from "@screens/AIChat/AIVoiceChat"; import { AIMascotIntroduction } from "@screens/AIChat/AIMascotIntroduction"; @@ -39,6 +41,8 @@ type AuthStackParamList = { CancelPremiumPlan: undefined, DestinationDetail: { destinationId: number }, EditProfile: undefined, + ExpenseControl: undefined, + FavoritePlaces: undefined, GenerateItineraryFeaturesIntroduction: undefined, GenerateItineraryMenu: undefined, GenerateItineraryPreferences: { title: CreatingItinerary["title"], dateBegin: CreatingItinerary["dateBegin"], dateEnd: CreatingItinerary["dateEnd"], days: CreatingItinerary["days"], continent: CreatingItinerary["continent"], countries: CreatingItinerary["countries"], originCountry: CreatingItinerary["originCountry"], contacts: CreatingItinerary["contacts"] }, @@ -173,6 +177,16 @@ export function AuthRoute() { component={ ItineraryVisaCheck } options={{ animation: 'none' }} /> + + { @@ -175,7 +176,7 @@ export function AIChat() { return { temperature: "--", condition: "--" }; } const { latitude, longitude } = location.coords; - const response = await fetch(`http://SEU-IP-AQUI:3000/api/weather?latitude=${latitude}&longitude=${longitude}`); + const response = await fetch(`https://guiaturisticoeztripai.vercel.app/api/weather?latitude=${latitude}&longitude=${longitude}`); if (!response.ok) { console.error(`Failed to fetch weather data: ${response.status} ${response.statusText}`); return { temperature: "--", condition: "--" }; diff --git a/expo-app/src/screens/HomePage/Home.tsx b/expo-app/src/screens/HomePage/Home.tsx index 2aa614d..5f0d6c5 100644 --- a/expo-app/src/screens/HomePage/Home.tsx +++ b/expo-app/src/screens/HomePage/Home.tsx @@ -116,7 +116,7 @@ export function Home() { const { latitude, longitude } = location.coords; const response = await fetch( - `http://SEU-IP-AQUI:3000/api/googlePlacesApi?latitude=${latitude}&longitude=${longitude}`, + `https://guiaturisticoeztripai.vercel.app/api/googlePlacesApi?latitude=${latitude}&longitude=${longitude}`, { method: 'GET', headers: { diff --git a/expo-app/src/screens/HomePage/MapsExpanded.tsx b/expo-app/src/screens/HomePage/MapsExpanded.tsx index cc380c5..cf68494 100644 --- a/expo-app/src/screens/HomePage/MapsExpanded.tsx +++ b/expo-app/src/screens/HomePage/MapsExpanded.tsx @@ -1,4 +1,4 @@ -import { useRef } from "react"; +import { useRef, useContext } from "react"; import { SafeAreaView, StatusBar } from "react-native"; import MapView from "react-native-maps"; @@ -12,6 +12,7 @@ import { SlideUp } from "@components/Sliders/SlideUpPlaces"; import { RecenterButton } from "@components/Maps/RecenterButton"; import { AuthNavigationProp } from "@routes/auth.routes"; +import { LocationContext } from "@contexts/requestDeviceLocation"; import { Place } from "../../../@types/PlacesTypes"; @@ -21,15 +22,17 @@ export function MapsExpanded() { const navigation = useNavigation(); const route = useRoute(); const { places, isLoading } = route.params; + const locationContext = useContext(LocationContext); + const location = locationContext?.location || null; const mapUserPositionRef = useRef(null); const recenterMap = () => { - if (mapUserPositionRef.current) { + if (mapUserPositionRef.current && location) { mapUserPositionRef.current.animateToRegion( { - latitude: places[0]?.geometry.location.lat || 0, - longitude: places[0]?.geometry.location.lng || 0, + latitude: location.coords.latitude, + longitude: location.coords.longitude, latitudeDelta: 0.0102, longitudeDelta: 0.0021 }, 1000 diff --git a/expo-app/src/screens/Itinerary/ExpenseControl.tsx b/expo-app/src/screens/Itinerary/ExpenseControl.tsx new file mode 100644 index 0000000..edf7149 --- /dev/null +++ b/expo-app/src/screens/Itinerary/ExpenseControl.tsx @@ -0,0 +1,655 @@ +import { useState, useCallback } from "react"; + +import { SafeAreaView, StatusBar, TouchableOpacity, Alert, TextInput, Modal, KeyboardAvoidingView, Platform } from "react-native"; +import { useNavigation, useFocusEffect } from "@react-navigation/native"; + +import { ScrollView, Text, View, Spinner, Button, ButtonText, Progress, ProgressFilledTrack } from "@gluestack-ui/themed"; + +import { + ArrowLeft, + Trash2, + TrendingUp, + Wallet, + CreditCard, + Plane, + Bed, + UtensilsCrossed, + ShoppingCart, + Activity, + AlertCircle, + MoreHorizontal, + Banknote, + Edit2, + X, + Check, + DollarSign +} from "lucide-react-native"; + +import { IconButton } from "@components/Buttons/IconButton"; + +import { AuthNavigationProp } from "@routes/auth.routes"; + +import { useExpenseControl } from "../../hooks/useExpenseControl"; + +import { Expense, ExpenseCategory } from "../../../@types/ExpenseControlTypes"; + +export function ExpenseControl() { + const navigation = useNavigation(); + const { expenses, isLoading, budgetLimit, removeExpense, updateExpense, getTotalExpenses, getExpensesByCategory, clearAllExpenses, setBudgetLimitValue, getBudgetProgress, reloadExpenses } = useExpenseControl(); + const [isDeleting, setIsDeleting] = useState(null); + const [selectedFilter, setSelectedFilter] = useState<"Todos" | ExpenseCategory>("Todos"); + const [isEditingBudget, setIsEditingBudget] = useState(false); + const [budgetInput, setBudgetInput] = useState(""); + const [editingExpense, setEditingExpense] = useState(null); + const [editAmount, setEditAmount] = useState(""); + + useFocusEffect( + useCallback(() => { + reloadExpenses(); + }, [reloadExpenses]) + ); + + const handleRemoveExpense = async (expenseId: string, expenseTitle: string) => { + Alert.alert( + "Remover Gasto", + `Deseja remover "${expenseTitle}"?`, + [ + { text: "Cancelar", style: "cancel" }, + { + text: "Remover", + style: "destructive", + onPress: async () => { + setIsDeleting(expenseId); + await removeExpense(expenseId); + setIsDeleting(null); + } + } + ] + ); + }; + + const handleClearAll = () => { + Alert.alert( + "Limpar Todos os Gastos", + "Deseja realmente remover todos os gastos? Esta ação não pode ser desfeita.", + [ + { text: "Cancelar", style: "cancel" }, + { + text: "Limpar Tudo", + style: "destructive", + onPress: clearAllExpenses + } + ] + ); + }; + + const handleSetBudget = () => { + if (isEditingBudget) { + const value = parseFloat(budgetInput); + if (!isNaN(value) && value > 0) { + setBudgetLimitValue(value); + } else if (budgetInput === "") { + setBudgetLimitValue(null); + } + setIsEditingBudget(false); + setBudgetInput(""); + } else { + setIsEditingBudget(true); + setBudgetInput(budgetLimit?.toString() || ""); + } + }; + + const handleCancelBudgetEdit = () => { + setIsEditingBudget(false); + setBudgetInput(""); + }; + + const handleEditExpense = (expense: Expense) => { + setEditingExpense(expense); + setEditAmount(expense.amount.toString()); + }; + + const handleSaveEditExpense = async () => { + if (!editingExpense || !editAmount || parseFloat(editAmount) <= 0) { + return; + } + + await updateExpense(editingExpense.id, { + amount: parseFloat(editAmount) + }); + + setEditingExpense(null); + setEditAmount(""); + }; + + const handleCancelEditExpense = () => { + setEditingExpense(null); + setEditAmount(""); + }; + + const formatCurrency = (value: number) => { + return new Intl.NumberFormat('pt-BR', { + style: 'currency', + currency: 'BRL' + }).format(value); + }; + + const formatDate = (dateString: string) => { + try { + const [year, month, day] = dateString.split('-').map(Number); + const date = new Date(year, month - 1, day); + return date.toLocaleDateString('pt-BR', { day: '2-digit', month: 'short' }); + } catch { + return dateString; + } + }; + + const getCategoryIcon = (category: ExpenseCategory) => { + switch (category) { + case "Transporte": + return Plane; + case "Hospedagem": + return Bed; + case "Alimentação": + return UtensilsCrossed; + case "Atividades": + return Activity; + case "Compras": + return ShoppingCart; + case "Emergência": + return AlertCircle; + default: + return MoreHorizontal; + } + }; + + const getCategoryColor = (category: ExpenseCategory) => { + switch (category) { + case "Transporte": + return "#3B82F6"; + case "Hospedagem": + return "#8B5CF6"; + case "Alimentação": + return "#10B981"; + case "Atividades": + return "#F59E0B"; + case "Compras": + return "#EC4899"; + case "Emergência": + return "#EF4444"; + default: + return "#6B7280"; + } + }; + + const filteredExpenses = selectedFilter === "Todos" + ? expenses + : expenses.filter(exp => exp.category === selectedFilter); + + const totalExpenses = getTotalExpenses(); + const expensesByCategory = getExpensesByCategory(); + + const categories: Array<"Todos" | ExpenseCategory> = [ + "Todos", + "Transporte", + "Hospedagem", + "Alimentação", + "Atividades", + "Compras", + "Emergência", + "Outros" + ]; + + return ( + + + + + navigation.goBack()} + styles={{ marginLeft: -15 }} + /> + { expenses.length > 0 && ( + + + + Limpar Tudo + + + )} + + + Controle de Gastos + + + + + + Total de Gastos + + + + + + + + { formatCurrency(totalExpenses) } + + {expenses.length} {expenses.length === 1 ? 'gasto registrado' : 'gastos registrados'} + + + { budgetLimit && ( + + + + Limite: {formatCurrency(budgetLimit)} + + = 100 ? "#FEE2E2" : getBudgetProgress() >= 80 ? "#FEF3C7" : "#E0E7FF" } + > + { getBudgetProgress().toFixed(1) }% + + + + = 100 + ? "#FEE2E2" + : getBudgetProgress() >= 80 + ? "#FEF3C7" + : "#E0E7FF" + } + /> + + { getBudgetProgress() >= 80 && ( + = 100 ? "#FEE2E2" : "#FEF3C7" } + p={10} + borderRadius={10} + mt={10} + flexDirection="row" + alignItems="center" + > + = 100 ? "#991B1B" : "#92400E" } + style={{ marginRight: 8 }} + /> + = 100 ? "#991B1B" : "#92400E" } + flex={1} + > + { getBudgetProgress() >= 100 + ? "Limite ultrapassado!" + : "Próximo do limite"} + + + )} + + )} + + + { isEditingBudget && ( + + + + + + {budgetLimit ? "Editar Limite" : "Definir Limite"} + + + + { + const numericValue = text.replace(/[^0-9.]/g, ''); + setBudgetInput(numericValue); + }} + placeholder="Digite o limite em R$" + placeholderTextColor="#999" + keyboardType="decimal-pad" + autoFocus + style={{ + backgroundColor: "#F8F8F8", + borderRadius: 12, + padding: 14, + fontSize: 16, + color: "#000", + borderWidth: 1, + borderColor: "#2752B7", + marginBottom: 10 + }} + /> + + + + + + )} + + + { categories.map((category) => ( + setSelectedFilter(category)} + style={{ marginRight: 10 }} + > + + + {category} + + + + ))} + + + { selectedFilter !== "Todos" && expensesByCategory[selectedFilter as ExpenseCategory] !== undefined && ( + + Total em {selectedFilter} + + {formatCurrency(expensesByCategory[selectedFilter as ExpenseCategory] || 0)} + + + )} + + { selectedFilter === "Todos" && expenses.length > 0 && ( + + + + Você pode filtrar os gastos por categoria. Experimente! + + + )} + + + { isLoading ? ( + + + Carregando gastos... + + ) : filteredExpenses.length === 0 ? ( + + + + {selectedFilter === "Todos" ? "Nenhum gasto registrado" : `Nenhum gasto em ${selectedFilter}`} + + + Adicione gastos durante a visualização dos seus roteiros + + + ) : ( + filteredExpenses.map((expense) => { + const CategoryIcon = getCategoryIcon(expense.category); + const categoryColor = getCategoryColor(expense.category); + + return ( + + + + + + + + { expense.title } + + + + + + { expense.category } + + + + { formatDate(expense.date) } + + + + { expense.description && ( + + { expense.description } + + )} + + + { expense.itineraryTitle } + + + + + + { formatCurrency(expense.amount) } + + + + handleEditExpense(expense) } + > + + + + + + handleRemoveExpense(expense.id, expense.title) } + disabled={ isDeleting === expense.id } + > + + {isDeleting === expense.id ? ( + + ) : ( + + )} + + + + + + ); + }) + )} + + + + + { editingExpense && ( + + + + + + + Editar Valor do Gasto + + + + + + + + + { editingExpense.title } + + + Valor atual: { formatCurrency(editingExpense.amount) } + + + + + + Novo Valor + + + { + const numericValue = text.replace(/[^0-9.]/g, ''); + setEditAmount(numericValue); + }} + placeholder="0.00" + placeholderTextColor="#999" + keyboardType="decimal-pad" + autoFocus + style={{ + backgroundColor: "#F8F8F8", + borderRadius: 12, + padding: 14, + fontSize: 16, + color: "#000", + borderWidth: 1, + borderColor: "#2752B7" + }} + /> + + + + + + + + + + + )} + + ); +} \ No newline at end of file diff --git a/expo-app/src/screens/Itinerary/FavoritePlaces.tsx b/expo-app/src/screens/Itinerary/FavoritePlaces.tsx new file mode 100644 index 0000000..3a2987b --- /dev/null +++ b/expo-app/src/screens/Itinerary/FavoritePlaces.tsx @@ -0,0 +1,260 @@ +import { useState, useCallback } from "react"; +import { SafeAreaView, StatusBar, Image as RNImage, TouchableOpacity, Alert } from "react-native"; +import { useNavigation, useFocusEffect } from "@react-navigation/native"; + +import { ScrollView, Text, View, Spinner } from "@gluestack-ui/themed"; + +import { IconButton } from "@components/Buttons/IconButton"; + +import { AuthNavigationProp } from "@routes/auth.routes"; + +import { useFavoritePlaces } from "../../hooks/useFavoritePlaces"; + +import DefaultImage from '@assets/adaptive-icon.png'; + +import { ArrowLeft, Trash2, MapPin, Calendar, Heart } from "lucide-react-native"; + +export function FavoritePlaces() { + const navigation = useNavigation(); + const { favoritePlaces, isLoading, removeFavoritePlace, clearAllFavorites, reloadFavorites } = useFavoritePlaces(); + const [isDeleting, setIsDeleting] = useState(null); + + useFocusEffect( + useCallback(() => { + reloadFavorites(); + }, [reloadFavorites]) + ); + + const handleRemoveFavorite = async (placeId: string, placeTitle: string) => { + Alert.alert( + "Remover Favorito", + `Deseja remover "${placeTitle}" dos favoritos?`, + [ + { text: "Cancelar", style: "cancel" }, + { + text: "Remover", + style: "destructive", + onPress: async () => { + setIsDeleting(placeId); + await removeFavoritePlace(placeId); + setIsDeleting(null); + } + } + ] + ); + }; + + const handleClearAll = () => { + Alert.alert( + "Limpar Todos os Favoritos", + "Deseja realmente remover todos os locais favoritos? Esta ação não pode ser desfeita.", + [ + { text: "Cancelar", style: "cancel" }, + { + text: "Limpar Tudo", + style: "destructive", + onPress: clearAllFavorites + } + ] + ); + }; + + const formatDate = (dateString: string) => { + try { + const [year, month, day] = dateString.split('-').map(Number); + const date = new Date(year, month - 1, day); + return date.toLocaleDateString('pt-BR', { day: '2-digit', month: 'long', year: 'numeric' }); + } catch { + return dateString; + } + }; + + const formatCoordinates = (coordinates: string) => { + const [lat, lng] = coordinates.split(',').map(coord => coord.trim()); + return `${parseFloat(lat).toFixed(4)}, ${parseFloat(lng).toFixed(4)}`; + }; + + return ( + + + + {/* Header */} + + navigation.goBack()} + styles={{ marginLeft: -15 }} + /> + {favoritePlaces.length > 0 && ( + + + + Limpar Tudo + + + )} + + + Locais Favoritados + + + {favoritePlaces.length === 0 + ? "Nenhum local favoritado ainda" + : `${favoritePlaces.length} ${favoritePlaces.length === 1 ? 'local favorito' : 'locais favoritos'}` + } + + + {/* Lista de Favoritos */} + + {isLoading ? ( + + + Carregando favoritos... + + ) : favoritePlaces.length === 0 ? ( + + + + Nenhum local favoritado + + + Adicione locais aos seus favoritos durante a visualização dos seus roteiros + + + ) : ( + favoritePlaces.map((place, index) => ( + + {/* Imagem do Local */} + {place.images && place.images.length > 0 ? ( + + ) : ( + + )} + + {/* Informações do Local */} + + {/* Título e Botão de Remover */} + + + + {place.title} + + {place.category && ( + + + {place.category} + + + )} + + + handleRemoveFavorite(place.id, place.title)} + disabled={isDeleting === place.id} + > + + {isDeleting === place.id ? ( + + ) : ( + + )} + + + + + {/* Descrição */} + + {place.description} + + + {/* Informações Adicionais */} + + {/* Roteiro de Origem */} + + + + + + Roteiro + {place.itineraryTitle} + + + + {/* Localização */} + + + + + + Localização + {place.location} + + + + {/* Data */} + + + + + + Data da Visita + {formatDate(place.date)} + + + + + + )) + )} + + + + + ); +} diff --git a/expo-app/src/screens/Itinerary/GenerateItineraryMenu.tsx b/expo-app/src/screens/Itinerary/GenerateItineraryMenu.tsx index 55d769f..39da9db 100644 --- a/expo-app/src/screens/Itinerary/GenerateItineraryMenu.tsx +++ b/expo-app/src/screens/Itinerary/GenerateItineraryMenu.tsx @@ -1,7 +1,9 @@ import { useEffect, useState, useRef } from "react"; + import { Platform, SafeAreaView, StatusBar, Image as RNImage, TouchableOpacity } from "react-native"; -import { useNavigation } from "@react-navigation/native"; +import { useNavigation, useFocusEffect } from "@react-navigation/native"; import AsyncStorage from "@react-native-async-storage/async-storage"; +import { useCallback } from "react"; import Constants from 'expo-constants'; @@ -25,10 +27,13 @@ import { ButtonIconLeft } from "@components/Buttons/ButtonIconLeft"; import { ItineraryCreateDialog } from "@components/Itinerary/ItineraryCreateDialog"; import { UnlockProgressModal } from "@components/Itinerary/UnlockProgressModal"; import { ItinerariesError } from "@components/Errors/ItinerariesError"; +import { PastItinerariesError } from "@components/Errors/PastItinerariesError"; import { IconButton } from "@components/Buttons/IconButton"; import { SimulatedAd } from "@components/SimulatedAd"; import { ChooseGenerateStyle } from "@components/Itinerary/ChooseGenerateStyle"; import { ItineraryPreferencesModal } from "@components/Itinerary/ItineraryPreferencesModal"; +import { ItineraryCard } from "@components/Cards/ItineraryCard"; +import { ItineraryActionsDialog } from "@components/Dialogs/ItineraryActionsDialog"; import { userTrips } from "@data/itineraries"; @@ -38,9 +43,10 @@ import { CreatingItinerary } from "../../../@types/CreatingItinerary"; import DefaultImage from '@assets/adaptive-icon.png'; -import { ArrowLeft, ChevronRight, Coins, Crown, Heart, Plus } from "lucide-react-native"; import { utilsGetSelectedTags } from "@utils/selectedTagsStore"; +import { ArrowLeft, ChevronRight, Coins, Crown, Heart, Plus } from "lucide-react-native"; + type MenuItineraryTypes = { dialog: boolean, filters: "Planejados" | "Rascunhos" | "Passados" @@ -58,6 +64,8 @@ export function GenerateItineraryMenu(){ const [watchedAdsCount, setWatchedAdsCount] = useState(0); const [isAdPlaying, setIsAdPlaying] = useState(false); const [allUserItineraries, setAllUserItineraries] = useState([]); + const [selectedItineraryIndex, setSelectedItineraryIndex] = useState(null); + const [showActionsDialog, setShowActionsDialog] = useState(false); const totalAdsRequired = 3; @@ -251,6 +259,83 @@ export function GenerateItineraryMenu(){ return daysDifference; } + // Função para obter o último itinerário válido (não passado) + const getLatestValidItinerary = (): CreatingItinerary | null => { + const today = new Date(); + today.setHours(0, 0, 0, 0); + + // Filtra itinerários que não passaram ainda + const validItineraries = allUserItineraries.filter(itinerary => { + const endDate = new Date(itinerary.dateEnd); + endDate.setHours(0, 0, 0, 0); + return endDate >= today; + }); + + // Retorna o último itinerário adicionado (último do array) + return validItineraries.length > 0 ? validItineraries[validItineraries.length - 1] : null; + }; + + // Função para filtrar itinerários com base no filtro selecionado + const getFilteredItineraries = (): CreatingItinerary[] => { + const today = new Date(); + today.setHours(0, 0, 0, 0); + + return allUserItineraries.filter(itinerary => { + const endDate = new Date(itinerary.dateEnd); + endDate.setHours(0, 0, 0, 0); + + // Se não tiver status definido, considera como Rascunho + const status = itinerary.status || "Rascunho"; + + if (selectedFilter === "Planejados") { + return status === "Planejado" && endDate >= today; + } else if (selectedFilter === "Rascunhos") { + return status === "Rascunho"; + } else if (selectedFilter === "Passados") { + return endDate < today || status === "Passado"; + } + return false; + }); + }; + + // Função para editar itinerário + const handleEditItinerary = (itinerary: CreatingItinerary) => { + navigation.navigate("ItineraryMapMenu", { + itineraryData: itinerary, + userPreferences: itinerary.visitPreferences || utilsGetSelectedTags(), + visaIssue: itinerary.visa === true ? "Positive" : itinerary.visa === false ? "Negative" : itinerary.visa + }); + }; + + // Função para excluir itinerário + const handleDeleteItinerary = async (index: number) => { + try { + const updatedItineraries = [...allUserItineraries]; + updatedItineraries.splice(index, 1); + + await AsyncStorage.setItem('@eztripai_allUserTripItineraries', JSON.stringify(updatedItineraries)); + setAllUserItineraries(updatedItineraries); + } catch (error) { + console.error('Erro ao excluir itinerário:', error); + } + }; + + // Função para mover itinerário entre status + const handleMoveItinerary = async (index: number) => { + try { + const updatedItineraries = [...allUserItineraries]; + const currentStatus = updatedItineraries[index].status || "Rascunho"; + + // Alternar entre Planejado e Rascunho + updatedItineraries[index].status = currentStatus === "Planejado" ? "Rascunho" : "Planejado"; + + await AsyncStorage.setItem('@eztripai_allUserTripItineraries', JSON.stringify(updatedItineraries)); + setAllUserItineraries(updatedItineraries); + } catch (error) { + console.error('Erro ao mover itinerário:', error); + } + }; + useEffect(() => { loadNewAd(); }, []); @@ -275,7 +360,7 @@ export function GenerateItineraryMenu(){ const getUserTripsData = async () => { try { - //await AsyncStorage.clear(); + // PARA HARD RESET DOS ITINERÁRIOS PADRÕES: await AsyncStorage.clear(); const jsonValue = await AsyncStorage.getItem('@eztripai_allUserTripItineraries'); if (jsonValue) { setAllUserItineraries(JSON.parse(jsonValue)); @@ -290,6 +375,24 @@ export function GenerateItineraryMenu(){ getUserTripsData(); }, []); + + // Recarregar itinerários quando a tela receber foco + useFocusEffect( + useCallback(() => { + const reloadItineraries = async () => { + try { + const jsonValue = await AsyncStorage.getItem('@eztripai_allUserTripItineraries'); + if (jsonValue) { + setAllUserItineraries(JSON.parse(jsonValue)); + } + } catch (e) { + console.log("Erro ao recarregar itinerários: ", e); + } + }; + + reloadItineraries(); + }, []) + ); return( @@ -319,80 +422,115 @@ export function GenerateItineraryMenu(){ Itinerários - { - const itineraryData = allUserItineraries[0]; - if (itineraryData) { - navigation.navigate("ItineraryMapMenu", { - itineraryData: itineraryData, - userPreferences: utilsGetSelectedTags(), - visaIssue: itineraryData.visa === true ? "Positive" : itineraryData.visa === false ? "Negative" : itineraryData.visa - }); - } - }} - activeOpacity={0.8} - > - - {(() => { - const firstImage = itineraries?.[0]?.itinerary?.[0]?.images?.[0]; - - return firstImage ? ( - - ) : ( - - ); - })()} - - {(() => { - const itineraries = allUserItineraries as any[]; - const firstItinerary = itineraries?.[0]; - return firstItinerary ? ( - <> - - {firstItinerary.title} - - Em {daysUntilTravel(firstItinerary.dateBegin)} dias - - - - ) : null; - })()} - - - + {(() => { + const latestItinerary = getLatestValidItinerary(); + + if (!latestItinerary) { + return ( + + + + + + + ); + } + + const firstImage = (latestItinerary.itinerary as any)?.[0]?.images?.[0]; + const imageUri = latestItinerary.coverImage || firstImage; + + return ( + { + navigation.navigate("ItineraryMapMenu", { + itineraryData: latestItinerary, + userPreferences: latestItinerary.visitPreferences || utilsGetSelectedTags(), + visaIssue: latestItinerary.visa === true ? "Positive" : latestItinerary.visa === false ? "Negative" : latestItinerary.visa + }); + }} + activeOpacity={0.8} + > + + {imageUri ? ( + + ) : ( + + )} + + + + {latestItinerary.title} + + + Em {daysUntilTravel(latestItinerary.dateBegin)} dias + + + + + + ); + })()} - - - - - - + { + getFilteredItineraries().length > 0 ? ( + + + { + getFilteredItineraries().map((itinerary, index) => { + const firstImage = (itinerary.itinerary as any)?.[0]?.images?.[0]; + const imageUri = itinerary.coverImage || firstImage; + + // Encontrar o índice real no array original + const originalIndex = allUserItineraries.findIndex(item => + item.title === itinerary.title && + new Date(item.dateBegin).getTime() === new Date(itinerary.dateBegin).getTime() + ); + + return ( + handleEditItinerary(itinerary)} + onOptionsPress={() => { + setSelectedItineraryIndex(originalIndex); + setShowActionsDialog(true); + }} + /> + ); + }) + } + + + ) : ( + + { + selectedFilter === "Passados" ? ( + + ) : ( + <> + + + + ) + } + + ) + } + + {selectedItineraryIndex !== null && ( + { + setShowActionsDialog(false); + setSelectedItineraryIndex(null); + }} + onEdit={() => { + if (selectedItineraryIndex !== null) { + handleEditItinerary(allUserItineraries[selectedItineraryIndex]); + } + }} + onDelete={() => { + if (selectedItineraryIndex !== null) { + handleDeleteItinerary(selectedItineraryIndex); + } + }} + onMove={() => { + if (selectedItineraryIndex !== null) { + handleMoveItinerary(selectedItineraryIndex); + } + }} + /> + )} ) } \ No newline at end of file diff --git a/expo-app/src/screens/Itinerary/ItineraryMapMenu.tsx b/expo-app/src/screens/Itinerary/ItineraryMapMenu.tsx index 846c152..dee04e3 100644 --- a/expo-app/src/screens/Itinerary/ItineraryMapMenu.tsx +++ b/expo-app/src/screens/Itinerary/ItineraryMapMenu.tsx @@ -10,6 +10,8 @@ import { GlassView, GlassContainer, isLiquidGlassAvailable } from 'expo-glass-ef import { Maps } from "@components/Maps/Maps"; import { SlideUpItinerary } from "@components/Sliders/SlideUpItinerary"; +import { ChooseBackgroundDialog } from "@components/Dialogs/ChooseBackgroundDialog"; +import { SaveItineraryDialog } from "@components/Dialogs/SaveItineraryDialog"; import { generateItinerary } from '@utils/gptRequests'; import { useNotificationStore } from '@utils/notificationStore'; @@ -24,8 +26,9 @@ import { CategoriesCounterTypes } from "../../../@types/CategoriesCounterTypes"; import DefaultStatsBackground from "@assets/background.webp"; -import { Bed, ChevronLeft, Compass, Globe, Heart, Images, Landmark, PartyPopper, Plane, ShoppingBag, TreePine, UtensilsCrossed } from 'lucide-react-native'; -import { ChooseBackgroundDialog } from "@components/Dialogs/ChooseBackgroundDialog"; +import { Bed, ChevronLeft, Compass, FileDown, Globe, Landmark, Palette, PartyPopper, Plane, ShoppingBag, TreePine, UtensilsCrossed } from 'lucide-react-native'; + +import { exportItineraryToPDF } from './html/printExportItinerary'; type ShowMapStatsInformationType = { show: "Map" | "Stats" @@ -45,6 +48,8 @@ export function ItineraryMapMenu() { const [selectedDay, setSelectedDay] = useState(0); const [openChooseBackground, setOpenChooseBackground] = useState(false); const [imageBackground, setImageBackground] = useState(""); + const [openSaveDialog, setOpenSaveDialog] = useState(false); + const [isNewItinerary, setIsNewItinerary] = useState(false); const [categoriesCounter, setCategoriesCounter] = useState({ touristAttractions: 0, restaurant: 0, @@ -66,6 +71,147 @@ export function ItineraryMapMenu() { const mapUserPositionRef = useRef(null); const ITINERARY_STORAGE_KEY = '@eztripai_allUserTripItineraries'; + const BACKGROUND_STORAGE_KEY = '@eztripai_statsBackground'; + + // Detectar se é um roteiro novo ou já existente + useEffect(() => { + const checkIfNewItinerary = async () => { + try { + // Primeiro, verifica se tem a flag isNew nos params + if (route.params.itineraryData.isNew === true) { + setIsNewItinerary(true); + return; + } + + const savedItineraries = await AsyncStorage.getItem(ITINERARY_STORAGE_KEY); + if (savedItineraries) { + const itineraries: CreatingItinerary[] = JSON.parse(savedItineraries); + const exists = itineraries.some(item => + item.title === filteredItineraryData.title && + item.dateBegin === route.params.itineraryData.dateBegin + ); + setIsNewItinerary(!exists); + } else { + setIsNewItinerary(true); + } + } catch (error) { + console.error('Erro ao verificar itinerário:', error); + setIsNewItinerary(false); + } + }; + + checkIfNewItinerary(); + }, []); + + // Função para salvar alterações em um roteiro existente + const saveExistingItinerary = async () => { + try { + const savedItineraries = await AsyncStorage.getItem(ITINERARY_STORAGE_KEY); + if (savedItineraries) { + const itineraries: CreatingItinerary[] = JSON.parse(savedItineraries); + const index = itineraries.findIndex(item => + item.title === filteredItineraryData.title && + new Date(item.dateBegin).getTime() === new Date(route.params.itineraryData.dateBegin).getTime() + ); + + if (index !== -1) { + // Atualizar o roteiro existente com os dados atuais + const currentItinerary = itinerary.length > 0 ? itinerary : route.params.itineraryData.itinerary; + + itineraries[index] = { + ...itineraries[index], + itinerary: currentItinerary, + visitPreferences: filteredUserPreferences, + contacts: filteredItineraryData.contacts + }; + + await AsyncStorage.setItem(ITINERARY_STORAGE_KEY, JSON.stringify(itineraries)); + // DEBUG: console.log('Alterações salvas com sucesso'); + } + } + } catch (error) { + console.error('Erro ao salvar alterações do itinerário:', error); + } + }; + + // Função para salvar um novo roteiro + const saveNewItinerary = async (status: "Planejado" | "Rascunho", coverImage?: string) => { + try { + const savedItineraries = await AsyncStorage.getItem(ITINERARY_STORAGE_KEY); + const itineraries: CreatingItinerary[] = savedItineraries ? JSON.parse(savedItineraries) : []; + + const newTrip: CreatingItinerary = { + title: filteredItineraryData.title, + dateBegin: route.params.itineraryData.dateBegin, + dateEnd: route.params.itineraryData.dateEnd, + days: filteredItineraryData.days, + continent: filteredItineraryData.continent, + countries: filteredItineraryData.countries, + originCountry: filteredItineraryData.originCountry, + visa: filteredItineraryData.visa, + budget: filteredItineraryData.budget, + peopleQuantity: filteredItineraryData.peopleQuantity, + acconpanying: filteredItineraryData.acconpanying, + tripStyle: filteredItineraryData.tripStyle, + locomotionMethod: filteredItineraryData.locomotionMethod, + specialWish: filteredItineraryData.specialWish, + visitPreferences: filteredUserPreferences, + contacts: filteredItineraryData.contacts, + itinerary: itinerary.length > 0 ? itinerary : route.params.itineraryData.itinerary, + status: status, + coverImage: coverImage, + isNew: false + }; + + itineraries.push(newTrip); + await AsyncStorage.setItem(ITINERARY_STORAGE_KEY, JSON.stringify(itineraries)); + + addNotification({ + title: "Roteiro Salvo", + description: `Seu roteiro foi salvo como ${status}`, + routeIcon: Globe + }); + } catch (error) { + console.error('Erro ao salvar novo itinerário:', error); + } + }; + + // Função para lidar com o botão de voltar + const handleBackPress = () => { + const currentItinerary = itinerary.length > 0 ? itinerary : route.params.itineraryData.itinerary; + const hasItinerary = currentItinerary && (Array.isArray(currentItinerary) ? currentItinerary.length > 0 : Object.keys(currentItinerary).length > 0); + + if (!hasItinerary) { + navigation.navigate("GenerateItineraryMenu"); + return; + } + + if (isNewItinerary) { + // Mostrar modal de salvamento para novo itinerário + setOpenSaveDialog(true); + } else { + // Salvar automaticamente e navegar de volta + saveExistingItinerary().then(() => { + navigation.navigate("GenerateItineraryMenu"); + }); + } + }; + + // Carregar background salvo ao iniciar + useEffect(() => { + const loadSavedBackground = async () => { + try { + const savedBackground = await AsyncStorage.getItem(BACKGROUND_STORAGE_KEY); + if (savedBackground) { + setImageBackground(savedBackground); + } + } catch (error) { + console.error('Erro ao carregar background salvo:', error); + } + }; + + loadSavedBackground(); + }, []); // Aplicando filtros aos dados recebidos const filteredItineraryData = filterItineraryData(route.params.itineraryData); @@ -254,38 +400,16 @@ export function ItineraryMapMenu() { navigation.setParams({ itineraryData: { ...route.params.itineraryData, - itinerary: generatedItinerary + itinerary: generatedItinerary, + isNew: true } }); - let trip: CreatingItinerary = { - title: filteredItineraryData.title, - dateBegin: route.params.itineraryData.dateBegin, - dateEnd: route.params.itineraryData.dateEnd, - days: filteredItineraryData.days, - continent: filteredItineraryData.continent, - countries: filteredItineraryData.countries, - originCountry: filteredItineraryData.originCountry, - visa: filteredItineraryData.visa, - budget: filteredItineraryData.budget, - peopleQuantity: filteredItineraryData.peopleQuantity, - acconpanying: filteredItineraryData.acconpanying, - tripStyle: filteredItineraryData.tripStyle, - locomotionMethod: filteredItineraryData.locomotionMethod, - specialWish: filteredItineraryData.specialWish, - visitPreferences: filteredUserPreferences, - contacts: filteredItineraryData.contacts, - itinerary: generatedItinerary - } - userTrips.push(trip); - addNotification({ title: "Novo Roteiro Pronto", description: "Um novo roteiro para a sua incrível próxima viagem foi gerado pela Inteligência Artificial. Confira já!", routeIcon: Globe }); - - await AsyncStorage.setItem(ITINERARY_STORAGE_KEY, JSON.stringify(userTrips)); } } catch (error) { console.error('Erro ao gerar roteiro detalhado:', error); @@ -326,38 +450,16 @@ export function ItineraryMapMenu() { navigation.setParams({ itineraryData: { ...route.params.itineraryData, - itinerary: generatedItinerary + itinerary: generatedItinerary, + isNew: true } }); - let trip: CreatingItinerary = { - title: filteredItineraryData.title, - dateBegin: route.params.itineraryData.dateBegin, - dateEnd: route.params.itineraryData.dateEnd, - days: filteredItineraryData.days, - continent: filteredItineraryData.continent, - countries: filteredItineraryData.countries, - originCountry: filteredItineraryData.originCountry, - visa: filteredItineraryData.visa, - budget: filteredItineraryData.budget, - peopleQuantity: filteredItineraryData.peopleQuantity, - acconpanying: filteredItineraryData.acconpanying, - tripStyle: filteredItineraryData.tripStyle, - locomotionMethod: filteredItineraryData.locomotionMethod, - specialWish: filteredItineraryData.specialWish, - visitPreferences: filteredUserPreferences, - contacts: filteredItineraryData.contacts, - itinerary: generatedItinerary - } - userTrips.push(trip); - addNotification({ title: "Novo Roteiro Pronto", description: "Um novo roteiro para a sua incrível próxima viagem foi gerado pela Inteligência Artificial. Confira já!", routeIcon: Globe }); - - await AsyncStorage.setItem(ITINERARY_STORAGE_KEY, JSON.stringify(userTrips)); } } catch (error) { console.error('Erro ao gerar roteiro surpresa:', error); @@ -448,6 +550,42 @@ export function ItineraryMapMenu() { } }, [itinerary]); + // Função para salvar o background escolhido + const handleBackgroundChange = async (imagePath: any) => { + try { + setImageBackground(imagePath); + await AsyncStorage.setItem(BACKGROUND_STORAGE_KEY, imagePath.toString()); + } catch (error) { + console.error('Erro ao salvar background:', error); + } + }; + + // Função para exportar itinerário + const handleExportItinerary = async () => { + if (isExporting || !itinerary || itinerary.length === 0) { + return; + } + + try { + setIsExporting(true); + + // Formatar o nome do arquivo com título e datas + const fileName = `${filteredItineraryData.title || "Roteiro"}_${dateBegin}_${dateEnd}`.replace(/\s+/g, '_'); + + await exportItineraryToPDF({ + itinerary: itinerary, + title: filteredItineraryData.title || "Roteiro de Viagem", + dateBegin: dateBegin, + dateEnd: dateEnd, + fileName: fileName + }); + } catch (error) { + console.error('Erro ao exportar itinerário:', error); + } finally { + setIsExporting(false); + } + }; + const styles = StyleSheet.create({ containerStyle: { marginTop: 135, @@ -481,7 +619,7 @@ export function ItineraryMapMenu() { w={50} h={50} style={{ position: "absolute", top: 65, left: 10 }} - onPress={ () => navigation.navigate("GenerateItineraryMenu") } + onPress={ handleBackPress } > @@ -531,7 +669,10 @@ export function ItineraryMapMenu() { /> - + { + !hideBackButton && ( + <> + { isLiquidGlassAvailable() ? @@ -843,83 +984,52 @@ export function ItineraryMapMenu() { } - - { - isLiquidGlassAvailable() - ? - - : - - } - - - { - isLiquidGlassAvailable() - ? - - - - + - : - - - - + + Alterar Background + + + + + + Exportar{"\n"}Itinerário + + + + ) + } @@ -939,7 +1049,24 @@ export function ItineraryMapMenu() { { openChooseBackground - ? setOpenChooseBackground(false) } imageUri={ (imagePath) => setImageBackground(imagePath) } /> + ? setOpenChooseBackground(false) } imageUri={ handleBackgroundChange } /> + : null + } + { + openSaveDialog + ? { + setOpenSaveDialog(false); + // Navegar sem salvar + navigation.navigate("GenerateItineraryMenu"); + }} + onSave={ async (status, imageUri) => { + await saveNewItinerary(status, imageUri); + setIsNewItinerary(false); + navigation.navigate("GenerateItineraryMenu"); + }} + /> : null } diff --git a/expo-app/src/screens/Itinerary/ItineraryVisaCheck.tsx b/expo-app/src/screens/Itinerary/ItineraryVisaCheck.tsx index c065652..d08809b 100644 --- a/expo-app/src/screens/Itinerary/ItineraryVisaCheck.tsx +++ b/expo-app/src/screens/Itinerary/ItineraryVisaCheck.tsx @@ -41,7 +41,7 @@ export function ItineraryVisaCheck(){ try{ const originCode = getCountryCode(itineraryData.originCountry); setLastCheckedCountryCode(currentCountry); - const response = await fetch(`http://SEU-IP-AQUI:3000/api/passportVisa?origin=${originCode}&destination=${currentCountry}`); + const response = await fetch(`https://guiaturisticoeztripai.vercel.app/api/passportVisa?origin=${originCode}&destination=${currentCountry}`); if(!response.ok){ throw new Error("Failed to fetch Visa Information"); diff --git a/expo-app/src/screens/Itinerary/html/printExportItinerary.ts b/expo-app/src/screens/Itinerary/html/printExportItinerary.ts index 082e833..1d9662b 100644 --- a/expo-app/src/screens/Itinerary/html/printExportItinerary.ts +++ b/expo-app/src/screens/Itinerary/html/printExportItinerary.ts @@ -1,131 +1,230 @@ -import { useState } from 'react'; import { Alert } from 'react-native'; -import * as FileSystem from "expo-file-system" import * as Sharing from 'expo-sharing'; import * as Print from 'expo-print'; -export const htmlContent = ` - - - - Roteiro de Viagem - - - -

Roteiro de Viagem

-

O seu roteiro de viagem personalizado com muito carinho

- ${createHtmlFromItinerary(itinerary)} - - +type DayItineraryTypes = { + day: number, + date: string, + location: string, + timeline: Array<{ + time: string, + title: string, + description: string, + coordinates?: string, + category: string + }>, + suggestedActivities?: string[], + pixabayTags?: string, + images?: string[] +} + +type ExportItineraryParams = { + itinerary: DayItineraryTypes[], + title?: string, + dateBegin?: string, + dateEnd?: string, + fileName?: string +} + +const createHtmlFromItinerary = (itineraryData: DayItineraryTypes[]) => { + let htmlDays = ''; + + itineraryData.forEach((day, index) => { + const isEven = index % 2 === 0; + const bgColor = isEven ? '#f8f9fa' : '#ffffff'; + + const dayTitle = `Dia ${day.day}`; + const dateFormatted = day.date; + const location = day.location ? day.location : ''; + + const activityItems = day.timeline + .map((activity, idx) => { + const activityBg = idx % 2 === 0 ? 'rgba(39, 82, 183, 0.03)' : 'rgba(39, 82, 183, 0.06)'; + return ` +
+
+ ${activity.time} + ${activity.title} +
+

${activity.description}

+
+ `; + }) + .join(''); + + htmlDays += ` +
+
+

${dayTitle}

+ ${dateFormatted} +
+ ${location ? `

📍 ${location}

` : ''} + ${activityItems} +
+ `; + + // Adicionar atividades sugeridas se existirem + if (day.suggestedActivities && day.suggestedActivities.length > 0) { + const suggestedItems = day.suggestedActivities + .map(activity => ` +
  • ✨ ${activity}
  • + `) + .join(''); + htmlDays += ` +
    +

    Atividades Sugeridas

    +
      ${suggestedItems}
    +
    `; + } + }); + + return htmlDays; +}; -async function handleExportPDF() { - if (isExporting || !itinerary) { +export async function exportItineraryToPDF({ itinerary, title = "Roteiro de Viagem", dateBegin, dateEnd, fileName }: ExportItineraryParams) { + if (!itinerary || itinerary.length === 0) { + Alert.alert("Exportar PDF", "Não há itinerário para exportar."); return; } try { - setIsExporting(true); - - const createHtmlFromItinerary = (itineraryText: string) => { - const days = itineraryText.split(/(Dia \d+:)/).slice(1); - let htmlDays = ''; - - for (let i = 0; i < days.length; i += 2) { - const dayTitle = days[i]; - const activitiesText = days[i + 1]; - - const activityItems = activitiesText - .split('\n') - .map(line => line.trim()) - .map(line => line.startsWith('-') ? line.substring(1).trim() : line) - .filter(line => line.length > 0) - .map(activity => `
  • ${activity}
  • `) - .join(''); - - if (activityItems.length > 0) { - htmlDays += `

    ${dayTitle}

      ${activityItems}
    `; - } - } - return htmlDays; - }; - - - - const { uri: tempUri } = await Print.printToFileAsync({ + const dateInfo = dateBegin && dateEnd ? `

    ${dateBegin} até ${dateEnd}

    ` : ''; + + const htmlContent = ` + + + + ${title} + + + +

    ${title}

    + ${dateInfo} +

    Seu roteiro de viagem personalizado com muito carinho

    + ${createHtmlFromItinerary(itinerary)} + + + `; + + const { uri } = await Print.printToFileAsync({ html: htmlContent, base64: false, }); - const fileName = `Roteiro_de_Viagem_${new Date().toISOString().slice(0, 10)}.pdf`; - const newUri = `${FileSystem.cacheDirectory}${fileName}`; - - await FileSystem.moveAsync({ - from: tempUri, - to: newUri, - }); - if (!await Sharing.isAvailableAsync()) { Alert.alert("Exportar PDF", "Compartilhamento não está disponível neste dispositivo."); return; } - await Sharing.shareAsync(newUri, { + await Sharing.shareAsync(uri, { mimeType: 'application/pdf', dialogTitle: 'Salve ou compartilhe seu roteiro', UTI: '.pdf' }); - } catch (error) { - Alert.alert("Exportar", "Não foi possível exportar o roteiro."); - } finally { - setIsExporting(false); + console.error('Erro ao exportar PDF:', error); + Alert.alert("Erro", "Não foi possível exportar o roteiro."); } -}; \ No newline at end of file +} \ No newline at end of file diff --git a/expo-app/src/utils/gptRequests.ts b/expo-app/src/utils/gptRequests.ts index 51b707e..5017f02 100644 --- a/expo-app/src/utils/gptRequests.ts +++ b/expo-app/src/utils/gptRequests.ts @@ -8,13 +8,13 @@ * @throws Will throw an error if the request fails or the response is not successful. * * @remarks - * - Ensure that the API endpoint (`http://SEU-IP-AQUI:3000/api/generateItinerary`) is accessible. + * - Ensure that the API endpoint (`https://guiaturisticoeztripai.vercel.app/api/generateItinerary`) is accessible. * - If the response status is 429, it indicates that the quota limit has been reached. * - Logs relevant information to the console in case of errors or specific response statuses. */ export const generateItinerary = async (prompt: string) => { try { - const response = await fetch(`http://SEU-IP-AQUI:3000/api/generateItinerary`, { + const response = await fetch(`https://guiaturisticoeztripai.vercel.app/api/generateItinerary`, { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -47,13 +47,13 @@ export const generateItinerary = async (prompt: string) => { * @throws Will throw an error if the API request fails or the response status is not OK. * * @remarks - * - Ensure that the API endpoint (`http://SEU-IP-AQUI:3000/api/justchat`) is correctly configured. + * - Ensure that the API endpoint (`https://guiaturisticoeztripai.vercel.app/api/justchat`) is correctly configured. * - If the API returns a 429 status code, it indicates that the quota limit has been reached. * - Logs relevant error messages to the console for debugging purposes. */ export const generateChatAnswers = async (prompt: string) => { try { - const response = await fetch(`http://SEU-IP-AQUI:3000/api/justchat`, { + const response = await fetch(`https://guiaturisticoeztripai.vercel.app/api/justchat`, { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/expo-app/src/utils/responseCache.ts b/expo-app/src/utils/responseCache.ts new file mode 100644 index 0000000..6633a4b --- /dev/null +++ b/expo-app/src/utils/responseCache.ts @@ -0,0 +1,179 @@ +// Sistema de cache para respostas similares do Felipe +export interface CachedResponse { + query: string; + response: string; + timestamp: number; + useCount: number; +} + +export class ResponseCache { + private cache = new Map(); + private readonly CACHE_TTL = 24 * 60 * 60 * 1000; // 24 horas + private readonly MAX_CACHE_SIZE = 100; + private readonly SIMILARITY_THRESHOLD = 0.8; + + // Respostas pré-definidas para perguntas comuns + private predefinedResponses = new Map([ + // Saudações + ['oi', 'Olá! Sou o Felipe, seu guia turístico virtual. Como posso ajudar você hoje?'], + ['olá', 'Oi! Muito prazer, sou o Felipe. Estou aqui para te ajudar com dicas de viagem!'], + ['hello', 'E aí! Felipe aqui, pronto para te dar as melhores dicas de turismo!'], + ['bom dia', 'Bom dia! Sou o Felipe, seu guia virtual. Que destino vamos explorar hoje?'], + ['boa tarde', 'Boa tarde! Felipe aqui, pronto para suas aventuras turísticas!'], + ['boa noite', 'Boa noite! Mesmo à noite estou aqui para planejar suas viagens!'], + + // Agradecimentos + ['obrigado', 'Por nada! Estou aqui sempre que precisar de dicas de viagem!'], + ['obrigada', 'De nada! Foi um prazer ajudar. Boa viagem!'], + ['valeu', 'Sempre às ordens! Qualquer dúvida sobre turismo, pode contar comigo!'], + ['brigado', 'Imagina! Adoro ajudar com dicas de viagem!'], + + // Despedidas + ['tchau', 'Tchau! Tenha uma ótima viagem e volte sempre que precisar de dicas!'], + ['até logo', 'Até mais! Estarei aqui quando quiser planejar sua próxima aventura!'], + ['bye', 'Bye! Boa viagem e lembre-se: o mundo está cheio de lugares incríveis!'], + + // Perguntas básicas + ['quem é você', 'Sou o Felipe, seu guia turístico virtual! Especialista em destinos brasileiros e internacionais.'], + ['o que você faz', 'Ajudo viajantes com dicas de destinos, roteiros, hospedagem, gastronomia e tudo sobre turismo!'], + ['como você pode me ajudar', 'Posso sugerir destinos, criar roteiros, dar dicas de economia, indicar atrações e muito mais!'], + ]); + + // Normalizar texto para comparação + private normalizeText(text: string): string { + return text + .toLowerCase() + .trim() + .replace(/[áàãâä]/g, 'a') + .replace(/[éèêë]/g, 'e') + .replace(/[íìîï]/g, 'i') + .replace(/[óòõôö]/g, 'o') + .replace(/[úùûü]/g, 'u') + .replace(/[ç]/g, 'c') + .replace(/[^\w\s]/g, '') + .replace(/\s+/g, ' '); + } + + // Calcular similaridade entre strings (algoritmo simples) + private calculateSimilarity(str1: string, str2: string): number { + const normalized1 = this.normalizeText(str1); + const normalized2 = this.normalizeText(str2); + + if (normalized1 === normalized2) return 1; + + const words1 = normalized1.split(' '); + const words2 = normalized2.split(' '); + + let commonWords = 0; + const totalWords = Math.max(words1.length, words2.length); + + for (const word1 of words1) { + if (words2.includes(word1) && word1.length > 2) { + commonWords++; + } + } + + return commonWords / totalWords; + } + + // Buscar resposta em cache ou respostas pré-definidas + getCachedResponse(query: string): string | null { + const normalizedQuery = this.normalizeText(query); + + // 1. Verificar respostas pré-definidas primeiro + for (const [key, response] of this.predefinedResponses) { + if (this.calculateSimilarity(normalizedQuery, key) >= this.SIMILARITY_THRESHOLD) { + //DEBUG: console.log(`Cache hit (predefinido): "${query}" → "${key}"`); + return response; + } + } + + // 2. Verificar cache de respostas dinâmicas + const now = Date.now(); + + for (const [cachedKey, cached] of this.cache) { + // Verificar se não expirou + if (now - cached.timestamp > this.CACHE_TTL) { + this.cache.delete(cachedKey); + continue; + } + + // Verificar similaridade + if (this.calculateSimilarity(normalizedQuery, this.normalizeText(cached.query)) >= this.SIMILARITY_THRESHOLD) { + cached.useCount++; + //DEBUG: console.log(`Cache hit (dinâmico): "${query}" → "${cached.query}" (usado ${cached.useCount}x)`); + return cached.response; + } + } + + console.log(`Cache miss: "${query}"`); + return null; + } + + // Armazenar nova resposta no cache + storeResponse(query: string, response: string): void { + // Não armazenar se for muito similar a respostas pré-definidas + const normalizedQuery = this.normalizeText(query); + for (const key of this.predefinedResponses.keys()) { + if (this.calculateSimilarity(normalizedQuery, key) >= this.SIMILARITY_THRESHOLD) { + //DEBUG: console.log(`Não armazenando no cache: muito similar a resposta pré-definida`); + return; + } + } + + // Limpar cache se estiver muito cheio + if (this.cache.size >= this.MAX_CACHE_SIZE) { + this.cleanOldEntries(); + } + + const cacheKey = normalizedQuery; + this.cache.set(cacheKey, { + query, + response, + timestamp: Date.now(), + useCount: 1 + }); + + //DEBUG: console.log(`Resposta armazenada no cache: "${query}"`); + } + + // Limpar entradas antigas do cache + private cleanOldEntries(): void { + const now = Date.now(); + const entries = Array.from(this.cache.entries()); + + // Ordenar por: menos usado e mais antigo + entries.sort((a, b) => { + const scoreA = a[1].useCount * 1000 - (now - a[1].timestamp); + const scoreB = b[1].useCount * 1000 - (now - b[1].timestamp); + return scoreA - scoreB; + }); + + // Remover 20% das entradas menos úteis + const toRemove = Math.floor(this.cache.size * 0.2); + for (let i = 0; i < toRemove; i++) { + this.cache.delete(entries[i][0]); + } + + //DEBUG: console.log(`Cache limpo: ${toRemove} entradas removidas`); + } + + // Estatísticas do cache + getStats(): { size: number; hitRate: number; predefinedCount: number } { + const totalUses = Array.from(this.cache.values()).reduce((sum, cached) => sum + cached.useCount, 0); + return { + size: this.cache.size, + hitRate: totalUses > 0 ? totalUses / (totalUses + this.cache.size) : 0, + predefinedCount: this.predefinedResponses.size + }; + } + + // Limpar todo o cache + clear(): void { + this.cache.clear(); + //DEBUG: console.log('Cache completamente limpo'); + } +} + +// Instância singleton do cache +export const responseCache = new ResponseCache(); diff --git a/nextjs-api/pages/api/weather.ts b/nextjs-api/pages/api/weather.ts index 8184ae8..8c891c8 100644 --- a/nextjs-api/pages/api/weather.ts +++ b/nextjs-api/pages/api/weather.ts @@ -8,6 +8,11 @@ export default async function CurrentWeather(req: NextApiRequest, res: NextApiRe if (!latitude || !longitude) { return res.status(400).json({ error: "Latitude e longitude são obrigatórios" }); } + + if (!weatherApi) { + console.error("WEATHER API key is not configured"); + return res.status(500).json({ error: "Weather API key not configured" }); + } try { const response = await fetch(`http://api.weatherapi.com/v1/current.json?key=${weatherApi}&q=${latitude},${longitude}&aqi=no`) diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index eb3e9e0..0000000 --- a/package-lock.json +++ /dev/null @@ -1,5780 +0,0 @@ -{ - "name": "GuiaTuristico-Docker", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@expo/config-plugins": "~10.1.1", - "@react-navigation/drawer": "^7.7.3", - "react-native-html-to-pdf": "^0.12.0", - "react-native-reanimated": "^3.17.4", - "react-native-share": "^12.2.0", - "react-native-svg": "^15.12.0", - "zustand": "^5.0.6" - }, - "devDependencies": { - "react-native-svg-transformer": "^1.5.1" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", - "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.4.tgz", - "integrity": "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.3", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.27.3", - "@babel/helpers": "^7.27.4", - "@babel/parser": "^7.27.4", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.27.4", - "@babel/types": "^7.27.3", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", - "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", - "dependencies": { - "@babel/parser": "^7.28.3", - "@babel/types": "^7.28.2", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", - "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", - "dependencies": { - "@babel/types": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", - "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz", - "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-member-expression-to-functions": "^7.27.1", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.28.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", - "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "regexpu-core": "^6.2.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", - "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", - "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", - "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", - "dependencies": { - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", - "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.27.1", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", - "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz", - "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.27.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz", - "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", - "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", - "dependencies": { - "@babel/types": "^7.28.4" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", - "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", - "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.27.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.27.7.tgz", - "integrity": "sha512-CuLkokN1PEZ0Fsjtq+001aog/C2drDK9nTfK/NRK0n6rBin6cBrvM+zfQjDE+UllhR6/J4a6w8Xq9i4yi3mQrw==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.27.7", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", - "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", - "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", - "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", - "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", - "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.27.1.tgz", - "integrity": "sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", - "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz", - "integrity": "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-typescript": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", - "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", - "peer": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", - "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.4", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse--for-generate-function-map": { - "name": "@babel/traverse", - "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz", - "integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.3", - "@babel/parser": "^7.27.4", - "@babel/template": "^7.27.2", - "@babel/types": "^7.27.3", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@egjs/hammerjs": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", - "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==", - "peer": true, - "dependencies": { - "@types/hammerjs": "^2.0.36" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@expo/config-plugins": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-10.1.2.tgz", - "integrity": "sha512-IMYCxBOcnuFStuK0Ay+FzEIBKrwW8OVUMc65+v0+i7YFIIe8aL342l7T4F8lR4oCfhXn7d6M5QPgXvjtc/gAcw==", - "dependencies": { - "@expo/config-types": "^53.0.5", - "@expo/json-file": "~9.1.5", - "@expo/plist": "^0.3.5", - "@expo/sdk-runtime-versions": "^1.0.0", - "chalk": "^4.1.2", - "debug": "^4.3.5", - "getenv": "^2.0.0", - "glob": "^10.4.2", - "resolve-from": "^5.0.0", - "semver": "^7.5.4", - "slash": "^3.0.0", - "slugify": "^1.6.6", - "xcode": "^3.0.1", - "xml2js": "0.6.0" - } - }, - "node_modules/@expo/config-plugins/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@expo/config-plugins/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@expo/config-plugins/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@expo/config-types": { - "version": "53.0.5", - "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-53.0.5.tgz", - "integrity": "sha512-kqZ0w44E+HEGBjy+Lpyn0BVL5UANg/tmNixxaRMLS6nf37YsDrLk2VMAmeKMMk5CKG0NmOdVv3ngeUjRQMsy9g==" - }, - "node_modules/@expo/json-file": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-9.1.5.tgz", - "integrity": "sha512-prWBhLUlmcQtvN6Y7BpW2k9zXGd3ySa3R6rAguMJkp1z22nunLN64KYTUWfijFlprFoxm9r2VNnGkcbndAlgKA==", - "dependencies": { - "@babel/code-frame": "~7.10.4", - "json5": "^2.2.3" - } - }, - "node_modules/@expo/json-file/node_modules/@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/@expo/plist": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.3.5.tgz", - "integrity": "sha512-9RYVU1iGyCJ7vWfg3e7c/NVyMFs8wbl+dMWZphtFtsqyN9zppGREU3ctlD3i8KUE0sCUTVnLjCWr+VeUIDep2g==", - "dependencies": { - "@xmldom/xmldom": "^0.8.8", - "base64-js": "^1.2.3", - "xmlbuilder": "^15.1.1" - } - }, - "node_modules/@expo/sdk-runtime-versions": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz", - "integrity": "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==" - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/ttlcache": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz", - "integrity": "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==", - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "peer": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/create-cache-key-function": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz", - "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==", - "peer": true, - "dependencies": { - "@jest/types": "^29.6.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", - "peer": true, - "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", - "peer": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "peer": true, - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", - "peer": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "peer": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "peer": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@react-native/assets-registry": { - "version": "0.80.0", - "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.80.0.tgz", - "integrity": "sha512-MlScsKAz99zoYghe5Rf5mUqsqz2rMB02640NxtPtBMSHNdGxxRlWu/pp1bFexDa1DYJwyIjnLgt3Z/Y90ikHfw==", - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-native/codegen": { - "version": "0.80.0", - "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.80.0.tgz", - "integrity": "sha512-X9TsPgytoUkNrQjzAZh4dXa4AuouvYT0NzYyvnjw1ry4LESCZtKba+eY4x3+M30WPR52zjgu+UFL//14BSdCCA==", - "peer": true, - "dependencies": { - "glob": "^7.1.1", - "hermes-parser": "0.28.1", - "invariant": "^2.2.4", - "nullthrows": "^1.1.1", - "yargs": "^17.6.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@babel/core": "*" - } - }, - "node_modules/@react-native/community-cli-plugin": { - "version": "0.80.0", - "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.80.0.tgz", - "integrity": "sha512-uadfVvzZfz5tGpqwslL12i+rELK9m6cLhtqICX0JQvS7Bu12PJwrozhKzEzIYwN9i3wl2dWrKDUr08izt7S9Iw==", - "peer": true, - "dependencies": { - "@react-native/dev-middleware": "0.80.0", - "chalk": "^4.0.0", - "debug": "^4.4.0", - "invariant": "^2.2.4", - "metro": "^0.82.2", - "metro-config": "^0.82.2", - "metro-core": "^0.82.2", - "semver": "^7.1.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@react-native-community/cli": "*" - }, - "peerDependenciesMeta": { - "@react-native-community/cli": { - "optional": true - } - } - }, - "node_modules/@react-native/debugger-frontend": { - "version": "0.80.0", - "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.80.0.tgz", - "integrity": "sha512-lpu9Z3xtKUaKFvEcm5HSgo1KGfkDa/W3oZHn22Zy0WQ9MiOu2/ar1txgd1wjkoNiK/NethKcRdCN7mqnc6y2mA==", - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-native/dev-middleware": { - "version": "0.80.0", - "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.80.0.tgz", - "integrity": "sha512-lLyTnJ687A5jF3fn8yR/undlCis3FG+N/apQ+Q0Lcl+GV6FsZs0U5H28YmL6lZtjOj4TLek6uGPMPmZasHx7cQ==", - "peer": true, - "dependencies": { - "@isaacs/ttlcache": "^1.4.1", - "@react-native/debugger-frontend": "0.80.0", - "chrome-launcher": "^0.15.2", - "chromium-edge-launcher": "^0.2.0", - "connect": "^3.6.5", - "debug": "^4.4.0", - "invariant": "^2.2.4", - "nullthrows": "^1.1.1", - "open": "^7.0.3", - "serve-static": "^1.16.2", - "ws": "^6.2.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-native/gradle-plugin": { - "version": "0.80.0", - "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.80.0.tgz", - "integrity": "sha512-drmS68rabSMOuDD+YsAY2luNT8br82ycodSDORDqAg7yWQcieHMp4ZUOcdOi5iW+JCqobablT/b6qxcrBg+RaA==", - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-native/js-polyfills": { - "version": "0.80.0", - "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.80.0.tgz", - "integrity": "sha512-dMX7IcBuwghySTgIeK8q03tYz/epg5ScGmJEfBQAciuhzMDMV1LBR/9wwdgD73EXM/133yC5A+TlHb3KQil4Ew==", - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-native/normalize-colors": { - "version": "0.80.0", - "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.80.0.tgz", - "integrity": "sha512-bJZDSopadjJxMDvysc634eTfLL4w7cAx5diPe14Ez5l+xcKjvpfofS/1Ja14DlgdMJhxGd03MTXlrxoWust3zg==", - "peer": true - }, - "node_modules/@react-native/virtualized-lists": { - "version": "0.80.0", - "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.80.0.tgz", - "integrity": "sha512-d9zZdPS/ZRexVAkxo1eRp85U7XnnEpXA1ZpSomRKxBuStYKky1YohfEX5YD5MhphemKK24tT7JR4UhaLlmeX8Q==", - "peer": true, - "dependencies": { - "invariant": "^2.2.4", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/react": "^19.0.0", - "react": "*", - "react-native": "*" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@react-navigation/core": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-7.13.1.tgz", - "integrity": "sha512-aPf1vjQhMytPC9CmJu28hT5eTaBJuqIf9T6IRICtap5HHgFLrsYizLZrg3D0H2AoPyOoijMPWzwf7VCBzfGvrg==", - "peer": true, - "dependencies": { - "@react-navigation/routers": "^7.5.1", - "escape-string-regexp": "^4.0.0", - "fast-deep-equal": "^3.1.3", - "nanoid": "^3.3.11", - "query-string": "^7.1.3", - "react-is": "^19.1.0", - "use-latest-callback": "^0.2.4", - "use-sync-external-store": "^1.5.0" - }, - "peerDependencies": { - "react": ">= 18.2.0" - } - }, - "node_modules/@react-navigation/core/node_modules/react-is": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.0.tgz", - "integrity": "sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==", - "peer": true - }, - "node_modules/@react-navigation/drawer": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@react-navigation/drawer/-/drawer-7.7.3.tgz", - "integrity": "sha512-AVbeoy5/svO1AdIftYL/VBfRf7/86d2K7jG6iYy3AWvPyYNbfiepq0YlnJBBKIxg4XXzKQiRgYFeZHw1WUoRLw==", - "dependencies": { - "@react-navigation/elements": "^2.8.2", - "color": "^4.2.3", - "react-native-drawer-layout": "^4.2.0", - "use-latest-callback": "^0.2.4" - }, - "peerDependencies": { - "@react-navigation/native": "^7.1.20", - "react": ">= 18.2.0", - "react-native": "*", - "react-native-gesture-handler": ">= 2.0.0", - "react-native-reanimated": ">= 2.0.0", - "react-native-safe-area-context": ">= 4.0.0", - "react-native-screens": ">= 4.0.0" - } - }, - "node_modules/@react-navigation/elements": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-2.8.2.tgz", - "integrity": "sha512-K5NWIMar81oAoRAgLwrWcLpXzY2K5yG3gNU/56uyC12u+i5SyIVAv+ygP36UXvrNLzDigg8OdRSdEBb8ePqQtA==", - "dependencies": { - "color": "^4.2.3", - "use-latest-callback": "^0.2.4", - "use-sync-external-store": "^1.5.0" - }, - "peerDependencies": { - "@react-native-masked-view/masked-view": ">= 0.2.0", - "@react-navigation/native": "^7.1.20", - "react": ">= 18.2.0", - "react-native": "*", - "react-native-safe-area-context": ">= 4.0.0" - }, - "peerDependenciesMeta": { - "@react-native-masked-view/masked-view": { - "optional": true - } - } - }, - "node_modules/@react-navigation/native": { - "version": "7.1.20", - "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.1.20.tgz", - "integrity": "sha512-15luFq+35M2IOMHgbTJ0XDkPY7gm3YlR3yQKTuOTOHs+EeAUX71DlUuqcWMRqB0tt+OT6HimDQR7OboTB0N30g==", - "peer": true, - "dependencies": { - "@react-navigation/core": "^7.13.1", - "escape-string-regexp": "^4.0.0", - "fast-deep-equal": "^3.1.3", - "nanoid": "^3.3.11", - "use-latest-callback": "^0.2.4" - }, - "peerDependencies": { - "react": ">= 18.2.0", - "react-native": "*" - } - }, - "node_modules/@react-navigation/routers": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-7.5.1.tgz", - "integrity": "sha512-pxipMW/iEBSUrjxz2cDD7fNwkqR4xoi0E/PcfTQGCcdJwLoaxzab5kSadBLj1MTJyT0YRrOXL9umHpXtp+Dv4w==", - "peer": true, - "dependencies": { - "nanoid": "^3.3.11" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "peer": true - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "peer": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "peer": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", - "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", - "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", - "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", - "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", - "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", - "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-preset": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", - "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", - "dev": true, - "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", - "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", - "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", - "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", - "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", - "@svgr/babel-plugin-transform-svg-component": "8.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/core": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", - "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^8.1.3", - "snake-case": "^3.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/core/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/@svgr/core/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@svgr/core/node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dev": true, - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@svgr/core/node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@svgr/core/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@svgr/core/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@svgr/core/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", - "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", - "dev": true, - "dependencies": { - "@babel/types": "^7.21.3", - "entities": "^4.4.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/plugin-jsx": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", - "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "@svgr/hast-util-to-babel-ast": "8.0.0", - "svg-parser": "^2.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@svgr/plugin-svgo": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", - "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", - "dev": true, - "dependencies": { - "cosmiconfig": "^8.1.3", - "deepmerge": "^4.3.1", - "svgo": "^3.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@svgr/plugin-svgo/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/@svgr/plugin-svgo/node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dev": true, - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@svgr/plugin-svgo/node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@svgr/plugin-svgo/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@svgr/plugin-svgo/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@svgr/plugin-svgo/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "peer": true, - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "peer": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "peer": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", - "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", - "peer": true, - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "peer": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/hammerjs": { - "version": "2.0.46", - "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.46.tgz", - "integrity": "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==", - "peer": true - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "peer": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "peer": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "peer": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/node": { - "version": "24.0.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.3.tgz", - "integrity": "sha512-R4I/kzCYAdRLzfiCabn9hxWfbuHS573x+r0dJMkkzThEa7pbrcDWK+9zu3e7aBOouf+rQAciqPFMnxwr0aWgKg==", - "peer": true, - "dependencies": { - "undici-types": "~7.8.0" - } - }, - "node_modules/@types/react": { - "version": "19.1.8", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", - "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", - "optional": true, - "peer": true, - "dependencies": { - "csstype": "^3.0.2" - } - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "peer": true - }, - "node_modules/@types/yargs": { - "version": "17.0.33", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", - "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", - "peer": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "peer": true - }, - "node_modules/@xmldom/xmldom": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", - "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "peer": true, - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "peer": true, - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", - "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", - "peer": true, - "engines": { - "node": ">= 14" - } - }, - "node_modules/anser": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", - "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==", - "peer": true - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "peer": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "peer": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "peer": true - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "peer": true - }, - "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", - "peer": true, - "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "peer": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", - "peer": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-plugin-syntax-hermes-parser": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.28.1.tgz", - "integrity": "sha512-meT17DOuUElMNsL5LZN56d+KBp22hb0EfxWfuPUeoSi54e40v1W4C2V36P75FpsH9fVEfDKpw5Nnkahc8haSsQ==", - "peer": true, - "dependencies": { - "hermes-parser": "0.28.1" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", - "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", - "peer": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "peer": true, - "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/baseline-browser-mapping": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.4.tgz", - "integrity": "sha512-L+YvJwGAgwJBV1p6ffpSTa2KRc69EeeYGYjRVWKs0GKrK+LON0GC0gV+rKSNtALEDvMDqkvCFq9r1r94/Gjwxw==", - "bin": { - "baseline-browser-mapping": "dist/cli.js" - } - }, - "node_modules/big-integer": { - "version": "1.6.52", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", - "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" - }, - "node_modules/bplist-creator": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz", - "integrity": "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==", - "dependencies": { - "stream-buffers": "2.2.x" - } - }, - "node_modules/bplist-parser": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz", - "integrity": "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==", - "dependencies": { - "big-integer": "1.6.x" - }, - "engines": { - "node": ">= 5.10.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "peer": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.26.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.2.tgz", - "integrity": "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "baseline-browser-mapping": "^2.8.3", - "caniuse-lite": "^1.0.30001741", - "electron-to-chromium": "^1.5.218", - "node-releases": "^2.0.21", - "update-browserslist-db": "^1.1.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "peer": true, - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "peer": true - }, - "node_modules/caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", - "peer": true, - "dependencies": { - "callsites": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", - "peer": true, - "dependencies": { - "caller-callsite": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001743", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001743.tgz", - "integrity": "sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chrome-launcher": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", - "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", - "peer": true, - "dependencies": { - "@types/node": "*", - "escape-string-regexp": "^4.0.0", - "is-wsl": "^2.2.0", - "lighthouse-logger": "^1.0.0" - }, - "bin": { - "print-chrome-path": "bin/print-chrome-path.js" - }, - "engines": { - "node": ">=12.13.0" - } - }, - "node_modules/chromium-edge-launcher": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/chromium-edge-launcher/-/chromium-edge-launcher-0.2.0.tgz", - "integrity": "sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg==", - "peer": true, - "dependencies": { - "@types/node": "*", - "escape-string-regexp": "^4.0.0", - "is-wsl": "^2.2.0", - "lighthouse-logger": "^1.0.0", - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "peer": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "peer": true - }, - "node_modules/connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "peer": true, - "dependencies": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/connect/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/connect/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "peer": true - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" - }, - "node_modules/cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "peer": true, - "dependencies": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-tree/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "dev": true, - "dependencies": { - "css-tree": "~2.2.0" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "dev": true - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "optional": true, - "peer": true - }, - "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "peer": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "peer": true, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "peer": true - }, - "node_modules/electron-to-chromium": { - "version": "1.5.218", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.218.tgz", - "integrity": "sha512-uwwdN0TUHs8u6iRgN8vKeWZMRll4gBkz+QMqdS7DDe49uiK68/UX92lFb61oiFPrpYZNeZIqa4bA7O6Aiasnzg==" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/error-stack-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", - "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", - "peer": true, - "dependencies": { - "stackframe": "^1.3.4" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "peer": true - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "peer": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/exponential-backoff": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", - "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==", - "peer": true - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "peer": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "peer": true - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "peer": true, - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "peer": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/filter-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", - "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "peer": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "peer": true - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "peer": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flow-enums-runtime": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz", - "integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==", - "peer": true - }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "peer": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "peer": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "peer": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/getenv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/getenv/-/getenv-2.0.0.tgz", - "integrity": "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "peer": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/hermes-estree": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.28.1.tgz", - "integrity": "sha512-w3nxl/RGM7LBae0v8LH2o36+8VqwOZGv9rX1wyoWT6YaKZLqpJZ0YQ5P0LVr3tuRpf7vCx0iIG4i/VmBJejxTQ==", - "peer": true - }, - "node_modules/hermes-parser": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.28.1.tgz", - "integrity": "sha512-nf8o+hE8g7UJWParnccljHumE9Vlq8F7MqIdeahl+4x0tvCUJYRrT0L7h0MMg/X9YJmkNwsfbaNNrzPtFXOscg==", - "peer": true, - "dependencies": { - "hermes-estree": "0.28.1" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "peer": true, - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hoist-non-react-statics/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "peer": true - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "peer": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-errors/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "peer": true, - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/image-size": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz", - "integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==", - "peer": true, - "dependencies": { - "queue": "6.0.2" - }, - "bin": { - "image-size": "bin/image-size.js" - }, - "engines": { - "node": ">=16.x" - } - }, - "node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", - "peer": true, - "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "peer": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "peer": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "peer": true - }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, - "node_modules/is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "peer": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "peer": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "peer": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "peer": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "peer": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", - "peer": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "peer": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", - "peer": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", - "peer": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", - "peer": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "peer": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", - "peer": true, - "dependencies": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "peer": true, - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "peer": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsc-safe-url": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/jsc-safe-url/-/jsc-safe-url-0.2.4.tgz", - "integrity": "sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==", - "peer": true - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "peer": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/lighthouse-logger": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", - "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", - "peer": true, - "dependencies": { - "debug": "^2.6.9", - "marky": "^1.2.2" - } - }, - "node_modules/lighthouse-logger/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/lighthouse-logger/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "peer": true - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "peer": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash.throttle": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", - "peer": true - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "peer": true, - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/marky": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz", - "integrity": "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==", - "peer": true - }, - "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "node_modules/memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", - "peer": true - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "peer": true - }, - "node_modules/metro": { - "version": "0.82.4", - "resolved": "https://registry.npmjs.org/metro/-/metro-0.82.4.tgz", - "integrity": "sha512-/gFmw3ux9CPG5WUmygY35hpyno28zi/7OUn6+OFfbweA8l0B+PPqXXLr0/T6cf5nclCcH0d22o+02fICaShVxw==", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/core": "^7.25.2", - "@babel/generator": "^7.25.0", - "@babel/parser": "^7.25.3", - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.3", - "@babel/types": "^7.25.2", - "accepts": "^1.3.7", - "chalk": "^4.0.0", - "ci-info": "^2.0.0", - "connect": "^3.6.5", - "debug": "^4.4.0", - "error-stack-parser": "^2.0.6", - "flow-enums-runtime": "^0.0.6", - "graceful-fs": "^4.2.4", - "hermes-parser": "0.28.1", - "image-size": "^1.0.2", - "invariant": "^2.2.4", - "jest-worker": "^29.7.0", - "jsc-safe-url": "^0.2.2", - "lodash.throttle": "^4.1.1", - "metro-babel-transformer": "0.82.4", - "metro-cache": "0.82.4", - "metro-cache-key": "0.82.4", - "metro-config": "0.82.4", - "metro-core": "0.82.4", - "metro-file-map": "0.82.4", - "metro-resolver": "0.82.4", - "metro-runtime": "0.82.4", - "metro-source-map": "0.82.4", - "metro-symbolicate": "0.82.4", - "metro-transform-plugins": "0.82.4", - "metro-transform-worker": "0.82.4", - "mime-types": "^2.1.27", - "nullthrows": "^1.1.1", - "serialize-error": "^2.1.0", - "source-map": "^0.5.6", - "throat": "^5.0.0", - "ws": "^7.5.10", - "yargs": "^17.6.2" - }, - "bin": { - "metro": "src/cli.js" - }, - "engines": { - "node": ">=18.18" - } - }, - "node_modules/metro-babel-transformer": { - "version": "0.82.4", - "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.82.4.tgz", - "integrity": "sha512-4juJahGRb1gmNbQq48lNinB6WFNfb6m0BQqi/RQibEltNiqTCxew/dBspI2EWA4xVCd3mQWGfw0TML4KurQZnQ==", - "peer": true, - "dependencies": { - "@babel/core": "^7.25.2", - "flow-enums-runtime": "^0.0.6", - "hermes-parser": "0.28.1", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">=18.18" - } - }, - "node_modules/metro-cache": { - "version": "0.82.4", - "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.82.4.tgz", - "integrity": "sha512-vX0ylSMGtORKiZ4G8uP6fgfPdDiCWvLZUGZ5zIblSGylOX6JYhvExl0Zg4UA9pix/SSQu5Pnp9vdODMFsNIxhw==", - "peer": true, - "dependencies": { - "exponential-backoff": "^3.1.1", - "flow-enums-runtime": "^0.0.6", - "https-proxy-agent": "^7.0.5", - "metro-core": "0.82.4" - }, - "engines": { - "node": ">=18.18" - } - }, - "node_modules/metro-cache-key": { - "version": "0.82.4", - "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.82.4.tgz", - "integrity": "sha512-2JCTqcpF+f2OghOpe/+x+JywfzDkrHdAqinPFWmK2ezNAU/qX0jBFaTETogPibFivxZJil37w9Yp6syX8rFUng==", - "peer": true, - "dependencies": { - "flow-enums-runtime": "^0.0.6" - }, - "engines": { - "node": ">=18.18" - } - }, - "node_modules/metro-config": { - "version": "0.82.4", - "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.82.4.tgz", - "integrity": "sha512-Ki3Wumr3hKHGDS7RrHsygmmRNc/PCJrvkLn0+BWWxmbOmOcMMJDSmSI+WRlT8jd5VPZFxIi4wg+sAt5yBXAK0g==", - "peer": true, - "dependencies": { - "connect": "^3.6.5", - "cosmiconfig": "^5.0.5", - "flow-enums-runtime": "^0.0.6", - "jest-validate": "^29.7.0", - "metro": "0.82.4", - "metro-cache": "0.82.4", - "metro-core": "0.82.4", - "metro-runtime": "0.82.4" - }, - "engines": { - "node": ">=18.18" - } - }, - "node_modules/metro-core": { - "version": "0.82.4", - "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.82.4.tgz", - "integrity": "sha512-Xo4ozbxPg2vfgJGCgXZ8sVhC2M0lhTqD+tsKO2q9aelq/dCjnnSb26xZKcQO80CQOQUL7e3QWB7pLFGPjZm31A==", - "peer": true, - "dependencies": { - "flow-enums-runtime": "^0.0.6", - "lodash.throttle": "^4.1.1", - "metro-resolver": "0.82.4" - }, - "engines": { - "node": ">=18.18" - } - }, - "node_modules/metro-file-map": { - "version": "0.82.4", - "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.82.4.tgz", - "integrity": "sha512-eO7HD1O3aeNsbEe6NBZvx1lLJUrxgyATjnDmb7bm4eyF6yWOQot9XVtxTDLNifECuvsZ4jzRiTInrbmIHkTdGA==", - "peer": true, - "dependencies": { - "debug": "^4.4.0", - "fb-watchman": "^2.0.0", - "flow-enums-runtime": "^0.0.6", - "graceful-fs": "^4.2.4", - "invariant": "^2.2.4", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "nullthrows": "^1.1.1", - "walker": "^1.0.7" - }, - "engines": { - "node": ">=18.18" - } - }, - "node_modules/metro-minify-terser": { - "version": "0.82.4", - "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.82.4.tgz", - "integrity": "sha512-W79Mi6BUwWVaM8Mc5XepcqkG+TSsCyyo//dmTsgYfJcsmReQorRFodil3bbJInETvjzdnS1mCsUo9pllNjT1Hg==", - "peer": true, - "dependencies": { - "flow-enums-runtime": "^0.0.6", - "terser": "^5.15.0" - }, - "engines": { - "node": ">=18.18" - } - }, - "node_modules/metro-resolver": { - "version": "0.82.4", - "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.82.4.tgz", - "integrity": "sha512-uWoHzOBGQTPT5PjippB8rRT3iI9CTgFA9tRiLMzrseA5o7YAlgvfTdY9vFk2qyk3lW3aQfFKWkmqENryPRpu+Q==", - "peer": true, - "dependencies": { - "flow-enums-runtime": "^0.0.6" - }, - "engines": { - "node": ">=18.18" - } - }, - "node_modules/metro-runtime": { - "version": "0.82.4", - "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.82.4.tgz", - "integrity": "sha512-vVyFO7H+eLXRV2E7YAUYA7aMGBECGagqxmFvC2hmErS7oq90BbPVENfAHbUWq1vWH+MRiivoRxdxlN8gBoF/dw==", - "peer": true, - "dependencies": { - "@babel/runtime": "^7.25.0", - "flow-enums-runtime": "^0.0.6" - }, - "engines": { - "node": ">=18.18" - } - }, - "node_modules/metro-source-map": { - "version": "0.82.4", - "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.82.4.tgz", - "integrity": "sha512-9jzDQJ0FPas1FuQFtwmBHsez2BfhFNufMowbOMeG3ZaFvzeziE8A0aJwILDS3U+V5039ssCQFiQeqDgENWvquA==", - "peer": true, - "dependencies": { - "@babel/traverse": "^7.25.3", - "@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3", - "@babel/types": "^7.25.2", - "flow-enums-runtime": "^0.0.6", - "invariant": "^2.2.4", - "metro-symbolicate": "0.82.4", - "nullthrows": "^1.1.1", - "ob1": "0.82.4", - "source-map": "^0.5.6", - "vlq": "^1.0.0" - }, - "engines": { - "node": ">=18.18" - } - }, - "node_modules/metro-symbolicate": { - "version": "0.82.4", - "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.82.4.tgz", - "integrity": "sha512-LwEwAtdsx7z8rYjxjpLWxuFa2U0J6TS6ljlQM4WAATKa4uzV8unmnRuN2iNBWTmRqgNR77mzmI2vhwD4QSCo+w==", - "peer": true, - "dependencies": { - "flow-enums-runtime": "^0.0.6", - "invariant": "^2.2.4", - "metro-source-map": "0.82.4", - "nullthrows": "^1.1.1", - "source-map": "^0.5.6", - "vlq": "^1.0.0" - }, - "bin": { - "metro-symbolicate": "src/index.js" - }, - "engines": { - "node": ">=18.18" - } - }, - "node_modules/metro-transform-plugins": { - "version": "0.82.4", - "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.82.4.tgz", - "integrity": "sha512-NoWQRPHupVpnDgYguiEcm7YwDhnqW02iWWQjO2O8NsNP09rEMSq99nPjARWfukN7+KDh6YjLvTIN20mj3dk9kw==", - "peer": true, - "dependencies": { - "@babel/core": "^7.25.2", - "@babel/generator": "^7.25.0", - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.3", - "flow-enums-runtime": "^0.0.6", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">=18.18" - } - }, - "node_modules/metro-transform-worker": { - "version": "0.82.4", - "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.82.4.tgz", - "integrity": "sha512-kPI7Ad/tdAnI9PY4T+2H0cdgGeSWWdiPRKuytI806UcN4VhFL6OmYa19/4abYVYF+Cd2jo57CDuwbaxRfmXDhw==", - "peer": true, - "dependencies": { - "@babel/core": "^7.25.2", - "@babel/generator": "^7.25.0", - "@babel/parser": "^7.25.3", - "@babel/types": "^7.25.2", - "flow-enums-runtime": "^0.0.6", - "metro": "0.82.4", - "metro-babel-transformer": "0.82.4", - "metro-cache": "0.82.4", - "metro-cache-key": "0.82.4", - "metro-minify-terser": "0.82.4", - "metro-source-map": "0.82.4", - "metro-transform-plugins": "0.82.4", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">=18.18" - } - }, - "node_modules/metro/node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "peer": true - }, - "node_modules/metro/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "peer": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "peer": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "peer": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "peer": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "peer": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "peer": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "peer": true - }, - "node_modules/node-releases": { - "version": "2.0.21", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.21.tgz", - "integrity": "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/nullthrows": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", - "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", - "peer": true - }, - "node_modules/ob1": { - "version": "0.82.4", - "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.82.4.tgz", - "integrity": "sha512-n9S8e4l5TvkrequEAMDidl4yXesruWTNTzVkeaHSGywoTOIwTzZzKw7Z670H3eaXDZui5MJXjWGNzYowVZIxCA==", - "peer": true, - "dependencies": { - "flow-enums-runtime": "^0.0.6" - }, - "engines": { - "node": ">=18.18" - } - }, - "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "peer": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "peer": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "peer": true, - "dependencies": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "peer": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "peer": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-module/node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "peer": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "peer": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pirates": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", - "peer": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/plist": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", - "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", - "dependencies": { - "@xmldom/xmldom": "^0.8.8", - "base64-js": "^1.5.1", - "xmlbuilder": "^15.1.1" - }, - "engines": { - "node": ">=10.4.0" - } - }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "peer": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/promise": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", - "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", - "peer": true, - "dependencies": { - "asap": "~2.0.6" - } - }, - "node_modules/query-string": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", - "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", - "peer": true, - "dependencies": { - "decode-uri-component": "^0.2.2", - "filter-obj": "^1.1.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/queue": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", - "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", - "peer": true, - "dependencies": { - "inherits": "~2.0.3" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/react": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-devtools-core": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-6.1.2.tgz", - "integrity": "sha512-ldFwzufLletzCikNJVYaxlxMLu7swJ3T2VrGfzXlMsVhZhPDKXA38DEROidaYZVgMAmQnIjymrmqto5pyfrwPA==", - "peer": true, - "dependencies": { - "shell-quote": "^1.6.1", - "ws": "^7" - } - }, - "node_modules/react-devtools-core/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "peer": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/react-freeze": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.4.tgz", - "integrity": "sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==", - "peer": true, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": ">=17.0.0" - } - }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "peer": true - }, - "node_modules/react-native": { - "version": "0.80.0", - "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.80.0.tgz", - "integrity": "sha512-b9K1ygb2MWCBtKAodKmE3UsbUuC29Pt4CrJMR0ocTA8k+8HJQTPleBPDNKL4/p0P01QO9aL/gZUddoxHempLow==", - "peer": true, - "dependencies": { - "@jest/create-cache-key-function": "^29.7.0", - "@react-native/assets-registry": "0.80.0", - "@react-native/codegen": "0.80.0", - "@react-native/community-cli-plugin": "0.80.0", - "@react-native/gradle-plugin": "0.80.0", - "@react-native/js-polyfills": "0.80.0", - "@react-native/normalize-colors": "0.80.0", - "@react-native/virtualized-lists": "0.80.0", - "abort-controller": "^3.0.0", - "anser": "^1.4.9", - "ansi-regex": "^5.0.0", - "babel-jest": "^29.7.0", - "babel-plugin-syntax-hermes-parser": "0.28.1", - "base64-js": "^1.5.1", - "chalk": "^4.0.0", - "commander": "^12.0.0", - "flow-enums-runtime": "^0.0.6", - "glob": "^7.1.1", - "invariant": "^2.2.4", - "jest-environment-node": "^29.7.0", - "memoize-one": "^5.0.0", - "metro-runtime": "^0.82.2", - "metro-source-map": "^0.82.2", - "nullthrows": "^1.1.1", - "pretty-format": "^29.7.0", - "promise": "^8.3.0", - "react-devtools-core": "^6.1.1", - "react-refresh": "^0.14.0", - "regenerator-runtime": "^0.13.2", - "scheduler": "0.26.0", - "semver": "^7.1.3", - "stacktrace-parser": "^0.1.10", - "whatwg-fetch": "^3.0.0", - "ws": "^6.2.3", - "yargs": "^17.6.2" - }, - "bin": { - "react-native": "cli.js" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/react": "^19.1.0", - "react": "^19.1.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-native-drawer-layout": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/react-native-drawer-layout/-/react-native-drawer-layout-4.2.0.tgz", - "integrity": "sha512-XFGK5RMcVhEqr2F4iH/cTXrcTm1uK3gIBNFPqHNO7rCXuXZTPBbQYA5yc9/Lqgw2KNQ3sAeHKvW6/WoTURo/eA==", - "dependencies": { - "color": "^4.2.3", - "use-latest-callback": "^0.2.4" - }, - "peerDependencies": { - "react": ">= 18.2.0", - "react-native": "*", - "react-native-gesture-handler": ">= 2.0.0", - "react-native-reanimated": ">= 2.0.0" - } - }, - "node_modules/react-native-gesture-handler": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.29.1.tgz", - "integrity": "sha512-du3qmv0e3Sm7qsd9SfmHps+AggLiylcBBQ8ztz7WUtd8ZjKs5V3kekAbi9R2W9bRLSg47Ntp4GGMYZOhikQdZA==", - "peer": true, - "dependencies": { - "@egjs/hammerjs": "^2.0.17", - "hoist-non-react-statics": "^3.3.0", - "invariant": "^2.2.4" - }, - "peerDependencies": { - "react": "*", - "react-native": "*" - } - }, - "node_modules/react-native-html-to-pdf": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/react-native-html-to-pdf/-/react-native-html-to-pdf-0.12.0.tgz", - "integrity": "sha512-Yb5WO9SfF86s5Yv9PqXQ7fZDr9zZOJ+6jtweT9zFLraPNHWX7pSxe2dSkeg3cGiNrib65ZXGN6ksHymfYLFSSg==", - "license": "MIT" - }, - "node_modules/react-native-is-edge-to-edge": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.1.7.tgz", - "integrity": "sha512-EH6i7E8epJGIcu7KpfXYXiV2JFIYITtq+rVS8uEb+92naMRBdxhTuS8Wn2Q7j9sqyO0B+Xbaaf9VdipIAmGW4w==", - "peerDependencies": { - "react": "*", - "react-native": "*" - } - }, - "node_modules/react-native-reanimated": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.17.4.tgz", - "integrity": "sha512-vmkG/N5KZrexHr4v0rZB7ohPVseGVNaCXjGxoRo+NYKgC9+mIZAkg/QIfy9xxfJ73FfTrryO9iYUrxks3ZfKbA==", - "dependencies": { - "@babel/plugin-transform-arrow-functions": "^7.0.0-0", - "@babel/plugin-transform-class-properties": "^7.0.0-0", - "@babel/plugin-transform-classes": "^7.0.0-0", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.0.0-0", - "@babel/plugin-transform-optional-chaining": "^7.0.0-0", - "@babel/plugin-transform-shorthand-properties": "^7.0.0-0", - "@babel/plugin-transform-template-literals": "^7.0.0-0", - "@babel/plugin-transform-unicode-regex": "^7.0.0-0", - "@babel/preset-typescript": "^7.16.7", - "convert-source-map": "^2.0.0", - "invariant": "^2.2.4", - "react-native-is-edge-to-edge": "1.1.7" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0", - "react": "*", - "react-native": "*" - } - }, - "node_modules/react-native-safe-area-context": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.2.tgz", - "integrity": "sha512-4XGqMNj5qjUTYywJqpdWZ9IG8jgkS3h06sfVjfw5yZQZfWnRFXczi0GnYyFyCc2EBps/qFmoCH8fez//WumdVg==", - "peer": true, - "peerDependencies": { - "react": "*", - "react-native": "*" - } - }, - "node_modules/react-native-screens": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.18.0.tgz", - "integrity": "sha512-mRTLWL7Uc1p/RFNveEIIrhP22oxHduC2ZnLr/2iHwBeYpGXR0rJZ7Bgc0ktxQSHRjWTPT70qc/7yd4r9960PBQ==", - "peer": true, - "dependencies": { - "react-freeze": "^1.0.0", - "warn-once": "^0.1.0" - }, - "peerDependencies": { - "react": "*", - "react-native": "*" - } - }, - "node_modules/react-native-share": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/react-native-share/-/react-native-share-12.2.0.tgz", - "integrity": "sha512-f6MB9BsKa9xVvu0DKbxq5jw4IyYHqQeqUlCNkD8eAFoJx6SD31ObPAn7SQ6NG9AOuhCy6aYuSJYJvx25DaoMZQ==", - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "node_modules/react-native-svg": { - "version": "15.12.0", - "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.12.0.tgz", - "integrity": "sha512-iE25PxIJ6V0C6krReLquVw6R0QTsRTmEQc4K2Co3P6zsimU/jltcDBKYDy1h/5j9S/fqmMeXnpM+9LEWKJKI6A==", - "dependencies": { - "css-select": "^5.1.0", - "css-tree": "^1.1.3", - "warn-once": "0.1.1" - }, - "peerDependencies": { - "react": "*", - "react-native": "*" - } - }, - "node_modules/react-native-svg-transformer": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/react-native-svg-transformer/-/react-native-svg-transformer-1.5.1.tgz", - "integrity": "sha512-dFvBNR8A9VPum9KCfh+LE49YiJEF8zUSnEFciKQroR/bEOhlPoZA0SuQ0qNk7m2iZl2w59FYjdRe0pMHWMDl0Q==", - "dev": true, - "dependencies": { - "@svgr/core": "^8.1.0", - "@svgr/plugin-jsx": "^8.1.0", - "@svgr/plugin-svgo": "^8.1.0", - "path-dirname": "^1.0.2" - }, - "peerDependencies": { - "react-native": ">=0.59.0", - "react-native-svg": ">=12.0.0" - } - }, - "node_modules/react-refresh": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", - "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", - "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "peer": true - }, - "node_modules/regexpu-core": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", - "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", - "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.2.0", - "regjsgen": "^0.8.0", - "regjsparser": "^0.12.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==" - }, - "node_modules/regjsparser": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", - "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", - "dependencies": { - "jsesc": "~3.0.2" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "peer": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" - }, - "node_modules/scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", - "peer": true - }, - "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "peer": true, - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "peer": true - }, - "node_modules/send/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "peer": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/serialize-error": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", - "integrity": "sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "peer": true, - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-static/node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "peer": true - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "peer": true - }, - "node_modules/simple-plist": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.1.tgz", - "integrity": "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw==", - "dependencies": { - "bplist-creator": "0.1.0", - "bplist-parser": "0.3.1", - "plist": "^3.0.5" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", - "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", - "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/slugify": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz", - "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/snake-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", - "dev": true, - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "peer": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-on-first": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", - "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "peer": true - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "peer": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/stackframe": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", - "peer": true - }, - "node_modules/stacktrace-parser": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz", - "integrity": "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==", - "peer": true, - "dependencies": { - "type-fest": "^0.7.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/stream-buffers": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", - "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==", - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/strict-uri-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", - "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", - "dev": true - }, - "node_modules/svgo": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", - "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", - "dev": true, - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^5.1.0", - "css-tree": "^2.3.1", - "css-what": "^6.1.0", - "csso": "^5.0.5", - "picocolors": "^1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/svgo" - } - }, - "node_modules/svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/svgo/node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/svgo/node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true - }, - "node_modules/terser": { - "version": "5.43.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", - "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", - "peer": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.14.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "peer": true - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "peer": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "peer": true - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "peer": true - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "peer": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "peer": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/undici-types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", - "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", - "peer": true - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", - "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", - "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/use-latest-callback": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.2.6.tgz", - "integrity": "sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg==", - "peerDependencies": { - "react": ">=16.8" - } - }, - "node_modules/use-sync-external-store": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", - "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "peer": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/vlq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz", - "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==", - "peer": true - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "peer": true, - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/warn-once": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/warn-once/-/warn-once-0.1.1.tgz", - "integrity": "sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q==" - }, - "node_modules/whatwg-fetch": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", - "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", - "peer": true - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "peer": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "peer": true - }, - "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "peer": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/ws": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", - "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==", - "peer": true, - "dependencies": { - "async-limiter": "~1.0.0" - } - }, - "node_modules/xcode": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz", - "integrity": "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==", - "dependencies": { - "simple-plist": "^1.1.0", - "uuid": "^7.0.3" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/xml2js": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.0.tgz", - "integrity": "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xml2js/node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "engines": { - "node": ">=8.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "peer": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "peer": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/zustand": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.6.tgz", - "integrity": "sha512-ihAqNeUVhe0MAD+X8M5UzqyZ9k3FFZLBTtqo6JLPwV53cbRB/mJwBI0PxcIgqhBBHlEs8G45OTDTMq3gNcLq3A==", - "engines": { - "node": ">=12.20.0" - }, - "peerDependencies": { - "@types/react": ">=18.0.0", - "immer": ">=9.0.6", - "react": ">=18.0.0", - "use-sync-external-store": ">=1.2.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "immer": { - "optional": true - }, - "react": { - "optional": true - }, - "use-sync-external-store": { - "optional": true - } - } - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index c6c51f1..0000000 --- a/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "dependencies": { - "@expo/config-plugins": "~10.1.1", - "@react-navigation/drawer": "^7.7.3", - "react-native-html-to-pdf": "^0.12.0", - "react-native-reanimated": "^3.17.4", - "react-native-share": "^12.2.0", - "react-native-svg": "^15.12.0", - "zustand": "^5.0.6" - }, - "devDependencies": { - "react-native-svg-transformer": "^1.5.1" - } -}