,
, etc.
+ .replace(/<[^>]*>/g, " ")
+ // Convert HTML entities
+ .replace(/&/g, "&")
+ .replace(/</g, "<")
+ .replace(/>/g, ">")
+ .replace(/"/g, '"')
+ .replace(/'/g, "'")
+ .replace(/ /g, " ")
+ // Convert markdown links [text](url) to just text
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1")
+ // Remove bold/italic markers **text** or *text*
+ .replace(/\*\*([^*]+)\*\*/g, "$1")
+ .replace(/\*([^*]+)\*/g, "$1")
+ // Remove inline code `text`
+ .replace(/`([^`]+)`/g, "$1")
+ // Remove strikethrough ~~text~~
+ .replace(/~~([^~]+)~~/g, "$1")
+ // Remove heading markers # ## ###
+ .replace(/^#{1,6}\s+/gm, "")
+ // Remove blockquote markers >
+ .replace(/^>\s+/gm, "")
+ // Remove list markers - * +
+ .replace(/^[\s]*[-*+]\s+/gm, "")
+ // Remove numbered list markers 1. 2. etc
+ .replace(/^[\s]*\d+\.\s+/gm, "")
+ // Normalize multiple whitespace/newlines to single space
+ .replace(/\s+/g, " ")
+ // Trim whitespace
+ .trim()
+ );
+ };
+
+ const handleEventTypePress = (eventType: EventType) => {
+ handleEdit(eventType);
+ };
+
+ const handleEventTypeLongPress = (eventType: EventType) => {
+ if (Platform.OS === "web") {
+ // Show custom modal for web platform
+ setSelectedEventType(eventType);
+ setShowActionModal(true);
+ return;
+ }
+
+ if (Platform.OS !== "ios") {
+ // Fallback for non-iOS platforms (Android)
+ Alert.alert(eventType.title, eventType.description || "", [
+ { text: "Cancel", style: "cancel" },
+ { text: "Edit", onPress: () => handleEdit(eventType) },
+ { text: "Duplicate", onPress: () => handleDuplicate(eventType) },
+ { text: "Delete", style: "destructive", onPress: () => handleDelete(eventType) },
+ ]);
+ return;
+ }
+
+ ActionSheetIOS.showActionSheetWithOptions(
+ {
+ options: ["Cancel", "Edit", "Duplicate", "Delete"],
+ destructiveButtonIndex: 3, // Delete button
+ cancelButtonIndex: 0,
+ title: eventType.title,
+ message: eventType.description ? normalizeMarkdown(eventType.description) : undefined,
+ },
+ (buttonIndex) => {
+ switch (buttonIndex) {
+ case 1: // Edit
+ handleEdit(eventType);
+ break;
+ case 2: // Duplicate
+ handleDuplicate(eventType);
+ break;
+ case 3: // Delete
+ handleDelete(eventType);
+ break;
+ default:
+ // Cancel - do nothing
+ break;
+ }
+ }
+ );
+ };
+
+ const handleCopyLink = async (eventType: EventType) => {
+ try {
+ const link = await CalComAPIService.buildEventTypeLink(eventType.slug);
+ Clipboard.setString(link);
+
+ if (Platform.OS === "web") {
+ showToastMessage("Link copied!", eventType.id);
+ } else {
+ Alert.alert("Link Copied", "Event type link copied!");
+ }
+ } catch (error) {
+ if (Platform.OS === "web") {
+ showToastMessage("Failed to copy link");
+ } else {
+ Alert.alert("Error", "Failed to copy link. Please try again.");
+ }
+ }
+ };
+
+ const handleShare = async (eventType: EventType) => {
+ try {
+ const link = await CalComAPIService.buildEventTypeLink(eventType.slug);
+ await Share.share({
+ message: `Book a meeting: ${eventType.title}`,
+ url: link,
+ });
+ } catch (error) {
+ Alert.alert("Error", "Failed to share link. Please try again.");
+ }
+ };
+
+ const handleEdit = (eventType: EventType) => {
+ const duration = getDuration(eventType);
+ router.push({
+ pathname: "/event-type-detail",
+ params: {
+ id: eventType.id.toString(),
+ title: eventType.title,
+ description: eventType.description || "",
+ duration: duration.toString(),
+ price: eventType.price?.toString() || "",
+ currency: eventType.currency || "",
+ slug: eventType.slug || "",
+ },
+ });
+ };
+
+ const handleDelete = (eventType: EventType) => {
+ setEventTypeToDelete(eventType);
+ setShowDeleteModal(true);
+ };
+
+ const confirmDelete = async () => {
+ if (!eventTypeToDelete) return;
+
+ setIsDeleting(true);
+ try {
+ await CalComAPIService.deleteEventType(eventTypeToDelete.id);
+
+ // Only update state if component is still mounted
+ if (isMountedRef.current) {
+ // Remove the deleted event type from local state
+ const updatedEventTypes = eventTypes.filter((et) => et.id !== eventTypeToDelete.id);
+ setEventTypes(updatedEventTypes);
+ setFilteredEventTypes(updatedEventTypes);
+
+ // Close modal and reset state
+ setShowDeleteModal(false);
+ setEventTypeToDelete(null);
+
+ if (Platform.OS === "web") {
+ showToastMessage("Event type deleted successfully");
+ } else {
+ Alert.alert("Success", "Event type deleted successfully");
+ }
+ }
+ } catch (error) {
+ console.error("Failed to delete event type:", error);
+ if (isMountedRef.current) {
+ if (Platform.OS === "web") {
+ showToastMessage("Failed to delete event type");
+ } else {
+ Alert.alert("Error", "Failed to delete event type. Please try again.");
+ }
+ }
+ } finally {
+ setIsDeleting(false);
+ }
+ };
+
+ const handleDuplicate = async (eventType: EventType) => {
+ try {
+ // Generate a new title and slug for the duplicate
+ const newTitle = `${eventType.title} (copy)`;
+ let newSlug = `${eventType.slug}-copy`;
+
+ // Check if slug already exists and append a number if needed
+ let counter = 1;
+ while (eventTypes.some((et) => et.slug === newSlug)) {
+ newSlug = `${eventType.slug}-copy-${counter}`;
+ counter++;
+ }
+
+ const duration = getDuration(eventType);
+
+ // Create the duplicate event type
+ const duplicatedEventType = await CalComAPIService.createEventType({
+ title: newTitle,
+ slug: newSlug,
+ lengthInMinutes: duration,
+ description: eventType.description || undefined,
+ });
+
+ // Refresh the list
+ await fetchEventTypes();
+
+ if (Platform.OS === "web") {
+ showToastMessage("Event type duplicated successfully");
+ } else {
+ Alert.alert("Success", "Event type duplicated successfully");
+ }
+
+ // Navigate to edit the newly created duplicate
+ router.push({
+ pathname: "/event-type-detail",
+ params: {
+ id: duplicatedEventType.id.toString(),
+ title: duplicatedEventType.title,
+ description: duplicatedEventType.description || "",
+ duration: (
+ duplicatedEventType.lengthInMinutes ||
+ duplicatedEventType.length ||
+ duration
+ ).toString(),
+ slug: duplicatedEventType.slug || "",
+ },
+ });
+ } catch (error) {
+ console.error("Failed to duplicate event type:", error);
+ if (Platform.OS === "web") {
+ showToastMessage("Failed to duplicate event type");
+ } else {
+ Alert.alert("Error", "Failed to duplicate event type. Please try again.");
+ }
+ }
+ };
+
+ const handlePreview = async (eventType: EventType) => {
+ try {
+ const link = await CalComAPIService.buildEventTypeLink(eventType.slug);
+ // Open in browser
+ if (Platform.OS === "web") {
+ window.open(link, "_blank");
+ } else {
+ // For mobile, use Linking
+ await Linking.openURL(link);
+ }
+ } catch (error) {
+ console.error("Failed to open preview:", error);
+ if (Platform.OS === "web") {
+ showToastMessage("Failed to open preview");
+ } else {
+ Alert.alert("Error", "Failed to open preview. Please try again.");
+ }
+ }
+ };
+
+ const handleCreateNew = () => {
+ handleOpenCreateModal();
+ };
+
+ const handleOpenCreateModal = () => {
+ setShowCreateModal(true);
+ };
+
+ const handleCloseCreateModal = () => {
+ setShowCreateModal(false);
+ setNewEventTitle("");
+ setNewEventSlug("");
+ setNewEventDescription("");
+ setNewEventDuration("15");
+ setIsSlugManuallyEdited(false);
+ };
+
+ const handleCreateEventType = async () => {
+ if (!newEventTitle.trim()) {
+ Alert.alert("Error", "Please enter a title for your event type");
+ return;
+ }
+
+ if (!newEventSlug.trim()) {
+ Alert.alert("Error", "Please enter a URL for your event type");
+ return;
+ }
+
+ const duration = parseInt(newEventDuration);
+ if (isNaN(duration) || duration <= 0) {
+ Alert.alert("Error", "Please enter a valid duration");
+ return;
+ }
+
+ setCreating(true);
+ try {
+ // Create the event type with the form data
+ const newEventType = await CalComAPIService.createEventType({
+ title: newEventTitle.trim(),
+ slug: newEventSlug.trim(),
+ lengthInMinutes: duration,
+ description: newEventDescription.trim() || undefined,
+ });
+
+ // Close modal and reset form
+ handleCloseCreateModal();
+
+ // Refresh the list
+ await fetchEventTypes();
+
+ // Navigate to edit the newly created event type
+ router.push({
+ pathname: "/event-type-detail",
+ params: {
+ id: newEventType.id.toString(),
+ title: newEventType.title,
+ description: newEventType.description || "",
+ duration: (newEventType.lengthInMinutes || newEventType.length || 15).toString(),
+ slug: newEventType.slug || "",
+ },
+ });
+ } catch (error) {
+ console.error("Failed to create event type:", error);
+ Alert.alert("Error", "Failed to create event type. Please try again.");
+ } finally {
+ setCreating(false);
+ }
+ };
+
+ const renderEventType = ({ item, index }: { item: EventType; index: number }) => {
+ const duration = getDuration(item);
+ const isLast = index === filteredEventTypes.length - 1;
+
+ return (
+ handleEventTypePress(item)}
+ onLongPress={() => handleEventTypeLongPress(item)}
+ style={{ paddingHorizontal: 16, paddingVertical: 16 }}
+ >
+
+
+
+ {item.title}
+
+ {item.description && (
+
+ {normalizeMarkdown(item.description)}
+
+ )}
+
+
+
+ {formatDuration(duration)}
+
+
+ {(item.price != null && item.price > 0) || item.requiresConfirmation ? (
+
+ {item.price != null && item.price > 0 && (
+
+ {item.currency || "$"}
+ {item.price}
+
+ )}
+ {item.requiresConfirmation && (
+
+ Requires Confirmation
+
+ )}
+
+ ) : null}
+
+
+
+ handlePreview(item)}
+ >
+
+
+
+
+ handleCopyLink(item)}
+ >
+ {copiedEventTypeId === item.id ? (
+
+ ) : (
+
+
+
+
+ )}
+
+
+
+ handleEventTypeLongPress(item)}
+ >
+
+
+
+
+
+
+ );
+ };
+
+ if (loading) {
+ return (
+
+
+
+
+ Loading event types...
+
+
+ );
+ }
+
+ if (error) {
+ return (
+
+
+
+
+
+ Unable to load event types
+
+ {error}
+
+ Retry
+
+
+
+ );
+ }
+
+ if (eventTypes.length === 0) {
+ return (
+
+
+
+
+
+
+
+ No event types found
+
+ Create your first event type in Cal.com
+
+
+
+ );
+ }
+
+ if (filteredEventTypes.length === 0 && searchQuery.trim() !== "") {
+ return (
+
+
+
+
+
+
+
+ No results found
+
+ Try searching with different keywords
+
+
+
+ );
+ }
+
+ return (
+
+
+
+
+
+
+ New
+
+
+ }
+ showsVerticalScrollIndicator={false}
+ >
+
+
+ {filteredEventTypes.map((item, index) => (
+ {renderEventType({ item, index })}
+ ))}
+
+
+
+
+ {/* Create Event Type Modal */}
+
+
+ e.stopPropagation()}
+ style={{
+ shadowColor: "#000",
+ shadowOffset: { width: 0, height: 20 },
+ shadowOpacity: 0.25,
+ shadowRadius: 25,
+ elevation: 24,
+ }}
+ >
+ {/* Header */}
+
+
+ Add a new event type
+
+
+ Set up event types to offer different types of meetings.
+
+
+
+ {/* Content */}
+
+ {/* Title */}
+
+ Title
+ {
+ setNewEventTitle(text);
+ // Auto-generate slug from title if user hasn't manually edited it
+ if (!isSlugManuallyEdited) {
+ setNewEventSlug(slugify(text, true));
+ }
+ }}
+ autoFocus
+ autoCapitalize="words"
+ returnKeyType="next"
+ />
+
+
+ {/* URL */}
+
+ URL
+
+ https://cal.com/{username}/
+ {
+ setIsSlugManuallyEdited(true);
+ setNewEventSlug(slugify(text, true));
+ }}
+ autoCapitalize="none"
+ autoCorrect={false}
+ returnKeyType="next"
+ />
+
+
+
+ {/* Description */}
+
+ Description
+
+
+
+ {/* Duration */}
+
+ Duration
+
+
+ minutes
+
+
+
+
+ {/* Footer */}
+
+
+
+ Close
+
+
+ Continue
+
+
+
+
+
+
+
+ {/* Action Modal for Web Platform */}
+ {
+ setShowActionModal(false);
+ setSelectedEventType(null);
+ }}
+ >
+ {
+ setShowActionModal(false);
+ setSelectedEventType(null);
+ }}
+ >
+ e.stopPropagation()}
+ >
+ {selectedEventType && (
+ <>
+
+
+ {selectedEventType.title}
+
+ {selectedEventType.description && (
+
+ {normalizeMarkdown(selectedEventType.description)}
+
+ )}
+
+
+
+ {
+ setShowActionModal(false);
+ const eventType = selectedEventType;
+ setSelectedEventType(null);
+ if (eventType) handleEdit(eventType);
+ }}
+ >
+
+ Edit
+
+
+ {
+ setShowActionModal(false);
+ const eventType = selectedEventType;
+ setSelectedEventType(null);
+ if (eventType) handleDuplicate(eventType);
+ }}
+ >
+
+ Duplicate
+
+
+ {/* Separator before delete button */}
+
+
+ {
+ setShowActionModal(false);
+ const eventType = selectedEventType;
+ setSelectedEventType(null);
+ if (eventType) handleDelete(eventType);
+ }}
+ >
+
+ Delete
+
+
+
+
+ {
+ setShowActionModal(false);
+ setSelectedEventType(null);
+ }}
+ >
+ Cancel
+
+
+ >
+ )}
+
+
+
+
+ {/* New Menu Modal for Web Platform */}
+ setShowNewModal(false)}
+ >
+ setShowNewModal(false)}
+ >
+ e.stopPropagation()}
+ >
+ {/* Header */}
+
+ New
+ Choose what to create
+
+
+ {/* Options List */}
+
+ {/* New Event Type */}
+ {
+ setShowNewModal(false);
+ // Small delay to ensure the "New" modal closes before opening create modal
+ setTimeout(() => {
+ handleOpenCreateModal();
+ }, 100);
+ }}
+ className="flex-row items-center p-2 hover:bg-gray-50 md:p-4"
+ >
+
+ New Event Type
+
+
+
+ {/* Cancel button */}
+
+ setShowNewModal(false)}
+ >
+ Cancel
+
+
+
+
+
+
+ {/* Delete Confirmation Modal */}
+ {
+ if (!isDeleting) {
+ setShowDeleteModal(false);
+ setEventTypeToDelete(null);
+ }
+ }}
+ >
+
+
+ {/* Header with icon and title */}
+
+
+ {/* Danger icon */}
+
+
+
+
+ {/* Title and description */}
+
+
+ Delete Event Type
+
+
+ {eventTypeToDelete && (
+ <>
+ This will permanently delete the "{eventTypeToDelete.title}" event type.
+ This action cannot be undone.
+ >
+ )}
+
+
+
+
+
+ {/* Footer with buttons */}
+
+
+ Delete
+
+
+ {
+ setShowDeleteModal(false);
+ setEventTypeToDelete(null);
+ }}
+ disabled={isDeleting}
+ >
+ Cancel
+
+
+
+
+
+
+ {/* Toast for Web Platform */}
+ {showToast && (
+
+
+ {toastMessage}
+
+
+ )}
+
+ );
+}
diff --git a/companion/app/(tabs)/more.tsx b/companion/app/(tabs)/more.tsx
new file mode 100644
index 0000000000..d33ca5250b
--- /dev/null
+++ b/companion/app/(tabs)/more.tsx
@@ -0,0 +1,114 @@
+import React from "react";
+import { View, Text, TouchableOpacity, ScrollView, Linking, Alert } from "react-native";
+import { Ionicons } from "@expo/vector-icons";
+import { useRouter } from "expo-router";
+import { Header } from "../../components/Header";
+import { LogoutButton } from "../../components/LogoutButton";
+
+interface MoreMenuItem {
+ name: string;
+ icon: keyof typeof Ionicons.glyphMap;
+ isExternal?: boolean;
+ href?: string;
+ onPress?: () => void;
+}
+
+export default function More() {
+ const router = useRouter();
+
+ const openExternalLink = async (url: string, fallbackMessage: string) => {
+ try {
+ const supported = await Linking.canOpenURL(url);
+ if (supported) {
+ await Linking.openURL(url);
+ } else {
+ Alert.alert("Error", `Cannot open ${fallbackMessage} on your device.`);
+ }
+ } catch (error) {
+ console.error(`Failed to open ${url}:`, error);
+ Alert.alert("Error", `Failed to open ${fallbackMessage}. Please try again.`);
+ }
+ };
+
+ const menuItems: MoreMenuItem[] = [
+ {
+ name: "Profile",
+ icon: "person-outline",
+ isExternal: true,
+ onPress: () =>
+ openExternalLink("https://app.cal.com/settings/my-account/profile", "Profile page"),
+ },
+ {
+ name: "Apps",
+ icon: "grid-outline",
+ isExternal: true,
+ onPress: () => openExternalLink("https://app.cal.com/apps", "Apps page"),
+ },
+ {
+ name: "Routing",
+ icon: "git-branch-outline",
+ isExternal: true,
+ onPress: () => openExternalLink("https://app.cal.com/routing", "Routing page"),
+ },
+ {
+ name: "Workflows",
+ icon: "flash-outline",
+ isExternal: true,
+ onPress: () => openExternalLink("https://app.cal.com/workflows", "Workflows page"),
+ },
+ {
+ name: "Insights",
+ icon: "bar-chart-outline",
+ isExternal: true,
+ onPress: () => openExternalLink("https://app.cal.com/insights", "Insights page"),
+ },
+ {
+ name: "Support",
+ icon: "help-circle-outline",
+ isExternal: true,
+ onPress: () => openExternalLink("https://go.cal.com/support", "Support"),
+ },
+ ];
+
+ return (
+
+
+
+
+ {menuItems.map((item, index) => (
+ router.push(item.href!) : item.onPress}
+ className={`flex-row items-center justify-between bg-white px-5 py-5 active:bg-[#F8F9FA] ${
+ index < menuItems.length - 1 ? "border-b border-[#E5E5EA]" : ""
+ }`}
+ >
+
+
+ {item.name}
+
+ {item.isExternal ? (
+
+ ) : (
+
+ )}
+
+ ))}
+
+
+ {/* Authentication Info and Logout */}
+
+
+
+
+
+ We view the companion as an extension of the web application. If you are performing any
+ complicated actions, please refer back to the web application.
+
+
+
+ );
+}
diff --git a/companion/app/_layout.tsx b/companion/app/_layout.tsx
new file mode 100644
index 0000000000..da89a2764f
--- /dev/null
+++ b/companion/app/_layout.tsx
@@ -0,0 +1,48 @@
+import { Stack } from "expo-router";
+import { Platform, View, StatusBar } from "react-native";
+import { AuthProvider, useAuth } from "../contexts/AuthContext";
+import LoginScreen from "../components/LoginScreen";
+import "../global.css";
+
+function RootLayoutContent() {
+ const { isAuthenticated } = useAuth();
+
+ const content = isAuthenticated ? (
+
+
+
+ ) : (
+
+ );
+
+ const containerClass =
+ Platform.OS === "web"
+ ? "w-[400px] flex-1 flex-col self-end border-l border-gray-200 bg-white"
+ : "bg-white";
+
+ const containerStyle =
+ Platform.OS === "web"
+ ? {
+ width: 400,
+ flex: 1,
+ display: "flex",
+ flexDirection: "column",
+ pointerEvents: "auto",
+ }
+ : { flex: 1 };
+
+ return (
+
+
+ {content}
+
+ );
+}
+
+export default function RootLayout() {
+ return (
+
+
+
+ );
+}
diff --git a/companion/app/availability-detail.tsx b/companion/app/availability-detail.tsx
new file mode 100644
index 0000000000..4e0f33ab8e
--- /dev/null
+++ b/companion/app/availability-detail.tsx
@@ -0,0 +1,994 @@
+import { Ionicons } from "@expo/vector-icons";
+import { GlassView } from "expo-glass-effect";
+import { useRouter, useLocalSearchParams, Stack } from "expo-router";
+import React, { useState, useEffect } from "react";
+import {
+ View,
+ Text,
+ ScrollView,
+ TouchableOpacity,
+ TextInput,
+ Alert,
+ ActivityIndicator,
+ Switch,
+} from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+
+import { CalComAPIService, Schedule } from "../services/calcom";
+import { ScheduleAvailability } from "../services/types";
+import { FullScreenModal } from "../components/FullScreenModal";
+
+const DAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
+const DAY_ABBREVIATIONS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
+
+// Convert 24-hour time to 12-hour format with AM/PM
+const formatTime12Hour = (time24: string): string => {
+ const [hours, minutes] = time24.split(":");
+ const hour = parseInt(hours, 10);
+ const min = minutes || "00";
+ const period = hour >= 12 ? "PM" : "AM";
+ const hour12 = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
+ // Pad single-digit hours with leading zero for consistent width
+ const hour12Padded = hour12.toString().padStart(2, "0");
+ return `${hour12Padded}:${min} ${period}`;
+};
+
+// Format availability for display
+const formatAvailabilityDisplay = (
+ availability: Record
+): string[] => {
+ // Group slots by time range
+ const timeRangeMap: Record = {};
+
+ Object.keys(availability).forEach((dayIndexStr) => {
+ const dayIndex = Number(dayIndexStr);
+ const slots = availability[dayIndex];
+ if (slots && slots.length > 0) {
+ slots.forEach((slot) => {
+ const timeKey = `${slot.startTime}-${slot.endTime}`;
+ if (!timeRangeMap[timeKey]) {
+ timeRangeMap[timeKey] = [];
+ }
+ timeRangeMap[timeKey].push(dayIndex);
+ });
+ }
+ });
+
+ // Format each time range group
+ const formatted: string[] = [];
+ Object.keys(timeRangeMap).forEach((timeKey) => {
+ const days = timeRangeMap[timeKey].sort((a, b) => a - b);
+ const [startTime, endTime] = timeKey.split("-");
+ const dayNames = days.map((day) => DAY_ABBREVIATIONS[day]).join(", ");
+ const timeRange = `${formatTime12Hour(startTime)} - ${formatTime12Hour(endTime)}`;
+ formatted.push(`${dayNames}, ${timeRange}`);
+ });
+
+ return formatted;
+};
+
+// Generate time options (15-minute intervals)
+const generateTimeOptions = () => {
+ const options: string[] = [];
+ for (let hour = 0; hour < 24; hour++) {
+ for (let minute = 0; minute < 60; minute += 15) {
+ const h = hour.toString().padStart(2, "0");
+ const m = minute.toString().padStart(2, "0");
+ options.push(`${h}:${m}`);
+ }
+ }
+ return options;
+};
+
+const TIME_OPTIONS = generateTimeOptions();
+
+export default function AvailabilityDetail() {
+ const router = useRouter();
+ const { id } = useLocalSearchParams<{ id: string }>();
+ const insets = useSafeAreaInsets();
+
+ const [loading, setLoading] = useState(true);
+ const [saving, setSaving] = useState(false);
+ const [schedule, setSchedule] = useState(null);
+ const [scheduleName, setScheduleName] = useState("");
+ const [timeZone, setTimeZone] = useState("");
+ const [isDefault, setIsDefault] = useState(false);
+ const [availability, setAvailability] = useState>({});
+ const [showTimezoneModal, setShowTimezoneModal] = useState(false);
+ const [showTimePicker, setShowTimePicker] = useState<{
+ dayIndex: number;
+ slotIndex: number;
+ type: "start" | "end";
+ } | null>(null);
+ const [overrides, setOverrides] = useState<
+ Array<{
+ date: string; // Format: "2024-05-20"
+ startTime: string; // Format: "12:00" or "00:00" for unavailable
+ endTime: string; // Format: "14:00" or "00:00" for unavailable
+ }>
+ >([]);
+ const [showOverrideModal, setShowOverrideModal] = useState(false);
+ const [editingOverride, setEditingOverride] = useState(null);
+ const [overrideDate, setOverrideDate] = useState("");
+ const [overrideStartTime, setOverrideStartTime] = useState("09:00");
+ const [overrideEndTime, setOverrideEndTime] = useState("17:00");
+ const [isUnavailable, setIsUnavailable] = useState(false);
+ const [showOverrideTimePicker, setShowOverrideTimePicker] = useState<{
+ type: "start" | "end";
+ } | null>(null);
+
+ // Common timezones
+ const timezones = [
+ "America/New_York",
+ "America/Chicago",
+ "America/Denver",
+ "America/Los_Angeles",
+ "Europe/London",
+ "Europe/Paris",
+ "Europe/Berlin",
+ "Asia/Tokyo",
+ "Asia/Shanghai",
+ "Asia/Kolkata",
+ "Australia/Sydney",
+ "UTC",
+ ];
+
+ useEffect(() => {
+ if (id) {
+ fetchSchedule();
+ }
+ }, [id]);
+
+ const fetchSchedule = async () => {
+ try {
+ setLoading(true);
+ const scheduleData = await CalComAPIService.getScheduleById(Number(id));
+
+ if (scheduleData) {
+ setSchedule(scheduleData);
+ setScheduleName(scheduleData.name || "");
+ setTimeZone(scheduleData.timeZone || "UTC");
+ setIsDefault(scheduleData.isDefault || false);
+
+ // Convert availability array to day-indexed object
+ const availabilityMap: Record = {};
+
+ // Map day names to numbers
+ const dayNameToNumber: Record = {
+ Sunday: 0,
+ Monday: 1,
+ Tuesday: 2,
+ Wednesday: 3,
+ Thursday: 4,
+ Friday: 5,
+ Saturday: 6,
+ };
+
+ if (scheduleData.availability && Array.isArray(scheduleData.availability)) {
+ scheduleData.availability.forEach((slot) => {
+ // Handle both string day names and number day formats
+ let days: number[] = [];
+ if (Array.isArray(slot.days)) {
+ days = slot.days
+ .map((day) => {
+ // If it's a day name string (e.g., "Sunday", "Monday")
+ if (typeof day === "string" && dayNameToNumber[day] !== undefined) {
+ return dayNameToNumber[day];
+ }
+ // If it's a number string (e.g., "0", "1")
+ if (typeof day === "string") {
+ const parsed = parseInt(day, 10);
+ if (!isNaN(parsed) && parsed >= 0 && parsed <= 6) {
+ return parsed;
+ }
+ }
+ // If it's already a number
+ if (typeof day === "number" && day >= 0 && day <= 6) {
+ return day;
+ }
+ return null;
+ })
+ .filter((day): day is number => day !== null);
+ }
+
+ days.forEach((day) => {
+ if (!availabilityMap[day]) {
+ availabilityMap[day] = [];
+ }
+ availabilityMap[day].push({
+ days: [day.toString()],
+ startTime: slot.startTime || "09:00:00",
+ endTime: slot.endTime || "17:00:00",
+ });
+ });
+ });
+ }
+
+ setAvailability(availabilityMap);
+
+ // Load overrides if they exist
+ if (scheduleData.overrides && Array.isArray(scheduleData.overrides)) {
+ const formattedOverrides = scheduleData.overrides.map((override) => ({
+ date: override.date || "",
+ startTime: override.startTime || "00:00",
+ endTime: override.endTime || "00:00",
+ }));
+ setOverrides(formattedOverrides);
+ } else {
+ setOverrides([]);
+ }
+ }
+ } catch (error) {
+ console.error("Error fetching schedule:", error);
+ Alert.alert("Error", "Failed to load schedule. Please try again.");
+ router.back();
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const toggleDay = (dayIndex: number) => {
+ setAvailability((prev) => {
+ const newAvailability = { ...prev };
+ if (newAvailability[dayIndex] && newAvailability[dayIndex].length > 0) {
+ // Disable day - remove availability
+ delete newAvailability[dayIndex];
+ } else {
+ // Enable day - add default time slot (9 AM - 5 PM)
+ newAvailability[dayIndex] = [
+ {
+ days: [dayIndex.toString()],
+ startTime: "09:00:00",
+ endTime: "17:00:00",
+ },
+ ];
+ }
+ return newAvailability;
+ });
+ };
+
+ const addTimeSlot = (dayIndex: number) => {
+ setAvailability((prev) => {
+ const newAvailability = { ...prev };
+ if (!newAvailability[dayIndex]) {
+ newAvailability[dayIndex] = [];
+ }
+ newAvailability[dayIndex].push({
+ days: [dayIndex.toString()],
+ startTime: "09:00:00",
+ endTime: "17:00:00",
+ });
+ return newAvailability;
+ });
+ };
+
+ const removeTimeSlot = (dayIndex: number, slotIndex: number) => {
+ setAvailability((prev) => {
+ const newAvailability = { ...prev };
+ if (newAvailability[dayIndex]) {
+ newAvailability[dayIndex] = newAvailability[dayIndex].filter((_, i) => i !== slotIndex);
+ if (newAvailability[dayIndex].length === 0) {
+ delete newAvailability[dayIndex];
+ }
+ }
+ return newAvailability;
+ });
+ };
+
+ const updateTimeSlot = (
+ dayIndex: number,
+ slotIndex: number,
+ type: "start" | "end",
+ time: string
+ ) => {
+ setAvailability((prev) => {
+ const newAvailability = { ...prev };
+ if (newAvailability[dayIndex] && newAvailability[dayIndex][slotIndex]) {
+ const slot = { ...newAvailability[dayIndex][slotIndex] };
+ if (type === "start") {
+ slot.startTime = `${time}:00`;
+ } else {
+ slot.endTime = `${time}:00`;
+ }
+ newAvailability[dayIndex][slotIndex] = slot;
+ }
+ return newAvailability;
+ });
+ };
+
+ const handleSave = async () => {
+ try {
+ setSaving(true);
+
+ // Convert availability object back to array format with day names
+ const availabilityArray: Array<{
+ days: string[]; // Day names like "Monday", "Tuesday"
+ startTime: string; // Format: "09:00"
+ endTime: string; // Format: "10:00"
+ }> = [];
+
+ Object.keys(availability).forEach((dayIndexStr) => {
+ const dayIndex = Number(dayIndexStr);
+ const slots = availability[dayIndex];
+ if (slots && slots.length > 0) {
+ slots.forEach((slot) => {
+ // Convert day number to day name
+ const dayName = DAYS[dayIndex];
+
+ // Format time from "09:00:00" to "09:00" (remove seconds)
+ const formatTimeForAPI = (time: string): string => {
+ return time.substring(0, 5); // Take only HH:MM
+ };
+
+ availabilityArray.push({
+ days: [dayName],
+ startTime: formatTimeForAPI(slot.startTime),
+ endTime: formatTimeForAPI(slot.endTime),
+ });
+ });
+ }
+ });
+
+ // Format overrides for API (ensure times are in HH:MM format)
+ const formattedOverrides = overrides.map((override) => ({
+ date: override.date,
+ startTime: override.startTime.substring(0, 5), // Ensure HH:MM format
+ endTime: override.endTime.substring(0, 5), // Ensure HH:MM format
+ }));
+
+ await CalComAPIService.updateSchedule(Number(id), {
+ name: scheduleName,
+ timeZone,
+ availability: availabilityArray,
+ isDefault: isDefault,
+ overrides: formattedOverrides,
+ });
+
+ Alert.alert("Success", "Schedule updated successfully", [
+ { text: "OK", onPress: () => router.back() },
+ ]);
+ } catch (error) {
+ Alert.alert("Error", "Failed to update schedule. Please try again.");
+ } finally {
+ setSaving(false);
+ }
+ };
+
+ const handleSetAsDefault = async () => {
+ try {
+ await CalComAPIService.updateSchedule(Number(id), {
+ isDefault: true,
+ });
+ setIsDefault(true);
+ Alert.alert("Success", "Schedule set as default successfully");
+ } catch (error) {
+ Alert.alert("Error", "Failed to set schedule as default. Please try again.");
+ }
+ };
+
+ const handleDelete = () => {
+ Alert.alert("Delete Schedule", `Are you sure you want to delete "${scheduleName}"?`, [
+ { text: "Cancel", style: "cancel" },
+ {
+ text: "Delete",
+ style: "destructive",
+ onPress: async () => {
+ try {
+ await CalComAPIService.deleteSchedule(Number(id));
+ Alert.alert("Success", "Schedule deleted successfully", [
+ { text: "OK", onPress: () => router.back() },
+ ]);
+ } catch (error) {
+ Alert.alert("Error", "Failed to delete schedule. Please try again.");
+ }
+ },
+ },
+ ]);
+ };
+
+ const handleAddOverride = () => {
+ setEditingOverride(null);
+ setOverrideDate("");
+ setOverrideStartTime("09:00");
+ setOverrideEndTime("17:00");
+ setIsUnavailable(false);
+ setShowOverrideModal(true);
+ };
+
+ const handleEditOverride = (index: number) => {
+ const override = overrides[index];
+ setEditingOverride(index);
+ setOverrideDate(override.date);
+ setOverrideStartTime(override.startTime);
+ setOverrideEndTime(override.endTime);
+ setIsUnavailable(override.startTime === "00:00" && override.endTime === "00:00");
+ setShowOverrideModal(true);
+ };
+
+ const handleDeleteOverride = (index: number) => {
+ Alert.alert("Delete Override", "Are you sure you want to delete this date override?", [
+ { text: "Cancel", style: "cancel" },
+ {
+ text: "Delete",
+ style: "destructive",
+ onPress: () => {
+ setOverrides(overrides.filter((_, i) => i !== index));
+ },
+ },
+ ]);
+ };
+
+ const handleSaveOverride = () => {
+ if (!overrideDate) {
+ Alert.alert("Error", "Please select a date");
+ return;
+ }
+
+ const newOverride = {
+ date: overrideDate,
+ startTime: isUnavailable ? "00:00" : overrideStartTime,
+ endTime: isUnavailable ? "00:00" : overrideEndTime,
+ };
+
+ if (editingOverride !== null) {
+ // Update existing override
+ const updated = [...overrides];
+ updated[editingOverride] = newOverride;
+ setOverrides(updated);
+ } else {
+ // Add new override
+ setOverrides([...overrides, newOverride]);
+ }
+
+ setShowOverrideModal(false);
+ };
+
+ const formatDateForDisplay = (dateStr: string): string => {
+ if (!dateStr) return "";
+ const date = new Date(dateStr + "T00:00:00");
+ return date.toLocaleDateString("en-US", {
+ month: "short",
+ day: "numeric",
+ year: "numeric",
+ });
+ };
+
+ if (loading) {
+ return (
+
+
+ Loading schedule...
+
+ );
+ }
+
+ return (
+ <>
+ (
+ Edit Availability
+ ),
+ headerLeft: () => (
+ router.back()} className="ml-4">
+
+
+ ),
+ headerRight: () => (
+
+ Save
+
+ ),
+ }}
+ />
+
+
+
+ {/* Schedule Name and Working Hours Display */}
+
+ {scheduleName}
+ {Object.keys(availability).length > 0 ? (
+
+ {formatAvailabilityDisplay(availability).map((line, index) => (
+
+ {line}
+
+ ))}
+
+ ) : (
+ No availability set
+ )}
+
+
+ {/* Availability Schedule */}
+
+ Availability
+ {DAYS.map((day, dayIndex) => {
+ const daySlots = availability[dayIndex] || [];
+ const isEnabled = daySlots.length > 0;
+ const firstSlot = daySlots[0];
+
+ return (
+
+
+
+ toggleDay(dayIndex)}
+ trackColor={{ false: "#E5E5EA", true: "#34C759" }}
+ thumbColor="#fff"
+ style={{ transform: [{ scaleX: 0.8 }, { scaleY: 0.8 }] }}
+ />
+
+ {DAY_ABBREVIATIONS[dayIndex]}
+
+ {isEnabled && firstSlot && (
+
+
+ setShowTimePicker({ dayIndex, slotIndex: 0, type: "start" })
+ }
+ className="rounded-lg border border-[#E5E5EA] bg-white px-2 py-1"
+ style={{ width: 85 }}
+ >
+
+ {formatTime12Hour(firstSlot.startTime)}
+
+
+ -
+
+ setShowTimePicker({ dayIndex, slotIndex: 0, type: "end" })
+ }
+ className="rounded-lg border border-[#E5E5EA] bg-white px-2 py-1"
+ style={{ width: 85 }}
+ >
+
+ {formatTime12Hour(firstSlot.endTime)}
+
+
+
+ )}
+
+ {isEnabled && (
+ addTimeSlot(dayIndex)} className="p-1">
+
+
+ )}
+
+
+ {isEnabled && daySlots.length > 1 && (
+
+ {daySlots.slice(1).map((slot, slotIndex) => (
+
+
+ setShowTimePicker({
+ dayIndex,
+ slotIndex: slotIndex + 1,
+ type: "start",
+ })
+ }
+ className="rounded-lg border border-[#E5E5EA] bg-white px-2 py-1"
+ style={{ width: 85 }}
+ >
+
+ {formatTime12Hour(slot.startTime)}
+
+
+ -
+
+ setShowTimePicker({
+ dayIndex,
+ slotIndex: slotIndex + 1,
+ type: "end",
+ })
+ }
+ className="rounded-lg border border-[#E5E5EA] bg-white px-2 py-1"
+ style={{ width: 85 }}
+ >
+
+ {formatTime12Hour(slot.endTime)}
+
+
+ removeTimeSlot(dayIndex, slotIndex + 1)}
+ className="p-1"
+ >
+
+
+
+ ))}
+
+ )}
+
+ );
+ })}
+
+
+ {/* Timezone */}
+
+ Timezone
+ setShowTimezoneModal(true)}
+ className="flex-row items-center justify-between rounded-lg border border-[#E5E5EA] bg-[#F8F9FA] px-3 py-3"
+ >
+ {timeZone}
+
+
+
+
+ {/* Date Overrides */}
+
+ Date overrides
+
+ Add dates when your availability changes from your daily hours.
+
+
+ {overrides.length > 0 && (
+
+ {overrides.map((override, index) => (
+
+
+
+ {formatDateForDisplay(override.date)}
+
+ {override.startTime === "00:00" && override.endTime === "00:00" ? (
+ Unavailable (All day)
+ ) : (
+
+ {formatTime12Hour(override.startTime + ":00")} -{" "}
+ {formatTime12Hour(override.endTime + ":00")}
+
+ )}
+
+
+ handleEditOverride(index)} className="p-2">
+
+
+ handleDeleteOverride(index)}
+ className="p-2"
+ >
+
+
+
+
+ ))}
+
+ )}
+
+
+
+ Add an override
+
+
+
+
+
+ {/* Bottom Action Bar */}
+
+
+
+ Set as Default
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Timezone Modal */}
+ setShowTimezoneModal(false)}
+ >
+ setShowTimezoneModal(false)}
+ >
+ e.stopPropagation()}
+ >
+
+ Select Timezone
+ setShowTimezoneModal(false)}>
+
+
+
+
+ {timezones.map((tz) => (
+ {
+ setTimeZone(tz);
+ setShowTimezoneModal(false);
+ }}
+ className="border-b border-[#E5E5EA] py-3"
+ >
+ {tz}
+
+ ))}
+
+
+
+
+
+ {/* Time Picker Modal */}
+ setShowTimePicker(null)}
+ >
+ setShowTimePicker(null)}
+ >
+ e.stopPropagation()}
+ >
+
+
+ Select {showTimePicker?.type === "start" ? "Start" : "End"} Time
+
+ setShowTimePicker(null)}>
+
+
+
+
+ {TIME_OPTIONS.map((time) => {
+ const currentTime =
+ showTimePicker?.type === "start"
+ ? availability[showTimePicker.dayIndex]?.[
+ showTimePicker.slotIndex
+ ]?.startTime.substring(0, 5)
+ : availability[showTimePicker?.dayIndex || 0]?.[
+ showTimePicker?.slotIndex || 0
+ ]?.endTime.substring(0, 5);
+ const isSelected = currentTime === time;
+
+ return (
+ {
+ if (showTimePicker) {
+ updateTimeSlot(
+ showTimePicker.dayIndex,
+ showTimePicker.slotIndex,
+ showTimePicker.type,
+ time
+ );
+ setShowTimePicker(null);
+ }
+ }}
+ className={`border-b border-[#E5E5EA] py-3 ${isSelected ? "bg-[#E3F2FD]" : ""}`}
+ >
+
+ {time}
+
+
+ );
+ })}
+
+
+
+
+
+ {/* Override Modal */}
+ setShowOverrideModal(false)}
+ >
+ setShowOverrideModal(false)}
+ >
+ e.stopPropagation()}
+ >
+
+
+ {editingOverride !== null ? "Edit Override" : "Add Override"}
+
+ setShowOverrideModal(false)}>
+
+
+
+
+
+
+ {/* Date Picker */}
+
+
+ Select the dates to override
+
+
+ Enter date in YYYY-MM-DD format
+
+
+ {/* Unavailable Toggle */}
+
+
+ Mark unavailable (All day)
+
+
+
+
+ {/* Time Picker (only if not unavailable) */}
+ {!isUnavailable && (
+
+
+ Which hours are you free?
+
+
+ setShowOverrideTimePicker({ type: "start" })}
+ className="flex-1 rounded-lg border border-[#E5E5EA] bg-white px-3 py-3"
+ >
+
+ {formatTime12Hour(overrideStartTime + ":00")}
+
+
+ -
+ setShowOverrideTimePicker({ type: "end" })}
+ className="flex-1 rounded-lg border border-[#E5E5EA] bg-white px-3 py-3"
+ >
+
+ {formatTime12Hour(overrideEndTime + ":00")}
+
+
+
+
+ )}
+
+ {/* Save Button */}
+
+
+ Save Override
+
+
+
+
+
+
+
+
+ {/* Override Time Picker Modal */}
+ setShowOverrideTimePicker(null)}
+ >
+ setShowOverrideTimePicker(null)}
+ >
+ e.stopPropagation()}
+ >
+
+
+ Select {showOverrideTimePicker?.type === "start" ? "Start" : "End"} Time
+
+ setShowOverrideTimePicker(null)}>
+
+
+
+
+ {TIME_OPTIONS.map((time) => {
+ const currentTime =
+ showOverrideTimePicker?.type === "start" ? overrideStartTime : overrideEndTime;
+ const isSelected = currentTime === time;
+ return (
+ {
+ if (showOverrideTimePicker?.type === "start") {
+ setOverrideStartTime(time);
+ } else {
+ setOverrideEndTime(time);
+ }
+ setShowOverrideTimePicker(null);
+ }}
+ className={`border-b border-[#E5E5EA] py-3 ${isSelected ? "bg-[#F0F9FF]" : ""}`}
+ >
+
+ {formatTime12Hour(time + ":00")}
+
+
+ );
+ })}
+
+
+
+
+ >
+ );
+}
diff --git a/companion/app/booking-detail.tsx b/companion/app/booking-detail.tsx
new file mode 100644
index 0000000000..821978e77e
--- /dev/null
+++ b/companion/app/booking-detail.tsx
@@ -0,0 +1,747 @@
+import { Ionicons } from "@expo/vector-icons";
+import { useRouter, useLocalSearchParams, Stack } from "expo-router";
+import React, { useState, useEffect } from "react";
+import {
+ View,
+ Text,
+ ScrollView,
+ TouchableOpacity,
+ Alert,
+ ActivityIndicator,
+ Linking,
+ TextInput,
+ Platform,
+} from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { CalComAPIService, Booking } from "../services/calcom";
+import { SvgImage } from "../components/SvgImage";
+import { FullScreenModal } from "../components/FullScreenModal";
+import { getAppIconUrl } from "../utils/getAppIconUrl";
+import { getDefaultLocationIconUrl, defaultLocations } from "../utils/defaultLocations";
+
+// Format date: "Tuesday, November 25, 2025"
+const formatDateFull = (dateString: string): string => {
+ if (!dateString) return "";
+ try {
+ const date = new Date(dateString);
+ return date.toLocaleDateString("en-US", {
+ weekday: "long",
+ month: "long",
+ day: "numeric",
+ year: "numeric",
+ });
+ } catch (error) {
+ return "";
+ }
+};
+
+// Format time: "9:40pm - 10:00pm"
+const formatTime12Hour = (dateString: string): string => {
+ if (!dateString) return "";
+ try {
+ const date = new Date(dateString);
+ const hours = date.getHours();
+ const minutes = date.getMinutes();
+ const period = hours >= 12 ? "pm" : "am";
+ const hour12 = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours;
+ const minStr = minutes.toString().padStart(2, "0");
+ return `${hour12}:${minStr}${period}`;
+ } catch (error) {
+ return "";
+ }
+};
+
+// Get timezone from date string
+const getTimezone = (dateString: string): string => {
+ if (!dateString) return "";
+ try {
+ const date = new Date(dateString);
+ const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
+ return timeZone;
+ } catch (error) {
+ return "";
+ }
+};
+
+// Get initials from a name (e.g., "Keith Williams" -> "KW", "Dhairyashil Shinde" -> "DS")
+const getInitials = (name: string): string => {
+ if (!name) return "";
+ const parts = name.trim().split(/\s+/);
+ if (parts.length === 0) return "";
+ if (parts.length === 1) {
+ return parts[0].charAt(0).toUpperCase();
+ }
+ // Get first letter of first name and first letter of last name
+ return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();
+};
+
+// Get location provider info
+const getLocationProvider = (location: string | undefined, metadata?: Record) => {
+ // Check metadata for videoCallUrl first
+ const videoCallUrl = metadata?.videoCallUrl;
+ const locationToCheck = videoCallUrl || location;
+
+ if (!locationToCheck) return null;
+
+ // Check if it's a video call URL
+ if (typeof locationToCheck === "string" && locationToCheck.startsWith("http")) {
+ // Try to detect provider from URL
+ if (locationToCheck.includes("cal.com/video") || locationToCheck.includes("cal-video")) {
+ const iconUrl = getAppIconUrl("daily_video", "cal-video");
+ return {
+ label: "Cal Video",
+ iconUrl: iconUrl || "https://app.cal.com/app-store/dailyvideo/icon.svg",
+ url: locationToCheck,
+ };
+ }
+ // Check for other video providers by URL pattern
+ const videoProviders = [
+ { pattern: /zoom\.us/, label: "Zoom", type: "zoom_video", appId: "zoom" },
+ {
+ pattern: /meet\.google\.com/,
+ label: "Google Meet",
+ type: "google_video",
+ appId: "google-meet",
+ },
+ {
+ pattern: /teams\.microsoft\.com/,
+ label: "Microsoft Teams",
+ type: "office365_video",
+ appId: "msteams",
+ },
+ ];
+
+ for (const provider of videoProviders) {
+ if (provider.pattern.test(locationToCheck)) {
+ const iconUrl = getAppIconUrl(provider.type, provider.appId);
+ return {
+ label: provider.label,
+ iconUrl: iconUrl,
+ url: locationToCheck,
+ };
+ }
+ }
+
+ // Generic link meeting
+ const linkIconUrl = getDefaultLocationIconUrl("link") || "https://app.cal.com/link.svg";
+ return {
+ label: "Link Meeting",
+ iconUrl: linkIconUrl,
+ url: locationToCheck,
+ };
+ }
+
+ // Check if it's an integration location (e.g., "integrations:zoom", "integrations:cal-video")
+ if (typeof locationToCheck === "string" && locationToCheck.startsWith("integrations:")) {
+ const appId = locationToCheck.replace("integrations:", "");
+ const iconUrl = getAppIconUrl("", appId);
+
+ if (iconUrl) {
+ // Format appId to display name (e.g., "cal-video" -> "Cal Video")
+ const formatAppIdToDisplayName = (id: string): string => {
+ return id
+ .split("-")
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
+ .join(" ");
+ };
+
+ return {
+ label: formatAppIdToDisplayName(appId),
+ iconUrl: iconUrl,
+ url: null,
+ };
+ }
+ }
+
+ // Check if it's a default location type
+ const defaultLocation = defaultLocations.find((loc) => loc.type === locationToCheck);
+ if (defaultLocation) {
+ return {
+ label: defaultLocation.label,
+ iconUrl: defaultLocation.iconUrl,
+ url: null,
+ };
+ }
+
+ // Fallback: return as plain text location
+ return {
+ label: locationToCheck,
+ iconUrl: null,
+ url: null,
+ };
+};
+
+export default function BookingDetail() {
+ const router = useRouter();
+ const { uid } = useLocalSearchParams<{ uid: string }>();
+ const insets = useSafeAreaInsets();
+
+ const [loading, setLoading] = useState(true);
+ const [booking, setBooking] = useState(null);
+ const [error, setError] = useState(null);
+ const [showActionsModal, setShowActionsModal] = useState(false);
+ const [showRescheduleModal, setShowRescheduleModal] = useState(false);
+ const [rescheduleReason, setRescheduleReason] = useState("");
+ const [rescheduling, setRescheduling] = useState(false);
+
+ useEffect(() => {
+ if (uid) {
+ fetchBooking();
+ }
+ }, [uid]);
+
+ const fetchBooking = async () => {
+ try {
+ setLoading(true);
+ setError(null);
+ const bookingData = await CalComAPIService.getBookingByUid(uid);
+ console.log("Booking data received:", JSON.stringify(bookingData, null, 2));
+ console.log("User:", bookingData.user);
+ console.log("Hosts:", bookingData.hosts);
+ console.log("Attendees:", bookingData.attendees);
+ console.log("Recurring fields:", {
+ recurringEventId: bookingData.recurringEventId,
+ recurringBookingUid: (bookingData as any).recurringBookingUid,
+ metadata: (bookingData as any).metadata,
+ });
+ setBooking(bookingData);
+ } catch (err) {
+ console.error("Error fetching booking:", err);
+ setError("Failed to load booking. Please try again.");
+ Alert.alert("Error", "Failed to load booking. Please try again.", [
+ { text: "OK", onPress: () => router.back() },
+ ]);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const handleJoinMeeting = () => {
+ if (!booking?.location) return;
+
+ const provider = getLocationProvider(booking.location);
+ if (provider?.url) {
+ Linking.openURL(provider.url);
+ }
+ };
+
+ const handleReschedule = async () => {
+ if (!booking) return;
+
+ setRescheduling(true);
+ try {
+ // For now, we'll use the current start time
+ // In a full implementation, you'd show a date/time picker
+ await CalComAPIService.rescheduleBooking(booking.uid, {
+ start: booking.startTime,
+ reschedulingReason: rescheduleReason.trim() || undefined,
+ });
+
+ Alert.alert("Success", "Reschedule request sent successfully");
+ setShowRescheduleModal(false);
+ setRescheduleReason("");
+
+ // Refresh booking data
+ await fetchBooking();
+ } catch (error) {
+ console.error("Failed to reschedule booking:", error);
+ Alert.alert("Error", "Failed to send reschedule request. Please try again.");
+ } finally {
+ setRescheduling(false);
+ }
+ };
+
+ if (loading) {
+ return (
+
+
+ Loading booking...
+
+ );
+ }
+
+ if (error || !booking) {
+ return (
+
+
+
+ {error || "Booking not found"}
+
+ router.back()}
+ >
+ Go Back
+
+
+ );
+ }
+
+ const startTime = booking.start || booking.startTime || "";
+ const endTime = booking.end || booking.endTime || "";
+ const dateFormatted = formatDateFull(startTime);
+ const timeFormatted = `${formatTime12Hour(startTime)} - ${formatTime12Hour(endTime)}`;
+ const timezone = getTimezone(startTime);
+ const locationProvider = getLocationProvider(booking.location, booking.responses);
+
+ return (
+ <>
+ (
+ router.back()}
+ className="items-center justify-center rounded-full"
+ style={{ width: 40, height: 40, backgroundColor: "#F0F0F0" }}
+ >
+
+
+ ),
+ headerRight: () => (
+ setShowActionsModal(true)}
+ className="items-center justify-center rounded-full"
+ style={{ width: 40, height: 40, backgroundColor: "#F0F0F0" }}
+ >
+
+
+ ),
+ }}
+ />
+
+
+ {/* Title */}
+
+ {booking.title}
+
+ {dateFormatted} {timeFormatted} ({timezone})
+
+
+
+ {/* Who Section */}
+
+ Who
+ {/* Show host from user field or hosts array */}
+ {(booking.user || (booking.hosts && booking.hosts.length > 0)) && (
+
+ {booking.user ? (
+
+
+
+ {getInitials(booking.user.name)}
+
+
+
+
+
+ {booking.user.name}
+
+
+ host
+
+
+ {booking.user.email}
+
+
+ ) : booking.hosts && booking.hosts.length > 0 ? (
+ booking.hosts.map((host, hostIndex) => (
+ 0 ? "mt-4" : ""}`}
+ >
+
+
+ {getInitials(host.name || "Host")}
+
+
+
+
+
+ {host.name || "Host"}
+
+
+ host
+
+
+ {host.email && {host.email} }
+
+
+ ))
+ ) : null}
+
+ )}
+ {booking.attendees && booking.attendees.length > 0 && (
+
+ {booking.attendees.map((attendee, index) => (
+ 0 ? "mt-4" : ""}`}>
+
+
+ {getInitials(attendee.name)}
+
+
+
+
+ {attendee.name}
+
+ {attendee.email}
+
+
+ ))}
+
+ )}
+
+
+ {/* Where Section */}
+ {locationProvider && (
+
+ Where
+ {locationProvider.url ? (
+
+ {locationProvider.iconUrl && (
+
+ )}
+ {locationProvider.label}:
+
+ {locationProvider.url}
+
+
+ ) : (
+
+ {locationProvider.iconUrl && (
+
+ )}
+ {locationProvider.label}
+
+ )}
+
+ )}
+
+ {/* Recurring Event Section */}
+ {(booking.recurringEventId || booking.recurringBookingUid) && (
+
+ Recurring Event
+ Every 2 weeks for 6 occurrences
+
+ )}
+
+ {/* Description Section */}
+ {booking.description && (
+
+ Description
+ {booking.description}
+
+ )}
+
+ {/* Join Meeting Button */}
+ {locationProvider?.url && (
+
+ {locationProvider.iconUrl && (
+
+ )}
+
+ Join {locationProvider.label}
+
+
+ )}
+
+
+
+ {/* Booking Actions Modal */}
+ setShowActionsModal(false)}
+ >
+ setShowActionsModal(false)}
+ >
+ e.stopPropagation()}
+ >
+ {/* Header */}
+
+
+ Booking Actions
+
+
+ {/* Actions List */}
+
+ {/* View Booking */}
+ {
+ setShowActionsModal(false);
+ // TODO: Navigate to booking view page
+ console.log("View booking");
+ }}
+ className="flex-row items-center p-2 hover:bg-gray-50 md:p-4"
+ >
+
+ View Booking
+
+
+ {/* Separator */}
+
+
+ {/* Edit event label */}
+
+ Edit event
+
+
+ {/* Request Reschedule */}
+ {
+ setShowActionsModal(false);
+ setShowRescheduleModal(true);
+ }}
+ className="flex-row items-center p-2 hover:bg-gray-50 md:p-4"
+ >
+
+ Send Reschedule Request
+
+
+ {/* Edit Location */}
+ {
+ setShowActionsModal(false);
+ // TODO: Open edit location dialog
+ console.log("Edit location");
+ }}
+ className="flex-row items-center p-2 hover:bg-gray-50 md:p-4"
+ >
+
+ Edit Location
+
+
+ {/* Add Guests */}
+ {
+ setShowActionsModal(false);
+ // TODO: Open add guests dialog
+ console.log("Add guests");
+ }}
+ className="flex-row items-center p-2 hover:bg-gray-50 md:p-4"
+ >
+
+ Add Guests
+
+
+ {/* Separator */}
+
+
+ {/* After event label */}
+
+ After event
+
+
+ {/* View Recordings */}
+ {locationProvider?.url && (
+ {
+ setShowActionsModal(false);
+ // TODO: Open view recordings dialog
+ console.log("View recordings");
+ }}
+ className="flex-row items-center p-2 hover:bg-gray-50 md:p-4"
+ >
+
+ View Recordings
+
+ )}
+
+ {/* Meeting Session Details */}
+ {locationProvider?.url && (
+ {
+ setShowActionsModal(false);
+ // TODO: Open session details dialog
+ console.log("Meeting session details");
+ }}
+ className="flex-row items-center p-2 hover:bg-gray-50 md:p-4"
+ >
+
+ Meeting Session Details
+
+ )}
+
+ {/* Mark as No-Show */}
+ {
+ setShowActionsModal(false);
+ // TODO: Mark as no-show
+ console.log("Mark as no-show");
+ }}
+ className="flex-row items-center p-2 hover:bg-gray-50 md:p-4"
+ >
+
+ Mark as No-Show
+
+
+ {/* Separator */}
+
+
+ {/* Report Booking */}
+ {
+ setShowActionsModal(false);
+ // TODO: Open report booking dialog
+ console.log("Report booking");
+ }}
+ className="flex-row items-center p-2 hover:bg-gray-50 md:p-4"
+ >
+
+ Report Booking
+
+
+ {/* Separator */}
+
+
+ {/* Cancel Booking */}
+ {
+ setShowActionsModal(false);
+ Alert.alert("Cancel Booking", "Are you sure you want to cancel this booking?", [
+ { text: "No", style: "cancel" },
+ {
+ text: "Yes, Cancel",
+ style: "destructive",
+ onPress: () => {
+ // TODO: Cancel booking
+ console.log("Cancel booking");
+ },
+ },
+ ]);
+ }}
+ className="flex-row items-center p-2 hover:bg-gray-50 md:p-4"
+ >
+
+ Cancel Booking
+
+
+
+ {/* Cancel button */}
+
+ setShowActionsModal(false)}
+ >
+ Cancel
+
+
+
+
+
+
+ {/* Reschedule Modal */}
+ setShowRescheduleModal(false)}
+ >
+ setShowRescheduleModal(false)}
+ >
+ e.stopPropagation()}
+ style={{
+ shadowColor: "#000",
+ shadowOffset: { width: 0, height: 20 },
+ shadowOpacity: 0.25,
+ shadowRadius: 25,
+ elevation: 24,
+ }}
+ >
+ {/* Header */}
+
+
+
+
+
+
+
+ Reschedule request
+
+
+ Send a reschedule request to the organizer of this booking.
+
+
+
+
+
+ {/* Content */}
+
+
+ Reason for reschedule request
+ (Optional)
+
+
+
+
+ {/* Footer */}
+
+
+ {
+ setShowRescheduleModal(false);
+ setRescheduleReason("");
+ }}
+ disabled={rescheduling}
+ >
+ Cancel
+
+
+ Reschedule request
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/companion/app/event-type-detail.tsx b/companion/app/event-type-detail.tsx
new file mode 100644
index 0000000000..3991df5b37
--- /dev/null
+++ b/companion/app/event-type-detail.tsx
@@ -0,0 +1,2188 @@
+import { Ionicons } from "@expo/vector-icons";
+import { GlassView } from "expo-glass-effect";
+import { useRouter, useLocalSearchParams, Stack } from "expo-router";
+import React, { useState, useEffect } from "react";
+import {
+ View,
+ Text,
+ ScrollView,
+ TouchableOpacity,
+ TextInput,
+ Switch,
+ Modal,
+ Linking,
+ Alert,
+ Clipboard,
+ Animated,
+ Image,
+ Platform,
+} from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+
+import { CalComAPIService, Schedule, ConferencingOption, EventType } from "../services/calcom";
+import { getAppIconUrl } from "../utils/getAppIconUrl";
+import {
+ defaultLocations,
+ getDefaultLocationIconUrl,
+ isDefaultLocation,
+ DefaultLocationType,
+} from "../utils/defaultLocations";
+import { SvgImage } from "../components/SvgImage";
+import {
+ parseBufferTime,
+ parseMinimumNotice,
+ parseFrequencyUnit,
+ parseSlotInterval,
+} from "../utils/parsers/event-type-parsers";
+import { slugify } from "../utils/slugify";
+import { BasicsTab } from "./event-type-detail/tabs/BasicsTab";
+import { AvailabilityTab } from "./event-type-detail/tabs/AvailabilityTab";
+import { LimitsTab } from "./event-type-detail/tabs/LimitsTab";
+import { AdvancedTab } from "./event-type-detail/tabs/AdvancedTab";
+import { RecurringTab } from "./event-type-detail/tabs/RecurringTab";
+
+const tabs = [
+ { id: "basics", label: "Basics", icon: "link" },
+ { id: "availability", label: "Availability", icon: "calendar" },
+ { id: "limits", label: "Limits", icon: "time" },
+ { id: "advanced", label: "Advanced", icon: "settings" },
+ { id: "recurring", label: "Recurring", icon: "refresh" },
+ { id: "apps", label: "Apps", icon: "grid" },
+ { id: "workflows", label: "Workflows", icon: "flash" },
+ { id: "webhooks", label: "Webhooks", icon: "code" },
+];
+
+export default function EventTypeDetail() {
+ const router = useRouter();
+ const { id, title, description, duration, price, currency, slug } = useLocalSearchParams<{
+ id: string;
+ title: string;
+ description?: string;
+ duration: string;
+ price?: string;
+ currency?: string;
+ slug?: string;
+ }>();
+
+ const insets = useSafeAreaInsets();
+ const [activeTab, setActiveTab] = useState("basics");
+
+ // Form state
+ const [eventTitle, setEventTitle] = useState(title || "");
+ const [eventDescription, setEventDescription] = useState(description || "");
+ const [eventSlug, setEventSlug] = useState(slug || "");
+ const [eventDuration, setEventDuration] = useState(duration || "30");
+ const [username, setUsername] = useState("username");
+ const [allowMultipleDurations, setAllowMultipleDurations] = useState(false);
+ const [selectedLocation, setSelectedLocation] = useState("");
+ const [showLocationDropdown, setShowLocationDropdown] = useState(false);
+ const [locationAddress, setLocationAddress] = useState("");
+ const [locationLink, setLocationLink] = useState("");
+ const [locationPhone, setLocationPhone] = useState("");
+ const [selectedDurations, setSelectedDurations] = useState([]);
+ const [defaultDuration, setDefaultDuration] = useState("");
+ const [showDurationDropdown, setShowDurationDropdown] = useState(false);
+ const [showDefaultDurationDropdown, setShowDefaultDurationDropdown] = useState(false);
+ const [schedules, setSchedules] = useState([]);
+ const [selectedSchedule, setSelectedSchedule] = useState(null);
+ const [selectedScheduleDetails, setSelectedScheduleDetails] = useState(null);
+ const [showScheduleDropdown, setShowScheduleDropdown] = useState(false);
+ const [schedulesLoading, setSchedulesLoading] = useState(false);
+ const [scheduleDetailsLoading, setScheduleDetailsLoading] = useState(false);
+ const [isHidden, setIsHidden] = useState(false);
+ const [selectedTimezone, setSelectedTimezone] = useState("");
+ const [showTimezoneDropdown, setShowTimezoneDropdown] = useState(false);
+ const [conferencingOptions, setConferencingOptions] = useState([]);
+ const [conferencingLoading, setConferencingLoading] = useState(false);
+ const [eventTypeData, setEventTypeData] = useState(null);
+ const [saving, setSaving] = useState(false);
+ const [beforeEventBuffer, setBeforeEventBuffer] = useState("No buffer time");
+ const [afterEventBuffer, setAfterEventBuffer] = useState("No buffer time");
+ const [showBeforeBufferDropdown, setShowBeforeBufferDropdown] = useState(false);
+ const [showAfterBufferDropdown, setShowAfterBufferDropdown] = useState(false);
+ const [minimumNoticeValue, setMinimumNoticeValue] = useState("1");
+ const [minimumNoticeUnit, setMinimumNoticeUnit] = useState("Hours");
+ const [showMinimumNoticeUnitDropdown, setShowMinimumNoticeUnitDropdown] = useState(false);
+ const [limitBookingFrequency, setLimitBookingFrequency] = useState(false);
+ const [frequencyLimits, setFrequencyLimits] = useState([{ id: 1, value: "1", unit: "Per day" }]);
+ const [showFrequencyUnitDropdown, setShowFrequencyUnitDropdown] = useState(null);
+ const [frequencyAnimationValue] = useState(new Animated.Value(0));
+ const [limitTotalDuration, setLimitTotalDuration] = useState(false);
+ const [durationLimits, setDurationLimits] = useState([{ id: 1, value: "60", unit: "Per day" }]);
+ const [showDurationUnitDropdown, setShowDurationUnitDropdown] = useState(null);
+ const [durationAnimationValue] = useState(new Animated.Value(0));
+ const [slotInterval, setSlotInterval] = useState("Default");
+ const [showSlotIntervalDropdown, setShowSlotIntervalDropdown] = useState(false);
+ const [onlyShowFirstAvailableSlot, setOnlyShowFirstAvailableSlot] = useState(false);
+ const [maxActiveBookingsPerBooker, setMaxActiveBookingsPerBooker] = useState(false);
+ const [maxActiveBookingsValue, setMaxActiveBookingsValue] = useState("1");
+ const [limitFutureBookings, setLimitFutureBookings] = useState(false);
+ const [futureBookingType, setFutureBookingType] = useState<"rolling" | "range">("rolling");
+ const [rollingDays, setRollingDays] = useState("30");
+ const [rollingCalendarDays, setRollingCalendarDays] = useState(false);
+ const [rangeStartDate, setRangeStartDate] = useState("");
+ const [rangeEndDate, setRangeEndDate] = useState("");
+ const [offsetStartTimes, setOffsetStartTimes] = useState(false);
+ const [offsetStartValue, setOffsetStartValue] = useState("0");
+
+ // Advanced tab state
+ const [calendarEventName, setCalendarEventName] = useState("");
+ const [addToCalendarEmail, setAddToCalendarEmail] = useState("");
+ const [selectedLayouts, setSelectedLayouts] = useState(["MONTH_VIEW"]);
+ const [defaultLayout, setDefaultLayout] = useState("MONTH_VIEW");
+ const [requiresConfirmation, setRequiresConfirmation] = useState(false);
+ const [disableCancelling, setDisableCancelling] = useState(false);
+ const [disableRescheduling, setDisableRescheduling] = useState(false);
+ const [sendCalVideoTranscription, setSendCalVideoTranscription] = useState(false);
+ const [autoTranslate, setAutoTranslate] = useState(false);
+ const [requiresBookerEmailVerification, setRequiresBookerEmailVerification] = useState(false);
+ const [hideCalendarNotes, setHideCalendarNotes] = useState(false);
+ const [hideCalendarEventDetails, setHideCalendarEventDetails] = useState(false);
+ const [successRedirectUrl, setSuccessRedirectUrl] = useState("");
+ const [forwardParamsSuccessRedirect, setForwardParamsSuccessRedirect] = useState(false);
+ const [hideOrganizerEmail, setHideOrganizerEmail] = useState(false);
+ const [lockTimezone, setLockTimezone] = useState(false);
+ const [allowReschedulingPastEvents, setAllowReschedulingPastEvents] = useState(false);
+ const [allowBookingThroughRescheduleLink, setAllowBookingThroughRescheduleLink] = useState(false);
+ const [customReplyToEmail, setCustomReplyToEmail] = useState("");
+ const [eventTypeColorLight, setEventTypeColorLight] = useState("#292929");
+ const [eventTypeColorDark, setEventTypeColorDark] = useState("#FAFAFA");
+
+ // Recurring tab state
+ const [recurringEnabled, setRecurringEnabled] = useState(false);
+ const [recurringInterval, setRecurringInterval] = useState("1");
+ const [recurringFrequency, setRecurringFrequency] = useState<
+ "daily" | "weekly" | "monthly" | "yearly"
+ >("weekly");
+ const [recurringOccurrences, setRecurringOccurrences] = useState("12");
+
+ const bufferTimeOptions = [
+ "No buffer time",
+ "5 Minutes",
+ "10 Minutes",
+ "15 Minutes",
+ "20 Minutes",
+ "30 Minutes",
+ "45 Minutes",
+ "60 Minutes",
+ "90 Minutes",
+ "120 Minutes",
+ ];
+ const timeUnitOptions = ["Minutes", "Hours", "Days"];
+ const frequencyUnitOptions = ["Per day", "Per Month", "Per year"];
+ const durationUnitOptions = ["Per day", "Per week", "Per month"];
+ const slotIntervalOptions = [
+ "Default",
+ "5 Minutes",
+ "10 Minutes",
+ "15 Minutes",
+ "20 Minutes",
+ "30 Minutes",
+ "45 Minutes",
+ "60 Minutes",
+ "75 Minutes",
+ "90 Minutes",
+ "105 Minutes",
+ "120 Minutes",
+ ];
+ const availableDurations = [
+ "5 mins",
+ "10 mins",
+ "15 mins",
+ "20 mins",
+ "25 mins",
+ "30 mins",
+ "45 mins",
+ "50 mins",
+ "60 mins",
+ "75 mins",
+ "80 mins",
+ "90 mins",
+ "120 mins",
+ "150 mins",
+ "180 mins",
+ "240 mins",
+ "300 mins",
+ "360 mins",
+ "420 mins",
+ "480 mins",
+ ];
+
+ const formatDuration = (minutes: string) => {
+ const mins = parseInt(minutes) || 0;
+ if (mins < 60) return `${mins}m`;
+ const hours = Math.floor(mins / 60);
+ const remainingMins = mins % 60;
+ return remainingMins > 0 ? `${hours}h ${remainingMins}m` : `${hours}h`;
+ };
+
+ const truncateTitle = (text: string, maxLength: number = 20) => {
+ return text.length > maxLength ? `${text.substring(0, maxLength)}...` : text;
+ };
+
+ const formatAppIdToDisplayName = (appId: string): string => {
+ // Convert appId like "google-meet" to "Google Meet"
+ return appId
+ .split("-")
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
+ .join(" ");
+ };
+
+ const displayNameToLocationValue = (
+ displayName: string
+ ): {
+ type: string;
+ integration?: string;
+ address?: string;
+ link?: string;
+ phone?: string;
+ public?: boolean;
+ } | null => {
+ // First check if it's a default location
+ const defaultLocation = defaultLocations.find((loc) => loc.label === displayName);
+ if (defaultLocation) {
+ // Map internal location types to API location types
+ switch (defaultLocation.type) {
+ case "attendeeInPerson":
+ return { type: "attendeeAddress" };
+ case "inPerson":
+ // For organizer address, we need to preserve existing address if available
+ // or use empty string (will be filled by organizer later)
+ return { type: "address", address: "", public: true };
+ case "link":
+ // For link meeting, we need to preserve existing link if available
+ // or use empty string (will be filled by organizer later)
+ return { type: "link", link: "", public: true };
+ case "phone":
+ return { type: "attendeePhone" };
+ case "userPhone":
+ // For organizer phone, we need to preserve existing phone if available
+ // or use empty string (will be filled by organizer later)
+ return { type: "phone", phone: "", public: true };
+ case "somewhereElse":
+ return { type: "attendeeDefined" };
+ default:
+ return { type: defaultLocation.type };
+ }
+ }
+
+ // Otherwise, find matching conferencing option
+ const option = conferencingOptions.find(
+ (opt) => formatAppIdToDisplayName(opt.appId) === displayName
+ );
+ if (option) {
+ return { type: "integration", integration: option.appId, public: true };
+ }
+
+ return null;
+ };
+
+ const displayNameToAppId = (displayName: string): string | null => {
+ // Legacy function for backward compatibility - only for conferencing apps
+ const option = conferencingOptions.find(
+ (opt) => formatAppIdToDisplayName(opt.appId) === displayName
+ );
+ return option ? option.appId : null;
+ };
+
+ type LocationOption = { label: string; iconUrl: string | null; value: string };
+ type LocationGroup = { category: string; options: LocationOption[] };
+
+ const getLocationOptions = (): LocationGroup[] => {
+ // Group conferencing apps under "conferencing" category
+ const conferencingAppOptions: LocationOption[] = conferencingOptions.map((option) => {
+ const iconUrl = getAppIconUrl(option.type, option.appId);
+ return {
+ label: formatAppIdToDisplayName(option.appId),
+ iconUrl: iconUrl,
+ value: `integrations:${option.appId}`,
+ };
+ });
+
+ // Group default locations by their category
+ const defaultLocationOptions: LocationOption[] = defaultLocations.map((location) => ({
+ label: location.label,
+ iconUrl: location.iconUrl,
+ value: location.type,
+ }));
+
+ // Group options by category
+ const grouped: Record = {};
+
+ // Add conferencing apps
+ if (conferencingAppOptions.length > 0) {
+ grouped["conferencing"] = conferencingAppOptions;
+ }
+
+ // Add default locations by category
+ defaultLocations.forEach((location) => {
+ const category = location.category;
+ if (!grouped[category]) {
+ grouped[category] = [];
+ }
+ const option = defaultLocationOptions.find((opt) => opt.value === location.type);
+ if (option) {
+ grouped[category].push(option);
+ }
+ });
+
+ // Convert to array format with category labels
+ const categoryLabels: Record = {
+ conferencing: "Conferencing",
+ "in person": "In Person",
+ phone: "Phone",
+ other: "Other",
+ };
+
+ const result: LocationGroup[] = [];
+ for (const category in grouped) {
+ if (grouped[category].length > 0) {
+ result.push({
+ category: categoryLabels[category] || category,
+ options: grouped[category],
+ });
+ }
+ }
+
+ console.log(
+ "Total location groups:",
+ result.length,
+ result.map((g) => `${g.category}: ${g.options.length}`)
+ );
+ return result;
+ };
+
+ const getSelectedLocationIconUrl = (): string | null => {
+ if (!selectedLocation) return null;
+
+ // First, check if it's a default location
+ const defaultLocation = defaultLocations.find((loc) => loc.label === selectedLocation);
+ if (defaultLocation) {
+ return defaultLocation.iconUrl;
+ }
+
+ // Try to find in conferencing options
+ const option = conferencingOptions.find(
+ (opt) => formatAppIdToDisplayName(opt.appId) === selectedLocation
+ );
+ if (option) {
+ return getAppIconUrl(option.type, option.appId);
+ }
+
+ // Fallback: Handle Cal Video directly (it might not be in conferencing options as it's a global app)
+ // Check if selectedLocation matches Cal Video display names
+ const calVideoNames = ["Cal Video", "Cal-Video", "cal-video"];
+ if (
+ calVideoNames.includes(selectedLocation) ||
+ selectedLocation.toLowerCase().includes("cal video")
+ ) {
+ return getAppIconUrl("daily_video", "cal-video");
+ }
+
+ // Fallback: Try to reverse the formatAppIdToDisplayName to get appId
+ // Convert "Cal Video" back to "cal-video" and try to get icon
+ const reverseAppId = selectedLocation.toLowerCase().replace(/\s+/g, "-");
+ const fallbackIconUrl = getAppIconUrl("", reverseAppId);
+ if (fallbackIconUrl) {
+ return fallbackIconUrl;
+ }
+
+ return null;
+ };
+
+ const toggleDurationSelection = (duration: string) => {
+ const newSelected = selectedDurations.includes(duration)
+ ? selectedDurations.filter((d) => d !== duration)
+ : [...selectedDurations, duration];
+
+ setSelectedDurations(newSelected);
+
+ // Reset default duration if it's no longer in selected durations
+ if (!newSelected.includes(defaultDuration)) {
+ setDefaultDuration("");
+ }
+ };
+
+ const toggleBookingFrequency = (value: boolean) => {
+ setLimitBookingFrequency(value);
+
+ Animated.timing(frequencyAnimationValue, {
+ toValue: value ? 1 : 0,
+ duration: 300,
+ useNativeDriver: false,
+ }).start();
+ };
+
+ const addFrequencyLimit = () => {
+ const newId = Math.max(...frequencyLimits.map((limit) => limit.id)) + 1;
+ setFrequencyLimits([...frequencyLimits, { id: newId, value: "1", unit: "Per day" }]);
+ };
+
+ const removeFrequencyLimit = (id: number) => {
+ setFrequencyLimits(frequencyLimits.filter((limit) => limit.id !== id));
+ };
+
+ const updateFrequencyLimit = (id: number, field: "value" | "unit", newValue: string) => {
+ setFrequencyLimits(
+ frequencyLimits.map((limit) => (limit.id === id ? { ...limit, [field]: newValue } : limit))
+ );
+ };
+
+ const toggleTotalDuration = (value: boolean) => {
+ setLimitTotalDuration(value);
+
+ Animated.timing(durationAnimationValue, {
+ toValue: value ? 1 : 0,
+ duration: 300,
+ useNativeDriver: false,
+ }).start();
+ };
+
+ const addDurationLimit = () => {
+ const newId = Math.max(...durationLimits.map((limit) => limit.id)) + 1;
+ setDurationLimits([...durationLimits, { id: newId, value: "60", unit: "Per day" }]);
+ };
+
+ const removeDurationLimit = (id: number) => {
+ setDurationLimits(durationLimits.filter((limit) => limit.id !== id));
+ };
+
+ const updateDurationLimit = (id: number, field: "value" | "unit", newValue: string) => {
+ setDurationLimits(
+ durationLimits.map((limit) => (limit.id === id ? { ...limit, [field]: newValue } : limit))
+ );
+ };
+
+ const fetchSchedules = async () => {
+ try {
+ setSchedulesLoading(true);
+ const schedulesData = await CalComAPIService.getSchedules();
+ setSchedules(schedulesData);
+
+ // Set default schedule if one exists
+ const defaultSchedule = schedulesData.find((schedule) => schedule.isDefault);
+ if (defaultSchedule) {
+ setSelectedSchedule(defaultSchedule);
+ await fetchScheduleDetails(defaultSchedule.id);
+ }
+ } catch (error) {
+ console.error("Failed to fetch schedules:", error);
+ } finally {
+ setSchedulesLoading(false);
+ }
+ };
+
+ const fetchScheduleDetails = async (scheduleId: number) => {
+ try {
+ setScheduleDetailsLoading(true);
+ console.log("Fetching schedule details for ID:", scheduleId);
+ const scheduleDetails = await CalComAPIService.getScheduleById(scheduleId);
+ console.log("Raw schedule details response:", scheduleDetails);
+ setSelectedScheduleDetails(scheduleDetails);
+ if (scheduleDetails.timeZone) {
+ setSelectedTimezone(scheduleDetails.timeZone);
+ }
+ } catch (error) {
+ console.error("Failed to fetch schedule details:", error);
+ setSelectedScheduleDetails(null);
+ } finally {
+ setScheduleDetailsLoading(false);
+ }
+ };
+
+ const fetchConferencingOptions = async () => {
+ try {
+ setConferencingLoading(true);
+ const options = await CalComAPIService.getConferencingOptions();
+ console.log("Fetched conferencing options:", JSON.stringify(options, null, 2));
+ setConferencingOptions(options);
+ } catch (error) {
+ console.error("Failed to fetch conferencing options:", error);
+ } finally {
+ setConferencingLoading(false);
+ }
+ };
+
+ const fetchEventTypeData = async () => {
+ if (!id) return;
+
+ try {
+ const eventType = await CalComAPIService.getEventTypeById(parseInt(id));
+ if (eventType) {
+ setEventTypeData(eventType);
+
+ // Load basic fields
+ if (eventType.title) setEventTitle(eventType.title);
+ if (eventType.slug) setEventSlug(eventType.slug);
+ if (eventType.description) setEventDescription(eventType.description);
+ if (eventType.lengthInMinutes) setEventDuration(eventType.lengthInMinutes.toString());
+ if (eventType.hidden !== undefined) setIsHidden(eventType.hidden);
+
+ // Load buffer times
+ if (eventType.beforeEventBuffer) {
+ setBeforeEventBuffer(`${eventType.beforeEventBuffer} Minutes`);
+ }
+ if (eventType.afterEventBuffer) {
+ setAfterEventBuffer(`${eventType.afterEventBuffer} Minutes`);
+ }
+
+ // Load minimum booking notice
+ if (eventType.minimumBookingNotice) {
+ const minutes = eventType.minimumBookingNotice;
+ if (minutes >= 1440) {
+ // Days
+ setMinimumNoticeValue((minutes / 1440).toString());
+ setMinimumNoticeUnit("Days");
+ } else if (minutes >= 60) {
+ // Hours
+ setMinimumNoticeValue((minutes / 60).toString());
+ setMinimumNoticeUnit("Hours");
+ } else {
+ // Minutes
+ setMinimumNoticeValue(minutes.toString());
+ setMinimumNoticeUnit("Minutes");
+ }
+ }
+
+ // Load slot interval
+ if (eventType.slotInterval) {
+ setSlotInterval(`${eventType.slotInterval} Minutes`);
+ }
+
+ // Load booking frequency limits
+ if (eventType.bookingLimitsCount && !("disabled" in eventType.bookingLimitsCount)) {
+ setLimitBookingFrequency(true);
+ const limits = [];
+ let idCounter = 1;
+ if (eventType.bookingLimitsCount.day) {
+ limits.push({
+ id: idCounter++,
+ value: eventType.bookingLimitsCount.day.toString(),
+ unit: "Per day",
+ });
+ }
+ if (eventType.bookingLimitsCount.week) {
+ limits.push({
+ id: idCounter++,
+ value: eventType.bookingLimitsCount.week.toString(),
+ unit: "Per week",
+ });
+ }
+ if (eventType.bookingLimitsCount.month) {
+ limits.push({
+ id: idCounter++,
+ value: eventType.bookingLimitsCount.month.toString(),
+ unit: "Per month",
+ });
+ }
+ if (eventType.bookingLimitsCount.year) {
+ limits.push({
+ id: idCounter++,
+ value: eventType.bookingLimitsCount.year.toString(),
+ unit: "Per year",
+ });
+ }
+ if (limits.length > 0) {
+ setFrequencyLimits(limits);
+ }
+ }
+
+ // Load duration limits
+ if (eventType.bookingLimitsDuration && !("disabled" in eventType.bookingLimitsDuration)) {
+ setLimitTotalDuration(true);
+ const limits = [];
+ let idCounter = 1;
+ if (eventType.bookingLimitsDuration.day) {
+ limits.push({
+ id: idCounter++,
+ value: eventType.bookingLimitsDuration.day.toString(),
+ unit: "Per day",
+ });
+ }
+ if (eventType.bookingLimitsDuration.week) {
+ limits.push({
+ id: idCounter++,
+ value: eventType.bookingLimitsDuration.week.toString(),
+ unit: "Per week",
+ });
+ }
+ if (eventType.bookingLimitsDuration.month) {
+ limits.push({
+ id: idCounter++,
+ value: eventType.bookingLimitsDuration.month.toString(),
+ unit: "Per month",
+ });
+ }
+ if (eventType.bookingLimitsDuration.year) {
+ limits.push({
+ id: idCounter++,
+ value: eventType.bookingLimitsDuration.year.toString(),
+ unit: "Per year",
+ });
+ }
+ if (limits.length > 0) {
+ setDurationLimits(limits);
+ }
+ }
+
+ // Load only show first slot
+ if (eventType.onlyShowFirstAvailableSlot !== undefined) {
+ setOnlyShowFirstAvailableSlot(eventType.onlyShowFirstAvailableSlot);
+ }
+
+ // Load max active bookings
+ if (
+ eventType.bookerActiveBookingsLimit &&
+ !("disabled" in eventType.bookerActiveBookingsLimit)
+ ) {
+ setMaxActiveBookingsPerBooker(true);
+ setMaxActiveBookingsValue(eventType.bookerActiveBookingsLimit.count.toString());
+ }
+
+ // Load booking window (future bookings limit)
+ if (eventType.bookingWindow && !("disabled" in eventType.bookingWindow)) {
+ setLimitFutureBookings(true);
+ if (eventType.bookingWindow.type === "range") {
+ setFutureBookingType("range");
+ if (
+ Array.isArray(eventType.bookingWindow.value) &&
+ eventType.bookingWindow.value.length === 2
+ ) {
+ setRangeStartDate(eventType.bookingWindow.value[0]);
+ setRangeEndDate(eventType.bookingWindow.value[1]);
+ }
+ } else {
+ setFutureBookingType("rolling");
+ if (typeof eventType.bookingWindow.value === "number") {
+ setRollingDays(eventType.bookingWindow.value.toString());
+ }
+ setRollingCalendarDays(eventType.bookingWindow.type === "calendarDays");
+ }
+ }
+
+ // Load Advanced tab fields
+ if (eventType.metadata) {
+ if (eventType.metadata.calendarEventName) {
+ setCalendarEventName(eventType.metadata.calendarEventName);
+ }
+ if (eventType.metadata.addToCalendarEmail) {
+ setAddToCalendarEmail(eventType.metadata.addToCalendarEmail);
+ }
+ if (eventType.metadata.customReplyToEmail) {
+ setCustomReplyToEmail(eventType.metadata.customReplyToEmail);
+ }
+ if (eventType.metadata.disableCancelling) {
+ setDisableCancelling(true);
+ }
+ if (eventType.metadata.disableRescheduling) {
+ setDisableRescheduling(true);
+ }
+ if (eventType.metadata.sendCalVideoTranscription) {
+ setSendCalVideoTranscription(true);
+ }
+ if (eventType.metadata.autoTranslate) {
+ setAutoTranslate(true);
+ }
+ if (eventType.metadata.hideCalendarEventDetails) {
+ setHideCalendarEventDetails(true);
+ }
+ if (eventType.metadata.hideOrganizerEmail) {
+ setHideOrganizerEmail(true);
+ }
+ if (eventType.metadata.allowReschedulingPastEvents) {
+ setAllowReschedulingPastEvents(true);
+ }
+ if (eventType.metadata.allowBookingThroughRescheduleLink) {
+ setAllowBookingThroughRescheduleLink(true);
+ }
+ }
+
+ // Load booker layouts
+ if (eventType.bookerLayouts) {
+ if (
+ eventType.bookerLayouts.enabledLayouts &&
+ Array.isArray(eventType.bookerLayouts.enabledLayouts)
+ ) {
+ setSelectedLayouts(eventType.bookerLayouts.enabledLayouts);
+ }
+ if (eventType.bookerLayouts.defaultLayout) {
+ setDefaultLayout(eventType.bookerLayouts.defaultLayout);
+ }
+ }
+
+ // Load confirmation settings
+ if (eventType.requiresConfirmation !== undefined) {
+ setRequiresConfirmation(eventType.requiresConfirmation);
+ }
+
+ // Load other boolean fields
+ if (eventType.requiresBookerEmailVerification !== undefined) {
+ setRequiresBookerEmailVerification(eventType.requiresBookerEmailVerification);
+ }
+ if (eventType.hideCalendarNotes !== undefined) {
+ setHideCalendarNotes(eventType.hideCalendarNotes);
+ }
+ if (eventType.lockTimeZoneToggleOnBookingPage !== undefined) {
+ setLockTimezone(eventType.lockTimeZoneToggleOnBookingPage);
+ }
+
+ // Load redirect URL
+ if (eventType.successRedirectUrl) {
+ setSuccessRedirectUrl(eventType.successRedirectUrl);
+ if (eventType.forwardParamsSuccessRedirect !== undefined) {
+ setForwardParamsSuccessRedirect(eventType.forwardParamsSuccessRedirect);
+ }
+ }
+
+ // Load event type colors
+ if (eventType.eventTypeColor) {
+ if (eventType.eventTypeColor.lightEventTypeColor) {
+ setEventTypeColorLight(eventType.eventTypeColor.lightEventTypeColor);
+ }
+ if (eventType.eventTypeColor.darkEventTypeColor) {
+ setEventTypeColorDark(eventType.eventTypeColor.darkEventTypeColor);
+ }
+ }
+
+ // Load recurring event settings
+ if (eventType.recurrence && !("disabled" in eventType.recurrence)) {
+ setRecurringEnabled(true);
+ setRecurringInterval(eventType.recurrence.interval.toString());
+ setRecurringFrequency(eventType.recurrence.frequency);
+ setRecurringOccurrences(eventType.recurrence.occurrences.toString());
+ }
+
+ // Extract location from event type
+ if (eventType.locations && eventType.locations.length > 0) {
+ const firstLocation = eventType.locations[0];
+
+ // Handle conferencing apps (with integration field)
+ if (firstLocation.integration) {
+ // Format the integration name (e.g., "google-meet" -> "Google Meet")
+ const formattedLocation = formatAppIdToDisplayName(firstLocation.integration);
+ setSelectedLocation(formattedLocation);
+ }
+ // Handle default locations (with type field)
+ else if (firstLocation.type) {
+ // Map API location types to internal location types
+ // Need to distinguish between organizer and attendee types based on presence of fields
+ let internalType = firstLocation.type;
+
+ // Check if it's an organizer type (has address, link, or phone field)
+ if (
+ firstLocation.type === "address" ||
+ (firstLocation.type === "phone" && firstLocation.phone)
+ ) {
+ // Organizer types
+ if (firstLocation.type === "address") {
+ internalType = "inPerson"; // Organizer address
+ } else if (firstLocation.type === "phone" && firstLocation.phone) {
+ internalType = "userPhone"; // Organizer phone
+ }
+ } else if (firstLocation.type === "link") {
+ internalType = "link"; // Link meeting
+ } else {
+ // Attendee types - map API types to internal types
+ const apiToInternalTypeMap: Record = {
+ attendeeAddress: "attendeeInPerson",
+ attendeePhone: "phone",
+ attendeeDefined: "somewhereElse",
+ };
+
+ if (apiToInternalTypeMap[firstLocation.type]) {
+ internalType = apiToInternalTypeMap[firstLocation.type];
+ }
+ }
+
+ const defaultLocation = defaultLocations.find((loc) => loc.type === internalType);
+ if (defaultLocation) {
+ setSelectedLocation(defaultLocation.label);
+
+ // Populate location input values if they exist
+ if (firstLocation.address) {
+ setLocationAddress(firstLocation.address);
+ }
+ if (firstLocation.link) {
+ setLocationLink(firstLocation.link);
+ }
+ if (firstLocation.phone) {
+ setLocationPhone(firstLocation.phone);
+ }
+ } else {
+ // Fallback: try to format the type as display name
+ setSelectedLocation(firstLocation.type);
+ }
+ }
+ }
+ }
+ } catch (error) {
+ console.error("Failed to fetch event type data:", error);
+ }
+ };
+
+ useEffect(() => {
+ if (activeTab === "availability") {
+ fetchSchedules();
+ }
+ if (activeTab === "basics") {
+ fetchConferencingOptions();
+ }
+ }, [activeTab]);
+
+ useEffect(() => {
+ // Fetch event type data and conferencing options on initial load
+ fetchEventTypeData();
+ fetchConferencingOptions();
+ }, [id]);
+
+ useEffect(() => {
+ const fetchUsername = async () => {
+ try {
+ const userUsername = await CalComAPIService.getUsername();
+ setUsername(userUsername);
+ } catch (error) {
+ console.error("Failed to fetch username:", error);
+ }
+ };
+ fetchUsername();
+ }, []);
+
+ const formatTime = (time: string) => {
+ try {
+ // Handle different time formats that might come from the API
+ let date: Date;
+
+ if (time.includes(":")) {
+ // Format like "09:00" or "09:00:00"
+ const [hours, minutes] = time.split(":").map(Number);
+ date = new Date();
+ date.setHours(hours, minutes || 0, 0, 0);
+ } else {
+ // Other formats
+ date = new Date(time);
+ }
+
+ return date.toLocaleTimeString("en-US", {
+ hour: "numeric",
+ minute: "2-digit",
+ hour12: true,
+ });
+ } catch (error) {
+ return time; // Return original if parsing fails
+ }
+ };
+
+ const getDaySchedule = () => {
+ if (!selectedScheduleDetails) {
+ console.log("No selectedScheduleDetails");
+ return [];
+ }
+
+ console.log("selectedScheduleDetails:", selectedScheduleDetails);
+ console.log("availability:", selectedScheduleDetails.availability);
+
+ const daysOfWeek = [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+ ];
+
+ const daySchedule = daysOfWeek.map((day) => {
+ // Try different possible day formats
+ const dayLower = day.toLowerCase();
+ const dayUpper = day.toUpperCase();
+ const dayShort = day.substring(0, 3).toLowerCase(); // mon, tue, etc.
+ const dayShortUpper = day.substring(0, 3).toUpperCase();
+
+ const availability = selectedScheduleDetails.availability?.find((avail) => {
+ if (!avail.days || !Array.isArray(avail.days)) return false;
+
+ return avail.days.some(
+ (d) =>
+ d === dayLower ||
+ d === dayUpper ||
+ d === day ||
+ d === dayShort ||
+ d === dayShortUpper ||
+ d.toLowerCase() === dayLower
+ );
+ });
+
+ console.log(`${day}: availability found:`, availability);
+
+ return {
+ day,
+ available: !!availability,
+ startTime: availability?.startTime,
+ endTime: availability?.endTime,
+ };
+ });
+
+ return daySchedule;
+ };
+
+ const handlePreview = async () => {
+ try {
+ const eventTypeSlug = eventSlug || "preview";
+ const link = await CalComAPIService.buildEventTypeLink(eventTypeSlug);
+
+ const supported = await Linking.canOpenURL(link);
+ if (supported) {
+ await Linking.openURL(link);
+ } else {
+ Alert.alert("Error", "Cannot open this URL on your device.");
+ }
+ } catch (error) {
+ console.error("Failed to generate preview link:", error);
+ Alert.alert("Error", "Failed to generate preview link. Please try again.");
+ }
+ };
+
+ const handleCopyLink = async () => {
+ try {
+ const eventTypeSlug = eventSlug || "event-link";
+ const link = await CalComAPIService.buildEventTypeLink(eventTypeSlug);
+
+ Clipboard.setString(link);
+ Alert.alert("Success", "Link copied!");
+ } catch (error) {
+ console.error("Failed to copy link:", error);
+ Alert.alert("Error", "Failed to copy link. Please try again.");
+ }
+ };
+
+ const handleDelete = () => {
+ Alert.alert("Delete Event Type", `Are you sure you want to delete "${eventTitle}"?`, [
+ { text: "Cancel", style: "cancel" },
+ {
+ text: "Delete",
+ style: "destructive",
+ onPress: async () => {
+ try {
+ console.log("Attempting to delete event type with ID:", id);
+ const eventTypeId = parseInt(id);
+
+ if (isNaN(eventTypeId)) {
+ throw new Error("Invalid event type ID");
+ }
+
+ await CalComAPIService.deleteEventType(eventTypeId);
+ console.log("Event type deleted successfully");
+
+ Alert.alert("Success", "Event type deleted successfully", [
+ {
+ text: "OK",
+ onPress: () => {
+ console.log("Navigating back after successful deletion");
+ router.back();
+ },
+ },
+ ]);
+ } catch (error) {
+ console.error("Failed to delete event type:", error);
+ const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
+ Alert.alert("Error", `Failed to delete event type: ${errorMessage}`);
+ }
+ },
+ },
+ ]);
+ };
+
+ const handleSave = async () => {
+ if (!id) {
+ Alert.alert("Error", "Event type ID is missing");
+ return;
+ }
+
+ // Validate required fields
+ if (!eventTitle || !eventSlug) {
+ Alert.alert("Error", "Title and slug are required");
+ return;
+ }
+
+ const durationNum = parseInt(eventDuration);
+ if (isNaN(durationNum) || durationNum <= 0) {
+ Alert.alert("Error", "Duration must be a positive number");
+ return;
+ }
+
+ try {
+ setSaving(true);
+
+ // Build location payload if a location is selected
+ let locationsPayload:
+ | Array<{
+ type: string;
+ integration?: string;
+ address?: string;
+ link?: string;
+ phone?: string;
+ public?: boolean;
+ }>
+ | undefined;
+
+ if (selectedLocation) {
+ const locationValue = displayNameToLocationValue(selectedLocation);
+ if (!locationValue) {
+ Alert.alert("Error", "Invalid location selected");
+ setSaving(false);
+ return;
+ }
+
+ // Get existing location data to preserve values (address, link, phone)
+ const existingLocation = eventTypeData?.locations?.[0];
+
+ // Build location payload based on type
+ const locationPayload: {
+ type: string;
+ integration?: string;
+ address?: string;
+ link?: string;
+ phone?: string;
+ public?: boolean;
+ } = {
+ type: locationValue.type,
+ };
+
+ // Add type-specific fields based on location type
+ if (locationValue.type === "integration") {
+ locationPayload.integration = locationValue.integration;
+ locationPayload.public = locationValue.public ?? true;
+ } else if (locationValue.type === "address") {
+ locationPayload.address = locationAddress || existingLocation?.address || "";
+ locationPayload.public = true;
+ } else if (locationValue.type === "link") {
+ locationPayload.link = locationLink || existingLocation?.link || "";
+ locationPayload.public = true;
+ } else if (locationValue.type === "phone") {
+ locationPayload.phone = locationPhone || existingLocation?.phone || "";
+ locationPayload.public = true;
+ }
+
+ locationsPayload = [locationPayload];
+ }
+
+ // Build the payload with all fields
+ const payload: any = {
+ title: eventTitle,
+ slug: eventSlug,
+ lengthInMinutes: durationNum,
+ };
+
+ // Add optional fields if they have values
+ if (eventDescription) {
+ payload.description = eventDescription;
+ }
+
+ if (locationsPayload) {
+ payload.locations = locationsPayload;
+ }
+
+ if (selectedSchedule) {
+ payload.scheduleId = selectedSchedule.id;
+ }
+
+ if (isHidden !== undefined) {
+ payload.hidden = isHidden;
+ }
+
+ // Add buffer times if set
+ if (beforeEventBuffer && beforeEventBuffer !== "No buffer time") {
+ const bufferMinutes = parseBufferTime(beforeEventBuffer);
+ if (bufferMinutes > 0) {
+ payload.beforeEventBuffer = bufferMinutes;
+ }
+ }
+
+ if (afterEventBuffer && afterEventBuffer !== "No buffer time") {
+ const bufferMinutes = parseBufferTime(afterEventBuffer);
+ if (bufferMinutes > 0) {
+ payload.afterEventBuffer = bufferMinutes;
+ }
+ }
+
+ // Add minimum booking notice
+ if (minimumNoticeValue && minimumNoticeUnit) {
+ const noticeMinutes = parseMinimumNotice(minimumNoticeValue, minimumNoticeUnit);
+ if (noticeMinutes > 0) {
+ payload.minimumBookingNotice = noticeMinutes;
+ }
+ }
+
+ // Add booking limits if enabled
+ if (limitBookingFrequency && frequencyLimits.length > 0) {
+ const limitsCount: any = {};
+ frequencyLimits.forEach((limit) => {
+ const unit = parseFrequencyUnit(limit.unit);
+ if (unit) {
+ limitsCount[unit] = parseInt(limit.value) || 1;
+ }
+ });
+ if (Object.keys(limitsCount).length > 0) {
+ payload.bookingLimitsCount = limitsCount;
+ }
+ }
+
+ if (limitTotalDuration && durationLimits.length > 0) {
+ const limitsDuration: any = {};
+ durationLimits.forEach((limit) => {
+ const unit = parseFrequencyUnit(limit.unit);
+ if (unit) {
+ limitsDuration[unit] = parseInt(limit.value) || 60;
+ }
+ });
+ if (Object.keys(limitsDuration).length > 0) {
+ payload.bookingLimitsDuration = limitsDuration;
+ }
+ }
+
+ // Add slot interval if not default
+ if (slotInterval && slotInterval !== "Default") {
+ const intervalMinutes = parseSlotInterval(slotInterval);
+ if (intervalMinutes > 0) {
+ payload.slotInterval = intervalMinutes;
+ }
+ }
+
+ // Add other boolean flags
+ if (onlyShowFirstAvailableSlot) {
+ payload.onlyShowFirstAvailableSlot = true;
+ }
+
+ if (maxActiveBookingsPerBooker && maxActiveBookingsValue) {
+ const count = parseInt(maxActiveBookingsValue);
+ if (count > 0) {
+ payload.bookerActiveBookingsLimit = { count };
+ }
+ }
+
+ // Add booking window (future bookings limit)
+ if (limitFutureBookings) {
+ if (futureBookingType === "range") {
+ payload.bookingWindow = {
+ type: "range",
+ value: [rangeStartDate, rangeEndDate],
+ };
+ } else {
+ payload.bookingWindow = {
+ type: rollingCalendarDays ? "calendarDays" : "businessDays",
+ value: parseInt(rollingDays),
+ rolling: true,
+ };
+ }
+ } else {
+ payload.bookingWindow = { disabled: true };
+ }
+
+ // Add Advanced tab fields
+ if (calendarEventName) {
+ payload.metadata = payload.metadata || {};
+ payload.metadata.calendarEventName = calendarEventName;
+ }
+
+ if (addToCalendarEmail) {
+ payload.metadata = payload.metadata || {};
+ payload.metadata.addToCalendarEmail = addToCalendarEmail;
+ }
+
+ // Booker layouts
+ if (selectedLayouts.length > 0) {
+ payload.bookerLayouts = {
+ enabledLayouts: selectedLayouts,
+ defaultLayout: defaultLayout,
+ };
+ }
+
+ // Confirmation policy
+ payload.requiresConfirmation = requiresConfirmation;
+
+ // Boolean flags - always set the actual boolean value so toggling off works
+ payload.metadata = {
+ ...(payload.metadata || {}),
+ disableCancelling,
+ disableRescheduling,
+ sendCalVideoTranscription,
+ autoTranslate,
+ hideCalendarEventDetails,
+ hideOrganizerEmail,
+ allowReschedulingPastEvents,
+ allowBookingThroughRescheduleLink,
+ };
+ payload.requiresBookerEmailVerification = requiresBookerEmailVerification;
+ payload.hideCalendarNotes = hideCalendarNotes;
+ payload.lockTimeZoneToggleOnBookingPage = lockTimezone;
+
+ // Redirect URL
+ if (successRedirectUrl) {
+ payload.successRedirectUrl = successRedirectUrl;
+ if (forwardParamsSuccessRedirect) {
+ payload.forwardParamsSuccessRedirect = true;
+ }
+ }
+
+ // Custom reply-to email
+ if (customReplyToEmail) {
+ payload.metadata = payload.metadata || {};
+ payload.metadata.customReplyToEmail = customReplyToEmail;
+ }
+
+ // Event type colors
+ if (eventTypeColorLight || eventTypeColorDark) {
+ payload.eventTypeColor = {
+ lightEventTypeColor: eventTypeColorLight,
+ darkEventTypeColor: eventTypeColorDark,
+ };
+ }
+
+ // Recurring event
+ if (recurringEnabled) {
+ payload.recurrence = {
+ interval: parseInt(recurringInterval) || 1,
+ occurrences: parseInt(recurringOccurrences) || 12,
+ frequency: recurringFrequency,
+ };
+ } else {
+ payload.recurrence = { disabled: true };
+ }
+
+ // Detect create vs update mode
+ const isCreateMode = id === "new";
+
+ if (isCreateMode) {
+ // Create new event type
+ const newEventType = await CalComAPIService.createEventType(payload);
+ Alert.alert("Success", "Event type created successfully", [
+ {
+ text: "OK",
+ onPress: () => router.back(),
+ },
+ ]);
+ } else {
+ // Update existing event type
+ await CalComAPIService.updateEventType(parseInt(id), payload);
+ Alert.alert("Success", "Event type updated successfully");
+ // Refresh event type data
+ await fetchEventTypeData();
+ }
+ } catch (error) {
+ console.error("Failed to save event type:", error);
+ const action = id === "new" ? "create" : "update";
+ Alert.alert("Error", `Failed to ${action} event type. Please try again.`);
+ } finally {
+ setSaving(false);
+ }
+ };
+
+ return (
+ <>
+
+
+ {/* Glass Header */}
+
+
+ router.back()}
+ >
+
+
+
+
+ {id === "new" ? "Create Event Type" : truncateTitle(title)}
+
+
+
+
+ {id === "new" ? "Create" : "Save"}
+
+
+
+
+
+ {/* Tabs */}
+
+
+ {tabs.map((tab) => (
+ setActiveTab(tab.id)}
+ >
+
+
+
+ {tab.label}
+
+
+
+ ))}
+
+
+
+ {/* Content */}
+
+ {activeTab === "basics" && (
+
+ )}
+
+ {/* Duration Multi-Select Modal */}
+ setShowDurationDropdown(false)}
+ >
+ setShowDurationDropdown(false)}
+ >
+
+
+ Select Available Durations
+
+
+ {availableDurations.map((duration) => (
+ toggleDurationSelection(duration)}
+ >
+
+ {duration}
+
+ {selectedDurations.includes(duration) && (
+
+ )}
+
+ ))}
+
+ setShowDurationDropdown(false)}
+ >
+ Done
+
+
+
+
+
+ {/* Default Duration Dropdown Modal */}
+ setShowDefaultDurationDropdown(false)}
+ >
+ setShowDefaultDurationDropdown(false)}
+ >
+
+
+ Select Default Duration
+
+ {selectedDurations.map((duration) => (
+ {
+ setDefaultDuration(duration);
+ setShowDefaultDurationDropdown(false);
+ }}
+ >
+
+ {duration}
+
+ {defaultDuration === duration && (
+
+ )}
+
+ ))}
+
+
+
+
+ {/* Schedule Dropdown Modal */}
+ setShowScheduleDropdown(false)}
+ >
+ setShowScheduleDropdown(false)}
+ >
+
+
+ Select Schedule
+
+ {schedules.map((schedule) => (
+ {
+ setSelectedSchedule(schedule);
+ setShowScheduleDropdown(false);
+ fetchScheduleDetails(schedule.id);
+ }}
+ >
+
+
+ {schedule.name}
+
+ {schedule.isDefault && (
+
+ Default
+
+ )}
+
+ {selectedSchedule?.id === schedule.id && (
+
+ )}
+
+ ))}
+
+
+
+
+ {/* Timezone Dropdown Modal */}
+ setShowTimezoneDropdown(false)}
+ >
+ setShowTimezoneDropdown(false)}
+ >
+
+
+ Select Timezone
+
+
+ {[
+ "America/New_York",
+ "America/Chicago",
+ "America/Denver",
+ "America/Los_Angeles",
+ "Europe/London",
+ "Europe/Paris",
+ "Europe/Berlin",
+ "Asia/Tokyo",
+ "Asia/Shanghai",
+ "Asia/Kolkata",
+ "Australia/Sydney",
+ "UTC",
+ ].map((tz) => (
+ {
+ setSelectedTimezone(tz);
+ setShowTimezoneDropdown(false);
+ }}
+ >
+
+ {tz}
+
+ {(selectedTimezone === tz ||
+ (selectedScheduleDetails?.timeZone === tz && !selectedTimezone)) && (
+
+ )}
+
+ ))}
+
+
+
+
+
+ {/* Location Dropdown Modal */}
+ setShowLocationDropdown(false)}
+ >
+ setShowLocationDropdown(false)}
+ >
+
+ {conferencingLoading ? (
+
+ Loading locations...
+
+ ) : (
+ (() => {
+ const groups = getLocationOptions();
+ if (groups.length === 0) {
+ return (
+
+ No locations available
+
+ );
+ }
+ return (
+
+ {groups.map((group) => (
+
+ {/* Section Header */}
+
+
+ {group.category}
+
+
+ {/* Section Options */}
+ {group.options.map((option) => (
+ {
+ const newLocation = defaultLocations.find(
+ (loc) => loc.label === option.label
+ );
+ setSelectedLocation(option.label);
+ setShowLocationDropdown(false);
+ // Clear input values that are not needed for the new location
+ if (!newLocation || newLocation.type !== "inPerson") {
+ setLocationAddress("");
+ }
+ if (!newLocation || newLocation.type !== "link") {
+ setLocationLink("");
+ }
+ if (!newLocation || newLocation.type !== "userPhone") {
+ setLocationPhone("");
+ }
+ }}
+ >
+
+ {option.iconUrl ? (
+
+ ) : (
+
+
+ ?
+
+
+ )}
+
+ {option.label}
+
+
+ {selectedLocation === option.label && (
+
+ )}
+
+ ))}
+
+ ))}
+
+ );
+ })()
+ )}
+
+
+
+
+ {/* Before Event Buffer Dropdown Modal */}
+ setShowBeforeBufferDropdown(false)}
+ >
+ setShowBeforeBufferDropdown(false)}
+ >
+
+
+ Before event buffer
+
+ {bufferTimeOptions.map((option) => (
+ {
+ setBeforeEventBuffer(option);
+ setShowBeforeBufferDropdown(false);
+ }}
+ >
+
+ {option}
+
+ {beforeEventBuffer === option && (
+
+ )}
+
+ ))}
+
+
+
+
+ {/* After Event Buffer Dropdown Modal */}
+ setShowAfterBufferDropdown(false)}
+ >
+ setShowAfterBufferDropdown(false)}
+ >
+
+
+ After event buffer
+
+ {bufferTimeOptions.map((option) => (
+ {
+ setAfterEventBuffer(option);
+ setShowAfterBufferDropdown(false);
+ }}
+ >
+
+ {option}
+
+ {afterEventBuffer === option && (
+
+ )}
+
+ ))}
+
+
+
+
+ {/* Minimum Notice Unit Dropdown Modal */}
+ setShowMinimumNoticeUnitDropdown(false)}
+ >
+ setShowMinimumNoticeUnitDropdown(false)}
+ >
+
+
+ Time unit
+
+ {timeUnitOptions.map((option) => (
+ {
+ setMinimumNoticeUnit(option);
+ setShowMinimumNoticeUnitDropdown(false);
+ }}
+ >
+
+ {option}
+
+ {minimumNoticeUnit === option && (
+
+ )}
+
+ ))}
+
+
+
+
+ {/* Frequency Unit Dropdown Modal */}
+ setShowFrequencyUnitDropdown(null)}
+ >
+ setShowFrequencyUnitDropdown(null)}
+ >
+
+
+ Frequency unit
+
+ {frequencyUnitOptions.map((option) => {
+ const selectedLimit = frequencyLimits.find(
+ (limit) => limit.id === showFrequencyUnitDropdown
+ );
+ const isSelected = selectedLimit?.unit === option;
+ return (
+ {
+ if (showFrequencyUnitDropdown) {
+ updateFrequencyLimit(showFrequencyUnitDropdown, "unit", option);
+ }
+ setShowFrequencyUnitDropdown(null);
+ }}
+ >
+
+ {option}
+
+ {isSelected && }
+
+ );
+ })}
+
+
+
+
+ {/* Duration Unit Dropdown Modal */}
+ setShowDurationUnitDropdown(null)}
+ >
+ setShowDurationUnitDropdown(null)}
+ >
+
+
+ Duration unit
+
+ {durationUnitOptions.map((option) => {
+ const selectedLimit = durationLimits.find(
+ (limit) => limit.id === showDurationUnitDropdown
+ );
+ const isSelected = selectedLimit?.unit === option;
+ return (
+ {
+ if (showDurationUnitDropdown) {
+ updateDurationLimit(showDurationUnitDropdown, "unit", option);
+ }
+ setShowDurationUnitDropdown(null);
+ }}
+ >
+
+ {option}
+
+ {isSelected && }
+
+ );
+ })}
+
+
+
+
+ {/* Slot Interval Dropdown Modal */}
+ setShowSlotIntervalDropdown(false)}
+ >
+ setShowSlotIntervalDropdown(false)}
+ >
+
+
+ Slot interval
+
+ {slotIntervalOptions.map((option) => (
+ {
+ setSlotInterval(option);
+ setShowSlotIntervalDropdown(false);
+ }}
+ >
+
+ {option}
+
+ {slotInterval === option && (
+
+ )}
+
+ ))}
+
+
+
+
+ {activeTab === "availability" && (
+
+ )}
+
+ {activeTab === "limits" && (
+
+ )}
+
+ {activeTab === "advanced" && (
+
+ )}
+
+ {activeTab === "recurring" && (
+
+ )}
+
+ {activeTab === "apps" && (
+
+ Connected Apps
+
+ Manage app integrations for this event type.
+
+
+ )}
+
+ {activeTab === "workflows" && (
+
+ Workflows
+
+ Configure automated workflows and actions.
+
+
+ )}
+
+ {activeTab === "webhooks" && (
+
+ Webhooks
+
+ Set up webhook endpoints for event notifications.
+
+
+ )}
+
+
+ {/* Bottom Action Bar */}
+
+
+
+ Hidden
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/companion/app/event-type-detail/constants.ts b/companion/app/event-type-detail/constants.ts
new file mode 100644
index 0000000000..dff9194f1e
--- /dev/null
+++ b/companion/app/event-type-detail/constants.ts
@@ -0,0 +1,79 @@
+// Constants for Event Type Detail screen
+
+export const bufferTimeOptions = [
+ "No buffer time",
+ "5 Minutes",
+ "10 Minutes",
+ "15 Minutes",
+ "20 Minutes",
+ "30 Minutes",
+ "45 Minutes",
+ "60 Minutes",
+ "90 Minutes",
+ "120 Minutes",
+];
+
+export const timeUnitOptions = ["Minutes", "Hours", "Days"];
+
+export const frequencyUnitOptions = ["Per day", "Per Month", "Per year"];
+
+export const durationUnitOptions = ["Per day", "Per week", "Per month"];
+
+export const slotIntervalOptions = [
+ "Default",
+ "5 Minutes",
+ "10 Minutes",
+ "15 Minutes",
+ "20 Minutes",
+ "30 Minutes",
+ "45 Minutes",
+ "60 Minutes",
+ "75 Minutes",
+ "90 Minutes",
+ "105 Minutes",
+ "120 Minutes",
+];
+
+export const availableDurations = [
+ "5 mins",
+ "10 mins",
+ "15 mins",
+ "20 mins",
+ "25 mins",
+ "30 mins",
+ "45 mins",
+ "50 mins",
+ "60 mins",
+ "75 mins",
+ "80 mins",
+ "90 mins",
+ "120 mins",
+ "150 mins",
+ "180 mins",
+ "240 mins",
+ "300 mins",
+ "360 mins",
+ "420 mins",
+ "480 mins",
+];
+
+export const defaultLocations = [
+ { label: "Attendee Address", type: "attendeeInPerson" as const },
+ { label: "Organizer Address", type: "inPerson" as const },
+ { label: "Link Meeting", type: "link" as const },
+ { label: "Attendee Phone Number", type: "phone" as const },
+ { label: "Organizer Phone Number", type: "userPhone" as const },
+];
+
+export const tabs = [
+ { id: "basics", label: "Basics" },
+ { id: "availability", label: "Availability" },
+ { id: "limits", label: "Limits" },
+ { id: "advanced", label: "Advanced" },
+ { id: "recurring", label: "Recurring" },
+ { id: "apps", label: "Apps" },
+ { id: "webhooks", label: "Webhooks" },
+ { id: "private-links", label: "Private Links" },
+ { id: "seats", label: "Seats" },
+ { id: "colors", label: "Colors" },
+];
diff --git a/companion/app/event-type-detail/tabs/AdvancedTab.tsx b/companion/app/event-type-detail/tabs/AdvancedTab.tsx
new file mode 100644
index 0000000000..754d1ddf70
--- /dev/null
+++ b/companion/app/event-type-detail/tabs/AdvancedTab.tsx
@@ -0,0 +1,521 @@
+import React from "react";
+import { View, Text, TextInput, TouchableOpacity, Switch, Alert } from "react-native";
+import { Ionicons } from "@expo/vector-icons";
+
+interface AdvancedTabProps {
+ // Calendar event name
+ calendarEventName: string;
+ setCalendarEventName: (value: string) => void;
+
+ // Add to calendar email
+ addToCalendarEmail: string;
+ setAddToCalendarEmail: (value: string) => void;
+
+ // Layout
+ selectedLayouts: string[];
+ setSelectedLayouts: (layouts: string[]) => void;
+ defaultLayout: string;
+ setDefaultLayout: (layout: string) => void;
+
+ // Confirmation settings
+ requiresConfirmation: boolean;
+ setRequiresConfirmation: (value: boolean) => void;
+ disableCancelling: boolean;
+ setDisableCancelling: (value: boolean) => void;
+ disableRescheduling: boolean;
+ setDisableRescheduling: (value: boolean) => void;
+
+ // Additional settings
+ sendCalVideoTranscription: boolean;
+ setSendCalVideoTranscription: (value: boolean) => void;
+ autoTranslate: boolean;
+ setAutoTranslate: (value: boolean) => void;
+ requiresBookerEmailVerification: boolean;
+ setRequiresBookerEmailVerification: (value: boolean) => void;
+ hideCalendarNotes: boolean;
+ setHideCalendarNotes: (value: boolean) => void;
+ hideCalendarEventDetails: boolean;
+ setHideCalendarEventDetails: (value: boolean) => void;
+ hideOrganizerEmail: boolean;
+ setHideOrganizerEmail: (value: boolean) => void;
+ lockTimezone: boolean;
+ setLockTimezone: (value: boolean) => void;
+ allowReschedulingPastEvents: boolean;
+ setAllowReschedulingPastEvents: (value: boolean) => void;
+ allowBookingThroughRescheduleLink: boolean;
+ setAllowBookingThroughRescheduleLink: (value: boolean) => void;
+
+ // Redirect on booking
+ successRedirectUrl: string;
+ setSuccessRedirectUrl: (value: string) => void;
+ forwardParamsSuccessRedirect: boolean;
+ setForwardParamsSuccessRedirect: (value: boolean) => void;
+
+ // Custom reply-to email
+ customReplyToEmail: string;
+ setCustomReplyToEmail: (value: string) => void;
+
+ // Event type colors
+ eventTypeColorLight: string;
+ setEventTypeColorLight: (value: string) => void;
+ eventTypeColorDark: string;
+ setEventTypeColorDark: (value: string) => void;
+}
+
+export function AdvancedTab(props: AdvancedTabProps) {
+ const layoutOptions = [
+ { id: "MONTH_VIEW", label: "Month", icon: "calendar-outline" },
+ { id: "WEEK_VIEW", label: "Weekly", icon: "calendar-outline" },
+ { id: "COLUMN_VIEW", label: "Column", icon: "list-outline" },
+ ];
+
+ return (
+
+ {/* Calendar Event Name Card */}
+
+ Calendar event name
+
+
+ Use variables like {"{"}Scheduler{"}"} for booker name, {"{"}Organizer{"}"} for your name
+
+
+
+ {/* Add to Calendar Card */}
+
+ Add to calendar
+
+ We'll display this email address as the organizer, and send confirmation emails here.
+
+
+
+
+ {/* Layout Card */}
+
+ Layout
+
+ You can select multiple and your bookers can switch views.
+
+
+ {/* Layout Options */}
+
+ {layoutOptions.map((layout) => (
+ {
+ if (props.selectedLayouts.includes(layout.id)) {
+ // Don't allow deselecting if it's the only one
+ if (props.selectedLayouts.length > 1) {
+ props.setSelectedLayouts(props.selectedLayouts.filter((l) => l !== layout.id));
+ // If removing the default, set a new default
+ if (props.defaultLayout === layout.id) {
+ const remaining = props.selectedLayouts.filter((l) => l !== layout.id);
+ props.setDefaultLayout(remaining[0]);
+ }
+ }
+ } else {
+ props.setSelectedLayouts([...props.selectedLayouts, layout.id]);
+ }
+ }}
+ >
+
+
+ {layout.label}
+
+ {props.selectedLayouts.includes(layout.id) && (
+
+ )}
+
+ ))}
+
+
+ {/* Default View */}
+ {props.selectedLayouts.length > 1 && (
+
+ Default view
+
+ {props.selectedLayouts.map((layoutId) => {
+ const layout = layoutOptions.find((l) => l.id === layoutId);
+ if (!layout) return null;
+ return (
+ props.setDefaultLayout(layout.id)}
+ >
+ {layout.label}
+ {props.defaultLayout === layout.id && (
+
+ )}
+
+ );
+ })}
+
+
+ )}
+
+
+ {/* Booking Questions Card */}
+
+ Booking questions
+
+ Customize the questions asked on the booking page.
+
+
+ Alert.alert("Coming Soon", "Booking questions customization will be available soon.")
+ }
+ >
+
+ Manage booking questions
+
+
+
+ {/* Requires confirmation */}
+
+
+
+ Requires confirmation
+
+ The booking needs to be manually confirmed before it is pushed to your calendar
+
+
+
+
+
+
+ {/* Disable Cancelling */}
+
+
+
+ Disable Cancelling
+
+ Guests can no longer cancel the event with calendar invite or email
+
+
+
+
+
+
+ {/* Disable Rescheduling */}
+
+
+
+ Disable Rescheduling
+
+ Guests can no longer reschedule the event with calendar invite or email
+
+
+
+
+
+
+ {/* Send Cal Video Transcription Emails */}
+
+
+
+
+ Send Cal Video Transcription Emails
+
+
+ Send emails with the transcription of the Cal Video after the meeting ends
+
+
+
+
+
+
+ {/* Auto translate */}
+
+
+
+
+ Auto translate title and description
+
+
+ Automatically translate titles and descriptions to the visitor's browser language
+ using AI
+
+
+
+
+
+
+ {/* Requires booker email verification */}
+
+
+
+
+ Requires booker email verification
+
+
+ To ensure booker's email verification before scheduling events
+
+
+
+
+
+
+ {/* Hide notes in calendar */}
+
+
+
+ Hide notes in calendar
+
+ For privacy reasons, additional inputs and notes will be hidden in the calendar entry
+
+
+
+
+
+
+ {/* Hide calendar event details */}
+
+
+
+
+ Hide calendar event details on shared calendars
+
+
+ When a calendar is shared, events are visible but details are hidden from those
+ without write access
+
+
+
+
+
+
+ {/* Hide organizer's email */}
+
+
+
+ Hide organizer's email
+
+ Hide organizer's email address from the booking screen, email notifications, and
+ calendar events
+
+
+
+
+
+
+ {/* Lock timezone */}
+
+
+
+
+ Lock timezone on booking page
+
+
+ To lock the timezone on booking page, useful for in-person events
+
+
+
+
+
+
+ {/* Allow rescheduling past events */}
+
+
+
+
+ Allow rescheduling past events
+
+
+ Enabling this option allows for past events to be rescheduled
+
+
+
+
+
+
+ {/* Allow booking through reschedule link */}
+
+
+
+
+ Allow booking through reschedule link
+
+
+ When enabled, users will be able to create a new booking when trying to reschedule a
+ cancelled booking
+
+
+
+
+
+
+ {/* Redirect on booking Card */}
+
+ Redirect on booking
+
+ Redirect to a custom URL after a successful booking
+
+
+
+ Forward query parameters
+
+
+
+
+ {/* Custom Reply-To Email Card */}
+
+ Custom 'Reply-To' email
+
+ Use a different email address as the replyTo for confirmation emails instead of the
+ organizer's email
+
+
+
+
+ {/* Event Type Color Card */}
+
+ Event type color
+
+ This is only used for event type & booking differentiation within the app. It is not
+ displayed to bookers.
+
+
+
+ Light theme color
+
+
+
+
+
+
+ Dark theme color
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/companion/app/event-type-detail/tabs/AvailabilityTab.tsx b/companion/app/event-type-detail/tabs/AvailabilityTab.tsx
new file mode 100644
index 0000000000..6096989fcf
--- /dev/null
+++ b/companion/app/event-type-detail/tabs/AvailabilityTab.tsx
@@ -0,0 +1,110 @@
+import React from "react";
+import { View, Text, TouchableOpacity } from "react-native";
+import { Ionicons } from "@expo/vector-icons";
+import { Schedule } from "../../../services/calcom";
+
+interface DaySchedule {
+ day: string;
+ available: boolean;
+ startTime?: string;
+ endTime?: string;
+}
+
+interface AvailabilityTabProps {
+ selectedSchedule: Schedule | null;
+ setShowScheduleDropdown: (show: boolean) => void;
+ schedulesLoading: boolean;
+ scheduleDetailsLoading: boolean;
+ selectedScheduleDetails: any;
+ getDaySchedule: () => DaySchedule[];
+ formatTime: (time: string) => string;
+ selectedTimezone: string;
+}
+
+export function AvailabilityTab(props: AvailabilityTabProps) {
+ return (
+
+
+ Availability
+ props.setShowScheduleDropdown(true)}
+ disabled={props.schedulesLoading}
+ >
+
+ {props.schedulesLoading
+ ? "Loading schedules..."
+ : props.selectedSchedule
+ ? props.selectedSchedule.name
+ : "Select schedule"}
+
+
+
+
+
+ {props.selectedSchedule && (
+ <>
+
+ {props.scheduleDetailsLoading ? (
+
+ Loading schedule details...
+
+ ) : props.selectedScheduleDetails ? (
+ props.getDaySchedule().map((dayInfo, index) => (
+
+
+ {dayInfo.day}
+
+
+ {dayInfo.available && dayInfo.startTime && dayInfo.endTime
+ ? `${props.formatTime(dayInfo.startTime)} - ${props.formatTime(dayInfo.endTime)}`
+ : "Unavailable"}
+
+
+ ))
+ ) : (
+
+
+ Failed to load schedule details
+
+
+ )}
+
+
+
+ Timezone
+
+
+ {props.selectedTimezone || props.selectedScheduleDetails?.timeZone || "No timezone"}
+
+
+
+ >
+ )}
+
+ );
+}
diff --git a/companion/app/event-type-detail/tabs/BasicsTab.tsx b/companion/app/event-type-detail/tabs/BasicsTab.tsx
new file mode 100644
index 0000000000..939486c06d
--- /dev/null
+++ b/companion/app/event-type-detail/tabs/BasicsTab.tsx
@@ -0,0 +1,257 @@
+import React from "react";
+import { View, Text, TextInput, TouchableOpacity, Switch } from "react-native";
+import { Ionicons } from "@expo/vector-icons";
+import { SvgImage } from "../../../components/SvgImage";
+import { defaultLocations, DefaultLocationType } from "../../../utils/defaultLocations";
+import { slugify } from "../../../utils/slugify";
+
+interface BasicsTabProps {
+ // Title, description, URL
+ eventTitle: string;
+ setEventTitle: (value: string) => void;
+ eventDescription: string;
+ setEventDescription: (value: string) => void;
+ username: string;
+ eventSlug: string;
+ setEventSlug: (value: string) => void;
+
+ // Duration
+ allowMultipleDurations: boolean;
+ setAllowMultipleDurations: (value: boolean) => void;
+ eventDuration: string;
+ setEventDuration: (value: string) => void;
+ selectedDurations: string[];
+ setShowDurationDropdown: (show: boolean) => void;
+ defaultDuration: string;
+ setShowDefaultDurationDropdown: (show: boolean) => void;
+
+ // Location
+ selectedLocation: string;
+ setShowLocationDropdown: (show: boolean) => void;
+ conferencingLoading: boolean;
+ getSelectedLocationIconUrl: () => string | null;
+ locationAddress: string;
+ setLocationAddress: (value: string) => void;
+ locationLink: string;
+ setLocationLink: (value: string) => void;
+ locationPhone: string;
+ setLocationPhone: (value: string) => void;
+}
+
+export function BasicsTab(props: BasicsTabProps) {
+ return (
+
+ {/* Title and Description Card */}
+
+
+ Title
+
+
+
+
+ Description
+
+
+
+
+ URL
+
+
+ cal.com/{props.username}/
+
+ props.setEventSlug(slugify(text, true))}
+ placeholder="event-slug"
+ placeholderTextColor="#8E8E93"
+ />
+
+
+
+
+ {/* Duration Card */}
+
+ {!props.allowMultipleDurations && (
+
+ Duration
+
+
+ Minutes
+
+
+ )}
+
+ {props.allowMultipleDurations && (
+ <>
+
+
+ Available durations
+
+ props.setShowDurationDropdown(true)}
+ >
+
+ {props.selectedDurations.length > 0
+ ? `${props.selectedDurations.length} duration${
+ props.selectedDurations.length > 1 ? "s" : ""
+ } selected`
+ : "Select durations"}
+
+
+
+
+
+ {props.selectedDurations.length > 0 && (
+
+ Default duration
+ props.setShowDefaultDurationDropdown(true)}
+ >
+
+ {props.defaultDuration || "Select default duration"}
+
+
+
+
+ )}
+ >
+ )}
+
+
+ Allow multiple durations
+
+
+
+
+ {/* Location Card */}
+
+
+ Location
+ props.setShowLocationDropdown(true)}
+ disabled={props.conferencingLoading}
+ >
+
+ {!props.conferencingLoading &&
+ props.selectedLocation &&
+ props.getSelectedLocationIconUrl() && (
+
+ )}
+
+ {props.conferencingLoading
+ ? "Loading locations..."
+ : props.selectedLocation || "Select location"}
+
+
+
+
+
+ {/* Location Input Fields - shown conditionally based on selected location type */}
+ {(() => {
+ const currentLocation = defaultLocations.find(
+ (loc) => loc.label === props.selectedLocation
+ );
+ if (!currentLocation || !currentLocation.organizerInputType) {
+ return null;
+ }
+
+ if (currentLocation.organizerInputType === "text") {
+ // Text input for address or link
+ const isAddress = currentLocation.type === "inPerson";
+ const isLink = currentLocation.type === "link";
+
+ return (
+
+
+ {currentLocation.organizerInputLabel ||
+ (isAddress ? "Address" : "Meeting Link")}
+
+ {
+ if (isAddress) {
+ props.setLocationAddress(text);
+ } else {
+ props.setLocationLink(text);
+ }
+ }}
+ autoCapitalize="none"
+ autoCorrect={false}
+ keyboardType={isLink ? "url" : "default"}
+ />
+ {currentLocation.messageForOrganizer && (
+
+ {currentLocation.messageForOrganizer}
+
+ )}
+
+ );
+ } else if (currentLocation.organizerInputType === "phone") {
+ // Phone input
+ return (
+
+
+ {currentLocation.organizerInputLabel || "Phone Number"}
+
+
+ {currentLocation.messageForOrganizer && (
+
+ {currentLocation.messageForOrganizer}
+
+ )}
+
+ );
+ }
+ return null;
+ })()}
+
+
+
+ );
+}
diff --git a/companion/app/event-type-detail/tabs/LimitsTab.tsx b/companion/app/event-type-detail/tabs/LimitsTab.tsx
new file mode 100644
index 0000000000..5eea809a17
--- /dev/null
+++ b/companion/app/event-type-detail/tabs/LimitsTab.tsx
@@ -0,0 +1,500 @@
+import React from "react";
+import { View, Text, TextInput, TouchableOpacity, Switch, Animated } from "react-native";
+import { Ionicons } from "@expo/vector-icons";
+import {
+ bufferTimeOptions,
+ timeUnitOptions,
+ frequencyUnitOptions,
+ durationUnitOptions,
+ slotIntervalOptions,
+} from "../constants";
+
+interface FrequencyLimit {
+ id: number;
+ value: string;
+ unit: string;
+}
+
+interface DurationLimit {
+ id: number;
+ value: string;
+ unit: string;
+}
+
+interface LimitsTabProps {
+ // Buffer times
+ beforeEventBuffer: string;
+ setShowBeforeBufferDropdown: (show: boolean) => void;
+ afterEventBuffer: string;
+ setShowAfterBufferDropdown: (show: boolean) => void;
+
+ // Minimum notice
+ minimumNoticeValue: string;
+ setMinimumNoticeValue: (value: string) => void;
+ minimumNoticeUnit: string;
+ setShowMinimumNoticeUnitDropdown: (show: boolean) => void;
+
+ // Slot interval
+ slotInterval: string;
+ setShowSlotIntervalDropdown: (show: boolean) => void;
+
+ // Booking frequency
+ limitBookingFrequency: boolean;
+ toggleBookingFrequency: (value: boolean) => void;
+ frequencyAnimationValue: Animated.Value;
+ frequencyLimits: FrequencyLimit[];
+ updateFrequencyLimit: (id: number, field: string, value: string) => void;
+ setShowFrequencyUnitDropdown: (id: number) => void;
+ removeFrequencyLimit: (id: number) => void;
+ addFrequencyLimit: () => void;
+
+ // Total duration
+ limitTotalDuration: boolean;
+ toggleTotalDuration: (value: boolean) => void;
+ durationAnimationValue: Animated.Value;
+ durationLimits: DurationLimit[];
+ updateDurationLimit: (id: number, field: string, value: string) => void;
+ setShowDurationUnitDropdown: (id: number) => void;
+ removeDurationLimit: (id: number) => void;
+ addDurationLimit: () => void;
+
+ // Only show first slot
+ onlyShowFirstAvailableSlot: boolean;
+ setOnlyShowFirstAvailableSlot: (value: boolean) => void;
+
+ // Max active bookings
+ maxActiveBookingsPerBooker: boolean;
+ setMaxActiveBookingsPerBooker: (value: boolean) => void;
+ maxActiveBookingsValue: string;
+ setMaxActiveBookingsValue: (value: string) => void;
+
+ // Future bookings
+ limitFutureBookings: boolean;
+ setLimitFutureBookings: (value: boolean) => void;
+ futureBookingType: "rolling" | "range";
+ setFutureBookingType: (type: "rolling" | "range") => void;
+ rollingDays: string;
+ setRollingDays: (value: string) => void;
+ rollingCalendarDays: boolean;
+ setRollingCalendarDays: (value: boolean) => void;
+ rangeStartDate: string;
+ setRangeStartDate: (value: string) => void;
+ rangeEndDate: string;
+ setRangeEndDate: (value: string) => void;
+}
+
+export function LimitsTab(props: LimitsTabProps) {
+ return (
+
+ {/* Buffer Time, Minimum Notice, and Slot Interval Card */}
+
+
+ Before event
+ props.setShowBeforeBufferDropdown(true)}
+ >
+ {props.beforeEventBuffer}
+
+
+
+
+
+ After event
+ props.setShowAfterBufferDropdown(true)}
+ >
+ {props.afterEventBuffer}
+
+
+
+
+
+ Minimum Notice
+
+ {
+ const numericValue = text.replace(/[^0-9]/g, "");
+ const num = parseInt(numericValue) || 0;
+ if (num >= 0) {
+ props.setMinimumNoticeValue(numericValue || "0");
+ }
+ }}
+ placeholder="1"
+ placeholderTextColor="#8E8E93"
+ keyboardType="numeric"
+ />
+ props.setShowMinimumNoticeUnitDropdown(true)}
+ >
+ {props.minimumNoticeUnit}
+
+
+
+
+
+
+ Time-slot intervals
+ props.setShowSlotIntervalDropdown(true)}
+ >
+
+ {props.slotInterval === "Default" ? "Use event length (default)" : props.slotInterval}
+
+
+
+
+
+
+ {/* Booking Frequency Limit Card */}
+
+
+
+ Limit booking frequency
+
+ Limit how many times this event can be booked.
+
+
+
+
+
+
+ {props.limitBookingFrequency && (
+ <>
+ {props.frequencyLimits.map((limit, index) => (
+
+ {
+ const numericValue = text.replace(/[^0-9]/g, "");
+ const num = parseInt(numericValue) || 0;
+ if (num >= 0) {
+ props.updateFrequencyLimit(limit.id, "value", numericValue || "0");
+ }
+ }}
+ placeholder="1"
+ placeholderTextColor="#8E8E93"
+ keyboardType="numeric"
+ />
+ props.setShowFrequencyUnitDropdown(limit.id)}
+ >
+ {limit.unit}
+
+
+ {props.frequencyLimits.length > 1 && (
+ props.removeFrequencyLimit(limit.id)}
+ >
+
+
+ )}
+
+ ))}
+
+
+ Add Limit
+
+ >
+ )}
+
+
+
+ {/* Total Booking Duration Limit Card */}
+
+
+
+
+ Limit total booking duration
+
+
+ Limit total amount of time that this event can be booked.
+
+
+
+
+
+
+ {props.limitTotalDuration && (
+ <>
+ {props.durationLimits.map((limit, index) => (
+
+
+ {
+ const numericValue = text.replace(/[^0-9]/g, "");
+ const num = parseInt(numericValue) || 0;
+ if (num >= 0) {
+ props.updateDurationLimit(limit.id, "value", numericValue || "0");
+ }
+ }}
+ placeholder="60"
+ placeholderTextColor="#8E8E93"
+ keyboardType="numeric"
+ />
+ Minutes
+
+ props.setShowDurationUnitDropdown(limit.id)}
+ >
+ {limit.unit}
+
+
+ {props.durationLimits.length > 1 && (
+ props.removeDurationLimit(limit.id)}
+ >
+
+
+ )}
+
+ ))}
+
+
+ Add Limit
+
+ >
+ )}
+
+
+
+ {/* Only Show First Available Slot Card */}
+
+
+
+
+ Only show the first slot of each day as available
+
+
+ This will limit your availability for this event type to one slot per day, scheduled
+ at the earliest available time.
+
+
+
+
+
+
+ {/* Max Active Bookings Per Booker Card */}
+
+
+
+
+ Limit number of upcoming bookings per booker
+
+
+ Limit the number of active bookings a booker can make for this event type.
+
+
+
+
+ {props.maxActiveBookingsPerBooker && (
+
+ {
+ const numericValue = text.replace(/[^0-9]/g, "");
+ const num = parseInt(numericValue) || 0;
+ if (num >= 0) {
+ props.setMaxActiveBookingsValue(numericValue || "1");
+ }
+ }}
+ placeholder="1"
+ placeholderTextColor="#8E8E93"
+ keyboardType="numeric"
+ />
+
+ )}
+
+
+ {/* Limit Future Bookings Card */}
+
+
+
+ Limit future bookings
+
+ Limit how far in the future this event can be booked.
+
+
+
+
+ {props.limitFutureBookings && (
+
+
+ props.setFutureBookingType("rolling")}
+ >
+
+ Rolling
+
+
+ props.setFutureBookingType("range")}
+ >
+
+ Date Range
+
+
+
+ {props.futureBookingType === "rolling" && (
+
+
+ {
+ const numericValue = text.replace(/[^0-9]/g, "");
+ const num = parseInt(numericValue) || 0;
+ if (num >= 0) {
+ props.setRollingDays(numericValue || "30");
+ }
+ }}
+ placeholder="30"
+ placeholderTextColor="#8E8E93"
+ keyboardType="numeric"
+ />
+ props.setRollingCalendarDays(!props.rollingCalendarDays)}
+ >
+
+ {props.rollingCalendarDays ? "Calendar days" : "Business days"}
+
+
+
+ days into the future
+
+ )}
+ {props.futureBookingType === "range" && (
+
+
+ Start date
+
+
+
+ End date
+
+
+
+ )}
+
+ )}
+
+
+ );
+}
diff --git a/companion/app/event-type-detail/tabs/RecurringTab.tsx b/companion/app/event-type-detail/tabs/RecurringTab.tsx
new file mode 100644
index 0000000000..d779fdef14
--- /dev/null
+++ b/companion/app/event-type-detail/tabs/RecurringTab.tsx
@@ -0,0 +1,137 @@
+import React from "react";
+import { View, Text, TextInput, TouchableOpacity, Switch, Alert } from "react-native";
+import { Ionicons } from "@expo/vector-icons";
+
+interface RecurringTabProps {
+ recurringEnabled: boolean;
+ setRecurringEnabled: (value: boolean) => void;
+ recurringInterval: string;
+ setRecurringInterval: (value: string) => void;
+ recurringFrequency: "daily" | "weekly" | "monthly" | "yearly";
+ setRecurringFrequency: (value: "daily" | "weekly" | "monthly" | "yearly") => void;
+ recurringOccurrences: string;
+ setRecurringOccurrences: (value: string) => void;
+}
+
+export function RecurringTab({
+ recurringEnabled,
+ setRecurringEnabled,
+ recurringInterval,
+ setRecurringInterval,
+ recurringFrequency,
+ setRecurringFrequency,
+ recurringOccurrences,
+ setRecurringOccurrences,
+}: RecurringTabProps) {
+ return (
+
+ {/* Recurring Event Toggle Card */}
+
+
+
+ Recurring event
+
+ Set up this event type to repeat at regular intervals
+
+
+
+
+
+
+ {/* Recurring Configuration Card - shown when enabled */}
+ {recurringEnabled && (
+
+ Recurrence pattern
+
+ {/* Repeats Every */}
+
+ Repeats every
+
+ {
+ const numericValue = text.replace(/[^0-9]/g, "");
+ // Don't allow empty or 0 values; fall back to 1 so users can keep editing
+ if (numericValue === "" || numericValue === "0") {
+ setRecurringInterval("1");
+ return;
+ }
+ const num = parseInt(numericValue);
+ if (num >= 1 && num <= 20) {
+ setRecurringInterval(numericValue);
+ }
+ }}
+ placeholder="1"
+ placeholderTextColor="#8E8E93"
+ keyboardType="numeric"
+ />
+ {
+ Alert.alert("Select Frequency", "Choose how often this event repeats", [
+ {
+ text: "Daily",
+ onPress: () => setRecurringFrequency("daily"),
+ },
+ {
+ text: "Weekly",
+ onPress: () => setRecurringFrequency("weekly"),
+ },
+ {
+ text: "Monthly",
+ onPress: () => setRecurringFrequency("monthly"),
+ },
+ {
+ text: "Yearly",
+ onPress: () => setRecurringFrequency("yearly"),
+ },
+ { text: "Cancel", style: "cancel" },
+ ]);
+ }}
+ >
+ {recurringFrequency}
+
+
+
+
+
+ {/* Maximum Occurrences */}
+
+ Maximum number of events
+
+ {
+ const numericValue = text.replace(/[^0-9]/g, "");
+ // Don't allow empty or 0 values; fall back to 1 so users can keep editing
+ if (numericValue === "" || numericValue === "0") {
+ setRecurringOccurrences("1");
+ return;
+ }
+ const num = parseInt(numericValue);
+ if (num >= 1) {
+ setRecurringOccurrences(numericValue);
+ }
+ }}
+ placeholder="12"
+ placeholderTextColor="#8E8E93"
+ keyboardType="numeric"
+ />
+ occurrences
+
+
+ The booking will create {recurringOccurrences} events that repeat {recurringFrequency}
+
+
+
+ )}
+
+ );
+}
diff --git a/companion/app/event-type-detail/utils.ts b/companion/app/event-type-detail/utils.ts
new file mode 100644
index 0000000000..c6682935f6
--- /dev/null
+++ b/companion/app/event-type-detail/utils.ts
@@ -0,0 +1,58 @@
+// Utility functions for Event Type Detail
+
+export const formatDuration = (minutes: string) => {
+ const mins = parseInt(minutes) || 0;
+ if (mins < 60) return `${mins}m`;
+ const hours = Math.floor(mins / 60);
+ const remainingMins = mins % 60;
+ return remainingMins > 0 ? `${hours}h ${remainingMins}m` : `${hours}h`;
+};
+
+export const truncateTitle = (text: string, maxLength: number = 20) => {
+ return text.length > maxLength ? `${text.substring(0, maxLength)}...` : text;
+};
+
+export const formatAppIdToDisplayName = (appId: string): string => {
+ // Convert appId like "google-meet" to "Google Meet"
+ return appId
+ .split("-")
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
+ .join(" ");
+};
+
+export const displayNameToLocationValue = (
+ displayName: string,
+ defaultLocations: Array<{ label: string; type: string }>
+): {
+ type: string;
+ integration?: string;
+ address?: string;
+ link?: string;
+ phone?: string;
+ public?: boolean;
+} | null => {
+ // First check if it's a default location
+ const defaultLocation = defaultLocations.find((loc) => loc.label === displayName);
+ if (defaultLocation) {
+ // Map internal location types to API location types
+ switch (defaultLocation.type) {
+ case "attendeeInPerson":
+ return { type: "attendeeAddress" };
+ case "inPerson":
+ return { type: "address", address: "", public: true };
+ case "link":
+ return { type: "link", link: "", public: true };
+ case "phone":
+ return { type: "attendeePhone" };
+ case "userPhone":
+ return { type: "phone", phone: "", public: true };
+ default:
+ return null;
+ }
+ }
+
+ // Check if it's a conferencing app (formatted display name)
+ // e.g., "Google Meet", "Zoom", etc.
+ const appId = displayName.toLowerCase().replace(/\s+/g, "-");
+ return { type: "integration", integration: appId };
+};
diff --git a/companion/app/index.tsx b/companion/app/index.tsx
new file mode 100644
index 0000000000..b8113aefc7
--- /dev/null
+++ b/companion/app/index.tsx
@@ -0,0 +1,5 @@
+import { Redirect } from "expo-router";
+
+export default function Index() {
+ return ;
+}
diff --git a/companion/app/oauth/callback.tsx b/companion/app/oauth/callback.tsx
new file mode 100644
index 0000000000..b98a1a8681
--- /dev/null
+++ b/companion/app/oauth/callback.tsx
@@ -0,0 +1,97 @@
+import React, { useEffect } from "react";
+import { View, Text, ActivityIndicator } from "react-native";
+import { useRouter, useLocalSearchParams } from "expo-router";
+
+export default function OAuthCallback() {
+ const router = useRouter();
+ const params = useLocalSearchParams();
+
+ useEffect(() => {
+ // Extract code, state, and error parameters from URL
+ const code = params.code as string;
+ const state = params.state as string;
+ const error = params.error as string;
+ const errorDescription = params.error_description as string;
+
+ // Handle OAuth error response
+ if (error) {
+ const errorMessage = errorDescription || error || "OAuth authorization failed";
+ console.error("OAuth error:", error, errorDescription);
+
+ if (typeof window !== "undefined") {
+ if (window.opener) {
+ window.opener.postMessage(
+ {
+ type: "OAUTH_ERROR",
+ error: errorMessage,
+ errorCode: error,
+ },
+ "*"
+ );
+ window.close();
+ } else {
+ // Store error for main app to pick up
+ if (state) {
+ window.localStorage.setItem(`oauth_callback_error_${state}`, errorMessage);
+ window.localStorage.setItem(`oauth_callback_error_code_${state}`, error);
+ }
+ router.replace("/(tabs)");
+ }
+ }
+ return;
+ }
+
+ if (code && state) {
+ // Store the parameters temporarily using state-specific keys to prevent race conditions
+ // The OAuth service should be able to pick these up
+ if (typeof window !== "undefined") {
+ window.localStorage.setItem(`oauth_callback_code_${state}`, code);
+ window.localStorage.setItem(`oauth_callback_state_${state}`, state);
+
+ // Close the OAuth popup/tab if it exists
+ if (window.opener) {
+ window.opener.postMessage(
+ {
+ type: "OAUTH_SUCCESS",
+ code,
+ state,
+ },
+ "*"
+ );
+ window.close();
+ } else {
+ // Redirect to main app
+ router.replace("/(tabs)");
+ }
+ }
+ } else {
+ console.error("No authorization code or state in OAuth callback");
+
+ // Handle error case
+ if (typeof window !== "undefined") {
+ if (window.opener) {
+ window.opener.postMessage(
+ {
+ type: "OAUTH_ERROR",
+ error: "No authorization code received",
+ },
+ "*"
+ );
+ window.close();
+ } else {
+ router.replace("/(tabs)");
+ }
+ }
+ }
+ }, [params, router]);
+
+ return (
+
+
+ Processing OAuth callback...
+
+ Please wait while we complete the authentication.
+
+
+ );
+}
diff --git a/companion/assets/adaptive-icon.png b/companion/assets/adaptive-icon.png
new file mode 100644
index 0000000000..03d6f6b6c6
Binary files /dev/null and b/companion/assets/adaptive-icon.png differ
diff --git a/companion/assets/favicon.png b/companion/assets/favicon.png
new file mode 100644
index 0000000000..e75f697b18
Binary files /dev/null and b/companion/assets/favicon.png differ
diff --git a/companion/assets/icon.png b/companion/assets/icon.png
new file mode 100644
index 0000000000..a0b1526fc7
Binary files /dev/null and b/companion/assets/icon.png differ
diff --git a/companion/assets/logo.svg b/companion/assets/logo.svg
new file mode 100644
index 0000000000..bccfe813ef
--- /dev/null
+++ b/companion/assets/logo.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/companion/assets/splash-icon.png b/companion/assets/splash-icon.png
new file mode 100644
index 0000000000..03d6f6b6c6
Binary files /dev/null and b/companion/assets/splash-icon.png differ
diff --git a/companion/babel.config.js b/companion/babel.config.js
new file mode 100644
index 0000000000..18767383ab
--- /dev/null
+++ b/companion/babel.config.js
@@ -0,0 +1,6 @@
+module.exports = function (api) {
+ api.cache(true);
+ return {
+ presets: [["babel-preset-expo", { jsxImportSource: "nativewind" }], "nativewind/babel"],
+ };
+};
diff --git a/companion/components/AuthTokenProvider.tsx b/companion/components/AuthTokenProvider.tsx
new file mode 100644
index 0000000000..b6d6f0f261
--- /dev/null
+++ b/companion/components/AuthTokenProvider.tsx
@@ -0,0 +1,21 @@
+import { useEffect } from "react";
+import { useAuth } from "../contexts/AuthContext";
+import { setAuthToken, setWebSession } from "../services/calcom";
+
+export function AuthTokenProvider({ children }: { children: React.ReactNode }) {
+ const { accessToken, isAuthenticated, isWebSession } = useAuth();
+
+ useEffect(() => {
+ if (isAuthenticated) {
+ if (accessToken) {
+ setAuthToken(accessToken);
+ }
+ setWebSession(isWebSession);
+ } else {
+ setAuthToken(null);
+ setWebSession(false);
+ }
+ }, [isAuthenticated, accessToken, isWebSession]);
+
+ return <>{children}>;
+}
diff --git a/companion/components/CalComLogo.tsx b/companion/components/CalComLogo.tsx
new file mode 100644
index 0000000000..d6df1b423d
--- /dev/null
+++ b/companion/components/CalComLogo.tsx
@@ -0,0 +1,40 @@
+import React from "react";
+import Svg, { Path } from "react-native-svg";
+
+interface CalComLogoProps {
+ width?: number;
+ height?: number;
+ color?: string;
+}
+
+export function CalComLogo({ width = 101, height = 22, color = "#292929" }: CalComLogoProps) {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/companion/components/FullScreenModal.tsx b/companion/components/FullScreenModal.tsx
new file mode 100644
index 0000000000..bb4ce8281e
--- /dev/null
+++ b/companion/components/FullScreenModal.tsx
@@ -0,0 +1,65 @@
+import React, { useEffect } from "react";
+import { Modal, ModalProps, Platform, View } from "react-native";
+
+interface FullScreenModalProps extends ModalProps {
+ visible: boolean;
+ onRequestClose: () => void;
+ children: React.ReactNode;
+}
+
+/**
+ * A modal wrapper that expands the browser extension iframe to full screen
+ * when running in the web platform (browser extension).
+ *
+ * For mobile platforms, it behaves like a regular Modal.
+ */
+export function FullScreenModal({
+ visible,
+ onRequestClose,
+ children,
+ ...modalProps
+}: FullScreenModalProps) {
+ useEffect(() => {
+ // Only send expand/collapse messages on web platform (browser extension)
+ if (Platform.OS !== "web") {
+ return;
+ }
+
+ if (visible) {
+ // Expand the iframe to full width when modal opens
+ window.parent.postMessage({ type: "cal-companion-expand" }, "*");
+ } else {
+ // Collapse the iframe back to 400px when modal closes
+ window.parent.postMessage({ type: "cal-companion-collapse" }, "*");
+ }
+
+ // Cleanup: collapse on unmount if still visible
+ return () => {
+ if (visible && Platform.OS === "web") {
+ window.parent.postMessage({ type: "cal-companion-collapse" }, "*");
+ }
+ };
+ }, [visible]);
+
+ // For non-web platforms, just use the regular Modal
+ if (Platform.OS !== "web") {
+ return (
+
+ {children}
+
+ );
+ }
+
+ // For web platform (browser extension), use the modal with full-screen behavior
+ return (
+
+ {children}
+
+ );
+}
diff --git a/companion/components/Header.tsx b/companion/components/Header.tsx
new file mode 100644
index 0000000000..237e8d67e9
--- /dev/null
+++ b/companion/components/Header.tsx
@@ -0,0 +1,300 @@
+import { Ionicons } from "@expo/vector-icons";
+import { useRouter } from "expo-router";
+import React, { useState, useEffect } from "react";
+import {
+ View,
+ Text,
+ TouchableOpacity,
+ Image,
+ ActivityIndicator,
+ Modal,
+ Alert,
+ Linking,
+ Platform,
+ ActionSheetIOS,
+} from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { CalComAPIService, UserProfile } from "../services/calcom";
+import { CalComLogo } from "./CalComLogo";
+import { FullScreenModal } from "./FullScreenModal";
+
+export function Header() {
+ const router = useRouter();
+ const insets = useSafeAreaInsets();
+ const [userProfile, setUserProfile] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const [showProfileModal, setShowProfileModal] = useState(false);
+
+ useEffect(() => {
+ fetchUserProfile();
+ }, []);
+
+ const fetchUserProfile = async () => {
+ try {
+ const profile = await CalComAPIService.getUserProfile();
+ setUserProfile(profile);
+ } catch (error) {
+ console.error("Failed to fetch user profile:", error);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const handleProfile = () => {
+ if (Platform.OS === "ios") {
+ const options = ["Cancel", "My Profile", "My Settings", "Out of Office", "Help", "Sign Out"];
+
+ ActionSheetIOS.showActionSheetWithOptions(
+ {
+ options,
+ destructiveButtonIndex: 6, // Sign Out
+ cancelButtonIndex: 0,
+ title: userProfile?.name || "Profile Menu",
+ },
+ (buttonIndex) => {
+ switch (buttonIndex) {
+ case 1: // My Profile
+ handleMenuOption("profile");
+ break;
+ case 2: // My Settings
+ handleMenuOption("settings");
+ break;
+ case 3: // Out of Office
+ handleMenuOption("outOfOffice");
+ break;
+ case 4: // Support
+ handleMenuOption("help");
+ break;
+ case 5: // Sign Out
+ handleMenuOption("signOut");
+ break;
+ }
+ }
+ );
+ } else {
+ setShowProfileModal(true);
+ }
+ };
+
+ const openExternalLink = async (url: string, fallbackMessage: string) => {
+ try {
+ const supported = await Linking.canOpenURL(url);
+ if (supported) {
+ await Linking.openURL(url);
+ } else {
+ Alert.alert("Error", `Cannot open ${fallbackMessage} on your device.`);
+ }
+ } catch (error) {
+ console.error(`Failed to open ${url}:`, error);
+ Alert.alert("Error", `Failed to open ${fallbackMessage}. Please try again.`);
+ }
+ };
+
+ const handleMenuOption = (option: string) => {
+ if (Platform.OS !== "ios") {
+ setShowProfileModal(false);
+ }
+ switch (option) {
+ case "profile":
+ openExternalLink("https://app.cal.com/settings/my-account/profile", "Profile page");
+ break;
+ case "settings":
+ openExternalLink("https://app.cal.com/settings/my-account", "Settings page");
+ break;
+ case "outOfOffice":
+ openExternalLink(
+ "https://app.cal.com/settings/my-account/out-of-office",
+ "Out of Office page"
+ );
+ break;
+ case "roadmap":
+ openExternalLink("https://cal.com/roadmap", "Roadmap");
+ break;
+ case "help":
+ openExternalLink("https://cal.com/help", "Help page");
+ break;
+ case "signOut":
+ Alert.alert("Sign Out", "Are you sure you want to sign out?", [
+ { text: "Cancel", style: "cancel" },
+ {
+ text: "Sign Out",
+ style: "destructive",
+ onPress: () => {
+ // TODO: Implement sign out
+ console.log("Sign Out pressed");
+ },
+ },
+ ]);
+ break;
+ }
+ };
+
+ return (
+ <>
+
+ {/* Left: Cal.com Logo */}
+
+
+
+
+ {/* Right: Icons */}
+
+ {/* Profile Picture */}
+
+ {loading ? (
+
+ ) : userProfile?.avatarUrl ? (
+
+ ) : (
+
+
+
+ )}
+
+
+
+
+ {/* Profile Menu Modal */}
+ setShowProfileModal(false)}
+ >
+ setShowProfileModal(false)}
+ >
+ e.stopPropagation()}
+ >
+ {/* Header with profile info */}
+
+
+
+ {userProfile?.avatarUrl ? (
+
+ ) : (
+
+ {userProfile?.name
+ ? userProfile.name.charAt(0).toUpperCase()
+ : userProfile?.email?.charAt(0).toUpperCase() || "?"}
+
+ )}
+
+
+
+ {userProfile?.name || "User"}
+
+ {userProfile?.email && (
+ {userProfile.email}
+ )}
+
+
+
+
+ {/* Menu Items */}
+
+ handleMenuOption("profile")}
+ >
+
+
+ My Profile
+
+
+
+
+ handleMenuOption("settings")}
+ >
+
+
+ My Settings
+
+
+
+
+ handleMenuOption("outOfOffice")}
+ >
+
+
+ Out of Office
+
+
+
+
+
+
+ handleMenuOption("roadmap")}
+ >
+
+
+ Roadmap
+
+
+
+
+ handleMenuOption("help")}
+ >
+
+
+ Help
+
+
+
+
+
+
+ handleMenuOption("signOut")}
+ >
+
+ Sign Out
+
+
+
+ {/* Cancel button */}
+
+ setShowProfileModal(false)}
+ >
+ Cancel
+
+
+
+
+
+ >
+ );
+}
diff --git a/companion/components/LoginScreen.tsx b/companion/components/LoginScreen.tsx
new file mode 100644
index 0000000000..d20ea5e0f2
--- /dev/null
+++ b/companion/components/LoginScreen.tsx
@@ -0,0 +1,48 @@
+import React from "react";
+import { View, Text, TouchableOpacity, Alert, ActivityIndicator } from "react-native";
+import { useAuth } from "../contexts/AuthContext";
+
+export function LoginScreen() {
+ const { loginWithOAuth, loading } = useAuth();
+
+ const handleOAuthLogin = async () => {
+ try {
+ await loginWithOAuth();
+ } catch (error) {
+ console.error("OAuth login error:", error);
+ Alert.alert(
+ "Login Failed",
+ error instanceof Error
+ ? error.message
+ : "Failed to login with OAuth. Please check your configuration and try again.",
+ [{ text: "OK" }]
+ );
+ }
+ };
+
+ return (
+
+
+
+ Welcome to Cal.com Companion
+
+
+ Sign in to manage your bookings and event types
+
+
+
+ {loading ? : null}
+
+ {loading ? "Signing in..." : "Sign in with Cal.com"}
+
+
+
+ );
+}
+
+export default LoginScreen;
diff --git a/companion/components/LogoutButton.tsx b/companion/components/LogoutButton.tsx
new file mode 100644
index 0000000000..14defc4fa3
--- /dev/null
+++ b/companion/components/LogoutButton.tsx
@@ -0,0 +1,76 @@
+import React, { useState } from "react";
+import { TouchableOpacity, Text, Alert, Platform } from "react-native";
+import { useAuth } from "../contexts/AuthContext";
+import { LogoutConfirmModal } from "./LogoutConfirmModal";
+
+interface LogoutButtonProps {
+ className?: string;
+ variant?: "default" | "destructive" | "ghost";
+}
+
+export function LogoutButton({ className = "" }: LogoutButtonProps) {
+ const { logout } = useAuth();
+ const [showConfirmModal, setShowConfirmModal] = useState(false);
+
+ const handleLogoutPress = () => {
+ if (Platform.OS === "web") {
+ setShowConfirmModal(true);
+ } else {
+ // Mobile: use Alert.alert
+ Alert.alert("Sign Out", "Are you sure you want to sign out?", [
+ {
+ text: "Cancel",
+ style: "cancel",
+ },
+ {
+ text: "Sign Out",
+ style: "destructive",
+ onPress: performLogout,
+ },
+ ]);
+ }
+ };
+
+ const performLogout = async () => {
+ try {
+ await logout();
+ } catch (error) {
+ console.error("Logout error:", error);
+ if (Platform.OS === "web") {
+ window.alert("Failed to sign out. Please try again.");
+ } else {
+ Alert.alert("Error", "Failed to sign out. Please try again.");
+ }
+ }
+ };
+
+ const handleConfirmLogout = () => {
+ setShowConfirmModal(false);
+ performLogout();
+ };
+
+ const handleCancelLogout = () => {
+ setShowConfirmModal(false);
+ };
+
+ return (
+ <>
+
+ Sign Out
+
+
+
+ >
+ );
+}
+
+export default LogoutButton;
diff --git a/companion/components/LogoutConfirmModal.tsx b/companion/components/LogoutConfirmModal.tsx
new file mode 100644
index 0000000000..fc83ca65bb
--- /dev/null
+++ b/companion/components/LogoutConfirmModal.tsx
@@ -0,0 +1,42 @@
+import React from "react";
+import { View, Text, TouchableOpacity, Platform } from "react-native";
+import { FullScreenModal } from "./FullScreenModal";
+
+interface LogoutConfirmModalProps {
+ visible: boolean;
+ onConfirm: () => void;
+ onCancel: () => void;
+}
+
+export function LogoutConfirmModal({ visible, onConfirm, onCancel }: LogoutConfirmModalProps) {
+ return (
+
+
+
+ Sign Out
+ Are you sure you want to sign out?
+
+
+
+ Cancel
+
+
+
+ Sign Out
+
+
+
+
+
+ );
+}
diff --git a/companion/components/SvgImage.tsx b/companion/components/SvgImage.tsx
new file mode 100644
index 0000000000..4848f1fd25
--- /dev/null
+++ b/companion/components/SvgImage.tsx
@@ -0,0 +1,51 @@
+import React, { useState } from "react";
+import { View, Image } from "react-native";
+import { SvgUri } from "react-native-svg";
+
+interface SvgImageProps {
+ uri: string;
+ width: number;
+ height: number;
+ style?: { marginRight?: number };
+}
+
+/**
+ * Component that can display both SVG and regular images
+ * Falls back to regular Image if SVG fails
+ */
+export const SvgImage: React.FC = ({ uri, width, height, style }) => {
+ const [useFallback, setUseFallback] = useState(false);
+ // Extract pathname (ignore query strings and hash) to detect SVG correctly
+ // Handles URLs like: icon.svg?variant=dark or icon.svg#hash
+ const pathname = uri.split("?")[0].split("#")[0];
+ const isSvg = pathname.toLowerCase().endsWith(".svg");
+
+ if (!isSvg || useFallback) {
+ // Use regular Image for non-SVG or if SVG failed
+ return (
+
+ console.log("Image load error:", uri)}
+ />
+
+ );
+ }
+
+ // Use SvgUri for SVG files
+ return (
+
+ {
+ console.log("SVG load error, falling back to Image:", error);
+ setUseFallback(true);
+ }}
+ />
+
+ );
+};
diff --git a/companion/components/Tooltip.tsx b/companion/components/Tooltip.tsx
new file mode 100644
index 0000000000..08757504c2
--- /dev/null
+++ b/companion/components/Tooltip.tsx
@@ -0,0 +1,75 @@
+import React, { useState, useRef, useEffect } from "react";
+import { View, Text, Platform } from "react-native";
+
+interface TooltipProps {
+ text: string;
+ children: React.ReactElement;
+}
+
+export function Tooltip({ text, children }: TooltipProps) {
+ const [showTooltip, setShowTooltip] = useState(false);
+ const [position, setPosition] = useState({ top: 0, left: 0 });
+ const containerRef = useRef(null);
+
+ // Only show tooltips on web platform
+ if (Platform.OS !== "web") {
+ return children;
+ }
+
+ const handleMouseEnter = (e: any) => {
+ if (containerRef.current) {
+ const rect = containerRef.current.getBoundingClientRect();
+ setPosition({
+ top: rect.top - 40,
+ left: rect.left + rect.width / 2 + 20,
+ });
+ setShowTooltip(true);
+ }
+ };
+
+ const handleMouseLeave = () => {
+ setShowTooltip(false);
+ };
+
+ return (
+
+ {children}
+ {showTooltip && (
+
+
+ {text}
+
+
+ )}
+
+ );
+}
diff --git a/companion/contexts/AuthContext.tsx b/companion/contexts/AuthContext.tsx
new file mode 100644
index 0000000000..b93645ffcf
--- /dev/null
+++ b/companion/contexts/AuthContext.tsx
@@ -0,0 +1,367 @@
+///
+
+import React, { createContext, useContext, useState, useEffect, ReactNode } from "react";
+import * as SecureStore from "expo-secure-store";
+import { Platform } from "react-native";
+import { WebAuthService } from "../services/webAuth";
+import { CalComAPIService } from "../services/calcom";
+import {
+ createCalComOAuthService,
+ OAuthTokens,
+ CalComOAuthService,
+} from "../services/oauthService";
+
+interface AuthContextType {
+ isAuthenticated: boolean;
+ accessToken: string | null;
+ refreshToken: string | null;
+ userInfo: any;
+ isWebSession: boolean;
+ loginFromWebSession: (userInfo: any) => Promise;
+ loginWithOAuth: () => Promise;
+ logout: () => Promise;
+ loading: boolean;
+}
+
+const AuthContext = createContext(undefined);
+
+const ACCESS_TOKEN_KEY = "cal_access_token";
+const REFRESH_TOKEN_KEY = "cal_refresh_token";
+const OAUTH_TOKENS_KEY = "cal_oauth_tokens";
+const AUTH_TYPE_KEY = "cal_auth_type";
+
+type AuthType = "oauth" | "web_session";
+
+interface AuthProviderProps {
+ children: ReactNode;
+}
+
+// Check if chrome.storage is available (browser extension context)
+const isChromeStorageAvailable = (): boolean => {
+ return (
+ Platform.OS === "web" &&
+ typeof chrome !== "undefined" &&
+ chrome.storage !== undefined &&
+ chrome.storage.local !== undefined
+ );
+};
+
+// Unified storage helper to abstract web/mobile/extension differences
+const storage = {
+ get: async (key: string): Promise => {
+ // Use chrome.storage in browser extension context (most secure)
+ if (isChromeStorageAvailable()) {
+ return new Promise((resolve) => {
+ chrome.storage.local.get([key], (result) => {
+ resolve(result[key] || null);
+ });
+ });
+ }
+ // Fall back to localStorage for regular web apps
+ if (Platform.OS === "web") {
+ return localStorage.getItem(key);
+ }
+ // Use SecureStore for mobile
+ return await SecureStore.getItemAsync(key);
+ },
+ set: async (key: string, value: string): Promise => {
+ // Use chrome.storage in browser extension context (most secure)
+ if (isChromeStorageAvailable()) {
+ return new Promise((resolve, reject) => {
+ chrome.storage.local.set({ [key]: value }, () => {
+ if (chrome.runtime.lastError) {
+ reject(new Error(chrome.runtime.lastError.message));
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+ // Fall back to localStorage for regular web apps
+ if (Platform.OS === "web") {
+ localStorage.setItem(key, value);
+ return;
+ }
+ // Use SecureStore for mobile
+ await SecureStore.setItemAsync(key, value);
+ },
+ remove: async (key: string): Promise => {
+ // Use chrome.storage in browser extension context (most secure)
+ if (isChromeStorageAvailable()) {
+ return new Promise((resolve, reject) => {
+ chrome.storage.local.remove(key, () => {
+ if (chrome.runtime.lastError) {
+ reject(new Error(chrome.runtime.lastError.message));
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+ // Fall back to localStorage for regular web apps
+ if (Platform.OS === "web") {
+ localStorage.removeItem(key);
+ return;
+ }
+ // Use SecureStore for mobile
+ await SecureStore.deleteItemAsync(key);
+ },
+ removeAll: async (keys: string[]): Promise => {
+ // Use chrome.storage in browser extension context (most secure)
+ if (isChromeStorageAvailable()) {
+ return new Promise((resolve, reject) => {
+ chrome.storage.local.remove(keys, () => {
+ if (chrome.runtime.lastError) {
+ reject(new Error(chrome.runtime.lastError.message));
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+ // Fall back to localStorage for regular web apps
+ if (Platform.OS === "web") {
+ keys.forEach((key) => localStorage.removeItem(key));
+ return;
+ }
+ // Use SecureStore for mobile
+ await Promise.all(keys.map((key) => SecureStore.deleteItemAsync(key)));
+ },
+};
+
+export function AuthProvider({ children }: AuthProviderProps) {
+ const [isAuthenticated, setIsAuthenticated] = useState(false);
+ const [accessToken, setAccessToken] = useState(null);
+ const [refreshToken, setRefreshToken] = useState(null);
+ const [userInfo, setUserInfo] = useState(null);
+ const [isWebSession, setIsWebSession] = useState(false);
+ const [loading, setLoading] = useState(true);
+ const [oauthService] = useState(() => {
+ try {
+ return createCalComOAuthService();
+ } catch (error) {
+ console.warn("Failed to initialize OAuth service:", error);
+ return null;
+ }
+ });
+
+ // Setup refresh token function for OAuth
+ const setupRefreshTokenFunction = (service: CalComOAuthService) => {
+ CalComAPIService.setRefreshTokenFunction(async (refreshToken: string) => {
+ const newTokens = await service.refreshAccessToken(refreshToken);
+ return {
+ accessToken: newTokens.accessToken,
+ refreshToken: newTokens.refreshToken,
+ };
+ });
+ };
+
+ // Common post-login setup: configure API service and fetch user profile
+ const setupAfterLogin = async (token: string, refreshToken?: string) => {
+ CalComAPIService.setAccessToken(token, refreshToken);
+
+ try {
+ await CalComAPIService.getUserProfile();
+ } catch (profileError) {
+ console.error("Failed to fetch user profile:", profileError);
+ // Don't fail login if profile fetch fails
+ }
+ };
+
+ // Save OAuth tokens to storage
+ const saveOAuthTokens = async (tokens: OAuthTokens) => {
+ await storage.set(OAUTH_TOKENS_KEY, JSON.stringify(tokens));
+ await storage.set(AUTH_TYPE_KEY, "oauth");
+ };
+
+ // Clear all auth data from storage
+ const clearAuth = async () => {
+ await storage.removeAll([ACCESS_TOKEN_KEY, REFRESH_TOKEN_KEY, OAUTH_TOKENS_KEY, AUTH_TYPE_KEY]);
+ };
+
+ // Reset all auth state
+ const resetAuthState = () => {
+ setAccessToken(null);
+ setRefreshToken(null);
+ setUserInfo(null);
+ setIsAuthenticated(false);
+ setIsWebSession(false);
+ CalComAPIService.clearAuth();
+ CalComAPIService.clearUserProfile();
+ };
+
+ useEffect(() => {
+ checkAuthState();
+
+ // Set up token refresh callback
+ const handleTokenRefresh = async (newAccessToken: string, newRefreshToken?: string) => {
+ try {
+ const tokens: OAuthTokens = {
+ accessToken: newAccessToken,
+ refreshToken: newRefreshToken || refreshToken || undefined,
+ tokenType: "Bearer",
+ };
+
+ await saveOAuthTokens(tokens);
+ setAccessToken(newAccessToken);
+ if (newRefreshToken) {
+ setRefreshToken(newRefreshToken);
+ }
+
+ CalComAPIService.setAccessToken(
+ newAccessToken,
+ newRefreshToken || refreshToken || undefined
+ );
+ } catch (error) {
+ console.error("Failed to handle token refresh:", error);
+ await logout();
+ }
+ };
+
+ CalComAPIService.setTokenRefreshCallback(handleTokenRefresh);
+
+ return () => {
+ CalComAPIService.setTokenRefreshCallback(() => Promise.resolve());
+ };
+ }, [refreshToken]);
+
+ // Handle OAuth authentication
+ const handleOAuthAuth = async (storedTokens: OAuthTokens) => {
+ if (!oauthService) return;
+
+ // Refresh token if expired
+ let tokens = storedTokens;
+ if (oauthService.isTokenExpired(storedTokens) && storedTokens.refreshToken) {
+ try {
+ console.log("Access token expired, refreshing...");
+ tokens = await oauthService.refreshAccessToken(storedTokens.refreshToken);
+ await saveOAuthTokens(tokens);
+ } catch (refreshError) {
+ console.error("Failed to refresh token:", refreshError);
+ await clearAuth();
+ return;
+ }
+ }
+
+ // Set state
+ setAccessToken(tokens.accessToken);
+ setRefreshToken(tokens.refreshToken || null);
+ setIsAuthenticated(true);
+ setIsWebSession(false);
+
+ // Setup API service and refresh function
+ await setupAfterLogin(tokens.accessToken, tokens.refreshToken);
+ if (tokens.refreshToken) {
+ setupRefreshTokenFunction(oauthService);
+ }
+ };
+
+ // Handle web session authentication
+ const handleWebSessionAuth = () => {
+ setIsWebSession(true);
+ };
+
+ const checkAuthState = async () => {
+ try {
+ const authType = (await storage.get(AUTH_TYPE_KEY)) as AuthType | null;
+ const storedOAuthTokens = await storage.get(OAUTH_TOKENS_KEY);
+ const storedTokens = storedOAuthTokens ? JSON.parse(storedOAuthTokens) : null;
+
+ if (authType === "oauth" && storedTokens && oauthService) {
+ await handleOAuthAuth(storedTokens);
+ } else if (authType === "web_session") {
+ handleWebSessionAuth();
+ }
+ } catch (error) {
+ console.error("Failed to check auth state:", error);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const loginFromWebSession = async (sessionUserInfo: any) => {
+ try {
+ setUserInfo(sessionUserInfo);
+ setIsAuthenticated(true);
+ setIsWebSession(true);
+ await storage.set(AUTH_TYPE_KEY, "web_session");
+
+ // Try to get tokens from web session
+ const tokens = await WebAuthService.getTokensFromWebSession();
+ if (tokens.accessToken) {
+ setAccessToken(tokens.accessToken);
+ setRefreshToken(tokens.refreshToken || null);
+ await setupAfterLogin(tokens.accessToken, tokens.refreshToken);
+ }
+ } catch (error) {
+ console.error("Failed to login from web session:", error);
+ throw error;
+ }
+ };
+
+ const loginWithOAuth = async (): Promise => {
+ if (!oauthService) {
+ throw new Error("OAuth service not available. Please check your configuration.");
+ }
+
+ try {
+ setLoading(true);
+
+ const tokens = await oauthService.startAuthorizationFlow();
+
+ // Save tokens
+ await saveOAuthTokens(tokens);
+
+ // Update state
+ setAccessToken(tokens.accessToken);
+ setRefreshToken(tokens.refreshToken || null);
+ setIsAuthenticated(true);
+ setIsWebSession(false);
+
+ // Setup API service and refresh function
+ await setupAfterLogin(tokens.accessToken, tokens.refreshToken);
+ if (tokens.refreshToken) {
+ setupRefreshTokenFunction(oauthService);
+ }
+
+ // Clear PKCE parameters
+ oauthService.clearPKCEParams();
+ } catch (error) {
+ console.error("OAuth login failed:", error);
+ throw error;
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const logout = async () => {
+ try {
+ await clearAuth();
+ resetAuthState();
+ } catch (error) {
+ console.error("Failed to logout:", error);
+ }
+ };
+
+ const value: AuthContextType = {
+ isAuthenticated,
+ accessToken,
+ refreshToken,
+ userInfo,
+ isWebSession,
+ loginFromWebSession,
+ loginWithOAuth,
+ logout,
+ loading,
+ };
+
+ return {children} ;
+}
+
+export function useAuth(): AuthContextType {
+ const context = useContext(AuthContext);
+ if (context === undefined) {
+ throw new Error("useAuth must be used within an AuthProvider");
+ }
+ return context;
+}
diff --git a/companion/extension/entrypoints/background/index.ts b/companion/extension/entrypoints/background/index.ts
new file mode 100644
index 0000000000..557e4e7360
--- /dev/null
+++ b/companion/extension/entrypoints/background/index.ts
@@ -0,0 +1,223 @@
+///
+
+// @ts-ignore - WXT provides this globally
+export default defineBackground(() => {
+ chrome.action.onClicked.addListener((tab) => {
+ if (tab.id) {
+ chrome.tabs.sendMessage(tab.id, { action: "icon-clicked" }, (response) => {
+ if (chrome.runtime.lastError) {
+ // Expected on pages where content script isn't loaded
+ }
+ });
+ }
+ });
+
+ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
+ if (message.action === "fetch-event-types") {
+ fetchEventTypes()
+ .then((eventTypes) => {
+ sendResponse({ data: eventTypes });
+ })
+ .catch((error) => {
+ sendResponse({ error: error.message });
+ });
+
+ return true;
+ }
+
+ if (message.action === "start-extension-oauth") {
+ const authUrl = message.authUrl;
+ const urlObj = new URL(authUrl);
+ const state = urlObj.searchParams.get("state");
+
+ if (state) {
+ chrome.storage.local.set({ oauth_state: state }, () => {
+ if (chrome.runtime.lastError) {
+ console.warn("Failed to store OAuth state:", chrome.runtime.lastError.message);
+ }
+ });
+ }
+
+ handleExtensionOAuth(authUrl)
+ .then((responseUrl) => {
+ sendResponse({ success: true, responseUrl });
+ })
+ .catch((error) => {
+ sendResponse({ success: false, error: error.message });
+ });
+
+ return true;
+ }
+
+ if (message.action === "exchange-oauth-tokens") {
+ handleTokenExchange(message.tokenRequest, message.tokenEndpoint, message.state)
+ .then((tokens) => {
+ sendResponse({ success: true, tokens });
+ })
+ .catch((error) => {
+ sendResponse({ success: false, error: error.message });
+ });
+
+ return true;
+ }
+
+ return false;
+ });
+});
+
+async function handleExtensionOAuth(authUrl: string): Promise {
+ return new Promise((resolve, reject) => {
+ if (!chrome.identity) {
+ reject(new Error("Chrome identity API not available"));
+ return;
+ }
+
+ chrome.identity.launchWebAuthFlow(
+ {
+ url: authUrl,
+ interactive: true,
+ },
+ (responseUrl) => {
+ if (chrome.runtime.lastError) {
+ console.error("OAuth flow failed:", chrome.runtime.lastError.message);
+ reject(new Error(`OAuth flow failed: ${chrome.runtime.lastError.message}`));
+ } else if (responseUrl) {
+ resolve(responseUrl);
+ } else {
+ console.error("OAuth flow returned no response URL");
+ reject(new Error("OAuth flow cancelled or failed"));
+ }
+ }
+ );
+ });
+}
+
+async function handleTokenExchange(
+ tokenRequest: any,
+ tokenEndpoint: string,
+ state?: string
+): Promise {
+ // CSRF protection: validate state parameter (defense-in-depth)
+ // State is already validated in iframe context; this validates in background script
+ if (state) {
+ try {
+ const result = await chrome.storage.local.get(["oauth_state"]);
+ const storedState = result.oauth_state;
+
+ if (storedState && storedState !== state) {
+ await chrome.storage.local.remove("oauth_state");
+ console.error("State parameter mismatch - possible CSRF attack");
+ throw new Error("Invalid state parameter - possible CSRF attack");
+ }
+
+ if (storedState && storedState === state) {
+ await chrome.storage.local.remove("oauth_state");
+ }
+ } catch (error) {
+ if (error instanceof Error && error.message.includes("Invalid state parameter")) {
+ throw error;
+ }
+ // For storage errors, log but continue (non-blocking)
+ console.warn("State validation warning (non-blocking):", error);
+ }
+ }
+
+ const body = new URLSearchParams();
+ Object.keys(tokenRequest).forEach((key) => {
+ body.append(key, tokenRequest[key]);
+ });
+
+ try {
+ const response = await fetch(tokenEndpoint, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ Accept: "application/json",
+ },
+ body: body.toString(),
+ });
+
+ if (!response.ok) {
+ const errorData = await response.text();
+ console.error("Token exchange error response:", errorData);
+ throw new Error(`Token exchange failed: ${response.status} ${errorData}`);
+ }
+
+ const tokenData = await response.json();
+
+ const tokens = {
+ accessToken: tokenData.access_token,
+ refreshToken: tokenData.refresh_token,
+ tokenType: tokenData.token_type || "Bearer",
+ expiresAt: tokenData.expires_in ? Date.now() + tokenData.expires_in * 1000 : undefined,
+ scope: tokenData.scope,
+ };
+
+ return tokens;
+ } catch (error) {
+ console.error("Token exchange failed:", error);
+ throw error instanceof Error ? error : new Error(String(error));
+ }
+}
+
+async function fetchEventTypes() {
+ const API_BASE_URL = "https://api.cal.com/v2";
+
+ const result = await chrome.storage.local.get(["cal_oauth_tokens"]);
+ const oauthTokens = result.cal_oauth_tokens
+ ? JSON.parse(result.cal_oauth_tokens as string)
+ : null;
+
+ if (!oauthTokens?.accessToken) {
+ throw new Error("No OAuth access token found. Please sign in with OAuth.");
+ }
+
+ // Get current user to retrieve username
+ const userResponse = await fetch(`${API_BASE_URL}/me`, {
+ headers: {
+ Authorization: `Bearer ${oauthTokens.accessToken}`,
+ "Content-Type": "application/json",
+ "cal-api-version": "2024-06-11",
+ },
+ });
+
+ if (!userResponse.ok) {
+ throw new Error(`Failed to get user: ${userResponse.statusText}`);
+ }
+
+ const userData = await userResponse.json();
+ const username = userData?.data?.username;
+
+ const params = new URLSearchParams();
+ if (username) {
+ params.append("username", username);
+ }
+
+ const queryString = params.toString();
+ const endpoint = `${API_BASE_URL}/event-types${queryString ? `?${queryString}` : ""}`;
+
+ const response = await fetch(endpoint, {
+ headers: {
+ Authorization: `Bearer ${oauthTokens.accessToken}`,
+ "Content-Type": "application/json",
+ "cal-api-version": "2024-06-14",
+ },
+ });
+
+ if (!response.ok) {
+ throw new Error(`Failed to fetch event types: ${response.statusText}`);
+ }
+
+ const data = await response.json();
+
+ // Handle different response formats
+ if (Array.isArray(data)) {
+ return data;
+ } else if (data?.data && Array.isArray(data.data)) {
+ return data.data;
+ } else if (data?.eventTypes && Array.isArray(data.eventTypes)) {
+ return data.eventTypes;
+ }
+
+ return [];
+}
diff --git a/companion/extension/entrypoints/content.ts b/companion/extension/entrypoints/content.ts
new file mode 100644
index 0000000000..677d860db0
--- /dev/null
+++ b/companion/extension/entrypoints/content.ts
@@ -0,0 +1,2923 @@
+///
+
+export default defineContentScript({
+ matches: [""],
+ main() {
+ const existingSidebar = document.getElementById("cal-companion-sidebar");
+ if (existingSidebar) {
+ return;
+ }
+
+ // Initialize Gmail integration if on Gmail
+ // Wrapped in try-catch to prevent breaking Gmail if anything fails
+ if (window.location.hostname === "mail.google.com") {
+ try {
+ initGmailIntegration();
+ console.log("Cal.com: Gmail integration initialized successfully");
+ } catch (error) {
+ // Fail silently - don't break Gmail UI
+ console.error("Cal.com: Failed to initialize Gmail integration:", error);
+ }
+ }
+
+ let isVisible = false;
+ let isClosed = true;
+
+ // Create sidebar container
+ const sidebarContainer = document.createElement("div");
+ sidebarContainer.id = "cal-companion-sidebar";
+ sidebarContainer.style.position = "fixed";
+ sidebarContainer.style.top = "0";
+ sidebarContainer.style.right = "0";
+ sidebarContainer.style.pointerEvents = "none";
+ sidebarContainer.style.width = "100vw";
+ sidebarContainer.style.height = "100vh";
+ sidebarContainer.style.zIndex = "2147483647";
+ sidebarContainer.style.backgroundColor = "transparent";
+ sidebarContainer.style.transition = "none";
+ sidebarContainer.style.transform = "translateX(100%)";
+ sidebarContainer.style.display = "none";
+
+ // Create iframe container with max width
+ const iframeContainer = document.createElement("div");
+ iframeContainer.style.width = "100%";
+ iframeContainer.style.height = "100%";
+ iframeContainer.style.display = "flex";
+ iframeContainer.style.justifyContent = "flex-end";
+ iframeContainer.style.pointerEvents = "none";
+
+ // Create iframe
+ const iframe = document.createElement("iframe");
+ iframe.src = "http://localhost:8081";
+ iframe.style.width = "400px";
+ iframe.style.height = "100%";
+ iframe.style.border = "none";
+ iframe.style.borderRadius = "0";
+ iframe.style.backgroundColor = "transparent";
+ iframe.style.pointerEvents = "auto";
+ iframe.style.transition = "none";
+
+ iframeContainer.appendChild(iframe);
+
+ // Listen for messages from iframe to control width and handle OAuth
+ window.addEventListener("message", (event) => {
+ // Security: Only accept messages from our iframe's origin
+ // This prevents malicious scripts on the host page from manipulating the companion
+ const iframeOrigin = new URL(iframe.src).origin;
+ if (event.source !== iframe.contentWindow || event.origin !== iframeOrigin) {
+ return;
+ }
+
+ if (event.data.type === "cal-companion-expand") {
+ // Disable transition for instant expansion
+ iframe.style.transition = "none";
+ iframe.style.width = "100%";
+ iframeContainer.style.pointerEvents = "auto";
+ iframeContainer.style.justifyContent = "center";
+ } else if (event.data.type === "cal-companion-collapse") {
+ // Disable transition for instant collapse
+ iframe.style.transition = "none";
+ iframe.style.width = "400px";
+ iframeContainer.style.pointerEvents = "none";
+ iframeContainer.style.justifyContent = "flex-end";
+ } else if (event.data.type === "cal-extension-oauth-request") {
+ // Handle OAuth request from iframe
+ handleOAuthRequest(event.data.authUrl, iframe.contentWindow);
+ } else if (event.data.type === "cal-extension-token-exchange-request") {
+ // Handle token exchange request from iframe
+ handleTokenExchangeRequest(
+ event.data.tokenRequest,
+ event.data.tokenEndpoint,
+ event.data.state, // Pass state for CSRF validation
+ iframe.contentWindow
+ );
+ }
+ });
+
+ // Handle OAuth requests by forwarding to background script
+ function handleOAuthRequest(authUrl: string, iframeWindow: Window | null) {
+ // Send request to background script
+ chrome.runtime.sendMessage(
+ { action: "start-extension-oauth", authUrl: authUrl },
+ (response) => {
+ if (chrome.runtime.lastError) {
+ console.error(
+ "Failed to communicate with background script:",
+ chrome.runtime.lastError.message
+ );
+ iframeWindow?.postMessage(
+ {
+ type: "cal-extension-oauth-result",
+ success: false,
+ error: `Extension communication failed: ${chrome.runtime.lastError.message}`,
+ },
+ "*"
+ );
+ return;
+ }
+
+ // Forward the response back to iframe
+ if (response.success) {
+ iframeWindow?.postMessage(
+ {
+ type: "cal-extension-oauth-result",
+ success: true,
+ responseUrl: response.responseUrl,
+ },
+ "*"
+ );
+ } else {
+ iframeWindow?.postMessage(
+ {
+ type: "cal-extension-oauth-result",
+ success: false,
+ error: response.error || "OAuth flow failed",
+ },
+ "*"
+ );
+ }
+ }
+ );
+ }
+
+ // Handle token exchange requests by forwarding to background script
+ function handleTokenExchangeRequest(
+ tokenRequest: any,
+ tokenEndpoint: string,
+ state: string | undefined,
+ iframeWindow: Window | null
+ ) {
+ // Send request to background script
+ chrome.runtime.sendMessage(
+ {
+ action: "exchange-oauth-tokens",
+ tokenRequest: tokenRequest,
+ tokenEndpoint: tokenEndpoint,
+ state: state, // Include state for CSRF validation
+ },
+ (response) => {
+ if (chrome.runtime.lastError) {
+ console.error(
+ "Failed to communicate with background script:",
+ chrome.runtime.lastError.message
+ );
+ iframeWindow?.postMessage(
+ {
+ type: "cal-extension-token-exchange-result",
+ success: false,
+ error: `Extension communication failed: ${chrome.runtime.lastError.message}`,
+ },
+ "*"
+ );
+ return;
+ }
+
+ // Forward the response back to iframe
+ if (response.success) {
+ iframeWindow?.postMessage(
+ {
+ type: "cal-extension-token-exchange-result",
+ success: true,
+ tokens: response.tokens,
+ },
+ "*"
+ );
+ } else {
+ iframeWindow?.postMessage(
+ {
+ type: "cal-extension-token-exchange-result",
+ success: false,
+ error: response.error || "Token exchange failed",
+ },
+ "*"
+ );
+ }
+ }
+ );
+ }
+
+ sidebarContainer.appendChild(iframeContainer);
+
+ // Create floating buttons container
+ const buttonsContainer = document.createElement("div");
+ buttonsContainer.id = "cal-companion-buttons";
+ buttonsContainer.style.position = "fixed";
+ buttonsContainer.style.top = "20px";
+ buttonsContainer.style.right = "420px";
+ buttonsContainer.style.display = "flex";
+ buttonsContainer.style.flexDirection = "column";
+ buttonsContainer.style.gap = "8px";
+ buttonsContainer.style.zIndex = "2147483648";
+ buttonsContainer.style.transition = "none";
+ buttonsContainer.style.display = "none";
+
+ // Create toggle button
+ const toggleButton = document.createElement("button");
+ toggleButton.innerHTML = "◀";
+ toggleButton.style.width = "40px";
+ toggleButton.style.height = "40px";
+ toggleButton.style.borderRadius = "50%";
+ toggleButton.style.border = "1px solid white";
+ toggleButton.style.backgroundColor = "rgba(0, 0, 0, 0.5)";
+ toggleButton.style.backdropFilter = "blur(10px)";
+ toggleButton.style.color = "white";
+ toggleButton.style.cursor = "pointer";
+ toggleButton.style.fontSize = "16px";
+ toggleButton.style.boxShadow = "0 2px 8px rgba(0,0,0,0.2)";
+ toggleButton.style.transition = "all 0.2s ease";
+ toggleButton.style.display = "flex";
+ toggleButton.style.alignItems = "center";
+ toggleButton.style.justifyContent = "center";
+ toggleButton.title = "Toggle sidebar";
+
+ // Create close button
+ const closeButton = document.createElement("button");
+ closeButton.innerHTML = `
+
+
+
+`;
+ closeButton.style.width = "40px";
+ closeButton.style.height = "40px";
+ closeButton.style.borderRadius = "50%";
+ closeButton.style.border = "1px solid rgba(255, 255, 255, 0.5)";
+ closeButton.style.backgroundColor = "rgba(0, 0, 0, 0.5)";
+ closeButton.style.backdropFilter = "blur(10px)";
+ closeButton.style.color = "white";
+ closeButton.style.cursor = "pointer";
+ closeButton.style.fontSize = "16px";
+ closeButton.style.boxShadow = "0 2px 8px rgba(0,0,0,0.2)";
+ closeButton.style.transition = "all 0.2s ease";
+ closeButton.style.display = "flex";
+ closeButton.style.alignItems = "center";
+ closeButton.style.justifyContent = "center";
+ closeButton.title = "Close sidebar";
+
+ // Add hover effects
+ toggleButton.addEventListener("mouseenter", () => {
+ toggleButton.style.transform = "scale(1.1)";
+ });
+ toggleButton.addEventListener("mouseleave", () => {
+ toggleButton.style.transform = "scale(1)";
+ });
+
+ closeButton.addEventListener("mouseenter", () => {
+ closeButton.style.transform = "scale(1.1)";
+ });
+ closeButton.addEventListener("mouseleave", () => {
+ closeButton.style.transform = "scale(1)";
+ });
+
+ // Toggle functionality
+ toggleButton.addEventListener("click", () => {
+ if (isClosed) return;
+
+ isVisible = !isVisible;
+ if (isVisible) {
+ sidebarContainer.style.transform = "translateX(0)";
+ buttonsContainer.style.right = "420px";
+ toggleButton.innerHTML = `
+
+
+ `;
+ } else {
+ sidebarContainer.style.transform = "translateX(100%)";
+ buttonsContainer.style.right = "20px";
+ toggleButton.innerHTML = `
+
+
+ `;
+ }
+ });
+
+ // Close functionality
+ closeButton.addEventListener("click", () => {
+ isClosed = true;
+ isVisible = false;
+ sidebarContainer.style.display = "none";
+ buttonsContainer.style.display = "none";
+ });
+
+ // Add buttons to container
+ buttonsContainer.appendChild(toggleButton);
+ buttonsContainer.appendChild(closeButton);
+
+ // Add everything to DOM
+ document.body.appendChild(sidebarContainer);
+ document.body.appendChild(buttonsContainer);
+
+ // Listen for extension icon click
+ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
+ if (message.action === "icon-clicked") {
+ if (isClosed) {
+ // Reopen closed sidebar
+ isClosed = false;
+ isVisible = true;
+ sidebarContainer.style.display = "block";
+ buttonsContainer.style.display = "flex";
+ sidebarContainer.style.transform = "translateX(0)";
+ buttonsContainer.style.right = "420px";
+ toggleButton.innerHTML = `
+
+
+ `;
+ } else {
+ // Toggle visible sidebar
+ isVisible = !isVisible;
+ if (isVisible) {
+ sidebarContainer.style.transform = "translateX(0)";
+ buttonsContainer.style.right = "420px";
+ toggleButton.innerHTML = `
+
+
+ `;
+ } else {
+ sidebarContainer.style.transform = "translateX(100%)";
+ buttonsContainer.style.right = "20px";
+ toggleButton.innerHTML = `
+
+
+ `;
+ }
+ }
+ sendResponse({ success: true }); // Send response to acknowledge
+ }
+ });
+
+ // Gmail integration function
+ function initGmailIntegration() {
+ // Cache for event types (refreshed on page reload)
+ let eventTypesCache: any[] | null = null;
+ let cacheTimestamp: number | null = null;
+ const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes
+
+ // Function to inject Cal.com button as a new table cell after Send button
+ function injectCalButton() {
+ // Look specifically for Gmail compose Send buttons - they have specific attributes
+ // Gmail Send button usually has div[role="button"] with specific data attributes inside a td
+ const sendButtons = document.querySelectorAll(
+ 'div[role="button"][data-tooltip="Send (Ctrl-Enter)"], div[role="button"][data-tooltip*="Send"], div[role="button"][aria-label*="Send"]'
+ );
+
+ sendButtons.forEach((sendButton) => {
+ // Find the parent td cell that contains the send button
+ const sendButtonCell = sendButton.closest("td");
+ if (!sendButtonCell) return;
+
+ // Find the parent table row
+ const tableRow = sendButtonCell.closest("tr");
+ if (!tableRow) return;
+
+ // Check if we already injected our button for this specific send button
+ const existingCalButton = sendButtonCell.parentElement?.querySelector(
+ ".cal-companion-gmail-button"
+ );
+ if (existingCalButton) return;
+
+ // Additional check: make sure this is actually in a compose window
+ // Gmail compose windows have specific containers
+ const composeWindow = sendButton.closest('[role="dialog"]') || sendButton.closest(".nH");
+ if (!composeWindow) return;
+
+ // Create new table cell for Cal.com button
+ const calButtonCell = document.createElement("td");
+ calButtonCell.className = "cal-companion-gmail-button";
+ calButtonCell.style.cssText = `
+ padding: 0;
+ margin: 0;
+ vertical-align: middle;
+ border: none;
+ `;
+
+ // Create Cal.com button
+ const calButton = document.createElement("div");
+ calButton.style.cssText = `
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ margin: 2px 4px;
+ border-radius: 50%;
+ background-color: #000000;
+ border: 2px solid #ffffff;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
+ `;
+
+ // Add Cal.com icon (official logo)
+ calButton.innerHTML = `
+
+
+
+
+
+ `;
+
+ // Add hover effect
+ calButton.addEventListener("mouseenter", () => {
+ calButton.style.backgroundColor = "#333333";
+ calButton.style.transform = "scale(1.05)";
+ });
+
+ calButton.addEventListener("mouseleave", () => {
+ calButton.style.backgroundColor = "#000000";
+ calButton.style.transform = "scale(1)";
+ });
+
+ // Add click handler to show Cal.com menu
+ calButton.addEventListener("click", (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+
+ // Remove any existing menus
+ const existingMenu = document.querySelector(".cal-companion-gmail-menu");
+ if (existingMenu) {
+ existingMenu.remove();
+ return;
+ }
+
+ // Create menu
+ const menu = document.createElement("div");
+ menu.className = "cal-companion-gmail-menu";
+ menu.style.cssText = `
+ position: absolute;
+ bottom: 100%;
+ left: 0;
+ width: 400px;
+ max-height: 250px;
+ background: white;
+ border-radius: 8px;
+ box-shadow: 0 1px 2px 0 rgba(60,64,67,.3),0 2px 6px 2px rgba(60,64,67,.15);
+ font-family: "Google Sans",Roboto,RobotoDraft,Helvetica,Arial,sans-serif;
+ font-size: 14px;
+ z-index: 9999;
+ overflow-y: auto;
+ margin-bottom: 4px;
+ `;
+
+ // Show loading state
+ menu.innerHTML = `
+
+ Loading event types...
+
+ `;
+
+ // Array to track tooltips for cleanup
+ const tooltipsToCleanup: HTMLElement[] = [];
+
+ // Fetch event types from Cal.com API
+ fetchEventTypes(menu, tooltipsToCleanup);
+
+ // Position menu relative to button
+ calButtonCell.style.position = "relative";
+ calButtonCell.appendChild(menu);
+
+ // Close menu when clicking outside
+ setTimeout(() => {
+ document.addEventListener("click", function closeMenu(e) {
+ if (!menu.contains(e.target as Node)) {
+ // Clean up all tooltips
+ tooltipsToCleanup.forEach((tooltip) => tooltip.remove());
+ menu.remove();
+ document.removeEventListener("click", closeMenu);
+ }
+ });
+ }, 0);
+ });
+
+ function createTooltip(text, buttonElement) {
+ const tooltip = document.createElement("div");
+ tooltip.className = "cal-tooltip";
+ tooltip.style.cssText = `
+ position: fixed;
+ background-color: #1a1a1a;
+ color: white;
+ padding: 4px 8px;
+ border-radius: 6px;
+ font-size: 12px;
+ font-weight: 600;
+ white-space: nowrap;
+ pointer-events: none;
+ opacity: 0;
+ transition: opacity 0.15s ease;
+ z-index: 10002;
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+ display: none;
+ `;
+ tooltip.textContent = text;
+ document.body.appendChild(tooltip);
+
+ // Position tooltip on hover
+ const updatePosition = () => {
+ const rect = buttonElement.getBoundingClientRect();
+ tooltip.style.left = `${rect.left + rect.width / 2}px`;
+ tooltip.style.top = `${rect.top - 8}px`;
+ tooltip.style.transform = "translate(-50%, -100%)";
+ };
+
+ buttonElement.addEventListener("mouseenter", () => {
+ updatePosition();
+ tooltip.style.display = "block";
+ tooltip.style.opacity = "1";
+ });
+
+ buttonElement.addEventListener("mouseleave", () => {
+ tooltip.style.opacity = "0";
+ setTimeout(() => {
+ if (tooltip.style.opacity === "0") {
+ tooltip.style.display = "none";
+ }
+ }, 150);
+ });
+
+ return tooltip;
+ }
+
+ function openCalSidebar() {
+ // Open Cal.com sidebar or quick schedule flow
+ if (isClosed) {
+ // Trigger sidebar open
+ chrome.runtime.sendMessage({ action: "icon-clicked" });
+ } else {
+ // Toggle sidebar visibility
+ isVisible = !isVisible;
+ if (isVisible) {
+ sidebarContainer.style.transform = "translateX(0)";
+ } else {
+ sidebarContainer.style.transform = "translateX(100%)";
+ }
+ }
+ }
+
+ async function fetchEventTypes(menu, tooltipsToCleanup) {
+ try {
+ // Check cache first
+ const now = Date.now();
+ const isCacheValid =
+ eventTypesCache && cacheTimestamp && now - cacheTimestamp < CACHE_DURATION;
+
+ let eventTypes: any[] = [];
+
+ if (isCacheValid) {
+ // Use cached data
+ eventTypes = eventTypesCache!;
+ } else {
+ // Check if extension context is valid
+ if (!chrome.runtime?.id) {
+ throw new Error("Extension context invalidated. Please reload the page.");
+ }
+
+ // Fetch fresh data from background script
+ const response = await new Promise((resolve, reject) => {
+ try {
+ chrome.runtime.sendMessage({ action: "fetch-event-types" }, (response) => {
+ if (chrome.runtime.lastError) {
+ reject(new Error(chrome.runtime.lastError.message));
+ } else if (response && response.error) {
+ reject(new Error(response.error));
+ } else {
+ resolve(response);
+ }
+ });
+ } catch (err) {
+ reject(err);
+ }
+ });
+
+ if (response && (response as any).data) {
+ eventTypes = (response as any).data;
+ } else if (Array.isArray(response)) {
+ eventTypes = response;
+ } else {
+ eventTypes = [];
+ }
+
+ // Ensure eventTypes is an array
+ if (!Array.isArray(eventTypes)) {
+ eventTypes = [];
+ }
+
+ // Update cache
+ eventTypesCache = eventTypes;
+ cacheTimestamp = now;
+ }
+
+ // Clear loading state
+ menu.innerHTML = "";
+
+ if (eventTypes.length === 0) {
+ menu.innerHTML = `
+
+ No event types found
+
+ `;
+ return;
+ }
+
+ // Add event types - with additional safety checks
+ try {
+ eventTypes.forEach((eventType, index) => {
+ // Validate eventType object
+ if (!eventType || typeof eventType !== "object") {
+ return;
+ }
+
+ const title = eventType.title || "Untitled Event";
+ const length =
+ eventType.lengthInMinutes || eventType.length || eventType.duration || 30;
+ const description = eventType.description || "";
+
+ const menuItem = document.createElement("div");
+ menuItem.style.cssText = `
+ padding: 14px 16px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ transition: background-color 0.1s ease;
+ border-bottom: ${index < eventTypes.length - 1 ? "1px solid #E5E5EA" : "none"};
+ `;
+
+ // Create content wrapper
+ const contentWrapper = document.createElement("div");
+ contentWrapper.style.cssText = `
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ cursor: pointer;
+ margin-right: 12px;
+ position: relative;
+ min-width: 0;
+ overflow: hidden;
+ `;
+
+ contentWrapper.innerHTML = `
+
+ ${title}
+
+
+
+ ${length}min
+
+ ${description ? `${description} ` : ""}
+
+ `;
+
+ // Create tooltip for content wrapper
+ const contentTooltip = document.createElement("div");
+ contentTooltip.className = "cal-tooltip";
+ contentTooltip.style.cssText = `
+ position: fixed;
+ background-color: #1a1a1a;
+ color: white;
+ padding: 4px 8px;
+ border-radius: 6px;
+ font-size: 12px;
+ font-weight: 600;
+ white-space: nowrap;
+ pointer-events: none;
+ opacity: 0;
+ transition: opacity 0.15s ease;
+ z-index: 10002;
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+ display: none;
+ `;
+ contentTooltip.textContent = "Insert link";
+ document.body.appendChild(contentTooltip);
+ tooltipsToCleanup.push(contentTooltip);
+
+ // Show/hide tooltip
+ contentWrapper.addEventListener("mouseenter", (e) => {
+ const rect = contentWrapper.getBoundingClientRect();
+ // Shift right to better center on the visible content
+ contentTooltip.style.left = `${rect.left + rect.width / 2 + 80}px`;
+ contentTooltip.style.top = `${rect.top + 35}px`;
+ contentTooltip.style.transform = "translate(-50%, -100%)";
+ contentTooltip.style.display = "block";
+ contentTooltip.style.opacity = "1";
+ });
+ contentWrapper.addEventListener("mouseleave", () => {
+ contentTooltip.style.opacity = "0";
+ setTimeout(() => {
+ if (contentTooltip.style.opacity === "0") {
+ contentTooltip.style.display = "none";
+ }
+ }, 150);
+ });
+
+ // Add click handler to content wrapper to insert link
+ contentWrapper.addEventListener("click", (e) => {
+ e.stopPropagation();
+ // Remove tooltip
+ contentTooltip.remove();
+ menu.remove();
+ // Insert link into email text
+ insertEventTypeLink(eventType);
+ });
+
+ // Create buttons container
+ const buttonsContainer = document.createElement("div");
+ buttonsContainer.style.cssText = `
+ display: flex;
+ align-items: center;
+ gap: 0;
+ flex-shrink: 0;
+ `;
+
+ // Preview button
+ const previewBtn = document.createElement("button");
+ previewBtn.innerHTML = `
+
+
+
+
+
+ `;
+ previewBtn.style.cssText = `
+ width: 32px;
+ height: 32px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 1px solid #e5e5ea;
+ border-right: none;
+ border-radius: 6px 0 0 6px;
+ background: white;
+ cursor: pointer;
+ transition: background-color 0.1s ease;
+ padding: 0;
+ position: relative;
+ `;
+
+ // Create tooltip for preview button
+ const previewTooltip = createTooltip("Preview", previewBtn);
+ tooltipsToCleanup.push(previewTooltip);
+
+ previewBtn.addEventListener("click", (e) => {
+ e.stopPropagation();
+ const bookingUrl = `https://cal.com/${eventType.users?.[0]?.username || "user"}/${eventType.slug}`;
+ window.open(bookingUrl, "_blank");
+ });
+ previewBtn.addEventListener("mouseenter", () => {
+ previewBtn.style.backgroundColor = "#f8f9fa";
+ });
+ previewBtn.addEventListener("mouseleave", () => {
+ previewBtn.style.backgroundColor = "white";
+ });
+
+ // Copy link button
+ const copyBtn = document.createElement("button");
+ copyBtn.innerHTML = `
+
+
+
+
+ `;
+ copyBtn.style.cssText = `
+ width: 32px;
+ height: 32px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 1px solid #e5e5ea;
+ border-right: none;
+ background: white;
+ cursor: pointer;
+ transition: background-color 0.1s ease;
+ padding: 0;
+ position: relative;
+ `;
+
+ // Create tooltip for copy button
+ const copyTooltip = createTooltip("Copy link", copyBtn);
+ tooltipsToCleanup.push(copyTooltip);
+
+ copyBtn.addEventListener("click", (e) => {
+ e.stopPropagation();
+ // Copy to clipboard
+ const bookingUrl = `https://cal.com/${eventType.users?.[0]?.username || "user"}/${eventType.slug}`;
+ navigator.clipboard
+ .writeText(bookingUrl)
+ .then(() => {
+ showNotification("Link copied!", "success");
+ // Change icon to checkmark
+ copyBtn.innerHTML = `
+
+
+
+ `;
+ setTimeout(() => {
+ copyBtn.innerHTML = `
+
+
+
+
+ `;
+ }, 2000);
+ })
+ .catch(() => {
+ showNotification("Failed to copy link", "error");
+ });
+ });
+ copyBtn.addEventListener("mouseenter", () => {
+ copyBtn.style.backgroundColor = "#f8f9fa";
+ });
+ copyBtn.addEventListener("mouseleave", () => {
+ copyBtn.style.backgroundColor = "white";
+ });
+
+ // Edit button (replaces three dots menu)
+ const editBtn = document.createElement("button");
+ editBtn.innerHTML = `
+
+
+
+
+ `;
+ editBtn.style.cssText = `
+ width: 32px;
+ height: 32px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 1px solid #e5e5ea;
+ border-radius: 0 6px 6px 0;
+ background: white;
+ cursor: pointer;
+ transition: background-color 0.1s ease;
+ padding: 0;
+ position: relative;
+ `;
+
+ // Create tooltip for edit button
+ const editTooltip = createTooltip("Edit", editBtn);
+ tooltipsToCleanup.push(editTooltip);
+
+ editBtn.addEventListener("click", (e) => {
+ e.stopPropagation();
+ const editUrl = `https://app.cal.com/event-types/${eventType.id}`;
+ window.open(editUrl, "_blank");
+ });
+ editBtn.addEventListener("mouseenter", () => {
+ editBtn.style.backgroundColor = "#f8f9fa";
+ });
+ editBtn.addEventListener("mouseleave", () => {
+ editBtn.style.backgroundColor = "white";
+ });
+
+ // Assemble buttons
+ buttonsContainer.appendChild(previewBtn);
+ buttonsContainer.appendChild(copyBtn);
+ buttonsContainer.appendChild(editBtn);
+
+ // Hover effect for whole item
+ menuItem.addEventListener("mouseenter", () => {
+ menuItem.style.backgroundColor = "#f8f9fa";
+ });
+
+ menuItem.addEventListener("mouseleave", () => {
+ menuItem.style.backgroundColor = "transparent";
+ });
+
+ // Assemble menu item
+ menuItem.appendChild(contentWrapper);
+ menuItem.appendChild(buttonsContainer);
+
+ menu.appendChild(menuItem);
+ });
+ } catch (forEachError) {
+ menu.innerHTML = `
+
+ Error displaying event types
+
+ `;
+ }
+ } catch (error) {
+ menu.innerHTML = `
+
+ Failed to load event types
+
+
+ Error: ${(error as Error).message}
+
+
+ Close
+
+ `;
+ }
+ }
+
+ function insertEventTypeLink(eventType) {
+ // Construct the Cal.com booking link
+ const bookingUrl = `https://cal.com/${eventType.users?.[0]?.username || "user"}/${eventType.slug}`;
+
+ // Try to insert at cursor position in the compose field
+ const inserted = insertTextAtCursor(bookingUrl);
+
+ if (inserted) {
+ showNotification("Link inserted", "success");
+ } else {
+ // Fallback: copy to clipboard if insertion fails
+ navigator.clipboard
+ .writeText(bookingUrl)
+ .then(() => {
+ showNotification("Link copied!", "success");
+ })
+ .catch(() => {
+ showNotification("Failed to copy link", "error");
+ });
+ }
+ }
+
+ function copyEventTypeLink(eventType) {
+ // Construct the Cal.com booking link
+ const bookingUrl = `https://cal.com/${eventType.users?.[0]?.username || "user"}/${eventType.slug}`;
+
+ // Try to insert at cursor position in the compose field
+ const inserted = insertTextAtCursor(bookingUrl);
+
+ if (inserted) {
+ showNotification("Link inserted", "success");
+ } else {
+ // Fallback: copy to clipboard if insertion fails
+ navigator.clipboard
+ .writeText(bookingUrl)
+ .then(() => {
+ showNotification("Link copied!", "success");
+ })
+ .catch(() => {
+ showNotification("Failed to copy link", "error");
+ });
+ }
+ }
+
+ function insertTextAtCursor(text) {
+ // Find the active compose field
+ // Gmail uses contenteditable divs for the compose body
+ const composeBody =
+ document.querySelector('[role="textbox"][aria-label*="Message Body"]') ||
+ document.querySelector('[role="textbox"][g_editable="true"]') ||
+ document.querySelector('div[contenteditable="true"][role="textbox"]');
+
+ if (!composeBody) {
+ return false;
+ }
+
+ // Focus the compose field
+ (composeBody as HTMLElement).focus();
+
+ // Get the current selection
+ const selection = window.getSelection();
+ if (!selection || selection.rangeCount === 0) {
+ // If no selection, append to the end
+ const textNode = document.createTextNode(" " + text + " ");
+ composeBody.appendChild(textNode);
+
+ // Move cursor after inserted text
+ const range = document.createRange();
+ range.setStartAfter(textNode);
+ range.collapse(true);
+ selection?.removeAllRanges();
+ selection?.addRange(range);
+
+ return true;
+ }
+
+ // Insert at cursor position
+ const range = selection.getRangeAt(0);
+ range.deleteContents();
+
+ // Create a text node with the link (with spaces around it)
+ const textNode = document.createTextNode(" " + text + " ");
+ range.insertNode(textNode);
+
+ // Move cursor after inserted text
+ range.setStartAfter(textNode);
+ range.collapse(true);
+ selection.removeAllRanges();
+ selection.addRange(range);
+
+ // Trigger input event so Gmail knows content changed
+ composeBody.dispatchEvent(new Event("input", { bubbles: true }));
+ composeBody.dispatchEvent(new Event("change", { bubbles: true }));
+
+ return true;
+ }
+
+ function showNotification(message, type) {
+ const notification = document.createElement("div");
+ notification.style.cssText = `
+ position: fixed;
+ bottom: 80px;
+ right: 80px;
+ padding: 10px 12px;
+ background: ${type === "success" ? "#111827" : "#752522"};
+ color: white;
+ border: 1px solid #2b2b2b;
+ border-radius: 8px;
+ font-family: "Google Sans",Roboto,RobotoDraft,Helvetica,Arial,sans-serif;
+ font-size: 14px;
+ font-weight: 600;
+ z-index: 10000;
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.3), 0 2px 6px 2px rgba(0, 0, 0, 0.15);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ opacity: 0;
+ transform: translateY(10px);
+ transition: opacity 0.2s ease, transform 0.2s ease;
+ `;
+
+ // Add check icon for success
+ if (type === "success") {
+ const checkIcon = document.createElement("span");
+ checkIcon.innerHTML = `
+
+
+
+ `;
+ checkIcon.style.cssText = `
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ `;
+ notification.appendChild(checkIcon);
+ }
+
+ // Add message text
+ const messageText = document.createElement("span");
+ messageText.textContent = message;
+ notification.appendChild(messageText);
+
+ document.body.appendChild(notification);
+
+ // Trigger fade-in animation
+ requestAnimationFrame(() => {
+ notification.style.opacity = "1";
+ notification.style.transform = "translateY(0)";
+ });
+
+ // Fade out and remove after 3 seconds
+ setTimeout(() => {
+ notification.style.opacity = "0";
+ notification.style.transform = "translateY(10px)";
+ setTimeout(() => {
+ notification.remove();
+ }, 200);
+ }, 3000);
+ }
+
+ // Add tooltip
+ calButton.title = "Schedule with Cal.com";
+
+ // Add button to cell
+ calButtonCell.appendChild(calButton);
+
+ // Insert the new cell after the send button cell
+ if (sendButtonCell.nextSibling) {
+ tableRow.insertBefore(calButtonCell, sendButtonCell.nextSibling);
+ } else {
+ tableRow.appendChild(calButtonCell);
+ }
+ });
+ }
+
+ // Initial injection
+ setTimeout(injectCalButton, 1000);
+
+ // Watch for DOM changes (Gmail is a SPA)
+ const observer = new MutationObserver(() => {
+ injectCalButton();
+ });
+
+ observer.observe(document.body, {
+ childList: true,
+ subtree: true,
+ });
+
+ // Also inject on URL changes (Gmail navigation)
+ let currentUrl = window.location.href;
+ setInterval(() => {
+ if (window.location.href !== currentUrl) {
+ currentUrl = window.location.href;
+ setTimeout(injectCalButton, 500);
+ }
+ }, 1000);
+
+ // ========== Google Calendar Chip Integration ==========
+
+ /**
+ * Generate HTML email embed for Cal.com booking
+ * Based on the email embed feature in main Cal.com codebase
+ */
+ function generateEmailEmbedHTML(params: {
+ eventType: any;
+ username: string;
+ slots: any[];
+ duration: number;
+ timezone: string;
+ timezoneOffset: string;
+ }): string {
+ const { eventType, username, slots, duration, timezone, timezoneOffset } = params;
+
+ // Group slots by date
+ const slotsByDate: { [date: string]: any[] } = {};
+ slots.forEach((slot) => {
+ if (!slotsByDate[slot.isoDate]) {
+ slotsByDate[slot.isoDate] = [];
+ }
+ slotsByDate[slot.isoDate].push(slot);
+ });
+
+ // Generate time slot buttons HTML
+ const datesHTML = Object.keys(slotsByDate)
+ .sort()
+ .map((date) => {
+ const dateSlots = slotsByDate[date];
+ const formattedDate = dateSlots[0].date; // Already formatted like "Thu, 27 November"
+
+ const slotsHTML = dateSlots
+ .map((slot) => {
+ // URL-encode the timezone to handle special characters like "/"
+ const encodedTimezone = encodeURIComponent(timezone);
+ const bookingURL = `https://cal.com/${username}/${eventType.slug}?duration=${duration}&date=${slot.isoDate}&slot=${slot.isoTimestamp}&cal.tz=${encodedTimezone}`;
+
+ return `
+
+
+
+ `;
+ })
+ .join("");
+
+ return `
+
+
+
+
+
+ ${formattedDate}
+
+
+
+
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ // Complete HTML structure
+ return `
+
+
+ ${eventType.title}
+
+
+ Duration: ${duration} mins
+
+
+
+ Timezone: ${timezone} (${timezoneOffset})
+
+
+ ${datesHTML}
+
+
+ Powered by Cal.com
+
+
+
+ `;
+ }
+
+ /**
+ * Helper function to insert HTML into Gmail compose field
+ * @param html - The HTML content to insert
+ * @param targetComposeElement - Optional: The chip's compose element to ensure we insert in the correct window
+ */
+ function insertGmailHTML(html: string, targetComposeElement?: HTMLElement): boolean {
+ try {
+ // Validate input
+ if (!html || typeof html !== "string") {
+ console.warn("Cal.com: Invalid HTML to insert");
+ return false;
+ }
+
+ // If a target compose element is provided, find the compose body within its scope
+ let composeBody: Element | null = null;
+
+ if (targetComposeElement) {
+ const composeWindow =
+ targetComposeElement.closest('[role="dialog"]') ||
+ targetComposeElement.closest(".nH") ||
+ targetComposeElement.closest('div[contenteditable="true"]')?.parentElement;
+
+ if (composeWindow) {
+ composeBody =
+ composeWindow.querySelector('[role="textbox"][aria-label*="Message Body"]') ||
+ composeWindow.querySelector('[role="textbox"][g_editable="true"]') ||
+ composeWindow.querySelector('div[contenteditable="true"][role="textbox"]');
+ }
+ }
+
+ // Fallback: Try global selectors
+ if (!composeBody) {
+ composeBody =
+ document.querySelector('[role="textbox"][aria-label*="Message Body"]') ||
+ document.querySelector('[role="textbox"][g_editable="true"]') ||
+ document.querySelector('div[contenteditable="true"][role="textbox"]');
+ }
+
+ if (!composeBody) {
+ console.warn("Cal.com: Gmail compose field not found");
+ return false;
+ }
+
+ // Focus the compose body
+ try {
+ (composeBody as HTMLElement).focus();
+ } catch (focusError) {
+ console.warn("Cal.com: Failed to focus compose field:", focusError);
+ }
+
+ const selection = window.getSelection();
+ if (!selection || selection.rangeCount === 0) {
+ // No selection - append at end
+ try {
+ const tempDiv = document.createElement("div");
+ tempDiv.innerHTML = html;
+ composeBody.appendChild(tempDiv);
+ return true;
+ } catch (appendError) {
+ console.warn("Cal.com: Failed to append HTML:", appendError);
+ return false;
+ }
+ }
+
+ // Insert at cursor position
+ try {
+ const range = selection.getRangeAt(0);
+ range.deleteContents();
+
+ const tempDiv = document.createElement("div");
+ tempDiv.innerHTML = html;
+
+ // Insert all child nodes
+ const fragment = document.createDocumentFragment();
+ while (tempDiv.firstChild) {
+ fragment.appendChild(tempDiv.firstChild);
+ }
+
+ range.insertNode(fragment);
+ range.collapse(false);
+ selection.removeAllRanges();
+ selection.addRange(range);
+
+ // Trigger input events
+ (composeBody as HTMLElement).dispatchEvent(new Event("input", { bubbles: true }));
+ (composeBody as HTMLElement).dispatchEvent(new Event("change", { bubbles: true }));
+
+ return true;
+ } catch (insertError) {
+ console.warn("Cal.com: Failed to insert HTML at cursor:", insertError);
+ return false;
+ }
+ } catch (error) {
+ console.error("Cal.com: Critical error inserting HTML:", error);
+ return false;
+ }
+ }
+
+ /**
+ * Helper function to insert text into Gmail compose field
+ * @param text - The text to insert
+ * @param targetComposeElement - Optional: The chip's compose element to ensure we insert in the correct window
+ */
+ function insertGmailText(text: string, targetComposeElement?: HTMLElement): boolean {
+ try {
+ // Validate input
+ if (!text || typeof text !== "string") {
+ console.warn("Cal.com: Invalid text to insert");
+ return false;
+ }
+
+ // If a target compose element is provided, find the compose body within its scope
+ // Otherwise, fall back to the first compose field (legacy behavior)
+ let composeBody: Element | null = null;
+
+ if (targetComposeElement) {
+ // Find the compose window that contains the chip
+ const composeWindow =
+ targetComposeElement.closest('[role="dialog"]') ||
+ targetComposeElement.closest(".nH") ||
+ targetComposeElement.closest('div[contenteditable="true"]')?.parentElement;
+
+ if (composeWindow) {
+ // Look for compose body within this specific window
+ composeBody =
+ composeWindow.querySelector('[role="textbox"][aria-label*="Message Body"]') ||
+ composeWindow.querySelector('[role="textbox"][g_editable="true"]') ||
+ composeWindow.querySelector('div[contenteditable="true"][role="textbox"]');
+ }
+ }
+
+ // Fallback: Try global selectors if no target or if scoped search failed
+ if (!composeBody) {
+ composeBody =
+ document.querySelector('[role="textbox"][aria-label*="Message Body"]') ||
+ document.querySelector('[role="textbox"][g_editable="true"]') ||
+ document.querySelector('div[contenteditable="true"][role="textbox"]');
+ }
+
+ if (!composeBody) {
+ console.warn("Cal.com: Gmail compose field not found (structure may have changed)");
+ return false;
+ }
+
+ // Try to focus the compose body
+ try {
+ (composeBody as HTMLElement).focus();
+ } catch (focusError) {
+ console.warn("Cal.com: Failed to focus compose field:", focusError);
+ // Continue anyway - might still work
+ }
+
+ const selection = window.getSelection();
+ if (!selection || selection.rangeCount === 0) {
+ try {
+ const textNode = document.createTextNode(" " + text + " ");
+ composeBody.appendChild(textNode);
+ const range = document.createRange();
+ range.setStartAfter(textNode);
+ range.collapse(true);
+ selection?.removeAllRanges();
+ selection?.addRange(range);
+ return true;
+ } catch (appendError) {
+ console.warn("Cal.com: Failed to append text (fallback method):", appendError);
+ return false;
+ }
+ }
+
+ try {
+ const range = selection.getRangeAt(0);
+ range.deleteContents();
+ const textNode = document.createTextNode(" " + text + " ");
+ range.insertNode(textNode);
+ range.setStartAfter(textNode);
+ range.collapse(true);
+ selection.removeAllRanges();
+ selection.addRange(range);
+ composeBody.dispatchEvent(new Event("input", { bubbles: true }));
+ composeBody.dispatchEvent(new Event("change", { bubbles: true }));
+ return true;
+ } catch (insertError) {
+ console.warn("Cal.com: Failed to insert text at cursor:", insertError);
+ return false;
+ }
+ } catch (error) {
+ console.error(
+ "Cal.com: Critical error inserting text (Gmail structure may have changed):",
+ error
+ );
+ return false;
+ }
+ }
+
+ /**
+ * Helper function to show notification
+ * Fail silently if DOM manipulation fails (prevents breaking Gmail)
+ */
+ function showGmailNotification(message: string, type: "success" | "error"): void {
+ try {
+ const notification = document.createElement("div");
+ notification.style.cssText = `
+ position: fixed;
+ bottom: 80px;
+ right: 80px;
+ padding: 10px 12px;
+ background: ${type === "success" ? "#111827" : "#752522"};
+ color: white;
+ border: 1px solid #2b2b2b;
+ border-radius: 8px;
+ font-family: "Google Sans",Roboto,Arial,sans-serif;
+ font-size: 14px;
+ font-weight: 600;
+ z-index: 10000;
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.3), 0 2px 6px 2px rgba(0, 0, 0, 0.15);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ opacity: 0;
+ transform: translateY(10px);
+ transition: opacity 0.2s ease, transform 0.2s ease;
+ `;
+
+ if (type === "success") {
+ const icon = document.createElement("span");
+ icon.innerHTML = `
+
+
+
+ `;
+ icon.style.cssText =
+ "display: flex; align-items: center; justify-content: center; flex-shrink: 0;";
+ notification.appendChild(icon);
+ }
+
+ const text = document.createElement("span");
+ text.textContent = message;
+ notification.appendChild(text);
+
+ document.body.appendChild(notification);
+
+ requestAnimationFrame(() => {
+ try {
+ notification.style.opacity = "1";
+ notification.style.transform = "translateY(0)";
+ } catch (e) {
+ // Ignore animation errors
+ }
+ });
+
+ setTimeout(() => {
+ try {
+ notification.style.opacity = "0";
+ notification.style.transform = "translateY(10px)";
+ setTimeout(() => {
+ try {
+ notification.remove();
+ } catch (e) {
+ // Ignore removal errors
+ }
+ }, 200);
+ } catch (e) {
+ // Ignore animation errors
+ }
+ }, 3000);
+ } catch (error) {
+ // Silently fail - notifications are non-critical
+ console.warn("Cal.com: Failed to show notification:", error);
+ }
+ }
+
+ /**
+ * Auto-remove all Cal.com action bars before sending email
+ */
+ function setupAutoRemoveOnSend() {
+ try {
+ // Helper function to remove all action bars and marked Google chips
+ const removeAllActionBars = () => {
+ // Remove action bars
+ const allActionBars = document.querySelectorAll(".cal-companion-action-bar");
+ if (allActionBars.length > 0) {
+ console.log(`Cal.com: Removing ${allActionBars.length} action bar(s) before send`);
+ allActionBars.forEach((bar) => {
+ try {
+ // Call cleanup function to remove event listeners before removing DOM node
+ if ((bar as any).__cleanup) {
+ (bar as any).__cleanup();
+ }
+ bar.remove();
+ } catch (error) {
+ console.warn("Cal.com: Failed to remove action bar:", error);
+ }
+ });
+ }
+
+ // Remove Google chips that were marked for removal (user used Cal.com)
+ const markedChips = document.querySelectorAll(
+ '.gmail_chip[data-calcom-remove-on-send="true"]'
+ );
+ if (markedChips.length > 0) {
+ console.log(
+ `Cal.com: Removing ${markedChips.length} Google chip(s) before send (user used Cal.com)`
+ );
+ markedChips.forEach((chip) => {
+ try {
+ chip.remove();
+ } catch (error) {
+ console.warn("Cal.com: Failed to remove Google chip:", error);
+ }
+ });
+ }
+ };
+
+ // Method 1: Watch for clicks on Send button
+ document.addEventListener(
+ "click",
+ (e) => {
+ const target = e.target as HTMLElement;
+
+ // Check if the clicked element is a Send button
+ const isSendButton =
+ target.getAttribute("data-tooltip")?.includes("Send") ||
+ target.getAttribute("aria-label")?.includes("Send") ||
+ target.textContent?.trim() === "Send" ||
+ target.closest('[data-tooltip*="Send"]') ||
+ target.closest('[aria-label*="Send"]') ||
+ target
+ .closest('[role="button"][data-tooltip]')
+ ?.getAttribute("data-tooltip")
+ ?.includes("Send");
+
+ if (isSendButton) {
+ console.log("Cal.com: Send button clicked");
+ removeAllActionBars();
+ }
+ },
+ true
+ ); // Use capture phase
+
+ // Method 2: Watch for keyboard shortcuts (Ctrl+Enter / Cmd+Enter)
+ document.addEventListener(
+ "keydown",
+ (e) => {
+ const isCtrlOrCmd = e.ctrlKey || e.metaKey;
+ const isEnter = e.key === "Enter";
+
+ if (isCtrlOrCmd && isEnter) {
+ // Check if we're in a compose window
+ const activeElement = document.activeElement;
+ const isInCompose =
+ activeElement?.getAttribute("role") === "textbox" ||
+ activeElement?.getAttribute("contenteditable") === "true" ||
+ activeElement?.closest('[role="textbox"]');
+
+ if (isInCompose) {
+ console.log("Cal.com: Send keyboard shortcut detected (Ctrl/Cmd+Enter)");
+ removeAllActionBars();
+ }
+ }
+ },
+ true
+ );
+
+ // Note: Action bars are now overlays (like Grammarly), so they won't be included in emails.
+ // We keep the click and keyboard listeners for clean UI (removing overlays when sending).
+ // Removed the MutationObserver as it was too aggressive and removing action bars prematurely.
+
+ console.log("Cal.com: Auto-remove on send listeners added (click, keyboard)");
+ } catch (error) {
+ console.warn("Cal.com: Failed to setup auto-remove on send:", error);
+ }
+ }
+
+ /**
+ * Watch for Google Calendar scheduling chips and add Cal.com suggestion button
+ */
+ function watchForGoogleChips() {
+ try {
+ const observer = new MutationObserver((mutations) => {
+ try {
+ const chips = document.querySelectorAll(
+ ".gmail_chip.gmail_ad_hoc_v2_content:not([data-calcom-chip-processed])"
+ );
+
+ chips.forEach((chip) => {
+ try {
+ chip.setAttribute("data-calcom-chip-processed", "true");
+ handleGoogleChipDetected(chip as HTMLElement);
+ } catch (error) {
+ // Silently fail for individual chips to prevent breaking other chips
+ console.warn("Cal.com: Failed to process chip:", error);
+ }
+ });
+ } catch (error) {
+ // Silently fail to prevent Gmail UI from breaking
+ console.warn("Cal.com: Failed to detect chips:", error);
+ }
+ });
+
+ observer.observe(document.body, {
+ childList: true,
+ subtree: true,
+ });
+
+ // Also check for existing chips on page load
+ setTimeout(() => {
+ try {
+ const existingChips = document.querySelectorAll(
+ ".gmail_chip.gmail_ad_hoc_v2_content:not([data-calcom-chip-processed])"
+ );
+ existingChips.forEach((chip) => {
+ try {
+ chip.setAttribute("data-calcom-chip-processed", "true");
+ handleGoogleChipDetected(chip as HTMLElement);
+ } catch (error) {
+ console.warn("Cal.com: Failed to process existing chip:", error);
+ }
+ });
+ } catch (error) {
+ console.warn("Cal.com: Failed to find existing chips:", error);
+ }
+ }, 1000);
+ } catch (error) {
+ // Critical failure - log but don't break Gmail
+ console.error("Cal.com: Failed to initialize chip watcher:", error);
+ }
+ }
+
+ /**
+ * Handle when a Google Calendar chip is detected
+ */
+ function handleGoogleChipDetected(chipElement: HTMLElement) {
+ try {
+ console.log("Cal.com: handleGoogleChipDetected called");
+
+ // Validate chip element exists and is in DOM
+ if (!chipElement || !chipElement.isConnected) {
+ console.warn("Cal.com: Invalid or disconnected chip element");
+ return;
+ }
+
+ // Only show action bars in ACTIVE compose windows (not in sent/inbox emails)
+ // Check if chip is in a contenteditable area (compose window)
+ const composeBody = chipElement.closest('[contenteditable="true"]');
+
+ if (!composeBody) {
+ // Silently skip - chip not in compose area (likely in sent/inbox)
+ return;
+ }
+
+ const parsedData = parseGoogleChip(chipElement);
+
+ if (!parsedData || parsedData.slots.length === 0) {
+ // Silently skip - chip not fully loaded or invalid
+ return;
+ }
+
+ console.log(
+ `Cal.com: ✅ Google chip detected - ${parsedData.slots.length} slot${parsedData.slots.length > 1 ? "s" : ""} (${parsedData.detectedDuration}min)`
+ );
+
+ // Safely check for parent element
+ if (!chipElement.parentElement) {
+ return;
+ }
+
+ // Check if button already exists
+ const existingActionBar = chipElement.parentElement.querySelector(
+ ".cal-companion-action-bar"
+ );
+ const scheduleId = chipElement.getAttribute("data-ad-hoc-schedule-id");
+
+ if (existingActionBar) {
+ // Action bar exists - check if schedule ID or duration changed
+ const existingScheduleId = existingActionBar.getAttribute("data-schedule-id");
+ const existingDuration = existingActionBar.getAttribute("data-duration");
+
+ if (
+ existingScheduleId === scheduleId &&
+ existingDuration === String(parsedData.detectedDuration)
+ ) {
+ // Nothing changed, no need to recreate
+ return;
+ }
+ // Something changed - remove old action bar and create new one
+ console.log(`Cal.com: 🔄 Chip updated - ${parsedData.detectedDuration}min`);
+ try {
+ existingActionBar.remove();
+ } catch (e) {
+ // Silently ignore removal errors
+ }
+ }
+
+ // Watch for mutations on this chip to detect ANY changes
+ const observer = new MutationObserver(() => {
+ try {
+ const newScheduleId = chipElement.getAttribute("data-ad-hoc-schedule-id");
+ const actionBar = chipElement.parentElement?.querySelector(
+ ".cal-companion-action-bar"
+ );
+ const currentScheduleId = actionBar?.getAttribute("data-schedule-id");
+
+ // Check if schedule ID changed (this changes when time range or duration changes)
+ if (currentScheduleId && newScheduleId && currentScheduleId !== newScheduleId) {
+ console.log(`Cal.com: 🔄 Time range/duration changed`);
+ try {
+ actionBar?.remove();
+ // Recreate action bar with new data
+ handleGoogleChipDetected(chipElement);
+ } catch (e) {
+ // Silently ignore recreation errors
+ }
+ }
+ } catch (error) {
+ // Silently ignore observer errors - expected during DOM updates
+ }
+ });
+
+ try {
+ observer.observe(chipElement, {
+ childList: true,
+ subtree: true,
+ attributes: true,
+ attributeFilter: ["data-ad-hoc-v2-params"],
+ });
+ } catch (error) {
+ // Silently ignore observer setup errors
+ }
+
+ // Create our own action bar below the chip
+ const actionBar = document.createElement("div");
+ actionBar.className = "cal-companion-action-bar";
+ actionBar.setAttribute("contenteditable", "false"); // Make non-editable
+ actionBar.setAttribute("data-cal-companion", "true"); // Marker for our elements
+ actionBar.setAttribute("data-duration", String(parsedData.detectedDuration));
+ actionBar.setAttribute("data-slot-count", String(parsedData.slots.length));
+ if (scheduleId) {
+ actionBar.setAttribute("data-schedule-id", scheduleId);
+ }
+ actionBar.style.cssText = `
+ position: absolute;
+ z-index: 1000;
+ padding: 10px 14px;
+ background: #f8f9fa;
+ border: 1px solid #e0e0e0;
+ border-radius: 8px;
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ font-family: 'Google Sans', Roboto, Arial, sans-serif;
+ font-size: 14px;
+ width: 434px;
+ max-width: 100%;
+ box-sizing: border-box;
+ user-select: none;
+ pointer-events: auto;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ `;
+
+ // Cal.com icon with circular background
+ const icon = document.createElement("div");
+ icon.style.cssText = `
+ width: 32px;
+ height: 32px;
+ flex-shrink: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: #111827;
+ border-radius: 50%;
+ `;
+ icon.innerHTML = `
+
+
+
+
+
+ `;
+
+ // Text with duration indicator
+ const text = document.createElement("span");
+ text.textContent = `Suggest ${parsedData.detectedDuration}min Cal.com links`;
+ text.setAttribute("contenteditable", "false"); // Make text non-editable
+ text.style.cssText = `
+ color: #1f1f1f;
+ font-weight: 500;
+ flex: 1;
+ user-select: none;
+ `;
+
+ // Buttons container
+ const buttonsContainer = document.createElement("div");
+ buttonsContainer.style.cssText = `
+ display: flex;
+ gap: 8px;
+ flex-shrink: 0;
+ `;
+
+ // "Suggest Links" Button
+ const suggestButton = document.createElement("button");
+ suggestButton.className = "cal-companion-suggest-button";
+ suggestButton.textContent = "Suggest Links";
+ suggestButton.style.cssText = `
+ padding: 8px 16px;
+ background: #111827;
+ color: white;
+ border: none;
+ border-radius: 6px;
+ font-size: 14px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: background 0.2s ease;
+ font-family: 'Google Sans', Roboto, Arial, sans-serif;
+ `;
+
+ suggestButton.addEventListener("mouseenter", () => {
+ suggestButton.style.background = "#1f2937";
+ });
+
+ suggestButton.addEventListener("mouseleave", () => {
+ suggestButton.style.background = "#111827";
+ });
+
+ suggestButton.addEventListener("click", (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ // Re-parse the chip to get fresh data (in case it changed)
+ const freshParsedData = parseGoogleChip(chipElement);
+ console.log(
+ "Cal.com: Suggest Links clicked, fresh parsed data:",
+ freshParsedData?.detectedDuration,
+ "min"
+ );
+ if (freshParsedData && freshParsedData.slots.length > 0) {
+ showCalcomSuggestionMenu(chipElement, freshParsedData);
+ } else {
+ console.log("Cal.com: Failed to parse fresh data or no slots found");
+ }
+ });
+
+ // "Insert Embed" Button
+ const embedButton = document.createElement("button");
+ embedButton.className = "cal-companion-embed-button";
+ embedButton.textContent = "Insert Embed";
+ embedButton.style.cssText = `
+ padding: 8px 16px;
+ background: white;
+ color: #111827;
+ border: 1px solid #111827;
+ border-radius: 6px;
+ font-size: 14px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ font-family: 'Google Sans', Roboto, Arial, sans-serif;
+ `;
+
+ embedButton.addEventListener("mouseenter", () => {
+ embedButton.style.background = "#f8f9fa";
+ });
+
+ embedButton.addEventListener("mouseleave", () => {
+ embedButton.style.background = "white";
+ });
+
+ embedButton.addEventListener("click", async (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+
+ // Re-parse the chip to get fresh data
+ const freshParsedData = parseGoogleChip(chipElement);
+ console.log(
+ "Cal.com: Insert Embed clicked, fresh parsed data:",
+ freshParsedData?.detectedDuration,
+ "min"
+ );
+
+ if (!freshParsedData || freshParsedData.slots.length === 0) {
+ showGmailNotification("No time slots found", "error");
+ return;
+ }
+
+ // Fetch event types to get the matching one
+ try {
+ // Disable button and show loading state with opacity
+ embedButton.disabled = true;
+ embedButton.style.opacity = "0.6";
+ embedButton.style.cursor = "not-allowed";
+
+ const response: any = await new Promise((resolve, reject) => {
+ chrome.runtime.sendMessage({ action: "fetch-event-types" }, (result) => {
+ if (chrome.runtime.lastError) {
+ reject(new Error(chrome.runtime.lastError.message));
+ } else if (result && result.error) {
+ reject(new Error(result.error));
+ } else {
+ resolve(result);
+ }
+ });
+ });
+
+ const eventTypes = response?.data || (Array.isArray(response) ? response : []);
+ const matchingEventType = eventTypes.find(
+ (et: any) => et.lengthInMinutes === freshParsedData.detectedDuration
+ );
+
+ if (!matchingEventType) {
+ showGmailNotification(
+ `No ${freshParsedData.detectedDuration}min event type found`,
+ "error"
+ );
+ embedButton.disabled = false;
+ embedButton.style.opacity = "1";
+ embedButton.style.cursor = "pointer";
+ return;
+ }
+
+ const username = matchingEventType.users?.[0]?.username || "user";
+
+ // Generate HTML embed
+ const embedHTML = generateEmailEmbedHTML({
+ eventType: matchingEventType,
+ username: username,
+ slots: freshParsedData.slots,
+ duration: freshParsedData.detectedDuration,
+ timezone: freshParsedData.timezone,
+ timezoneOffset: freshParsedData.timezoneOffset,
+ });
+
+ // Insert HTML into Gmail
+ const inserted = insertGmailHTML(embedHTML, chipElement);
+
+ if (inserted) {
+ showGmailNotification("Cal.com embed inserted!", "success");
+ console.log("Cal.com: ✅ Email embed inserted successfully");
+
+ // Mark chip for removal on send (don't remove yet - keep it visible for user reference)
+ chipElement.setAttribute("data-calcom-remove-on-send", "true");
+ } else {
+ showGmailNotification("Failed to insert embed", "error");
+ }
+
+ embedButton.disabled = false;
+ embedButton.style.opacity = "1";
+ embedButton.style.cursor = "pointer";
+ } catch (error) {
+ console.error("Cal.com: Failed to insert embed:", error);
+
+ // Check if this is the "Extension context invalidated" error
+ const isContextInvalidated =
+ error instanceof Error && error.message.includes("Extension context invalidated");
+
+ if (isContextInvalidated) {
+ showGmailNotification("Extension reloaded - please reload Gmail", "error");
+ } else {
+ showGmailNotification("Failed to insert embed", "error");
+ }
+
+ embedButton.disabled = false;
+ embedButton.style.opacity = "1";
+ embedButton.style.cursor = "pointer";
+ }
+ });
+
+ buttonsContainer.appendChild(suggestButton);
+ buttonsContainer.appendChild(embedButton);
+
+ // Close button (×) to remove the action bar completely
+ const closeBtn = document.createElement("button");
+ closeBtn.className = "cal-companion-close-btn";
+ closeBtn.setAttribute("aria-label", "Close");
+ closeBtn.style.cssText = `
+ padding: 6px;
+ background: transparent;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.15s;
+ flex-shrink: 0;
+ color: #5f6368;
+ `;
+ closeBtn.innerHTML = `
+
+
+
+ `;
+
+ closeBtn.addEventListener("mouseenter", () => {
+ closeBtn.style.background = "#e8eaed";
+ });
+
+ closeBtn.addEventListener("mouseleave", () => {
+ closeBtn.style.background = "transparent";
+ });
+
+ closeBtn.addEventListener("click", (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+
+ // Remove the action bar completely
+ try {
+ // Call cleanup function if it exists
+ if ((actionBar as any).__cleanup) {
+ (actionBar as any).__cleanup();
+ }
+ actionBar.remove();
+ } catch (error) {
+ // Silently ignore removal errors
+ }
+ });
+
+ // Assemble action bar
+ try {
+ actionBar.appendChild(icon);
+ actionBar.appendChild(text);
+ actionBar.appendChild(buttonsContainer);
+ actionBar.appendChild(closeBtn);
+
+ // Position the action bar as an overlay (like Grammarly)
+ // This ensures it never becomes part of the email body
+ const positionActionBar = () => {
+ try {
+ if (!document.body.contains(chipElement)) {
+ // Chip removed, clean up
+ actionBar.remove();
+ return;
+ }
+
+ const chipRect = chipElement.getBoundingClientRect();
+
+ // Position below the chip with 8px gap
+ const top = chipRect.bottom + window.scrollY + 8;
+ const left = chipRect.left + window.scrollX;
+
+ actionBar.style.top = `${top}px`;
+ actionBar.style.left = `${left}px`;
+ } catch (error) {
+ // Silently ignore positioning errors
+ }
+ };
+
+ // Before appending, clean up orphaned or duplicate action bars for THIS chip only
+ // (happens when Google changes duration - creates new chip, but old action bar still floating)
+ const existingOverlayBars = document.querySelectorAll(".cal-companion-action-bar");
+ existingOverlayBars.forEach((bar) => {
+ const barScheduleId = bar.getAttribute("data-schedule-id");
+
+ // Only remove action bars that:
+ // 1. Belong to THIS chip (same schedule ID) - we're about to create a new one
+ // 2. OR their chip no longer exists (orphaned)
+ if (barScheduleId === scheduleId) {
+ // This bar belongs to the current chip - remove it (we'll create a fresh one)
+ try {
+ if ((bar as any).__cleanup) {
+ (bar as any).__cleanup();
+ }
+ bar.remove();
+ } catch (e) {
+ // Ignore removal errors
+ }
+ } else {
+ // This bar belongs to a different chip - check if that chip still exists
+ try {
+ const chipForBar = document.querySelector(
+ `.gmail_chip.gmail_ad_hoc_v2_content[data-ad-hoc-schedule-id="${barScheduleId}"]`
+ );
+ if (!chipForBar) {
+ // Chip is gone, this is an orphaned action bar - remove it
+ if ((bar as any).__cleanup) {
+ (bar as any).__cleanup();
+ }
+ bar.remove();
+ }
+ // Else: chip exists, keep this action bar (belongs to another chip)
+ } catch (e) {
+ // Ignore errors when checking
+ }
+ }
+ });
+
+ // Append to document.body (outside email content, like Grammarly)
+ document.body.appendChild(actionBar);
+
+ // Initial positioning with slight delay to ensure chip is rendered
+ setTimeout(() => {
+ positionActionBar();
+ }, 100);
+
+ // Update position on scroll and resize
+ const updatePosition = () => {
+ if (document.body.contains(chipElement) && document.body.contains(actionBar)) {
+ positionActionBar();
+ } else {
+ // Chip removed, clean up
+ try {
+ actionBar.remove();
+ } catch (e) {
+ // Ignore
+ }
+ }
+ };
+
+ window.addEventListener("scroll", updatePosition, true);
+ window.addEventListener("resize", updatePosition);
+
+ // Store cleanup function
+ (actionBar as any).__cleanup = () => {
+ window.removeEventListener("scroll", updatePosition, true);
+ window.removeEventListener("resize", updatePosition);
+ };
+ } catch (error) {
+ console.error("Cal.com: Failed to create or insert action bar:", error);
+ // Clean up if something failed
+ try {
+ actionBar.remove();
+ } catch (e) {
+ // Ignore cleanup errors
+ }
+ }
+ } catch (error) {
+ // Catch-all to prevent breaking Gmail UI
+ console.error("Cal.com: Error handling Google chip:", error);
+ return;
+ }
+ }
+
+ /**
+ * Show Cal.com suggestion menu for Google Calendar chip - CENTERED FULL-SCREEN MODAL
+ */
+ async function showCalcomSuggestionMenu(chipElement: HTMLElement, parsedData: any) {
+ console.log(
+ "Cal.com: Opening menu for",
+ parsedData.detectedDuration,
+ "min with",
+ parsedData.slots.length,
+ "slots"
+ );
+
+ // Remove existing menu if any (to support reopening with new data)
+ const existingBackdrop = document.querySelector(".cal-companion-google-chip-backdrop");
+ if (existingBackdrop) {
+ console.log("Cal.com: Removing existing backdrop");
+ existingBackdrop.remove();
+ // Wait a tick to ensure DOM is updated before creating new menu
+ await new Promise((resolve) => setTimeout(resolve, 0));
+ }
+
+ // Create full-screen backdrop (like FullScreenModal in companion)
+ const backdrop = document.createElement("div");
+ backdrop.className = "cal-companion-google-chip-backdrop";
+ backdrop.style.cssText = `
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 2147483647;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: rgba(0, 0, 0, 0.5);
+ backdrop-filter: blur(4px);
+ `;
+
+ // Create menu (centered modal content)
+ const menu = document.createElement("div");
+ menu.className = "cal-companion-google-chip-menu";
+ menu.style.cssText = `
+ width: 480px;
+ max-width: 90vw;
+ max-height: 80vh;
+ background: white;
+ border-radius: 16px;
+ box-shadow: 0 20px 60px rgba(0,0,0,0.3);
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ font-family: "Google Sans", Roboto, Arial, sans-serif;
+ pointer-events: auto;
+ `;
+
+ // Header
+ const header = document.createElement("div");
+ header.style.cssText = `
+ padding: 20px 24px;
+ border-bottom: 1px solid #e5e5ea;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ background: white;
+ flex-shrink: 0;
+ `;
+ header.innerHTML = `
+
+
📅 Suggest Cal.com Links
+
${parsedData.slots.length} time slot${parsedData.slots.length > 1 ? "s" : ""} • ${parsedData.detectedDuration}min each
+
+
+ `;
+
+ menu.appendChild(header);
+ backdrop.appendChild(menu);
+ document.body.appendChild(backdrop);
+
+ // Close on backdrop click
+ backdrop.addEventListener("click", (e) => {
+ if (e.target === backdrop) {
+ backdrop.remove();
+ }
+ });
+
+ // Close button click and hover
+ const closeBtn = header.querySelector(".close-menu") as HTMLButtonElement;
+ closeBtn.addEventListener("click", () => {
+ backdrop.remove();
+ });
+ closeBtn.addEventListener("mouseenter", () => {
+ closeBtn.style.background = "#f0f0f0";
+ });
+ closeBtn.addEventListener("mouseleave", () => {
+ closeBtn.style.background = "none";
+ });
+
+ // Create scrollable content container
+ const contentContainer = document.createElement("div");
+ contentContainer.className = "cal-companion-menu-content";
+ contentContainer.style.cssText = `
+ overflow-y: auto;
+ flex: 1;
+ `;
+ menu.appendChild(contentContainer);
+
+ // Show loading
+ const loadingDiv = document.createElement("div");
+ loadingDiv.style.cssText =
+ "padding: 32px 20px; text-align: center; color: #666; font-size: 14px;";
+ loadingDiv.textContent = "Loading event types...";
+ contentContainer.appendChild(loadingDiv);
+
+ try {
+ // Fetch event types (will use cache if available)
+ let eventTypes: any[] = [];
+
+ // Check cache first
+ const now = Date.now();
+ const isCacheValid =
+ eventTypesCache && cacheTimestamp && now - cacheTimestamp < CACHE_DURATION;
+
+ if (isCacheValid) {
+ eventTypes = eventTypesCache!;
+ } else {
+ // Fetch from background script
+ const response: any = await new Promise((resolve, reject) => {
+ chrome.runtime.sendMessage({ action: "fetch-event-types" }, (response) => {
+ if (chrome.runtime.lastError) {
+ reject(new Error(chrome.runtime.lastError.message));
+ } else if (response && response.error) {
+ reject(new Error(response.error));
+ } else {
+ resolve(response);
+ }
+ });
+ });
+
+ if (response && response.data) {
+ eventTypes = response.data;
+ } else if (Array.isArray(response)) {
+ eventTypes = response;
+ }
+
+ // Update cache
+ eventTypesCache = eventTypes;
+ cacheTimestamp = now;
+ }
+
+ if (!eventTypes || eventTypes.length === 0) {
+ loadingDiv.textContent = "No event types found";
+ return;
+ }
+
+ loadingDiv.remove();
+
+ // Filter event types by matching duration
+ const matchingEventTypes = eventTypes.filter(
+ (et: any) => et.lengthInMinutes === parsedData.detectedDuration
+ );
+
+ // If no matching event types, show create prompt
+ if (matchingEventTypes.length === 0) {
+ const noMatchDiv = document.createElement("div");
+ noMatchDiv.style.cssText = "padding: 20px 16px; text-align: center;";
+ noMatchDiv.innerHTML = `
+
+
+
+
+
+
+
+
+ No ${parsedData.detectedDuration}min Event Type Found
+
+
+ Google is suggesting ${parsedData.detectedDuration}-minute time slots, but you don't have any ${parsedData.detectedDuration}min event types configured.
+
+
+ Create ${parsedData.detectedDuration}min Event Type
+
+ `;
+ contentContainer.appendChild(noMatchDiv);
+
+ // Add click handler for create button
+ const createBtn = noMatchDiv.querySelector(".create-event-type-btn");
+ createBtn?.addEventListener("click", () => {
+ // Get username from any existing event type, or use a default
+ const username =
+ eventTypes.length > 0 ? eventTypes[0].users?.[0]?.username || "user" : "user";
+
+ const createUrl = `https://app.cal.com/event-types?dialog=new&eventPage=${username}`;
+ window.open(createUrl, "_blank");
+ showGmailNotification(
+ `Opening Cal.com to create ${parsedData.detectedDuration}min event type`,
+ "success"
+ );
+
+ console.log("Cal.com: Opening create URL:", createUrl);
+ });
+
+ createBtn?.addEventListener("mouseenter", (e) => {
+ (e.target as HTMLElement).style.backgroundColor = "#333";
+ });
+
+ createBtn?.addEventListener("mouseleave", (e) => {
+ (e.target as HTMLElement).style.backgroundColor = "#000";
+ });
+
+ return; // Don't show slots if no matching event types
+ }
+
+ // Event type selector (only show matching event types)
+ const selectorDiv = document.createElement("div");
+ selectorDiv.style.cssText =
+ "padding: 12px 16px; border-bottom: 1px solid #e5e5ea; background: #f8f9fa; position: relative; z-index: 5; pointer-events: auto;";
+
+ // Create label
+ const label = document.createElement("label");
+ label.style.cssText =
+ "font-size: 12px; color: #666; font-weight: 500; display: block; margin-bottom: 6px;";
+ label.textContent =
+ matchingEventTypes.length === 1
+ ? `Event Type (${parsedData.detectedDuration}min)`
+ : `Select ${parsedData.detectedDuration}min Event Type`;
+ selectorDiv.appendChild(label);
+
+ // Track selected event type
+ let selectedEventTypeIndex = 0;
+
+ if (matchingEventTypes.length === 1) {
+ // Single event type - just show it
+ const displayDiv = document.createElement("div");
+ displayDiv.style.cssText = `
+ padding: 10px 12px;
+ border: 1px solid #e5e5ea;
+ border-radius: 8px;
+ font-size: 14px;
+ background: white;
+ font-family: inherit;
+ color: #000;
+ font-weight: 500;
+ box-sizing: border-box;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ `;
+ displayDiv.textContent = matchingEventTypes[0].title;
+ selectorDiv.appendChild(displayDiv);
+ } else {
+ // Multiple event types - custom dropdown
+ const customDropdown = document.createElement("div");
+ customDropdown.className = "custom-event-type-dropdown";
+ customDropdown.style.cssText = "position: relative;";
+
+ // Selected display button
+ const selectedDisplay = document.createElement("div");
+ selectedDisplay.style.cssText = `
+ padding: 10px 12px;
+ border: 1px solid #e5e5ea;
+ border-radius: 8px;
+ font-size: 14px;
+ background: white;
+ font-family: inherit;
+ color: #000;
+ cursor: pointer;
+ box-sizing: border-box;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ transition: border-color 0.15s;
+ pointer-events: auto;
+ `;
+ selectedDisplay.innerHTML = `
+ ${matchingEventTypes[0].title} (${matchingEventTypes[0].lengthInMinutes}min)
+
+
+
+ `;
+
+ // Dropdown options container
+ const optionsContainer = document.createElement("div");
+ optionsContainer.style.cssText = `
+ position: absolute;
+ top: 100%;
+ left: 0;
+ right: 0;
+ margin-top: 4px;
+ background: white;
+ border: 1px solid #e5e5ea;
+ border-radius: 8px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+ max-height: 200px;
+ overflow-y: auto;
+ display: none;
+ z-index: 1000;
+ pointer-events: auto;
+ `;
+
+ // Create options
+ matchingEventTypes.forEach((et: any, index: number) => {
+ const option = document.createElement("div");
+ option.className = "dropdown-option";
+ option.style.cssText = `
+ padding: 10px 12px;
+ font-size: 14px;
+ color: #000;
+ cursor: pointer;
+ transition: background-color 0.1s;
+ border-bottom: ${index < matchingEventTypes.length - 1 ? "1px solid #f0f0f0" : "none"};
+ pointer-events: auto;
+ `;
+ option.textContent = `${et.title} (${et.lengthInMinutes}min)`;
+ option.setAttribute("data-index", index.toString());
+
+ // Hover effect
+ option.addEventListener("mouseenter", () => {
+ option.style.backgroundColor = "#f8f9fa";
+ });
+ option.addEventListener("mouseleave", () => {
+ option.style.backgroundColor = "white";
+ });
+
+ // Click to select
+ option.addEventListener("click", (e) => {
+ e.stopPropagation();
+ selectedEventTypeIndex = index;
+ const selectedText = selectedDisplay.querySelector(".selected-text");
+ if (selectedText) {
+ selectedText.textContent = `${et.title} (${et.lengthInMinutes}min)`;
+ }
+ optionsContainer.style.display = "none";
+ console.log("Cal.com: Event type changed to:", et.slug);
+ });
+
+ optionsContainer.appendChild(option);
+ });
+
+ // Toggle dropdown on click
+ selectedDisplay.addEventListener("click", (e) => {
+ e.stopPropagation();
+ const isOpen = optionsContainer.style.display === "block";
+ optionsContainer.style.display = isOpen ? "none" : "block";
+ selectedDisplay.style.borderColor = isOpen ? "#e5e5ea" : "#000";
+ });
+
+ // Hover effect on selected display
+ selectedDisplay.addEventListener("mouseenter", () => {
+ selectedDisplay.style.borderColor = "#000";
+ });
+ selectedDisplay.addEventListener("mouseleave", () => {
+ if (optionsContainer.style.display !== "block") {
+ selectedDisplay.style.borderColor = "#e5e5ea";
+ }
+ });
+
+ customDropdown.appendChild(selectedDisplay);
+ customDropdown.appendChild(optionsContainer);
+ selectorDiv.appendChild(customDropdown);
+
+ // Close dropdown when clicking outside (with cleanup)
+ const closeDropdown = (e: MouseEvent) => {
+ if (!customDropdown.contains(e.target as Node)) {
+ optionsContainer.style.display = "none";
+ selectedDisplay.style.borderColor = "#e5e5ea";
+ }
+ };
+ document.addEventListener("click", closeDropdown);
+
+ // Clean up listener when modal closes
+ backdrop.addEventListener(
+ "remove",
+ () => {
+ document.removeEventListener("click", closeDropdown);
+ },
+ { once: true }
+ );
+ }
+
+ contentContainer.appendChild(selectorDiv);
+
+ // Time slots list
+ const slotsContainer = document.createElement("div");
+ slotsContainer.style.cssText = "padding: 12px;";
+
+ parsedData.slots.forEach((slot: any, index: number) => {
+ const slotItem = document.createElement("div");
+ slotItem.style.cssText = `
+ padding: 14px;
+ margin: 6px 0;
+ border: 1px solid #e5e5ea;
+ border-radius: 10px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ transition: all 0.15s;
+ cursor: default;
+ background: white;
+ `;
+
+ slotItem.innerHTML = `
+
+
${slot.date}
+
${slot.startTime} – ${slot.endTime}
+
+ Insert Link
+ `;
+
+ // Add pointer events to slot item
+ slotItem.style.pointerEvents = "auto";
+
+ // Hover effect on entire slot item
+ slotItem.addEventListener("mouseenter", () => {
+ console.log("Cal.com: Mouse entered slot", index);
+ slotItem.style.borderColor = "#000";
+ slotItem.style.backgroundColor = "#f8f9fa";
+ const btn = slotItem.querySelector(".insert-slot-btn") as HTMLElement;
+ if (btn) btn.style.backgroundColor = "#333";
+ });
+
+ slotItem.addEventListener("mouseleave", () => {
+ slotItem.style.borderColor = "#e5e5ea";
+ slotItem.style.backgroundColor = "white";
+ const btn = slotItem.querySelector(".insert-slot-btn") as HTMLElement;
+ if (btn) btn.style.backgroundColor = "#000";
+ });
+
+ slotsContainer.appendChild(slotItem);
+ });
+
+ contentContainer.appendChild(slotsContainer);
+
+ // Add event listeners for insert buttons
+ const insertButtons = menu.querySelectorAll(".insert-slot-btn");
+
+ console.log("Cal.com: Found", insertButtons.length, "insert buttons");
+
+ insertButtons.forEach((btn) => {
+ btn.addEventListener("click", (e) => {
+ console.log("Cal.com: Insert button clicked!");
+ e.preventDefault();
+ e.stopPropagation();
+ const slotIndex = parseInt(btn.getAttribute("data-slot-index")!);
+ const slot = parsedData.slots[slotIndex];
+ console.log("Cal.com: Inserting link for slot", slotIndex, slot);
+
+ // Get selected event type from the tracked index
+ const selectedEventType = matchingEventTypes[selectedEventTypeIndex];
+ const selectedSlug = selectedEventType.slug;
+ const selectedUsername = selectedEventType.users?.[0]?.username || "user";
+
+ // Generate Cal.com URL with slot parameters
+ const baseUrl = `https://cal.com/${selectedUsername}/${selectedSlug}`;
+ const params = new URLSearchParams({
+ overlayCalendar: "true",
+ date: slot.isoDate,
+ slot: slot.isoTimestamp,
+ });
+ const calcomUrl = `${baseUrl}?${params.toString()}`;
+
+ console.log("Cal.com: Generated URL:", calcomUrl);
+
+ // Insert link into Gmail compose (pass chipElement to target the correct compose window)
+ const inserted = insertGmailText(calcomUrl, chipElement);
+
+ if (inserted) {
+ showGmailNotification("Cal.com link inserted!", "success");
+ backdrop.remove();
+
+ // Mark chip for removal on send (don't remove yet - keep it visible for user reference)
+ chipElement.setAttribute("data-calcom-remove-on-send", "true");
+ } else {
+ showGmailNotification("Failed to insert link", "error");
+ }
+ });
+ });
+ } catch (error) {
+ console.error("Error showing Cal.com suggestion menu:", error);
+ loadingDiv.remove();
+
+ // Show user-friendly error message
+ const errorDiv = document.createElement("div");
+ errorDiv.style.cssText = "padding: 20px 16px; text-align: center;";
+
+ const isContextInvalidated =
+ error instanceof Error && error.message.includes("Extension context invalidated");
+
+ errorDiv.innerHTML = `
+
+
+
+
+
+
+
+
+ ${isContextInvalidated ? "Extension Reloaded" : "Failed to Load"}
+
+
+ ${
+ isContextInvalidated
+ ? "The extension was updated. Please reload this page to continue."
+ : "Failed to load event types. Please try again."
+ }
+
+ ${
+ isContextInvalidated
+ ? `
+ Reload Page
+ `
+ : ""
+ }
+ `;
+
+ contentContainer.appendChild(errorDiv);
+
+ // Add reload handler if context invalidated
+ if (isContextInvalidated) {
+ const reloadBtn = errorDiv.querySelector(".reload-page-btn");
+ reloadBtn?.addEventListener("click", () => {
+ window.location.reload();
+ });
+ reloadBtn?.addEventListener("mouseenter", (e) => {
+ (e.target as HTMLElement).style.backgroundColor = "#ff5252";
+ });
+ reloadBtn?.addEventListener("mouseleave", (e) => {
+ (e.target as HTMLElement).style.backgroundColor = "#ff6b6b";
+ });
+ }
+ }
+ }
+
+ /**
+ * Parse Google Calendar scheduling chip
+ * Returns null if structure has changed or parsing fails (fail gracefully)
+ */
+ function parseGoogleChip(chipElement: HTMLElement): any {
+ try {
+ // Validate input
+ if (!chipElement || typeof chipElement.getAttribute !== "function") {
+ console.warn("Cal.com: Invalid chip element passed to parser");
+ return null;
+ }
+
+ // Get schedule ID - if this is missing, this might not be a valid chip
+ const scheduleId = chipElement.getAttribute("data-ad-hoc-schedule-id");
+
+ if (!scheduleId) {
+ // Silently return - this is likely not a fully-loaded chip
+ // (happens frequently during Gmail DOM updates)
+ return null;
+ }
+
+ console.log(
+ "Cal.com: Valid chip detected - Schedule ID:",
+ scheduleId?.slice(0, 20) + "..."
+ );
+
+ // Parse timezone (non-critical - fallback to UTC if structure changed)
+ let timezone = "UTC";
+ let timezoneOffset = "GMT+00:00";
+
+ try {
+ // First, try to get the IANA timezone from data-ad-hoc-v2-params
+ const paramsAttr = chipElement.getAttribute("data-ad-hoc-v2-params");
+ console.log("Cal.com: data-ad-hoc-v2-params:", paramsAttr);
+
+ if (paramsAttr) {
+ // The timezone is at the end of the params string, like: "Asia/Kolkata"
+ // Try multiple patterns as Gmail might format it differently
+ let tzMatch = paramsAttr.match(/"([^&]+)"\]/);
+
+ // Also try without HTML entities
+ if (!tzMatch) {
+ tzMatch = paramsAttr.match(/"([^"]+)"\]/);
+ }
+
+ // Also try with escaped quotes
+ if (!tzMatch) {
+ tzMatch = paramsAttr.match(/\\"([^\\]+)\\"\]/);
+ }
+
+ if (tzMatch && tzMatch[1]) {
+ timezone = tzMatch[1]; // e.g., "Asia/Kolkata"
+ console.log("Cal.com: ✅ Parsed IANA timezone from data attribute:", timezone);
+ } else {
+ console.warn("Cal.com: ⚠️ Failed to extract timezone from params attribute");
+ }
+ } else {
+ console.warn("Cal.com: ⚠️ No data-ad-hoc-v2-params attribute found");
+ }
+
+ // Also get the display timezone and offset from the UI text
+ const timezoneText = chipElement.querySelector("td")?.textContent?.trim() || "";
+ const timezoneMatch = timezoneText.match(/^(.+?)\s*-\s*(.+?)\s*\((.+?)\)$/);
+
+ if (timezoneMatch) {
+ timezoneOffset = timezoneMatch[3]?.trim() || "GMT+00:00";
+ console.log("Cal.com: Parsed timezone offset from UI:", timezoneOffset);
+ }
+ } catch (tzError) {
+ // Non-critical error - continue with default timezone
+ console.warn("Cal.com: Failed to parse timezone, using UTC:", tzError);
+ }
+
+ // Find all time slot links - critical for functionality
+ let slotLinks: Element[] = [];
+ try {
+ slotLinks = Array.from(chipElement.querySelectorAll("a[href*='slotStartTime']"));
+ } catch (error) {
+ console.warn("Cal.com: Failed to find slot links:", error);
+ return null;
+ }
+
+ if (slotLinks.length === 0) {
+ // Gmail structure might have changed or chip not fully loaded
+ return null;
+ }
+
+ const slots: any[] = [];
+ let detectedDuration = 60;
+
+ slotLinks.forEach((link) => {
+ try {
+ const href = (link as HTMLAnchorElement).href;
+ if (!href) return;
+
+ const url = new URL(href);
+
+ const slotStartTime = url.searchParams.get("slotStartTime");
+ const slotDurationMinutes = url.searchParams.get("slotDurationMinutes");
+
+ if (!slotStartTime || !slotDurationMinutes) return;
+
+ const durationMinutes = parseInt(slotDurationMinutes, 10);
+ if (isNaN(durationMinutes) || durationMinutes <= 0) return;
+
+ detectedDuration = durationMinutes;
+
+ const startTimestamp = parseInt(slotStartTime, 10);
+ if (isNaN(startTimestamp)) return;
+
+ const startDate = new Date(startTimestamp);
+ const endDate = new Date(startDate.getTime() + durationMinutes * 60 * 1000);
+
+ // Validate dates
+ if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) return;
+
+ const dateOptions: Intl.DateTimeFormatOptions = {
+ weekday: "short",
+ day: "numeric",
+ month: "long",
+ };
+ const timeOptions: Intl.DateTimeFormatOptions = {
+ hour: "numeric",
+ minute: "2-digit",
+ hour12: true,
+ };
+
+ const date = startDate.toLocaleDateString("en-US", dateOptions);
+ const startTime = startDate.toLocaleTimeString("en-US", timeOptions).toLowerCase();
+ const endTime = endDate.toLocaleTimeString("en-US", timeOptions).toLowerCase();
+
+ const isoDate = startDate.toISOString().split("T")[0];
+ const isoTimestamp = startDate.toISOString();
+
+ slots.push({
+ date,
+ startTime,
+ endTime,
+ durationMinutes,
+ isoDate,
+ isoTimestamp,
+ googleUrl: href,
+ });
+ } catch (slotError) {
+ // Skip individual slot if it fails - don't break entire parsing
+ console.warn("Cal.com: Failed to parse individual slot:", slotError);
+ }
+ });
+
+ if (slots.length === 0) {
+ // No valid slots found - Gmail structure might have changed
+ return null;
+ }
+
+ console.log(
+ `Cal.com: ✅ Parsed chip - ${slots.length} slots, ${detectedDuration}min, timezone: ${timezone}`
+ );
+
+ return {
+ scheduleId,
+ timezone,
+ timezoneOffset,
+ slots,
+ detectedDuration,
+ };
+ } catch (error) {
+ // Critical error in parsing - fail gracefully without breaking Gmail
+ console.warn(
+ "Cal.com: Failed to parse Google chip (Gmail structure may have changed):",
+ error
+ );
+ return null;
+ }
+ }
+
+ // Start watching for Google Calendar chips
+ watchForGoogleChips();
+
+ // Setup auto-remove action bars before sending email
+ setupAutoRemoveOnSend();
+ }
+ },
+});
+
+function defineContentScript(config: { matches: string[]; main: () => void }) {
+ return config;
+}
diff --git a/companion/extension/public/icon-128.png b/companion/extension/public/icon-128.png
new file mode 100644
index 0000000000..6ad39d9bfb
Binary files /dev/null and b/companion/extension/public/icon-128.png differ
diff --git a/companion/extension/public/icon-16.png b/companion/extension/public/icon-16.png
new file mode 100644
index 0000000000..811fcdf3c4
Binary files /dev/null and b/companion/extension/public/icon-16.png differ
diff --git a/companion/extension/public/icon-48.png b/companion/extension/public/icon-48.png
new file mode 100644
index 0000000000..f570ab73d5
Binary files /dev/null and b/companion/extension/public/icon-48.png differ
diff --git a/companion/extension/public/icon.png b/companion/extension/public/icon.png
new file mode 100644
index 0000000000..2d352eca86
Binary files /dev/null and b/companion/extension/public/icon.png differ
diff --git a/companion/extension/public/manifest.json b/companion/extension/public/manifest.json
new file mode 100644
index 0000000000..9c3a63ef08
--- /dev/null
+++ b/companion/extension/public/manifest.json
@@ -0,0 +1,22 @@
+{
+ "manifest_version": 3,
+ "name": "Cal.com Companion",
+ "version": "1.7.0",
+ "description": "Your calendar companion for quick booking and scheduling",
+ "permissions": ["activeTab", "http://localhost:8081/*", "identity"],
+ "content_security_policy": {
+ "extension_pages": "script-src 'self'; object-src 'self'; frame-src 'self' http://localhost:8081;"
+ },
+ "action": {
+ "default_title": "Cal.com Companion"
+ },
+ "background": {
+ "service_worker": "background.js"
+ },
+ "content_scripts": [
+ {
+ "matches": [""],
+ "js": ["content-scripts/content.js"]
+ }
+ ]
+}
diff --git a/companion/extension/public/oauth/callback.html b/companion/extension/public/oauth/callback.html
new file mode 100644
index 0000000000..89188bb930
--- /dev/null
+++ b/companion/extension/public/oauth/callback.html
@@ -0,0 +1,10 @@
+
+
+
+
+ Cal.com OAuth Callback
+
+
+ Processing authentication...
+
+
diff --git a/companion/global.css b/companion/global.css
new file mode 100644
index 0000000000..28214b8222
--- /dev/null
+++ b/companion/global.css
@@ -0,0 +1,24 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@layer base {
+ /* Force light color scheme for all web components */
+ :root {
+ color-scheme: light only;
+ }
+
+ html {
+ color-scheme: light;
+ }
+
+ * {
+ color-scheme: light;
+ }
+
+ input:focus {
+ --tw-ring-color: rgb(0 0 0);
+ --tw-border-opacity: 1;
+ border-color: rgb(0 0 0);
+ }
+}
diff --git a/companion/index.js b/companion/index.js
new file mode 100644
index 0000000000..80d3d998f1
--- /dev/null
+++ b/companion/index.js
@@ -0,0 +1 @@
+import "expo-router/entry";
diff --git a/companion/metro.config.js b/companion/metro.config.js
new file mode 100644
index 0000000000..b0963fe7f7
--- /dev/null
+++ b/companion/metro.config.js
@@ -0,0 +1,6 @@
+const { getDefaultConfig } = require("expo/metro-config");
+const { withNativeWind } = require("nativewind/metro");
+
+const config = getDefaultConfig(__dirname);
+
+module.exports = withNativeWind(config, { input: "./global.css" });
diff --git a/companion/nativewind-env.d.ts b/companion/nativewind-env.d.ts
new file mode 100644
index 0000000000..a13e3136bb
--- /dev/null
+++ b/companion/nativewind-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/companion/package-lock.json b/companion/package-lock.json
new file mode 100644
index 0000000000..b22faeeba1
--- /dev/null
+++ b/companion/package-lock.json
@@ -0,0 +1,16506 @@
+{
+ "name": "cal-companion",
+ "version": "1.7.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "cal-companion",
+ "version": "1.7.0",
+ "dependencies": {
+ "@expo/ui": "^0.2.0-beta.7",
+ "@expo/vector-icons": "^15.0.3",
+ "@react-native-segmented-control/segmented-control": "^2.5.7",
+ "@types/react": "~19.1.10",
+ "@types/react-dom": "~19.1.7",
+ "base64-js": "^1.5.1",
+ "expo": "~54.0.0",
+ "expo-auth-session": "^7.0.9",
+ "expo-constants": "~18.0.10",
+ "expo-crypto": "^15.0.7",
+ "expo-device": "^8.0.9",
+ "expo-glass-effect": "~0.1.6",
+ "expo-linking": "~8.0.8",
+ "expo-router": "~6.0.14",
+ "expo-secure-store": "^15.0.7",
+ "expo-status-bar": "~3.0.8",
+ "expo-web-browser": "^15.0.9",
+ "nativewind": "^4.2.1",
+ "react": "^19.1.0",
+ "react-dom": "^19.1.0",
+ "react-native": "0.81.5",
+ "react-native-context-menu-view": "^1.20.0",
+ "react-native-gesture-handler": "^2.29.1",
+ "react-native-reanimated": "~3.17.4",
+ "react-native-safe-area-context": "5.4.0",
+ "react-native-svg": "^15.15.0",
+ "react-native-web": "^0.21.2",
+ "react-native-worklets": "^0.6.1"
+ },
+ "devDependencies": {
+ "@types/chrome": "^0.1.31",
+ "babel-preset-expo": "^54.0.7",
+ "husky": "^9.0.11",
+ "lint-staged": "^15.2.0",
+ "prettier": "^3.2.5",
+ "prettier-plugin-tailwindcss": "^0.5.11",
+ "tailwindcss": "^3.4.17",
+ "wxt": "^0.20.11"
+ }
+ },
+ "node_modules/@0no-co/graphql.web": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.2.0.tgz",
+ "integrity": "sha512-/1iHy9TTr63gE1YcR5idjx8UREz1s0kFhydf3bBLCXyqjhkIc6igAzTOx3zPifCwFR87tsh/4Pa9cNts6d2otw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
+ },
+ "peerDependenciesMeta": {
+ "graphql": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@1natsu/wait-element": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@1natsu/wait-element/-/wait-element-4.1.2.tgz",
+ "integrity": "sha512-qWxSJD+Q5b8bKOvESFifvfZ92DuMsY+03SBNjTO34ipJLP6mZ9yK4bQz/vlh48aEQXoJfaZBqUwKL5BdI5iiWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "defu": "^6.1.4",
+ "many-keys-map": "^2.0.1"
+ }
+ },
+ "node_modules/@aklinker1/rollup-plugin-visualizer": {
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/@aklinker1/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.12.0.tgz",
+ "integrity": "sha512-X24LvEGw6UFmy0lpGJDmXsMyBD58XmX1bbwsaMLhNoM+UMQfQ3b2RtC+nz4b/NoRK5r6QJSKJHBNVeUdwqybaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "open": "^8.4.0",
+ "picomatch": "^2.3.1",
+ "source-map": "^0.7.4",
+ "yargs": "^17.5.1"
+ },
+ "bin": {
+ "rollup-plugin-visualizer": "dist/bin/cli.js"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "rollup": "2.x || 3.x || 4.x"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@aklinker1/rollup-plugin-visualizer/node_modules/open": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
+ "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-lazy-prop": "^2.0.0",
+ "is-docker": "^2.1.1",
+ "is-wsl": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@aklinker1/rollup-plugin-visualizer/node_modules/source-map": {
+ "version": "0.7.6",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
+ "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/@alloc/quick-lru": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
+ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/highlight": "^7.10.4"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz",
+ "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
+ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.28.5",
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-module-transforms": "^7.28.3",
+ "@babel/helpers": "^7.28.4",
+ "@babel/parser": "^7.28.5",
+ "@babel/template": "^7.27.2",
+ "@babel/traverse": "^7.28.5",
+ "@babel/types": "^7.28.5",
+ "@jridgewell/remapping": "^2.3.5",
+ "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/@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==",
+ "license": "MIT",
+ "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/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==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz",
+ "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.28.5",
+ "@babel/types": "^7.28.5",
+ "@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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz",
+ "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-member-expression-to-functions": "^7.28.5",
+ "@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.5",
+ "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==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz",
+ "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "regexpu-core": "^6.3.1",
+ "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==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz",
+ "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "debug": "^4.4.1",
+ "lodash.debounce": "^4.0.8",
+ "resolve": "^1.22.10"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-member-expression-to-functions": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz",
+ "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.28.5",
+ "@babel/types": "^7.28.5"
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz",
+ "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "@babel/traverse": "^7.28.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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-remap-async-to-generator": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz",
+ "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.1",
+ "@babel/helper-wrap-function": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz",
+ "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.27.2",
+ "@babel/traverse": "^7.28.3",
+ "@babel/types": "^7.28.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz",
+ "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.28.4"
+ },
+ "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==",
+ "license": "MIT",
+ "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/parser": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
+ "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.5"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-decorators": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.28.0.tgz",
+ "integrity": "sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/plugin-syntax-decorators": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-export-default-from": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.27.1.tgz",
+ "integrity": "sha512-hjlsMBl1aJc5lp8MoCDEZCiYzlgdRAShOjAfRw6X+GlpLpUPU7c3XNLsKFZbQk/1cRzBlJ7CXg3xJAJMrFa1Uw==",
+ "license": "MIT",
+ "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-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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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-decorators": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.27.1.tgz",
+ "integrity": "sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==",
+ "license": "MIT",
+ "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-dynamic-import": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+ "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-export-default-from": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.27.1.tgz",
+ "integrity": "sha512-eBC/3KSekshx19+N40MzjWqJd7KTEdOoLesAfa4IDFI8eRz5a47i5Oszus6zG/cwIXN63YhgLOMSSNJx49sENg==",
+ "license": "MIT",
+ "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-flow": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.27.1.tgz",
+ "integrity": "sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA==",
+ "license": "MIT",
+ "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-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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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-async-generator-functions": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz",
+ "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-remap-async-to-generator": "^7.27.1",
+ "@babel/traverse": "^7.28.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-to-generator": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz",
+ "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-remap-async-to-generator": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoping": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz",
+ "integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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-class-static-block": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz",
+ "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.28.3",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.12.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz",
+ "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-replace-supers": "^7.27.1",
+ "@babel/traverse": "^7.28.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-computed-properties": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz",
+ "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/template": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-destructuring": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz",
+ "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/traverse": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-export-namespace-from": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz",
+ "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==",
+ "license": "MIT",
+ "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-flow-strip-types": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.27.1.tgz",
+ "integrity": "sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/plugin-syntax-flow": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-for-of": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz",
+ "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==",
+ "license": "MIT",
+ "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-function-name": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz",
+ "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-literals": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz",
+ "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==",
+ "license": "MIT",
+ "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-logical-assignment-operators": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz",
+ "integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==",
+ "license": "MIT",
+ "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-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==",
+ "license": "MIT",
+ "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-named-capturing-groups-regex": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz",
+ "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==",
+ "license": "MIT",
+ "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"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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-numeric-separator": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz",
+ "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==",
+ "license": "MIT",
+ "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-object-rest-spread": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz",
+ "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/plugin-transform-destructuring": "^7.28.0",
+ "@babel/plugin-transform-parameters": "^7.27.7",
+ "@babel/traverse": "^7.28.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-optional-catch-binding": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz",
+ "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==",
+ "license": "MIT",
+ "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.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz",
+ "integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==",
+ "license": "MIT",
+ "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-parameters": {
+ "version": "7.27.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz",
+ "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==",
+ "license": "MIT",
+ "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-private-methods": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz",
+ "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==",
+ "license": "MIT",
+ "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-private-property-in-object": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz",
+ "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==",
+ "license": "MIT",
+ "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"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-display-name": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz",
+ "integrity": "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==",
+ "license": "MIT",
+ "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-react-jsx": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz",
+ "integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.1",
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/plugin-syntax-jsx": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-development": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz",
+ "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/plugin-transform-react-jsx": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
+ "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
+ "license": "MIT",
+ "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-react-jsx-source": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
+ "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
+ "license": "MIT",
+ "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-react-pure-annotations": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz",
+ "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^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-regenerator": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz",
+ "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==",
+ "license": "MIT",
+ "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-runtime": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz",
+ "integrity": "sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "babel-plugin-polyfill-corejs2": "^0.4.14",
+ "babel-plugin-polyfill-corejs3": "^0.13.0",
+ "babel-plugin-polyfill-regenerator": "^0.6.5",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-runtime/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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-spread": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz",
+ "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==",
+ "license": "MIT",
+ "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-sticky-regex": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz",
+ "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz",
+ "integrity": "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-create-class-features-plugin": "^7.28.5",
+ "@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==",
+ "license": "MIT",
+ "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-react": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.28.5.tgz",
+ "integrity": "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-validator-option": "^7.27.1",
+ "@babel/plugin-transform-react-display-name": "^7.28.0",
+ "@babel/plugin-transform-react-jsx": "^7.27.1",
+ "@babel/plugin-transform-react-jsx-development": "^7.27.1",
+ "@babel/plugin-transform-react-pure-annotations": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/preset-typescript": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz",
+ "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==",
+ "license": "MIT",
+ "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.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
+ "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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/template/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==",
+ "license": "MIT",
+ "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/traverse": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz",
+ "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.28.5",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.28.5",
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.28.5",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse--for-generate-function-map": {
+ "name": "@babel/traverse",
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz",
+ "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.28.5",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.28.5",
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.28.5",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse--for-generate-function-map/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==",
+ "license": "MIT",
+ "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/traverse/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==",
+ "license": "MIT",
+ "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/types": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
+ "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@devicefarmer/adbkit": {
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit/-/adbkit-3.3.8.tgz",
+ "integrity": "sha512-7rBLLzWQnBwutH2WZ0EWUkQdihqrnLYCUMaB44hSol9e0/cdIhuNFcqZO0xNheAU6qqHVA8sMiLofkYTgb+lmw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@devicefarmer/adbkit-logcat": "^2.1.2",
+ "@devicefarmer/adbkit-monkey": "~1.2.1",
+ "bluebird": "~3.7",
+ "commander": "^9.1.0",
+ "debug": "~4.3.1",
+ "node-forge": "^1.3.1",
+ "split": "~1.0.1"
+ },
+ "bin": {
+ "adbkit": "bin/adbkit"
+ },
+ "engines": {
+ "node": ">= 0.10.4"
+ }
+ },
+ "node_modules/@devicefarmer/adbkit-logcat": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit-logcat/-/adbkit-logcat-2.1.3.tgz",
+ "integrity": "sha512-yeaGFjNBc/6+svbDeul1tNHtNChw6h8pSHAt5D+JsedUrMTN7tla7B15WLDyekxsuS2XlZHRxpuC6m92wiwCNw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@devicefarmer/adbkit-monkey": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit-monkey/-/adbkit-monkey-1.2.1.tgz",
+ "integrity": "sha512-ZzZY/b66W2Jd6NHbAhLyDWOEIBWC11VizGFk7Wx7M61JZRz7HR9Cq5P+65RKWUU7u6wgsE8Lmh9nE4Mz+U2eTg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">= 0.10.4"
+ }
+ },
+ "node_modules/@devicefarmer/adbkit/node_modules/commander": {
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
+ "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || >=14"
+ }
+ },
+ "node_modules/@devicefarmer/adbkit/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hammerjs": "^2.0.36"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
+ "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz",
+ "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz",
+ "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz",
+ "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz",
+ "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz",
+ "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz",
+ "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz",
+ "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz",
+ "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz",
+ "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz",
+ "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz",
+ "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz",
+ "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz",
+ "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz",
+ "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz",
+ "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz",
+ "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz",
+ "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz",
+ "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz",
+ "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz",
+ "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@expo/code-signing-certificates": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.5.tgz",
+ "integrity": "sha512-BNhXkY1bblxKZpltzAx98G2Egj9g1Q+JRcvR7E99DOj862FTCX+ZPsAUtPTr7aHxwtrL7+fL3r0JSmM9kBm+Bw==",
+ "license": "MIT",
+ "dependencies": {
+ "node-forge": "^1.2.1",
+ "nullthrows": "^1.1.1"
+ }
+ },
+ "node_modules/@expo/config": {
+ "version": "12.0.10",
+ "resolved": "https://registry.npmjs.org/@expo/config/-/config-12.0.10.tgz",
+ "integrity": "sha512-lJMof5Nqakq1DxGYlghYB/ogSBjmv4Fxn1ovyDmcjlRsQdFCXgu06gEUogkhPtc9wBt9WlTTfqENln5HHyLW6w==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "~7.10.4",
+ "@expo/config-plugins": "~54.0.2",
+ "@expo/config-types": "^54.0.8",
+ "@expo/json-file": "^10.0.7",
+ "deepmerge": "^4.3.1",
+ "getenv": "^2.0.0",
+ "glob": "^10.4.2",
+ "require-from-string": "^2.0.2",
+ "resolve-from": "^5.0.0",
+ "resolve-workspace-root": "^2.0.0",
+ "semver": "^7.6.0",
+ "slugify": "^1.3.4",
+ "sucrase": "3.35.0"
+ }
+ },
+ "node_modules/@expo/config-plugins": {
+ "version": "54.0.2",
+ "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-54.0.2.tgz",
+ "integrity": "sha512-jD4qxFcURQUVsUFGMcbo63a/AnviK8WUGard+yrdQE3ZrB/aurn68SlApjirQQLEizhjI5Ar2ufqflOBlNpyPg==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/config-types": "^54.0.8",
+ "@expo/json-file": "~10.0.7",
+ "@expo/plist": "^0.4.7",
+ "@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/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@expo/config-plugins/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/@expo/config-plugins/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/@expo/config-plugins/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==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/config-plugins/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@expo/config-plugins/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@expo/config-types": {
+ "version": "54.0.8",
+ "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-54.0.8.tgz",
+ "integrity": "sha512-lyIn/x/Yz0SgHL7IGWtgTLg6TJWC9vL7489++0hzCHZ4iGjVcfZmPTUfiragZ3HycFFj899qN0jlhl49IHa94A==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/devcert": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.2.0.tgz",
+ "integrity": "sha512-Uilcv3xGELD5t/b0eM4cxBFEKQRIivB3v7i+VhWLV/gL98aw810unLKKJbGAxAIhY6Ipyz8ChWibFsKFXYwstA==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/sudo-prompt": "^9.3.1",
+ "debug": "^3.1.0",
+ "glob": "^10.4.2"
+ }
+ },
+ "node_modules/@expo/devcert/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/@expo/devtools": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/@expo/devtools/-/devtools-0.1.7.tgz",
+ "integrity": "sha512-dfIa9qMyXN+0RfU6SN4rKeXZyzKWsnz6xBSDccjL4IRiE+fQ0t84zg0yxgN4t/WK2JU5v6v4fby7W7Crv9gJvA==",
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.2"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@expo/devtools/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@expo/devtools/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/@expo/devtools/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/@expo/devtools/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==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/devtools/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@expo/devtools/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@expo/env": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.0.7.tgz",
+ "integrity": "sha512-BNETbLEohk3HQ2LxwwezpG8pq+h7Fs7/vAMP3eAtFT1BCpprLYoBBFZH7gW4aqGfqOcVP4Lc91j014verrYNGg==",
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "debug": "^4.3.4",
+ "dotenv": "~16.4.5",
+ "dotenv-expand": "~11.0.6",
+ "getenv": "^2.0.0"
+ }
+ },
+ "node_modules/@expo/env/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@expo/env/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/@expo/env/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/@expo/env/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==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/env/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@expo/env/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@expo/fingerprint": {
+ "version": "0.15.3",
+ "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.15.3.tgz",
+ "integrity": "sha512-8YPJpEYlmV171fi+t+cSLMX1nC5ngY9j2FiN70dHldLpd6Ct6ouGhk96svJ4BQZwsqwII2pokwzrDAwqo4Z0FQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/spawn-async": "^1.7.2",
+ "arg": "^5.0.2",
+ "chalk": "^4.1.2",
+ "debug": "^4.3.4",
+ "getenv": "^2.0.0",
+ "glob": "^10.4.2",
+ "ignore": "^5.3.1",
+ "minimatch": "^9.0.0",
+ "p-limit": "^3.1.0",
+ "resolve-from": "^5.0.0",
+ "semver": "^7.6.0"
+ },
+ "bin": {
+ "fingerprint": "bin/cli.js"
+ }
+ },
+ "node_modules/@expo/fingerprint/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@expo/fingerprint/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/@expo/fingerprint/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/@expo/fingerprint/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==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/fingerprint/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@expo/fingerprint/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@expo/image-utils": {
+ "version": "0.8.7",
+ "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.7.tgz",
+ "integrity": "sha512-SXOww4Wq3RVXLyOaXiCCuQFguCDh8mmaHBv54h/R29wGl4jRY8GEyQEx8SypV/iHt1FbzsU/X3Qbcd9afm2W2w==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/spawn-async": "^1.7.2",
+ "chalk": "^4.0.0",
+ "getenv": "^2.0.0",
+ "jimp-compact": "0.16.1",
+ "parse-png": "^2.1.0",
+ "resolve-from": "^5.0.0",
+ "resolve-global": "^1.0.0",
+ "semver": "^7.6.0",
+ "temp-dir": "~2.0.0",
+ "unique-string": "~2.0.0"
+ }
+ },
+ "node_modules/@expo/image-utils/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@expo/image-utils/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/@expo/image-utils/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/@expo/image-utils/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==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/image-utils/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@expo/image-utils/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@expo/json-file": {
+ "version": "10.0.7",
+ "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.7.tgz",
+ "integrity": "sha512-z2OTC0XNO6riZu98EjdNHC05l51ySeTto6GP7oSQrCvQgG9ARBwD1YvMQaVZ9wU7p/4LzSf1O7tckL3B45fPpw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "~7.10.4",
+ "json5": "^2.2.3"
+ }
+ },
+ "node_modules/@expo/mcp-tunnel": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@expo/mcp-tunnel/-/mcp-tunnel-0.1.0.tgz",
+ "integrity": "sha512-rJ6hl0GnIZj9+ssaJvFsC7fwyrmndcGz+RGFzu+0gnlm78X01957yjtHgjcmnQAgL5hWEOR6pkT0ijY5nU5AWw==",
+ "license": "MIT",
+ "dependencies": {
+ "ws": "^8.18.3",
+ "zod": "^3.25.76",
+ "zod-to-json-schema": "^3.24.6"
+ },
+ "peerDependencies": {
+ "@modelcontextprotocol/sdk": "^1.13.2"
+ },
+ "peerDependenciesMeta": {
+ "@modelcontextprotocol/sdk": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@expo/mcp-tunnel/node_modules/ws": {
+ "version": "8.18.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
+ "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@expo/metro": {
+ "version": "54.1.0",
+ "resolved": "https://registry.npmjs.org/@expo/metro/-/metro-54.1.0.tgz",
+ "integrity": "sha512-MgdeRNT/LH0v1wcO0TZp9Qn8zEF0X2ACI0wliPtv5kXVbXWI+yK9GyrstwLAiTXlULKVIg3HVSCCvmLu0M3tnw==",
+ "license": "MIT",
+ "dependencies": {
+ "metro": "0.83.2",
+ "metro-babel-transformer": "0.83.2",
+ "metro-cache": "0.83.2",
+ "metro-cache-key": "0.83.2",
+ "metro-config": "0.83.2",
+ "metro-core": "0.83.2",
+ "metro-file-map": "0.83.2",
+ "metro-resolver": "0.83.2",
+ "metro-runtime": "0.83.2",
+ "metro-source-map": "0.83.2",
+ "metro-transform-plugins": "0.83.2",
+ "metro-transform-worker": "0.83.2"
+ }
+ },
+ "node_modules/@expo/metro-runtime": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/@expo/metro-runtime/-/metro-runtime-6.1.2.tgz",
+ "integrity": "sha512-nvM+Qv45QH7pmYvP8JB1G8JpScrWND3KrMA6ZKe62cwwNiX/BjHU28Ear0v/4bQWXlOY0mv6B8CDIm8JxXde9g==",
+ "license": "MIT",
+ "dependencies": {
+ "anser": "^1.4.9",
+ "pretty-format": "^29.7.0",
+ "stacktrace-parser": "^0.1.10",
+ "whatwg-fetch": "^3.0.0"
+ },
+ "peerDependencies": {
+ "expo": "*",
+ "react": "*",
+ "react-dom": "*",
+ "react-native": "*"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@expo/osascript": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.3.7.tgz",
+ "integrity": "sha512-IClSOXxR0YUFxIriUJVqyYki7lLMIHrrzOaP01yxAL1G8pj2DWV5eW1y5jSzIcIfSCNhtGsshGd1tU/AYup5iQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/spawn-async": "^1.7.2",
+ "exec-async": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@expo/package-manager": {
+ "version": "1.9.8",
+ "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.9.8.tgz",
+ "integrity": "sha512-4/I6OWquKXYnzo38pkISHCOCOXxfeEmu4uDoERq1Ei/9Ur/s9y3kLbAamEkitUkDC7gHk1INxRWEfFNzGbmOrA==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/json-file": "^10.0.7",
+ "@expo/spawn-async": "^1.7.2",
+ "chalk": "^4.0.0",
+ "npm-package-arg": "^11.0.0",
+ "ora": "^3.4.0",
+ "resolve-workspace-root": "^2.0.0"
+ }
+ },
+ "node_modules/@expo/package-manager/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@expo/package-manager/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/@expo/package-manager/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/@expo/package-manager/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==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/package-manager/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@expo/package-manager/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@expo/plist": {
+ "version": "0.4.7",
+ "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.4.7.tgz",
+ "integrity": "sha512-dGxqHPvCZKeRKDU1sJZMmuyVtcASuSYh1LPFVaM1DuffqPL36n6FMEL0iUqq2Tx3xhWk8wCnWl34IKplUjJDdA==",
+ "license": "MIT",
+ "dependencies": {
+ "@xmldom/xmldom": "^0.8.8",
+ "base64-js": "^1.2.3",
+ "xmlbuilder": "^15.1.1"
+ }
+ },
+ "node_modules/@expo/schema-utils": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/@expo/schema-utils/-/schema-utils-0.1.7.tgz",
+ "integrity": "sha512-jWHoSuwRb5ZczjahrychMJ3GWZu54jK9ulNdh1d4OzAEq672K9E5yOlnlBsfIHWHGzUAT+0CL7Yt1INiXTz68g==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/spawn-async": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.7.2.tgz",
+ "integrity": "sha512-QdWi16+CHB9JYP7gma19OVVg0BFkvU8zNj9GjWorYI8Iv8FUxjOCcYRuAmX4s/h91e4e7BPsskc8cSrZYho9Ew==",
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@expo/sudo-prompt": {
+ "version": "9.3.2",
+ "resolved": "https://registry.npmjs.org/@expo/sudo-prompt/-/sudo-prompt-9.3.2.tgz",
+ "integrity": "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/ui": {
+ "version": "0.2.0-beta.7",
+ "resolved": "https://registry.npmjs.org/@expo/ui/-/ui-0.2.0-beta.7.tgz",
+ "integrity": "sha512-oz2HEpwll+yMFUKbryZ84IgxjLx7RPxxMDVKpCEsK0OhETrLF5NxHlpCkKjdLuQL3QiVSvj5kn6hBFknco3aCw==",
+ "license": "MIT",
+ "dependencies": {
+ "sf-symbols-typescript": "^2.1.0"
+ },
+ "peerDependencies": {
+ "expo": "*",
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/@expo/vector-icons": {
+ "version": "15.0.3",
+ "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.0.3.tgz",
+ "integrity": "sha512-SBUyYKphmlfUBqxSfDdJ3jAdEVSALS2VUPOUyqn48oZmb2TL/O7t7/PQm5v4NQujYEPLPMTLn9KVw6H7twwbTA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "expo-font": ">=14.0.4",
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/@expo/ws-tunnel": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@expo/ws-tunnel/-/ws-tunnel-1.0.6.tgz",
+ "integrity": "sha512-nDRbLmSrJar7abvUjp3smDwH8HcbZcoOEa5jVPUv9/9CajgmWw20JNRwTuBRzWIWIkEJDkz20GoNA+tSwUqk0Q==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/xcpretty": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.3.2.tgz",
+ "integrity": "sha512-ReZxZ8pdnoI3tP/dNnJdnmAk7uLT4FjsKDGW7YeDdvdOMz2XCQSmSCM9IWlrXuWtMF9zeSB6WJtEhCQ41gQOfw==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/code-frame": "7.10.4",
+ "chalk": "^4.1.0",
+ "find-up": "^5.0.0",
+ "js-yaml": "^4.1.0"
+ },
+ "bin": {
+ "excpretty": "build/cli.js"
+ }
+ },
+ "node_modules/@expo/xcpretty/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@expo/xcpretty/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==",
+ "license": "Python-2.0"
+ },
+ "node_modules/@expo/xcpretty/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/@expo/xcpretty/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/@expo/xcpretty/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==",
+ "license": "MIT"
+ },
+ "node_modules/@expo/xcpretty/node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@expo/xcpretty/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@expo/xcpretty/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==",
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/@expo/xcpretty/node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@expo/xcpretty/node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@expo/xcpretty/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@isaacs/balanced-match": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
+ "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/@isaacs/brace-expansion": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz",
+ "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@isaacs/balanced-match": "^4.0.1"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "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==",
+ "license": "ISC",
+ "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/fs-minipass": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
+ "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.4"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "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==",
+ "license": "ISC",
+ "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==",
+ "license": "ISC",
+ "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/load-nyc-config/node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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/transform/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@jest/transform/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/@jest/transform/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/@jest/transform/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==",
+ "license": "MIT"
+ },
+ "node_modules/@jest/transform/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/transform/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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/@jest/types/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@jest/types/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/@jest/types/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/@jest/types/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==",
+ "license": "MIT"
+ },
+ "node_modules/@jest/types/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/types/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+ "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@pnpm/config.env-replace": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz",
+ "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.22.0"
+ }
+ },
+ "node_modules/@pnpm/network.ca-file": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz",
+ "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "4.2.10"
+ },
+ "engines": {
+ "node": ">=12.22.0"
+ }
+ },
+ "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@pnpm/npm-conf": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz",
+ "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@pnpm/config.env-replace": "^1.1.0",
+ "@pnpm/network.ca-file": "^1.0.1",
+ "config-chain": "^1.1.11"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@radix-ui/primitive": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
+ "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-collection": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
+ "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
+ "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
+ "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-context": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
+ "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-dialog": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz",
+ "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-dismissable-layer": "1.1.11",
+ "@radix-ui/react-focus-guards": "1.1.3",
+ "@radix-ui/react-focus-scope": "1.1.7",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-portal": "1.1.9",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.6.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
+ "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-direction": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
+ "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-dismissable-layer": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz",
+ "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-escape-keydown": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-focus-guards": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz",
+ "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-focus-scope": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz",
+ "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-id": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
+ "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-portal": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz",
+ "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-presence": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
+ "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-primitive": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
+ "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.2.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
+ "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-roving-focus": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz",
+ "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-collection": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-slot": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz",
+ "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-tabs": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz",
+ "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-roving-focus": "1.1.11",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
+ "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
+ "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-effect-event": "0.0.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-effect-event": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz",
+ "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-escape-keydown": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz",
+ "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-callback-ref": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
+ "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@react-native-segmented-control/segmented-control": {
+ "version": "2.5.7",
+ "resolved": "https://registry.npmjs.org/@react-native-segmented-control/segmented-control/-/segmented-control-2.5.7.tgz",
+ "integrity": "sha512-l84YeVX8xAU3lvOJSvV4nK/NbGhIm2gBfveYolwaoCbRp+/SLXtc6mYrQmM9ScXNwU14mnzjQTpTHWl5YPnkzQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=16.0",
+ "react-native": ">=0.62"
+ }
+ },
+ "node_modules/@react-native/assets-registry": {
+ "version": "0.81.5",
+ "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.81.5.tgz",
+ "integrity": "sha512-705B6x/5Kxm1RKRvSv0ADYWm5JOnoiQ1ufW7h8uu2E6G9Of/eE6hP/Ivw3U5jI16ERqZxiKQwk34VJbB0niX9w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 20.19.4"
+ }
+ },
+ "node_modules/@react-native/babel-plugin-codegen": {
+ "version": "0.81.5",
+ "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.81.5.tgz",
+ "integrity": "sha512-oF71cIH6je3fSLi6VPjjC3Sgyyn57JLHXs+mHWc9MoCiJJcM4nqsS5J38zv1XQ8d3zOW2JtHro+LF0tagj2bfQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.25.3",
+ "@react-native/codegen": "0.81.5"
+ },
+ "engines": {
+ "node": ">= 20.19.4"
+ }
+ },
+ "node_modules/@react-native/babel-preset": {
+ "version": "0.81.5",
+ "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.81.5.tgz",
+ "integrity": "sha512-UoI/x/5tCmi+pZ3c1+Ypr1DaRMDLI3y+Q70pVLLVgrnC3DHsHRIbHcCHIeG/IJvoeFqFM2sTdhSOLJrf8lOPrA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.25.2",
+ "@babel/plugin-proposal-export-default-from": "^7.24.7",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+ "@babel/plugin-syntax-export-default-from": "^7.24.7",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-transform-arrow-functions": "^7.24.7",
+ "@babel/plugin-transform-async-generator-functions": "^7.25.4",
+ "@babel/plugin-transform-async-to-generator": "^7.24.7",
+ "@babel/plugin-transform-block-scoping": "^7.25.0",
+ "@babel/plugin-transform-class-properties": "^7.25.4",
+ "@babel/plugin-transform-classes": "^7.25.4",
+ "@babel/plugin-transform-computed-properties": "^7.24.7",
+ "@babel/plugin-transform-destructuring": "^7.24.8",
+ "@babel/plugin-transform-flow-strip-types": "^7.25.2",
+ "@babel/plugin-transform-for-of": "^7.24.7",
+ "@babel/plugin-transform-function-name": "^7.25.1",
+ "@babel/plugin-transform-literals": "^7.25.2",
+ "@babel/plugin-transform-logical-assignment-operators": "^7.24.7",
+ "@babel/plugin-transform-modules-commonjs": "^7.24.8",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7",
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7",
+ "@babel/plugin-transform-numeric-separator": "^7.24.7",
+ "@babel/plugin-transform-object-rest-spread": "^7.24.7",
+ "@babel/plugin-transform-optional-catch-binding": "^7.24.7",
+ "@babel/plugin-transform-optional-chaining": "^7.24.8",
+ "@babel/plugin-transform-parameters": "^7.24.7",
+ "@babel/plugin-transform-private-methods": "^7.24.7",
+ "@babel/plugin-transform-private-property-in-object": "^7.24.7",
+ "@babel/plugin-transform-react-display-name": "^7.24.7",
+ "@babel/plugin-transform-react-jsx": "^7.25.2",
+ "@babel/plugin-transform-react-jsx-self": "^7.24.7",
+ "@babel/plugin-transform-react-jsx-source": "^7.24.7",
+ "@babel/plugin-transform-regenerator": "^7.24.7",
+ "@babel/plugin-transform-runtime": "^7.24.7",
+ "@babel/plugin-transform-shorthand-properties": "^7.24.7",
+ "@babel/plugin-transform-spread": "^7.24.7",
+ "@babel/plugin-transform-sticky-regex": "^7.24.7",
+ "@babel/plugin-transform-typescript": "^7.25.2",
+ "@babel/plugin-transform-unicode-regex": "^7.24.7",
+ "@babel/template": "^7.25.0",
+ "@react-native/babel-plugin-codegen": "0.81.5",
+ "babel-plugin-syntax-hermes-parser": "0.29.1",
+ "babel-plugin-transform-flow-enums": "^0.0.2",
+ "react-refresh": "^0.14.0"
+ },
+ "engines": {
+ "node": ">= 20.19.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "*"
+ }
+ },
+ "node_modules/@react-native/codegen": {
+ "version": "0.81.5",
+ "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.81.5.tgz",
+ "integrity": "sha512-a2TDA03Up8lpSa9sh5VRGCQDXgCTOyDOFH+aqyinxp1HChG8uk89/G+nkJ9FPd0rqgi25eCTR16TWdS3b+fA6g==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.25.2",
+ "@babel/parser": "^7.25.3",
+ "glob": "^7.1.1",
+ "hermes-parser": "0.29.1",
+ "invariant": "^2.2.4",
+ "nullthrows": "^1.1.1",
+ "yargs": "^17.6.2"
+ },
+ "engines": {
+ "node": ">= 20.19.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "*"
+ }
+ },
+ "node_modules/@react-native/codegen/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==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@react-native/codegen/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@react-native/codegen/node_modules/hermes-estree": {
+ "version": "0.29.1",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz",
+ "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==",
+ "license": "MIT"
+ },
+ "node_modules/@react-native/codegen/node_modules/hermes-parser": {
+ "version": "0.29.1",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz",
+ "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==",
+ "license": "MIT",
+ "dependencies": {
+ "hermes-estree": "0.29.1"
+ }
+ },
+ "node_modules/@react-native/codegen/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@react-native/community-cli-plugin": {
+ "version": "0.81.5",
+ "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.81.5.tgz",
+ "integrity": "sha512-yWRlmEOtcyvSZ4+OvqPabt+NS36vg0K/WADTQLhrYrm9qdZSuXmq8PmdJWz/68wAqKQ+4KTILiq2kjRQwnyhQw==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-native/dev-middleware": "0.81.5",
+ "debug": "^4.4.0",
+ "invariant": "^2.2.4",
+ "metro": "^0.83.1",
+ "metro-config": "^0.83.1",
+ "metro-core": "^0.83.1",
+ "semver": "^7.1.3"
+ },
+ "engines": {
+ "node": ">= 20.19.4"
+ },
+ "peerDependencies": {
+ "@react-native-community/cli": "*",
+ "@react-native/metro-config": "*"
+ },
+ "peerDependenciesMeta": {
+ "@react-native-community/cli": {
+ "optional": true
+ },
+ "@react-native/metro-config": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@react-native/debugger-frontend": {
+ "version": "0.81.5",
+ "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.81.5.tgz",
+ "integrity": "sha512-bnd9FSdWKx2ncklOetCgrlwqSGhMHP2zOxObJbOWXoj7GHEmih4MKarBo5/a8gX8EfA1EwRATdfNBQ81DY+h+w==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">= 20.19.4"
+ }
+ },
+ "node_modules/@react-native/dev-middleware": {
+ "version": "0.81.5",
+ "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.81.5.tgz",
+ "integrity": "sha512-WfPfZzboYgo/TUtysuD5xyANzzfka8Ebni6RIb2wDxhb56ERi7qDrE4xGhtPsjCL4pQBXSVxyIlCy0d8I6EgGA==",
+ "license": "MIT",
+ "dependencies": {
+ "@isaacs/ttlcache": "^1.4.1",
+ "@react-native/debugger-frontend": "0.81.5",
+ "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": ">= 20.19.4"
+ }
+ },
+ "node_modules/@react-native/dev-middleware/node_modules/ws": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
+ "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
+ "license": "MIT",
+ "dependencies": {
+ "async-limiter": "~1.0.0"
+ }
+ },
+ "node_modules/@react-native/gradle-plugin": {
+ "version": "0.81.5",
+ "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.81.5.tgz",
+ "integrity": "sha512-hORRlNBj+ReNMLo9jme3yQ6JQf4GZpVEBLxmTXGGlIL78MAezDZr5/uq9dwElSbcGmLEgeiax6e174Fie6qPLg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 20.19.4"
+ }
+ },
+ "node_modules/@react-native/js-polyfills": {
+ "version": "0.81.5",
+ "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.81.5.tgz",
+ "integrity": "sha512-fB7M1CMOCIUudTRuj7kzxIBTVw2KXnsgbQ6+4cbqSxo8NmRRhA0Ul4ZUzZj3rFd3VznTL4Brmocv1oiN0bWZ8w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 20.19.4"
+ }
+ },
+ "node_modules/@react-native/normalize-colors": {
+ "version": "0.81.5",
+ "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.81.5.tgz",
+ "integrity": "sha512-0HuJ8YtqlTVRXGZuGeBejLE04wSQsibpTI+RGOyVqxZvgtlLLC/Ssw0UmbHhT4lYMp2fhdtvKZSs5emWB1zR/g==",
+ "license": "MIT"
+ },
+ "node_modules/@react-native/virtualized-lists": {
+ "version": "0.81.5",
+ "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.81.5.tgz",
+ "integrity": "sha512-UVXgV/db25OPIvwZySeToXD/9sKKhOdkcWmmf4Jh8iBZuyfML+/5CasaZ1E7Lqg6g3uqVQq75NqIwkYmORJMPw==",
+ "license": "MIT",
+ "dependencies": {
+ "invariant": "^2.2.4",
+ "nullthrows": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 20.19.4"
+ },
+ "peerDependencies": {
+ "@types/react": "^19.1.0",
+ "react": "*",
+ "react-native": "*"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@react-navigation/bottom-tabs": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-7.8.4.tgz",
+ "integrity": "sha512-Ie+7EgUxfZmVXm4RCiJ96oaiwJVFgVE8NJoeUKLLcYEB/99wKbhuKPJNtbkpR99PHfhq64SE7476BpcP4xOFhw==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-navigation/elements": "^2.8.1",
+ "color": "^4.2.3",
+ "sf-symbols-typescript": "^2.1.0"
+ },
+ "peerDependencies": {
+ "@react-navigation/native": "^7.1.19",
+ "react": ">= 18.2.0",
+ "react-native": "*",
+ "react-native-safe-area-context": ">= 4.0.0",
+ "react-native-screens": ">= 4.0.0"
+ }
+ },
+ "node_modules/@react-navigation/core": {
+ "version": "7.13.0",
+ "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-7.13.0.tgz",
+ "integrity": "sha512-Fc/SO23HnlGnkou/z8JQUzwEMvhxuUhr4rdPTIZp/c8q1atq3k632Nfh8fEiGtk+MP1wtIvXdN2a5hBIWpLq3g==",
+ "license": "MIT",
+ "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/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/@react-navigation/elements": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-2.8.1.tgz",
+ "integrity": "sha512-MLmuS5kPAeAFFOylw89WGjgEFBqGj/KBK6ZrFrAOqLnTqEzk52/SO1olb5GB00k6ZUCDZKJOp1BrLXslxE6TgQ==",
+ "license": "MIT",
+ "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.19",
+ "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.19",
+ "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.1.19.tgz",
+ "integrity": "sha512-fM7q8di4Q8sp2WUhiUWOe7bEDRyRhbzsKQOd5N2k+lHeCx3UncsRYuw4Q/KN0EovM3wWKqMMmhy/YWuEO04kgw==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-navigation/core": "^7.13.0",
+ "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/native-stack": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-7.6.2.tgz",
+ "integrity": "sha512-CB6chGNLwJYiyOeyCNUKx33yT7XJSwRZIeKHf4S1vs+Oqu3u9zMnvGUIsesNgbgX0xy16gBqYsrWgr0ZczBTtA==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-navigation/elements": "^2.8.1",
+ "color": "^4.2.3",
+ "sf-symbols-typescript": "^2.1.0",
+ "warn-once": "^0.1.1"
+ },
+ "peerDependencies": {
+ "@react-navigation/native": "^7.1.19",
+ "react": ">= 18.2.0",
+ "react-native": "*",
+ "react-native-safe-area-context": ">= 4.0.0",
+ "react-native-screens": ">= 4.0.0"
+ }
+ },
+ "node_modules/@react-navigation/native/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11"
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.1.tgz",
+ "integrity": "sha512-bxZtughE4VNVJlL1RdoSE545kc4JxL7op57KKoi59/gwuU5rV6jLWFXXc8jwgFoT6vtj+ZjO+Z2C5nrY0Cl6wA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.1.tgz",
+ "integrity": "sha512-44a1hreb02cAAfAKmZfXVercPFaDjqXCK+iKeVOlJ9ltvnO6QqsBHgKVPTu+MJHSLLeMEUbeG2qiDYgbFPU48g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.1.tgz",
+ "integrity": "sha512-usmzIgD0rf1syoOZ2WZvy8YpXK5G1V3btm3QZddoGSa6mOgfXWkkv+642bfUUldomgrbiLQGrPryb7DXLovPWQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.1.tgz",
+ "integrity": "sha512-is3r/k4vig2Gt8mKtTlzzyaSQ+hd87kDxiN3uDSDwggJLUV56Umli6OoL+/YZa/KvtdrdyNfMKHzL/P4siOOmg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.1.tgz",
+ "integrity": "sha512-QJ1ksgp/bDJkZB4daldVmHaEQkG4r8PUXitCOC2WRmRaSaHx5RwPoI3DHVfXKwDkB+Sk6auFI/+JHacTekPRSw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.1.tgz",
+ "integrity": "sha512-J6ma5xgAzvqsnU6a0+jgGX/gvoGokqpkx6zY4cWizRrm0ffhHDpJKQgC8dtDb3+MqfZDIqs64REbfHDMzxLMqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.1.tgz",
+ "integrity": "sha512-JzWRR41o2U3/KMNKRuZNsDUAcAVUYhsPuMlx5RUldw0E4lvSIXFUwejtYz1HJXohUmqs/M6BBJAUBzKXZVddbg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.1.tgz",
+ "integrity": "sha512-L8kRIrnfMrEoHLHtHn+4uYA52fiLDEDyezgxZtGUTiII/yb04Krq+vk3P2Try+Vya9LeCE9ZHU8CXD6J9EhzHQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.1.tgz",
+ "integrity": "sha512-ysAc0MFRV+WtQ8li8hi3EoFi7us6d1UzaS/+Dp7FYZfg3NdDljGMoVyiIp6Ucz7uhlYDBZ/zt6XI0YEZbUO11Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.1.tgz",
+ "integrity": "sha512-UV6l9MJpDbDZZ/fJvqNcvO1PcivGEf1AvKuTcHoLjVZVFeAMygnamCTDikCVMRnA+qJe+B3pSbgX2+lBMqgBhA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.1.tgz",
+ "integrity": "sha512-UDUtelEprkA85g95Q+nj3Xf0M4hHa4DiJ+3P3h4BuGliY4NReYYqwlc0Y8ICLjN4+uIgCEvaygYlpf0hUj90Yg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.1.tgz",
+ "integrity": "sha512-vrRn+BYhEtNOte/zbc2wAUQReJXxEx2URfTol6OEfY2zFEUK92pkFBSXRylDM7aHi+YqEPJt9/ABYzmcrS4SgQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.1.tgz",
+ "integrity": "sha512-gto/1CxHyi4A7YqZZNznQYrVlPSaodOBPKM+6xcDSCMVZN/Fzb4K+AIkNz/1yAYz9h3Ng+e2fY9H6bgawVq17w==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.1.tgz",
+ "integrity": "sha512-KZ6Vx7jAw3aLNjFR8eYVcQVdFa/cvBzDNRFM3z7XhNNunWjA03eUrEwJYPk0G8V7Gs08IThFKcAPS4WY/ybIrQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.1.tgz",
+ "integrity": "sha512-HvEixy2s/rWNgpwyKpXJcHmE7om1M89hxBTBi9Fs6zVuLU4gOrEMQNbNsN/tBVIMbLyysz/iwNiGtMOpLAOlvA==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.1.tgz",
+ "integrity": "sha512-E/n8x2MSjAQgjj9IixO4UeEUeqXLtiA7pyoXCFYLuXpBA/t2hnbIdxHfA7kK9BFsYAoNU4st1rHYdldl8dTqGA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.1.tgz",
+ "integrity": "sha512-IhJ087PbLOQXCN6Ui/3FUkI9pWNZe/Z7rEIVOzMsOs1/HSAECCvSZ7PkIbkNqL/AZn6WbZvnoVZw/qwqYMo4/w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.1.tgz",
+ "integrity": "sha512-0++oPNgLJHBblreu0SFM7b3mAsBJBTY0Ksrmu9N6ZVrPiTkRgda52mWR7TKhHAsUb9noCjFvAw9l6ZO1yzaVbA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.1.tgz",
+ "integrity": "sha512-VJXivz61c5uVdbmitLkDlbcTk9Or43YC2QVLRkqp86QoeFSqI81bNgjhttqhKNMKnQMWnecOCm7lZz4s+WLGpQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.1.tgz",
+ "integrity": "sha512-NmZPVTUOitCXUH6erJDzTQ/jotYw4CnkMDjCYRxNHVD9bNyfrGoIse684F9okwzKCV4AIHRbUkeTBc9F2OOH5Q==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.1.tgz",
+ "integrity": "sha512-2SNj7COIdAf6yliSpLdLG8BEsp5lgzRehgfkP0Av8zKfQFKku6JcvbobvHASPJu4f3BFxej5g+HuQPvqPhHvpQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.1.tgz",
+ "integrity": "sha512-rLarc1Ofcs3DHtgSzFO31pZsCh8g05R2azN1q3fF+H423Co87My0R+tazOEvYVKXSLh8C4LerMK41/K7wlklcg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
+ "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
+ "license": "BSD-3-Clause",
+ "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==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.2"
+ }
+ },
+ "node_modules/@types/chrome": {
+ "version": "0.1.31",
+ "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.1.31.tgz",
+ "integrity": "sha512-8fC9t02LRdqlSQ9bktaiLjP0NKujPNPaCKPfXxfIjZ35A9u831XY0pt0UEf2oup2SjcUEAaIYOB8mzJ51jhjmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/filesystem": "*",
+ "@types/har-format": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/filesystem": {
+ "version": "0.0.36",
+ "resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.36.tgz",
+ "integrity": "sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/filewriter": "*"
+ }
+ },
+ "node_modules/@types/filewriter": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.33.tgz",
+ "integrity": "sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/@types/har-format": {
+ "version": "1.2.16",
+ "resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.16.tgz",
+ "integrity": "sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "node_modules/@types/minimatch": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
+ "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "24.10.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz",
+ "integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.16.0"
+ }
+ },
+ "node_modules/@types/react": {
+ "version": "19.1.17",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.17.tgz",
+ "integrity": "sha512-Qec1E3mhALmaspIrhWt9jkQMNdw6bReVu64mjvhbhq2NFPftLPVr+l1SZgmw/66WwBNpDh7ao5AT6gF5v41PFA==",
+ "license": "MIT",
+ "dependencies": {
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "19.1.11",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.11.tgz",
+ "integrity": "sha512-3BKc/yGdNTYQVVw4idqHtSOcFsgGuBbMveKCOgF8wQ5QtrYOc3jDIlzg3jef04zcXFIHLelyGlj0T+BJ8+KN+w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^19.0.0"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/@types/yargs": {
+ "version": "17.0.34",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.34.tgz",
+ "integrity": "sha512-KExbHVa92aJpw9WDQvzBaGVE2/Pz+pLZQloT2hjL8IqsZnV62rlPOYvNnLmf/L2dyllfVUOVBj64M0z/46eR2A==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
+ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
+ "license": "ISC"
+ },
+ "node_modules/@urql/core": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@urql/core/-/core-5.2.0.tgz",
+ "integrity": "sha512-/n0ieD0mvvDnVAXEQgX/7qJiVcvYvNkOHeBvkwtylfjydar123caCXcl58PXFY11oU1oquJocVXHxLAbtv4x1A==",
+ "license": "MIT",
+ "dependencies": {
+ "@0no-co/graphql.web": "^1.0.13",
+ "wonka": "^6.3.2"
+ }
+ },
+ "node_modules/@urql/exchange-retry": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@urql/exchange-retry/-/exchange-retry-1.3.2.tgz",
+ "integrity": "sha512-TQMCz2pFJMfpNxmSfX1VSfTjwUIFx/mL+p1bnfM1xjjdla7Z+KnGMW/EhFbpckp3LyWAH4PgOsMwOMnIN+MBFg==",
+ "license": "MIT",
+ "dependencies": {
+ "@urql/core": "^5.1.2",
+ "wonka": "^6.3.2"
+ },
+ "peerDependencies": {
+ "@urql/core": "^5.0.0"
+ }
+ },
+ "node_modules/@webext-core/fake-browser": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@webext-core/fake-browser/-/fake-browser-1.3.2.tgz",
+ "integrity": "sha512-jFyPWWz+VkHAC9DRIiIPOyu6X/KlC8dYqSKweHz6tsDb86QawtVgZSpYcM+GOQBlZc5DHFo92jJ7cIq4uBnU0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash.merge": "^4.6.2"
+ }
+ },
+ "node_modules/@webext-core/isolated-element": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@webext-core/isolated-element/-/isolated-element-1.1.2.tgz",
+ "integrity": "sha512-CNHYhsIR8TPkPb+4yqTIuzaGnVn/Fshev5fyoPW+/8Cyc93tJbCjP9PC1XSK6fDWu+xASdPHLZaoa2nWAYoxeQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-potential-custom-element-name": "^1.0.1"
+ }
+ },
+ "node_modules/@webext-core/match-patterns": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@webext-core/match-patterns/-/match-patterns-1.0.3.tgz",
+ "integrity": "sha512-NY39ACqCxdKBmHgw361M9pfJma8e4AZo20w9AY+5ZjIj1W2dvXC8J31G5fjfOGbulW9w4WKpT8fPooi0mLkn9A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@wxt-dev/browser": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/@wxt-dev/browser/-/browser-0.1.4.tgz",
+ "integrity": "sha512-9x03I15i79XU8qYwjv4le0K2HdMl/Yga2wUBSoUbcrCnamv8P3nvuYxREQ9C5QY/qPAfeEVdAtaTrS3KWak71g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/filesystem": "*",
+ "@types/har-format": "*"
+ }
+ },
+ "node_modules/@wxt-dev/storage": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/@wxt-dev/storage/-/storage-1.2.6.tgz",
+ "integrity": "sha512-f6AknnpJvhNHW4s0WqwSGCuZAj0fjP3EVNPBO5kB30pY+3Zt/nqZGqJN6FgBLCSkYjPJ8VL1hNX5LMVmvxQoDw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@wxt-dev/browser": "^0.1.4",
+ "async-mutex": "^0.5.0",
+ "dequal": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/wxt-dev"
+ }
+ },
+ "node_modules/@xmldom/xmldom": {
+ "version": "0.8.11",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz",
+ "integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/adm-zip": {
+ "version": "0.5.16",
+ "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz",
+ "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/ansi-align": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
+ "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.1.0"
+ }
+ },
+ "node_modules/ansi-align/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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ansi-align/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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-align/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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-escapes/node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/arg": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
+ "license": "MIT"
+ },
+ "node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/aria-hidden": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz",
+ "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/array-differ": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-4.0.0.tgz",
+ "integrity": "sha512-Q6VPTLMsmXZ47ENG3V+wQyZS1ZxXMxFyYzA+Z/GMrJ6yIutAIEf9wTyroTzmGjNfox9/h3GdGBCVh43GVFx4Uw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/array-timsort": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz",
+ "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==",
+ "license": "MIT"
+ },
+ "node_modules/array-union": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz",
+ "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
+ "license": "MIT"
+ },
+ "node_modules/async": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/async-mutex": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.5.0.tgz",
+ "integrity": "sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/atomic-sleep": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
+ "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/atomically": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/atomically/-/atomically-2.1.0.tgz",
+ "integrity": "sha512-+gDffFXRW6sl/HCwbta7zK4uNqbPjv4YJEAdz7Vu+FLQHe77eZ4bvbJGi4hE0QPeJlMYMA3piXEr1UL3dAwx7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "stubborn-fs": "^2.0.0",
+ "when-exit": "^2.1.4"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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-jest/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/babel-jest/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/babel-jest/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/babel-jest/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==",
+ "license": "MIT"
+ },
+ "node_modules/babel-jest/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/babel-jest/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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==",
+ "license": "BSD-3-Clause",
+ "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==",
+ "license": "MIT",
+ "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-polyfill-corejs2": {
+ "version": "0.4.14",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz",
+ "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.27.7",
+ "@babel/helper-define-polyfill-provider": "^0.6.5",
+ "semver": "^6.3.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs3": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz",
+ "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.5",
+ "core-js-compat": "^3.43.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-regenerator": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz",
+ "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.5"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-react-compiler": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz",
+ "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.26.0"
+ }
+ },
+ "node_modules/babel-plugin-react-native-web": {
+ "version": "0.21.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.21.2.tgz",
+ "integrity": "sha512-SPD0J6qjJn8231i0HZhlAGH6NORe+QvRSQM2mwQEzJ2Fb3E4ruWTiiicPlHjmeWShDXLcvoorOCXjeR7k/lyWA==",
+ "license": "MIT"
+ },
+ "node_modules/babel-plugin-syntax-hermes-parser": {
+ "version": "0.29.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.29.1.tgz",
+ "integrity": "sha512-2WFYnoWGdmih1I1J5eIqxATOeycOqRwYxAQBu3cUu/rhwInwHUg7k60AFNbuGjSDL8tje5GDrAnxzRLcu2pYcA==",
+ "license": "MIT",
+ "dependencies": {
+ "hermes-parser": "0.29.1"
+ }
+ },
+ "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-estree": {
+ "version": "0.29.1",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz",
+ "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==",
+ "license": "MIT"
+ },
+ "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-parser": {
+ "version": "0.29.1",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz",
+ "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==",
+ "license": "MIT",
+ "dependencies": {
+ "hermes-estree": "0.29.1"
+ }
+ },
+ "node_modules/babel-plugin-transform-flow-enums": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz",
+ "integrity": "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/plugin-syntax-flow": "^7.12.1"
+ }
+ },
+ "node_modules/babel-preset-current-node-syntax": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz",
+ "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==",
+ "license": "MIT",
+ "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 || ^8.0.0-0"
+ }
+ },
+ "node_modules/babel-preset-expo": {
+ "version": "54.0.7",
+ "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-54.0.7.tgz",
+ "integrity": "sha512-JENWk0bvxW4I1ftveO8GRtX2t2TH6N4Z0TPvIHxroZ/4SswUfyNsUNbbP7Fm4erj3ar/JHGri5kTZ+s3xdjHZw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/plugin-proposal-decorators": "^7.12.9",
+ "@babel/plugin-proposal-export-default-from": "^7.24.7",
+ "@babel/plugin-syntax-export-default-from": "^7.24.7",
+ "@babel/plugin-transform-class-static-block": "^7.27.1",
+ "@babel/plugin-transform-export-namespace-from": "^7.25.9",
+ "@babel/plugin-transform-flow-strip-types": "^7.25.2",
+ "@babel/plugin-transform-modules-commonjs": "^7.24.8",
+ "@babel/plugin-transform-object-rest-spread": "^7.24.7",
+ "@babel/plugin-transform-parameters": "^7.24.7",
+ "@babel/plugin-transform-private-methods": "^7.24.7",
+ "@babel/plugin-transform-private-property-in-object": "^7.24.7",
+ "@babel/plugin-transform-runtime": "^7.24.7",
+ "@babel/preset-react": "^7.22.15",
+ "@babel/preset-typescript": "^7.23.0",
+ "@react-native/babel-preset": "0.81.5",
+ "babel-plugin-react-compiler": "^1.0.0",
+ "babel-plugin-react-native-web": "~0.21.0",
+ "babel-plugin-syntax-hermes-parser": "^0.29.1",
+ "babel-plugin-transform-flow-enums": "^0.0.2",
+ "debug": "^4.3.4",
+ "resolve-from": "^5.0.0"
+ },
+ "peerDependencies": {
+ "@babel/runtime": "^7.20.0",
+ "expo": "*",
+ "react-refresh": ">=0.14.0 <1.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@babel/runtime": {
+ "optional": true
+ },
+ "expo": {
+ "optional": true
+ }
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT"
+ },
+ "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"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.8.25",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.25.tgz",
+ "integrity": "sha512-2NovHVesVF5TXefsGX1yzx1xgr7+m9JQenvz6FQY3qd+YXkKkYiv+vTCc7OriP9mcDZpTC5mAOYN4ocd29+erA==",
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.js"
+ }
+ },
+ "node_modules/better-opn": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz",
+ "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==",
+ "license": "MIT",
+ "dependencies": {
+ "open": "^8.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/better-opn/node_modules/open": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
+ "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
+ "license": "MIT",
+ "dependencies": {
+ "define-lazy-prop": "^2.0.0",
+ "is-docker": "^2.1.1",
+ "is-wsl": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "Unlicense",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "license": "ISC"
+ },
+ "node_modules/boxen": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz",
+ "integrity": "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-align": "^3.0.1",
+ "camelcase": "^8.0.0",
+ "chalk": "^5.3.0",
+ "cli-boxes": "^3.0.0",
+ "string-width": "^7.2.0",
+ "type-fest": "^4.21.0",
+ "widest-line": "^5.0.0",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/boxen/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/boxen/node_modules/camelcase": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz",
+ "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/boxen/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/boxen/node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/boxen/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/boxen/node_modules/type-fest": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz",
+ "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/boxen/node_modules/wrap-ansi": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+ "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "big-integer": "1.6.x"
+ },
+ "engines": {
+ "node": ">= 5.10.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.27.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz",
+ "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==",
+ "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"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.8.19",
+ "caniuse-lite": "^1.0.30001751",
+ "electron-to-chromium": "^1.5.238",
+ "node-releases": "^2.0.26",
+ "update-browserslist-db": "^1.1.4"
+ },
+ "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==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/bundle-name": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
+ "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "run-applescript": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/c12": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/c12/-/c12-3.3.1.tgz",
+ "integrity": "sha512-LcWQ01LT9tkoUINHgpIOv3mMs+Abv7oVCrtpMRi1PaapVEpWoMga5WuT7/DqFTu7URP9ftbOmimNw1KNIGh9DQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^4.0.3",
+ "confbox": "^0.2.2",
+ "defu": "^6.1.4",
+ "dotenv": "^17.2.3",
+ "exsolve": "^1.0.7",
+ "giget": "^2.0.0",
+ "jiti": "^2.6.1",
+ "ohash": "^2.0.11",
+ "pathe": "^2.0.3",
+ "perfect-debounce": "^2.0.0",
+ "pkg-types": "^2.3.0",
+ "rc9": "^2.1.2"
+ },
+ "peerDependencies": {
+ "magicast": "^0.3.5"
+ },
+ "peerDependenciesMeta": {
+ "magicast": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/c12/node_modules/dotenv": {
+ "version": "17.2.3",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz",
+ "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/cac": {
+ "version": "6.7.14",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/camelcase-css": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
+ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001754",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz",
+ "integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==",
+ "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"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/chownr": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
+ "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "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==",
+ "license": "Apache-2.0",
+ "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/chrome-launcher/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "Apache-2.0",
+ "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/chromium-edge-launcher/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/citty": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz",
+ "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "consola": "^3.2.3"
+ }
+ },
+ "node_modules/cli-boxes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz",
+ "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-cursor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==",
+ "license": "MIT",
+ "dependencies": {
+ "restore-cursor": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cli-spinners": {
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
+ "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-truncate": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz",
+ "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "slice-ansi": "^5.0.0",
+ "string-width": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-truncate/node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cli-truncate/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/client-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/cliui/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/cliui/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/cliui/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==",
+ "license": "MIT"
+ },
+ "node_modules/cliui/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==",
+ "license": "MIT"
+ },
+ "node_modules/cliui/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==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/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==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/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==",
+ "license": "MIT",
+ "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/clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/color": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
+ "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1",
+ "color-string": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=12.5.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "^1.0.0",
+ "simple-swizzle": "^0.2.2"
+ }
+ },
+ "node_modules/color/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color/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==",
+ "license": "MIT"
+ },
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/comment-json": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.4.1.tgz",
+ "integrity": "sha512-r1To31BQD5060QdkC+Iheai7gHwoSZobzunqkf2/kQ6xIAfJyrKNAFUwdKvkK7Qgu7pVTKQEa7ok7Ed3ycAJgg==",
+ "license": "MIT",
+ "dependencies": {
+ "array-timsort": "^1.0.3",
+ "core-util-is": "^1.0.3",
+ "esprima": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/compressible": {
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
+ "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": ">= 1.43.0 < 2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/compression": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz",
+ "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "compressible": "~2.0.18",
+ "debug": "2.6.9",
+ "negotiator": "~0.6.4",
+ "on-headers": "~1.1.0",
+ "safe-buffer": "5.2.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/compression/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/compression/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
+ },
+ "node_modules/compression/node_modules/negotiator": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
+ "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "license": "MIT"
+ },
+ "node_modules/concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "dev": true,
+ "engines": [
+ "node >= 0.8"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "node_modules/confbox": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz",
+ "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/config-chain": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
+ }
+ },
+ "node_modules/configstore": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-7.1.0.tgz",
+ "integrity": "sha512-N4oog6YJWbR9kGyXvS7jEykLDXIE2C0ILYqNBZBp9iwiJpoCBWYsuAdW6PPFn6w06jjnC+3JstVvWHO4cZqvRg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "atomically": "^2.0.3",
+ "dot-prop": "^9.0.0",
+ "graceful-fs": "^4.2.11",
+ "xdg-basedir": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/connect": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
+ "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/consola": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
+ "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.18.0 || >=16.10.0"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/core-js-compat": {
+ "version": "3.46.0",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.46.0.tgz",
+ "integrity": "sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==",
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.26.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "license": "MIT"
+ },
+ "node_modules/cross-fetch": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
+ "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==",
+ "license": "MIT",
+ "dependencies": {
+ "node-fetch": "^2.7.0"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/crypto-random-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
+ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/css-in-js-utils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz",
+ "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==",
+ "license": "MIT",
+ "dependencies": {
+ "hyphenate-style-name": "^1.0.3"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
+ "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
+ "license": "BSD-2-Clause",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
+ "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cssom": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz",
+ "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "license": "MIT"
+ },
+ "node_modules/debounce": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
+ "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/default-browser": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
+ "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bundle-name": "^4.1.0",
+ "default-browser-id": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/default-browser-id": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz",
+ "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/defaults": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
+ "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
+ "license": "MIT",
+ "dependencies": {
+ "clone": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/define-lazy-prop": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
+ "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/defu": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
+ "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/destr": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz",
+ "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/detect-node-es": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
+ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",
+ "license": "MIT"
+ },
+ "node_modules/didyoumean": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
+ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/dlv": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
+ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "license": "BSD-2-Clause",
+ "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==",
+ "license": "BSD-2-Clause",
+ "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-prop": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-9.0.0.tgz",
+ "integrity": "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^4.18.2"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/dot-prop/node_modules/type-fest": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz",
+ "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "16.4.7",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
+ "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/dotenv-expand": {
+ "version": "11.0.7",
+ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz",
+ "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dotenv": "^16.4.5"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.249",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.249.tgz",
+ "integrity": "sha512-5vcfL3BBe++qZ5kuFhD/p8WOM1N9m3nwvJPULJx+4xf2usSlZFJ0qoNYO2fOX4hi3ocuDcmDobtA+5SFr4OmBg==",
+ "license": "ISC"
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/env-editor": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-0.4.2.tgz",
+ "integrity": "sha512-ObFo8v4rQJAE59M69QzwloxPZtd33TpYEIjtKD1rrFDcM1Gd7IkDxEBU+HriziN6HSHQnBJi8Dmy+JWkav5HKA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/environment": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz",
+ "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz",
+ "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==",
+ "dev": true,
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "stackframe": "^1.3.4"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
+ "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/es6-error": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
+ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/esbuild": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",
+ "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.12",
+ "@esbuild/android-arm": "0.25.12",
+ "@esbuild/android-arm64": "0.25.12",
+ "@esbuild/android-x64": "0.25.12",
+ "@esbuild/darwin-arm64": "0.25.12",
+ "@esbuild/darwin-x64": "0.25.12",
+ "@esbuild/freebsd-arm64": "0.25.12",
+ "@esbuild/freebsd-x64": "0.25.12",
+ "@esbuild/linux-arm": "0.25.12",
+ "@esbuild/linux-arm64": "0.25.12",
+ "@esbuild/linux-ia32": "0.25.12",
+ "@esbuild/linux-loong64": "0.25.12",
+ "@esbuild/linux-mips64el": "0.25.12",
+ "@esbuild/linux-ppc64": "0.25.12",
+ "@esbuild/linux-riscv64": "0.25.12",
+ "@esbuild/linux-s390x": "0.25.12",
+ "@esbuild/linux-x64": "0.25.12",
+ "@esbuild/netbsd-arm64": "0.25.12",
+ "@esbuild/netbsd-x64": "0.25.12",
+ "@esbuild/openbsd-arm64": "0.25.12",
+ "@esbuild/openbsd-x64": "0.25.12",
+ "@esbuild/openharmony-arm64": "0.25.12",
+ "@esbuild/sunos-x64": "0.25.12",
+ "@esbuild/win32-arm64": "0.25.12",
+ "@esbuild/win32-ia32": "0.25.12",
+ "@esbuild/win32-x64": "0.25.12"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-goat": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz",
+ "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "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==",
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/eventemitter3": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
+ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/exec-async": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/exec-async/-/exec-async-2.2.0.tgz",
+ "integrity": "sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw==",
+ "license": "MIT"
+ },
+ "node_modules/execa": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
+ "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^8.0.1",
+ "human-signals": "^5.0.0",
+ "is-stream": "^3.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^5.1.0",
+ "onetime": "^6.0.0",
+ "signal-exit": "^4.1.0",
+ "strip-final-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/execa/node_modules/mimic-fn": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
+ "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/execa/node_modules/onetime": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+ "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/expo": {
+ "version": "54.0.23",
+ "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.23.tgz",
+ "integrity": "sha512-b4uQoiRwQ6nwqsT2709RS15CWYNGF3eJtyr1KyLw9WuMAK7u4jjofkhRiO0+3o1C2NbV+WooyYTOZGubQQMBaQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.20.0",
+ "@expo/cli": "54.0.16",
+ "@expo/config": "~12.0.10",
+ "@expo/config-plugins": "~54.0.2",
+ "@expo/devtools": "0.1.7",
+ "@expo/fingerprint": "0.15.3",
+ "@expo/metro": "~54.1.0",
+ "@expo/metro-config": "54.0.9",
+ "@expo/vector-icons": "^15.0.3",
+ "@ungap/structured-clone": "^1.3.0",
+ "babel-preset-expo": "~54.0.7",
+ "expo-asset": "~12.0.9",
+ "expo-constants": "~18.0.10",
+ "expo-file-system": "~19.0.17",
+ "expo-font": "~14.0.9",
+ "expo-keep-awake": "~15.0.7",
+ "expo-modules-autolinking": "3.0.21",
+ "expo-modules-core": "3.0.25",
+ "pretty-format": "^29.7.0",
+ "react-refresh": "^0.14.2",
+ "whatwg-url-without-unicode": "8.0.0-3"
+ },
+ "bin": {
+ "expo": "bin/cli",
+ "expo-modules-autolinking": "bin/autolinking",
+ "fingerprint": "bin/fingerprint"
+ },
+ "peerDependencies": {
+ "@expo/dom-webview": "*",
+ "@expo/metro-runtime": "*",
+ "react": "*",
+ "react-native": "*",
+ "react-native-webview": "*"
+ },
+ "peerDependenciesMeta": {
+ "@expo/dom-webview": {
+ "optional": true
+ },
+ "@expo/metro-runtime": {
+ "optional": true
+ },
+ "react-native-webview": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/expo-application": {
+ "version": "7.0.7",
+ "resolved": "https://registry.npmjs.org/expo-application/-/expo-application-7.0.7.tgz",
+ "integrity": "sha512-Jt1/qqnoDUbZ+bK91+dHaZ1vrPDtRBOltRa681EeedkisqguuEeUx4UHqwVyDK2oHWsK6lO3ojetoA4h8OmNcg==",
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
+ "node_modules/expo-auth-session": {
+ "version": "7.0.9",
+ "resolved": "https://registry.npmjs.org/expo-auth-session/-/expo-auth-session-7.0.9.tgz",
+ "integrity": "sha512-mPSwaRWOJYas160lXi5P/7BkLy0xbh+er+IMmAYHqf2+iz2WWs9W/4lMAklQVJG2mCyOZi24XrkffvB2izCa1g==",
+ "dependencies": {
+ "expo-application": "~7.0.7",
+ "expo-constants": "~18.0.10",
+ "expo-crypto": "~15.0.7",
+ "expo-linking": "~8.0.9",
+ "expo-web-browser": "~15.0.9",
+ "invariant": "^2.2.4"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/expo-constants": {
+ "version": "18.0.10",
+ "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.10.tgz",
+ "integrity": "sha512-Rhtv+X974k0Cahmvx6p7ER5+pNhBC0XbP1lRviL2J1Xl4sT2FBaIuIxF/0I0CbhOsySf0ksqc5caFweAy9Ewiw==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/config": "~12.0.10",
+ "@expo/env": "~2.0.7"
+ },
+ "peerDependencies": {
+ "expo": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/expo-crypto": {
+ "version": "15.0.7",
+ "resolved": "https://registry.npmjs.org/expo-crypto/-/expo-crypto-15.0.7.tgz",
+ "integrity": "sha512-FUo41TwwGT2e5rA45PsjezI868Ch3M6wbCZsmqTWdF/hr+HyPcrp1L//dsh/hsrsyrQdpY/U96Lu71/wXePJeg==",
+ "dependencies": {
+ "base64-js": "^1.3.0"
+ },
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
+ "node_modules/expo-device": {
+ "version": "8.0.9",
+ "resolved": "https://registry.npmjs.org/expo-device/-/expo-device-8.0.9.tgz",
+ "integrity": "sha512-XqRpaljDNAYZGZzMpC+b9KZfzfydtkwx3pJAp6ODDH+O/5wjAw+mLc5wQMGJCx8/aqVmMsAokec7iebxDPFZDA==",
+ "license": "MIT",
+ "dependencies": {
+ "ua-parser-js": "^0.7.33"
+ },
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
+ "node_modules/expo-device/node_modules/ua-parser-js": {
+ "version": "0.7.41",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.41.tgz",
+ "integrity": "sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/ua-parser-js"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/faisalman"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/faisalman"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "ua-parser-js": "script/cli.js"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/expo-font": {
+ "version": "14.0.9",
+ "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.9.tgz",
+ "integrity": "sha512-xCoQbR/36qqB6tew/LQ6GWICpaBmHLhg/Loix5Rku/0ZtNaXMJv08M9o1AcrdiGTn/Xf/BnLu6DgS45cWQEHZg==",
+ "license": "MIT",
+ "dependencies": {
+ "fontfaceobserver": "^2.1.0"
+ },
+ "peerDependencies": {
+ "expo": "*",
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/expo-glass-effect": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/expo-glass-effect/-/expo-glass-effect-0.1.6.tgz",
+ "integrity": "sha512-cwYJJJcvzwvl5XULEAVCrR5EPe/x/M/LOHq7wcsRR4ATuce2z/ZGGv/7cGcbOcHlWn30a3g3BIiuEynGCC47wg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "expo": "*",
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/expo-linking": {
+ "version": "8.0.9",
+ "resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-8.0.9.tgz",
+ "integrity": "sha512-a0UHhlVyfwIbn8b1PSFPoFiIDJeps2iEq109hVH3CHd0CMKuRxFfNio9Axe2BjXhiJCYWR4OV1iIyzY/GjiVkQ==",
+ "dependencies": {
+ "expo-constants": "~18.0.10",
+ "invariant": "^2.2.4"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/expo-modules-autolinking": {
+ "version": "3.0.21",
+ "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.21.tgz",
+ "integrity": "sha512-pOtPDLln3Ju8DW1zRW4OwZ702YqZ8g+kM/tEY1sWfv22kWUtxkvK+ytRDRpRdnKEnC28okbhWqeMnmVkSFzP6Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/spawn-async": "^1.7.2",
+ "chalk": "^4.1.0",
+ "commander": "^7.2.0",
+ "require-from-string": "^2.0.2",
+ "resolve-from": "^5.0.0"
+ },
+ "bin": {
+ "expo-modules-autolinking": "bin/expo-modules-autolinking.js"
+ }
+ },
+ "node_modules/expo-modules-autolinking/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/expo-modules-autolinking/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/expo-modules-autolinking/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/expo-modules-autolinking/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==",
+ "license": "MIT"
+ },
+ "node_modules/expo-modules-autolinking/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/expo-modules-autolinking/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/expo-modules-core": {
+ "version": "3.0.25",
+ "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-3.0.25.tgz",
+ "integrity": "sha512-0P8PT8UV6c5/+p8zeVM/FXvBgn/ErtGcMaasqUgbzzBUg94ktbkIrij9t9reGCrir03BYt/Bcpv+EQtYC8JOug==",
+ "license": "MIT",
+ "dependencies": {
+ "invariant": "^2.2.4"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/expo-router": {
+ "version": "6.0.14",
+ "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-6.0.14.tgz",
+ "integrity": "sha512-vizLO4SgnMEL+PPs2dXr+etEOuksjue7yUQBCtfCEdqoDkQlB0r35zI7rS34Wt53sxKWSlM2p+038qQEpxtiFw==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/metro-runtime": "^6.1.2",
+ "@expo/schema-utils": "^0.1.7",
+ "@radix-ui/react-slot": "1.2.0",
+ "@radix-ui/react-tabs": "^1.1.12",
+ "@react-navigation/bottom-tabs": "^7.4.0",
+ "@react-navigation/native": "^7.1.8",
+ "@react-navigation/native-stack": "^7.3.16",
+ "client-only": "^0.0.1",
+ "debug": "^4.3.4",
+ "escape-string-regexp": "^4.0.0",
+ "expo-server": "^1.0.3",
+ "fast-deep-equal": "^3.1.3",
+ "invariant": "^2.2.4",
+ "nanoid": "^3.3.8",
+ "query-string": "^7.1.3",
+ "react-fast-compare": "^3.2.2",
+ "react-native-is-edge-to-edge": "^1.1.6",
+ "semver": "~7.6.3",
+ "server-only": "^0.0.1",
+ "sf-symbols-typescript": "^2.1.0",
+ "shallowequal": "^1.1.0",
+ "use-latest-callback": "^0.2.1",
+ "vaul": "^1.1.2"
+ },
+ "peerDependencies": {
+ "@expo/metro-runtime": "^6.1.2",
+ "@react-navigation/drawer": "^7.5.0",
+ "@testing-library/react-native": ">= 12.0.0",
+ "expo": "*",
+ "expo-constants": "^18.0.10",
+ "expo-linking": "^8.0.8",
+ "react": "*",
+ "react-dom": "*",
+ "react-native": "*",
+ "react-native-gesture-handler": "*",
+ "react-native-reanimated": "*",
+ "react-native-safe-area-context": ">= 5.4.0",
+ "react-native-screens": "*",
+ "react-native-web": "*",
+ "react-server-dom-webpack": ">= 19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@react-navigation/drawer": {
+ "optional": true
+ },
+ "@testing-library/react-native": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ },
+ "react-native-gesture-handler": {
+ "optional": true
+ },
+ "react-native-reanimated": {
+ "optional": true
+ },
+ "react-native-web": {
+ "optional": true
+ },
+ "react-server-dom-webpack": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/expo-router/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/expo-router/node_modules/semver": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/expo-secure-store": {
+ "version": "15.0.7",
+ "resolved": "https://registry.npmjs.org/expo-secure-store/-/expo-secure-store-15.0.7.tgz",
+ "integrity": "sha512-9q7+G1Zxr5P6J5NRIlm86KulvmYwc6UnQlYPjQLDu1drDnerz6AT6l884dPu29HgtDTn4rR0heYeeGFhMKM7/Q==",
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
+ "node_modules/expo-server": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/expo-server/-/expo-server-1.0.4.tgz",
+ "integrity": "sha512-IN06r3oPxFh3plSXdvBL7dx0x6k+0/g0bgxJlNISs6qL5Z+gyPuWS750dpTzOeu37KyBG0RcyO9cXUKzjYgd4A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.16.0"
+ }
+ },
+ "node_modules/expo-status-bar": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-3.0.8.tgz",
+ "integrity": "sha512-L248XKPhum7tvREoS1VfE0H6dPCaGtoUWzRsUv7hGKdiB4cus33Rc0sxkWkoQ77wE8stlnUlL5lvmT0oqZ3ZBw==",
+ "license": "MIT",
+ "dependencies": {
+ "react-native-is-edge-to-edge": "^1.2.1"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/expo-web-browser": {
+ "version": "15.0.9",
+ "resolved": "https://registry.npmjs.org/expo-web-browser/-/expo-web-browser-15.0.9.tgz",
+ "integrity": "sha512-Dj8kNFO+oXsxqCDNlUT/GhOrJnm10kAElH++3RplLydogFm5jTzXYWDEeNIDmV+F+BzGYs+sIhxiBf7RyaxXZg==",
+ "peerDependencies": {
+ "expo": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/expo/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==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/expo/node_modules/@expo/cli": {
+ "version": "54.0.16",
+ "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.16.tgz",
+ "integrity": "sha512-hY/OdRaJMs5WsVPuVSZ+RLH3VObJmL/pv5CGCHEZHN2PxZjSZSdctyKV8UcFBXTF0yIKNAJ9XLs1dlNYXHh4Cw==",
+ "license": "MIT",
+ "dependencies": {
+ "@0no-co/graphql.web": "^1.0.8",
+ "@expo/code-signing-certificates": "^0.0.5",
+ "@expo/config": "~12.0.10",
+ "@expo/config-plugins": "~54.0.2",
+ "@expo/devcert": "^1.1.2",
+ "@expo/env": "~2.0.7",
+ "@expo/image-utils": "^0.8.7",
+ "@expo/json-file": "^10.0.7",
+ "@expo/mcp-tunnel": "~0.1.0",
+ "@expo/metro": "~54.1.0",
+ "@expo/metro-config": "~54.0.9",
+ "@expo/osascript": "^2.3.7",
+ "@expo/package-manager": "^1.9.8",
+ "@expo/plist": "^0.4.7",
+ "@expo/prebuild-config": "^54.0.6",
+ "@expo/schema-utils": "^0.1.7",
+ "@expo/spawn-async": "^1.7.2",
+ "@expo/ws-tunnel": "^1.0.1",
+ "@expo/xcpretty": "^4.3.0",
+ "@react-native/dev-middleware": "0.81.5",
+ "@urql/core": "^5.0.6",
+ "@urql/exchange-retry": "^1.3.0",
+ "accepts": "^1.3.8",
+ "arg": "^5.0.2",
+ "better-opn": "~3.0.2",
+ "bplist-creator": "0.1.0",
+ "bplist-parser": "^0.3.1",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.3.0",
+ "compression": "^1.7.4",
+ "connect": "^3.7.0",
+ "debug": "^4.3.4",
+ "env-editor": "^0.4.1",
+ "expo-server": "^1.0.4",
+ "freeport-async": "^2.0.0",
+ "getenv": "^2.0.0",
+ "glob": "^10.4.2",
+ "lan-network": "^0.1.6",
+ "minimatch": "^9.0.0",
+ "node-forge": "^1.3.1",
+ "npm-package-arg": "^11.0.0",
+ "ora": "^3.4.0",
+ "picomatch": "^3.0.1",
+ "pretty-bytes": "^5.6.0",
+ "pretty-format": "^29.7.0",
+ "progress": "^2.0.3",
+ "prompts": "^2.3.2",
+ "qrcode-terminal": "0.11.0",
+ "require-from-string": "^2.0.2",
+ "requireg": "^0.2.2",
+ "resolve": "^1.22.2",
+ "resolve-from": "^5.0.0",
+ "resolve.exports": "^2.0.3",
+ "semver": "^7.6.0",
+ "send": "^0.19.0",
+ "slugify": "^1.3.4",
+ "source-map-support": "~0.5.21",
+ "stacktrace-parser": "^0.1.10",
+ "structured-headers": "^0.4.1",
+ "tar": "^7.4.3",
+ "terminal-link": "^2.1.1",
+ "undici": "^6.18.2",
+ "wrap-ansi": "^7.0.0",
+ "ws": "^8.12.1"
+ },
+ "bin": {
+ "expo-internal": "build/bin/cli"
+ },
+ "peerDependencies": {
+ "expo": "*",
+ "expo-router": "*",
+ "react-native": "*"
+ },
+ "peerDependenciesMeta": {
+ "expo-router": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/expo/node_modules/@expo/cli/node_modules/@expo/prebuild-config": {
+ "version": "54.0.6",
+ "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-54.0.6.tgz",
+ "integrity": "sha512-xowuMmyPNy+WTNq+YX0m0EFO/Knc68swjThk4dKivgZa8zI1UjvFXOBIOp8RX4ljCXLzwxQJM5oBBTvyn+59ZA==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/config": "~12.0.10",
+ "@expo/config-plugins": "~54.0.2",
+ "@expo/config-types": "^54.0.8",
+ "@expo/image-utils": "^0.8.7",
+ "@expo/json-file": "^10.0.7",
+ "@react-native/normalize-colors": "0.81.5",
+ "debug": "^4.3.1",
+ "resolve-from": "^5.0.0",
+ "semver": "^7.6.0",
+ "xml2js": "0.6.0"
+ },
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
+ "node_modules/expo/node_modules/@expo/metro-config": {
+ "version": "54.0.9",
+ "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-54.0.9.tgz",
+ "integrity": "sha512-CRI4WgFXrQ2Owyr8q0liEBJveUIF9DcYAKadMRsJV7NxGNBdrIIKzKvqreDfsGiRqivbLsw6UoNb3UE7/SvPfg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.20.0",
+ "@babel/core": "^7.20.0",
+ "@babel/generator": "^7.20.5",
+ "@expo/config": "~12.0.10",
+ "@expo/env": "~2.0.7",
+ "@expo/json-file": "~10.0.7",
+ "@expo/metro": "~54.1.0",
+ "@expo/spawn-async": "^1.7.2",
+ "browserslist": "^4.25.0",
+ "chalk": "^4.1.0",
+ "debug": "^4.3.2",
+ "dotenv": "~16.4.5",
+ "dotenv-expand": "~11.0.6",
+ "getenv": "^2.0.0",
+ "glob": "^10.4.2",
+ "hermes-parser": "^0.29.1",
+ "jsc-safe-url": "^0.2.4",
+ "lightningcss": "^1.30.1",
+ "minimatch": "^9.0.0",
+ "postcss": "~8.4.32",
+ "resolve-from": "^5.0.0"
+ },
+ "peerDependencies": {
+ "expo": "*"
+ },
+ "peerDependenciesMeta": {
+ "expo": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/expo/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/expo/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/expo/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"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/expo/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/expo/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==",
+ "license": "MIT"
+ },
+ "node_modules/expo/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==",
+ "license": "MIT"
+ },
+ "node_modules/expo/node_modules/expo-asset": {
+ "version": "12.0.9",
+ "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-12.0.9.tgz",
+ "integrity": "sha512-vrdRoyhGhBmd0nJcssTSk1Ypx3Mbn/eXaaBCQVkL0MJ8IOZpAObAjfD5CTy8+8RofcHEQdh3wwZVCs7crvfOeg==",
+ "license": "MIT",
+ "dependencies": {
+ "@expo/image-utils": "^0.8.7",
+ "expo-constants": "~18.0.9"
+ },
+ "peerDependencies": {
+ "expo": "*",
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/expo/node_modules/expo-file-system": {
+ "version": "19.0.17",
+ "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-19.0.17.tgz",
+ "integrity": "sha512-WwaS01SUFrxBnExn87pg0sCTJjZpf2KAOzfImG0o8yhkU7fbYpihpl/oocXBEsNbj58a8hVt1Y4CVV5c1tzu/g==",
+ "license": "MIT",
+ "peerDependencies": {
+ "expo": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/expo/node_modules/expo-keep-awake": {
+ "version": "15.0.7",
+ "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.7.tgz",
+ "integrity": "sha512-CgBNcWVPnrIVII5G54QDqoE125l+zmqR4HR8q+MQaCfHet+dYpS5vX5zii/RMayzGN4jPgA4XYIQ28ePKFjHoA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "expo": "*",
+ "react": "*"
+ }
+ },
+ "node_modules/expo/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/expo/node_modules/hermes-estree": {
+ "version": "0.29.1",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz",
+ "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==",
+ "license": "MIT"
+ },
+ "node_modules/expo/node_modules/hermes-parser": {
+ "version": "0.29.1",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz",
+ "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==",
+ "license": "MIT",
+ "dependencies": {
+ "hermes-estree": "0.29.1"
+ }
+ },
+ "node_modules/expo/node_modules/picomatch": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz",
+ "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/expo/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==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/expo/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==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/expo/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/expo/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==",
+ "license": "MIT",
+ "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/expo/node_modules/ws": {
+ "version": "8.18.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
+ "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/exponential-backoff": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz",
+ "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/exsolve": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz",
+ "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/fast-redact": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz",
+ "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "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==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "bser": "2.1.1"
+ }
+ },
+ "node_modules/fbjs": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz",
+ "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==",
+ "license": "MIT",
+ "dependencies": {
+ "cross-fetch": "^3.1.5",
+ "fbjs-css-vars": "^1.0.0",
+ "loose-envify": "^1.0.0",
+ "object-assign": "^4.1.0",
+ "promise": "^7.1.1",
+ "setimmediate": "^1.0.5",
+ "ua-parser-js": "^1.0.35"
+ }
+ },
+ "node_modules/fbjs-css-vars": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
+ "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==",
+ "license": "MIT"
+ },
+ "node_modules/fbjs/node_modules/promise": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "license": "MIT",
+ "dependencies": {
+ "asap": "~2.0.3"
+ }
+ },
+ "node_modules/filesize": {
+ "version": "11.0.13",
+ "resolved": "https://registry.npmjs.org/filesize/-/filesize-11.0.13.tgz",
+ "integrity": "sha512-mYJ/qXKvREuO0uH8LTQJ6v7GsUvVOguqxg2VTwQUkyTPXXRRWPdjuUPVqdBrJQhvci48OHlNGRnux+Slr2Rnvw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">= 10.8.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/firefox-profile": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/firefox-profile/-/firefox-profile-4.7.0.tgz",
+ "integrity": "sha512-aGApEu5bfCNbA4PGUZiRJAIU6jKmghV2UVdklXAofnNtiDjqYw0czLS46W7IfFqVKgKhFB8Ao2YoNGHY4BoIMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "adm-zip": "~0.5.x",
+ "fs-extra": "^11.2.0",
+ "ini": "^4.1.3",
+ "minimist": "^1.2.8",
+ "xml2js": "^0.6.2"
+ },
+ "bin": {
+ "firefox-profile": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/firefox-profile/node_modules/ini": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz",
+ "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/firefox-profile/node_modules/xml2js": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
+ "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~11.0.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/firefox-profile/node_modules/xmlbuilder": {
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/fontfaceobserver": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz",
+ "integrity": "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg==",
+ "license": "BSD-2-Clause"
+ },
+ "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==",
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/form-data-encoder": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-4.1.0.tgz",
+ "integrity": "sha512-G6NsmEW15s0Uw9XnCg+33H3ViYRyiM0hMrMhhqQOR8NFc5GhYrI+6I3u7OTw7b91J2g8rtvMBZJDbcGb2YUniw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/formdata-node": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-6.0.3.tgz",
+ "integrity": "sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/freeport-async": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/freeport-async/-/freeport-async-2.0.0.tgz",
+ "integrity": "sha512-K7od3Uw45AJg00XUmy15+Hae2hOcgKcmN3/EF6Y7i01O0gaqiRx8sUSpsb9+BRNL8RPBrhzPsVfy8q9ADlJuWQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fs-extra": {
+ "version": "11.3.2",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz",
+ "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "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==",
+ "license": "ISC"
+ },
+ "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,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/fx-runner": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/fx-runner/-/fx-runner-1.4.0.tgz",
+ "integrity": "sha512-rci1g6U0rdTg6bAaBboP7XdRu01dzTAaKXxFf+PUqGuCv6Xu7o8NZdY1D5MvKGIjb6EdS1g3VlXOgksir1uGkg==",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "commander": "2.9.0",
+ "shell-quote": "1.7.3",
+ "spawn-sync": "1.0.15",
+ "when": "3.7.7",
+ "which": "1.2.4",
+ "winreg": "0.0.12"
+ },
+ "bin": {
+ "fx-runner": "bin/fx-runner"
+ }
+ },
+ "node_modules/fx-runner/node_modules/commander": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
+ "integrity": "sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-readlink": ">= 1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6.x"
+ }
+ },
+ "node_modules/fx-runner/node_modules/isexe": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz",
+ "integrity": "sha512-d2eJzK691yZwPHcv1LbeAOa91yMJ9QmfTgSO1oXB65ezVhXQsxBac2vEB4bMVms9cGzaA99n6V2viHMq82VLDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fx-runner/node_modules/shell-quote": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz",
+ "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fx-runner/node_modules/which": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.2.4.tgz",
+ "integrity": "sha512-zDRAqDSBudazdfM9zpiI30Fu9ve47htYXcGi3ln0wfKu2a7SmrT6F3VDoYONu//48V8Vz4TdCRNPjtvyRO3yBA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-absolute": "^0.1.7",
+ "isexe": "^1.1.1"
+ },
+ "bin": {
+ "which": "bin/which"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-east-asian-width": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz",
+ "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-nonce": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
+ "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/get-port-please": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/get-port-please/-/get-port-please-3.2.0.tgz",
+ "integrity": "sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/get-stream": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
+ "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/getenv": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/getenv/-/getenv-2.0.0.tgz",
+ "integrity": "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/giget": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz",
+ "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "citty": "^0.1.6",
+ "consola": "^3.4.0",
+ "defu": "^6.1.4",
+ "node-fetch-native": "^1.6.6",
+ "nypm": "^0.6.0",
+ "pathe": "^2.0.3"
+ },
+ "bin": {
+ "giget": "dist/cli.mjs"
+ }
+ },
+ "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==",
+ "license": "ISC",
+ "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/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/global-directory": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz",
+ "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ini": "4.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/global-directory/node_modules/ini": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz",
+ "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/global-dirs": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
+ "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==",
+ "license": "MIT",
+ "dependencies": {
+ "ini": "^1.3.4"
+ },
+ "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==",
+ "license": "ISC"
+ },
+ "node_modules/graceful-readlink": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
+ "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/growly": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
+ "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/hermes-estree": {
+ "version": "0.32.0",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.32.0.tgz",
+ "integrity": "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ==",
+ "license": "MIT"
+ },
+ "node_modules/hermes-parser": {
+ "version": "0.32.0",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.32.0.tgz",
+ "integrity": "sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw==",
+ "license": "MIT",
+ "dependencies": {
+ "hermes-estree": "0.32.0"
+ }
+ },
+ "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==",
+ "license": "BSD-3-Clause",
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/hosted-git-info": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
+ "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^10.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/hosted-git-info/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==",
+ "license": "ISC"
+ },
+ "node_modules/html-escaper": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz",
+ "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/htmlparser2": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz",
+ "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==",
+ "dev": true,
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.2.1",
+ "entities": "^6.0.0"
+ }
+ },
+ "node_modules/htmlparser2/node_modules/entities": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
+ "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=16.17.0"
+ }
+ },
+ "node_modules/husky": {
+ "version": "9.1.7",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz",
+ "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "husky": "bin.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/typicode"
+ }
+ },
+ "node_modules/hyphenate-style-name": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz",
+ "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "queue": "6.0.2"
+ },
+ "bin": {
+ "image-size": "bin/image-size.js"
+ },
+ "engines": {
+ "node": ">=16.x"
+ }
+ },
+ "node_modules/immediate": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/import-meta-resolve": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz",
+ "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "license": "MIT",
+ "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.",
+ "license": "ISC",
+ "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==",
+ "license": "ISC"
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "license": "ISC"
+ },
+ "node_modules/inline-style-prefixer": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz",
+ "integrity": "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==",
+ "license": "MIT",
+ "dependencies": {
+ "css-in-js-utils": "^3.1.0"
+ }
+ },
+ "node_modules/invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
+ "node_modules/is-absolute": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz",
+ "integrity": "sha512-Xi9/ZSn4NFapG8RP98iNPMOeaV3mXPisxKxzKtHVqr3g56j/fBn+yZmnxSVAA8lmZbl2J9b/a4kJvfU3hqQYgA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-relative": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-in-ci": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-1.0.0.tgz",
+ "integrity": "sha512-eUuAjybVTHMYWm/U+vBO1sY/JOCgoPCXRxzdju0K+K0BiGW0SChEL1MLC0PoCIR1OlPo5YAp8HuQoUlsWEICwg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "is-in-ci": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-inside-container": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
+ "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^3.0.0"
+ },
+ "bin": {
+ "is-inside-container": "cli.js"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-inside-container/node_modules/is-docker": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
+ "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-installed-globally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-1.0.0.tgz",
+ "integrity": "sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "global-directory": "^4.0.1",
+ "is-path-inside": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-interactive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz",
+ "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-npm": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.1.0.tgz",
+ "integrity": "sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz",
+ "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-primitive": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-3.0.1.tgz",
+ "integrity": "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-relative": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz",
+ "integrity": "sha512-wBOr+rNM4gkAZqoLRJI4myw5WzzIdQosFAAbnvfXP5z1LyzgAI3ivOKehC5KfqlQJZoihVhirgtCBj378Eg8GA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+ "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
+ "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "license": "ISC"
+ },
+ "node_modules/isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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==",
+ "license": "BSD-3-Clause",
+ "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==",
+ "license": "BSD-3-Clause",
+ "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==",
+ "license": "ISC",
+ "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==",
+ "license": "BlueOak-1.0.0",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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-message-util/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==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/jest-message-util/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/jest-message-util/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/jest-message-util/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==",
+ "license": "MIT"
+ },
+ "node_modules/jest-message-util/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-message-util/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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-util/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-util/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/jest-util/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"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-util/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/jest-util/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==",
+ "license": "MIT"
+ },
+ "node_modules/jest-util/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-util/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-validate/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/jest-validate/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/jest-validate/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==",
+ "license": "MIT"
+ },
+ "node_modules/jest-validate/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-validate/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/jimp-compact": {
+ "version": "0.16.1",
+ "resolved": "https://registry.npmjs.org/jimp-compact/-/jimp-compact-0.16.1.tgz",
+ "integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==",
+ "license": "MIT"
+ },
+ "node_modules/jiti": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
+ "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
+ "devOptional": true,
+ "license": "MIT",
+ "bin": {
+ "jiti": "lib/jiti-cli.mjs"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "0BSD"
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz",
+ "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jsonfile": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
+ "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/jszip": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
+ "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
+ "dev": true,
+ "license": "(MIT OR GPL-3.0-or-later)",
+ "dependencies": {
+ "lie": "~3.3.0",
+ "pako": "~1.0.2",
+ "readable-stream": "~2.3.6",
+ "setimmediate": "^1.0.5"
+ }
+ },
+ "node_modules/kleur": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ky": {
+ "version": "1.14.0",
+ "resolved": "https://registry.npmjs.org/ky/-/ky-1.14.0.tgz",
+ "integrity": "sha512-Rczb6FMM6JT0lvrOlP5WUOCB7s9XKxzwgErzhKlKde1bEV90FXplV1o87fpt4PU/asJFiqjYJxAJyzJhcrxOsQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/ky?sponsor=1"
+ }
+ },
+ "node_modules/lan-network": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/lan-network/-/lan-network-0.1.7.tgz",
+ "integrity": "sha512-mnIlAEMu4OyEvUNdzco9xpuB9YVcPkQec+QsgycBCtPZvEqWPCDPfbAE4OJMdBBWpZWtpCn1xw9jJYlwjWI5zQ==",
+ "license": "MIT",
+ "bin": {
+ "lan-network": "dist/lan-network-cli.js"
+ }
+ },
+ "node_modules/latest-version": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-9.0.0.tgz",
+ "integrity": "sha512-7W0vV3rqv5tokqkBAFV1LbR7HPOWzXQDpDgEuib/aJ1jsZZx6x3c2mBI+TJhJzOhkGeaLbCKEHXEXLfirtG2JA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "package-json": "^10.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/lie": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+ "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "immediate": "~3.0.5"
+ }
+ },
+ "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==",
+ "license": "Apache-2.0",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/lightningcss": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz",
+ "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==",
+ "license": "MPL-2.0",
+ "dependencies": {
+ "detect-libc": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-android-arm64": "1.30.2",
+ "lightningcss-darwin-arm64": "1.30.2",
+ "lightningcss-darwin-x64": "1.30.2",
+ "lightningcss-freebsd-x64": "1.30.2",
+ "lightningcss-linux-arm-gnueabihf": "1.30.2",
+ "lightningcss-linux-arm64-gnu": "1.30.2",
+ "lightningcss-linux-arm64-musl": "1.30.2",
+ "lightningcss-linux-x64-gnu": "1.30.2",
+ "lightningcss-linux-x64-musl": "1.30.2",
+ "lightningcss-win32-arm64-msvc": "1.30.2",
+ "lightningcss-win32-x64-msvc": "1.30.2"
+ }
+ },
+ "node_modules/lightningcss-android-arm64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz",
+ "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz",
+ "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz",
+ "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz",
+ "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz",
+ "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz",
+ "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz",
+ "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz",
+ "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz",
+ "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz",
+ "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz",
+ "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/linkedom": {
+ "version": "0.18.12",
+ "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.18.12.tgz",
+ "integrity": "sha512-jalJsOwIKuQJSeTvsgzPe9iJzyfVaEJiEXl+25EkKevsULHvMJzpNqwvj1jOESWdmgKDiXObyjOYwlUqG7wo1Q==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "css-select": "^5.1.0",
+ "cssom": "^0.5.0",
+ "html-escaper": "^3.0.3",
+ "htmlparser2": "^10.0.0",
+ "uhyphen": "^0.2.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "canvas": ">= 2"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/lint-staged": {
+ "version": "15.5.2",
+ "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.5.2.tgz",
+ "integrity": "sha512-YUSOLq9VeRNAo/CTaVmhGDKG+LBtA8KF1X4K5+ykMSwWST1vDxJRB2kv2COgLb1fvpCo+A/y9A0G0znNVmdx4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^5.4.1",
+ "commander": "^13.1.0",
+ "debug": "^4.4.0",
+ "execa": "^8.0.1",
+ "lilconfig": "^3.1.3",
+ "listr2": "^8.2.5",
+ "micromatch": "^4.0.8",
+ "pidtree": "^0.6.0",
+ "string-argv": "^0.3.2",
+ "yaml": "^2.7.0"
+ },
+ "bin": {
+ "lint-staged": "bin/lint-staged.js"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/lint-staged"
+ }
+ },
+ "node_modules/lint-staged/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/lint-staged/node_modules/commander": {
+ "version": "13.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
+ "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/listr2": {
+ "version": "8.3.3",
+ "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.3.3.tgz",
+ "integrity": "sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cli-truncate": "^4.0.0",
+ "colorette": "^2.0.20",
+ "eventemitter3": "^5.0.1",
+ "log-update": "^6.1.0",
+ "rfdc": "^1.4.1",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/listr2/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/listr2/node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/listr2/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/listr2/node_modules/wrap-ansi": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+ "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/local-pkg": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz",
+ "integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mlly": "^1.7.4",
+ "pkg-types": "^2.3.0",
+ "quansync": "^0.2.11"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/lodash.debounce": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/log-symbols": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
+ "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/log-update": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz",
+ "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-escapes": "^7.0.0",
+ "cli-cursor": "^5.0.0",
+ "slice-ansi": "^7.1.0",
+ "strip-ansi": "^7.1.0",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/ansi-escapes": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.2.0.tgz",
+ "integrity": "sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "environment": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/log-update/node_modules/cli-cursor": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
+ "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "restore-cursor": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/log-update/node_modules/is-fullwidth-code-point": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz",
+ "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-east-asian-width": "^1.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/onetime": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
+ "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-function": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/restore-cursor": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
+ "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^7.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/slice-ansi": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz",
+ "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "is-fullwidth-code-point": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/log-update/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/wrap-ansi": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+ "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "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==",
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/magicast": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz",
+ "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.25.4",
+ "@babel/types": "^7.25.4",
+ "source-map-js": "^1.2.0"
+ }
+ },
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/makeerror": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+ "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tmpl": "1.0.5"
+ }
+ },
+ "node_modules/many-keys-map": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/many-keys-map/-/many-keys-map-2.0.1.tgz",
+ "integrity": "sha512-DHnZAD4phTbZ+qnJdjoNEVU1NecYoSdbOOoVmTDH46AuxDkEVh3MxTVpXq10GtcTC6mndN9dkv1rNfpjRcLnOw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/fregante"
+ }
+ },
+ "node_modules/marky": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz",
+ "integrity": "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==",
+ "license": "Apache-2.0"
+ },
+ "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==",
+ "license": "CC0-1.0"
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/metro": {
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro/-/metro-0.83.2.tgz",
+ "integrity": "sha512-HQgs9H1FyVbRptNSMy/ImchTTE5vS2MSqLoOo7hbDoBq6hPPZokwJvBMwrYSxdjQZmLXz2JFZtdvS+ZfgTc9yw==",
+ "license": "MIT",
+ "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.32.0",
+ "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.83.2",
+ "metro-cache": "0.83.2",
+ "metro-cache-key": "0.83.2",
+ "metro-config": "0.83.2",
+ "metro-core": "0.83.2",
+ "metro-file-map": "0.83.2",
+ "metro-resolver": "0.83.2",
+ "metro-runtime": "0.83.2",
+ "metro-source-map": "0.83.2",
+ "metro-symbolicate": "0.83.2",
+ "metro-transform-plugins": "0.83.2",
+ "metro-transform-worker": "0.83.2",
+ "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": ">=20.19.4"
+ }
+ },
+ "node_modules/metro-babel-transformer": {
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.83.2.tgz",
+ "integrity": "sha512-rirY1QMFlA1uxH3ZiNauBninwTioOgwChnRdDcbB4tgRZ+bGX9DiXoh9QdpppiaVKXdJsII932OwWXGGV4+Nlw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.25.2",
+ "flow-enums-runtime": "^0.0.6",
+ "hermes-parser": "0.32.0",
+ "nullthrows": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=20.19.4"
+ }
+ },
+ "node_modules/metro-cache": {
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.83.2.tgz",
+ "integrity": "sha512-Z43IodutUZeIS7OTH+yQFjc59QlFJ6s5OvM8p2AP9alr0+F8UKr8ADzFzoGKoHefZSKGa4bJx7MZJLF6GwPDHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "exponential-backoff": "^3.1.1",
+ "flow-enums-runtime": "^0.0.6",
+ "https-proxy-agent": "^7.0.5",
+ "metro-core": "0.83.2"
+ },
+ "engines": {
+ "node": ">=20.19.4"
+ }
+ },
+ "node_modules/metro-cache-key": {
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.83.2.tgz",
+ "integrity": "sha512-3EMG/GkGKYoTaf5RqguGLSWRqGTwO7NQ0qXKmNBjr0y6qD9s3VBXYlwB+MszGtmOKsqE9q3FPrE5Nd9Ipv7rZw==",
+ "license": "MIT",
+ "dependencies": {
+ "flow-enums-runtime": "^0.0.6"
+ },
+ "engines": {
+ "node": ">=20.19.4"
+ }
+ },
+ "node_modules/metro-config": {
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.83.2.tgz",
+ "integrity": "sha512-1FjCcdBe3e3D08gSSiU9u3Vtxd7alGH3x/DNFqWDFf5NouX4kLgbVloDDClr1UrLz62c0fHh2Vfr9ecmrOZp+g==",
+ "license": "MIT",
+ "dependencies": {
+ "connect": "^3.6.5",
+ "flow-enums-runtime": "^0.0.6",
+ "jest-validate": "^29.7.0",
+ "metro": "0.83.2",
+ "metro-cache": "0.83.2",
+ "metro-core": "0.83.2",
+ "metro-runtime": "0.83.2",
+ "yaml": "^2.6.1"
+ },
+ "engines": {
+ "node": ">=20.19.4"
+ }
+ },
+ "node_modules/metro-core": {
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.83.2.tgz",
+ "integrity": "sha512-8DRb0O82Br0IW77cNgKMLYWUkx48lWxUkvNUxVISyMkcNwE/9ywf1MYQUE88HaKwSrqne6kFgCSA/UWZoUT0Iw==",
+ "license": "MIT",
+ "dependencies": {
+ "flow-enums-runtime": "^0.0.6",
+ "lodash.throttle": "^4.1.1",
+ "metro-resolver": "0.83.2"
+ },
+ "engines": {
+ "node": ">=20.19.4"
+ }
+ },
+ "node_modules/metro-file-map": {
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.83.2.tgz",
+ "integrity": "sha512-cMSWnEqZrp/dzZIEd7DEDdk72PXz6w5NOKriJoDN9p1TDQ5nAYrY2lHi8d6mwbcGLoSlWmpPyny9HZYFfPWcGQ==",
+ "license": "MIT",
+ "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": ">=20.19.4"
+ }
+ },
+ "node_modules/metro-minify-terser": {
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.83.2.tgz",
+ "integrity": "sha512-zvIxnh7U0JQ7vT4quasKsijId3dOAWgq+ip2jF/8TMrPUqQabGrs04L2dd0haQJ+PA+d4VvK/bPOY8X/vL2PWw==",
+ "license": "MIT",
+ "dependencies": {
+ "flow-enums-runtime": "^0.0.6",
+ "terser": "^5.15.0"
+ },
+ "engines": {
+ "node": ">=20.19.4"
+ }
+ },
+ "node_modules/metro-resolver": {
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.83.2.tgz",
+ "integrity": "sha512-Yf5mjyuiRE/Y+KvqfsZxrbHDA15NZxyfg8pIk0qg47LfAJhpMVEX+36e6ZRBq7KVBqy6VDX5Sq55iHGM4xSm7Q==",
+ "license": "MIT",
+ "dependencies": {
+ "flow-enums-runtime": "^0.0.6"
+ },
+ "engines": {
+ "node": ">=20.19.4"
+ }
+ },
+ "node_modules/metro-runtime": {
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.83.2.tgz",
+ "integrity": "sha512-nnsPtgRvFbNKwemqs0FuyFDzXLl+ezuFsUXDbX8o0SXOfsOPijqiQrf3kuafO1Zx1aUWf4NOrKJMAQP5EEHg9A==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.25.0",
+ "flow-enums-runtime": "^0.0.6"
+ },
+ "engines": {
+ "node": ">=20.19.4"
+ }
+ },
+ "node_modules/metro-source-map": {
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.83.2.tgz",
+ "integrity": "sha512-5FL/6BSQvshIKjXOennt9upFngq2lFvDakZn5LfauIVq8+L4sxXewIlSTcxAtzbtjAIaXeOSVMtCJ5DdfCt9AA==",
+ "license": "MIT",
+ "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.83.2",
+ "nullthrows": "^1.1.1",
+ "ob1": "0.83.2",
+ "source-map": "^0.5.6",
+ "vlq": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=20.19.4"
+ }
+ },
+ "node_modules/metro-symbolicate": {
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.83.2.tgz",
+ "integrity": "sha512-KoU9BLwxxED6n33KYuQQuc5bXkIxF3fSwlc3ouxrrdLWwhu64muYZNQrukkWzhVKRNFIXW7X2iM8JXpi2heIPw==",
+ "license": "MIT",
+ "dependencies": {
+ "flow-enums-runtime": "^0.0.6",
+ "invariant": "^2.2.4",
+ "metro-source-map": "0.83.2",
+ "nullthrows": "^1.1.1",
+ "source-map": "^0.5.6",
+ "vlq": "^1.0.0"
+ },
+ "bin": {
+ "metro-symbolicate": "src/index.js"
+ },
+ "engines": {
+ "node": ">=20.19.4"
+ }
+ },
+ "node_modules/metro-transform-plugins": {
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.83.2.tgz",
+ "integrity": "sha512-5WlW25WKPkiJk2yA9d8bMuZrgW7vfA4f4MBb9ZeHbTB3eIAoNN8vS8NENgG/X/90vpTB06X66OBvxhT3nHwP6A==",
+ "license": "MIT",
+ "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": ">=20.19.4"
+ }
+ },
+ "node_modules/metro-transform-worker": {
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.83.2.tgz",
+ "integrity": "sha512-G5DsIg+cMZ2KNfrdLnWMvtppb3+Rp1GMyj7Bvd9GgYc/8gRmvq1XVEF9XuO87Shhb03kFhGqMTgZerz3hZ1v4Q==",
+ "license": "MIT",
+ "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.83.2",
+ "metro-babel-transformer": "0.83.2",
+ "metro-cache": "0.83.2",
+ "metro-cache-key": "0.83.2",
+ "metro-minify-terser": "0.83.2",
+ "metro-source-map": "0.83.2",
+ "metro-transform-plugins": "0.83.2",
+ "nullthrows": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=20.19.4"
+ }
+ },
+ "node_modules/metro/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==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/metro/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/metro/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "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/metro/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/metro/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==",
+ "license": "MIT"
+ },
+ "node_modules/metro/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/metro/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mimic-function": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
+ "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/minizlib": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz",
+ "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==",
+ "license": "MIT",
+ "dependencies": {
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "license": "MIT",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/mlly": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz",
+ "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "pathe": "^2.0.3",
+ "pkg-types": "^1.3.1",
+ "ufo": "^1.6.1"
+ }
+ },
+ "node_modules/mlly/node_modules/confbox": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
+ "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mlly/node_modules/pkg-types": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
+ "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "confbox": "^0.1.8",
+ "mlly": "^1.7.4",
+ "pathe": "^2.0.1"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/multimatch": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-6.0.0.tgz",
+ "integrity": "sha512-I7tSVxHGPlmPN/enE3mS1aOSo6bWBfls+3HmuEeCUBCE7gWnm3cBXCBkpurzFjVRwC6Kld8lLaZ1Iv5vOcjvcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/minimatch": "^3.0.5",
+ "array-differ": "^4.0.0",
+ "array-union": "^3.0.1",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/multimatch/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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/multimatch/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "node_modules/nano-spawn": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-1.0.3.tgz",
+ "integrity": "sha512-jtpsQDetTnvS2Ts1fiRdci5rx0VYws5jGyC+4IYOTnIQ/wwdf6JdomlHBwqC3bJYOvaKu0C2GSZ1A60anrYpaA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.17"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/nano-spawn?sponsor=1"
+ }
+ },
+ "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"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/nativewind": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/nativewind/-/nativewind-4.2.1.tgz",
+ "integrity": "sha512-10uUB2Dlli3MH3NDL5nMHqJHz1A3e/E6mzjTj6cl7hHECClJ7HpE6v+xZL+GXdbwQSnWE+UWMIMsNz7yOQkAJQ==",
+ "license": "MIT",
+ "dependencies": {
+ "comment-json": "^4.2.5",
+ "debug": "^4.3.7",
+ "react-native-css-interop": "0.2.1"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "tailwindcss": ">3.3.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/nested-error-stacks": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.0.1.tgz",
+ "integrity": "sha512-SrQrok4CATudVzBS7coSz26QRSmlK9TzzoFbeKfcPBUFPjcQM9Rqvr/DlJkOrwI/0KcgvMub1n1g5Jt9EgRn4A==",
+ "license": "MIT"
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/node-fetch-native": {
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz",
+ "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-forge": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
+ "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
+ "license": "(BSD-3-Clause OR GPL-2.0)",
+ "engines": {
+ "node": ">= 6.13.0"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/node-notifier": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-10.0.1.tgz",
+ "integrity": "sha512-YX7TSyDukOZ0g+gmzjB6abKu+hTGvO8+8+gIFDsRCU2t8fLV/P2unmt+LGFaIa4y64aX98Qksa97rgz4vMNeLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "growly": "^1.3.0",
+ "is-wsl": "^2.2.0",
+ "semver": "^7.3.5",
+ "shellwords": "^0.1.1",
+ "uuid": "^8.3.2",
+ "which": "^2.0.2"
+ }
+ },
+ "node_modules/node-notifier/node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.27",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
+ "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm-package-arg": {
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz",
+ "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==",
+ "license": "ISC",
+ "dependencies": {
+ "hosted-git-info": "^7.0.0",
+ "proc-log": "^4.0.0",
+ "semver": "^7.3.5",
+ "validate-npm-package-name": "^5.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
+ "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm-run-path/node_modules/path-key": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "BSD-2-Clause",
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/nypm": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.2.tgz",
+ "integrity": "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "citty": "^0.1.6",
+ "consola": "^3.4.2",
+ "pathe": "^2.0.3",
+ "pkg-types": "^2.3.0",
+ "tinyexec": "^1.0.1"
+ },
+ "bin": {
+ "nypm": "dist/cli.mjs"
+ },
+ "engines": {
+ "node": "^14.16.0 || >=16.10.0"
+ }
+ },
+ "node_modules/ob1": {
+ "version": "0.83.2",
+ "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.83.2.tgz",
+ "integrity": "sha512-XlK3w4M+dwd1g1gvHzVbxiXEbUllRONEgcF2uEO0zm4nxa0eKlh41c6N65q1xbiDOeKKda1tvNOAD33fNjyvCg==",
+ "license": "MIT",
+ "dependencies": {
+ "flow-enums-runtime": "^0.0.6"
+ },
+ "engines": {
+ "node": ">=20.19.4"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-hash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/ofetch": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.5.1.tgz",
+ "integrity": "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "destr": "^2.0.5",
+ "node-fetch-native": "^1.6.7",
+ "ufo": "^1.6.1"
+ }
+ },
+ "node_modules/ohash": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz",
+ "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/on-exit-leak-free": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz",
+ "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/on-headers": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz",
+ "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
+ "license": "MIT",
+ "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==",
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+ "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==",
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^2.0.0",
+ "is-wsl": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ora": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz",
+ "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==",
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^2.4.2",
+ "cli-cursor": "^2.1.0",
+ "cli-spinners": "^2.0.0",
+ "log-symbols": "^2.2.0",
+ "strip-ansi": "^5.2.0",
+ "wcwidth": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ora/node_modules/ansi-regex": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+ "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ora/node_modules/strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/os-shim": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz",
+ "integrity": "sha512-jd0cvB8qQ5uVt0lvCIexBaROw1KyKm5sbulg2fWOHjETisuCzWyt+eTZKEMs8v6HwzoGs8xik26jg7eCM6pS+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-locate/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==",
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/package-json": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-10.0.1.tgz",
+ "integrity": "sha512-ua1L4OgXSBdsu1FPb7F3tYH0F48a6kxvod4pLUlGY9COeJAJQNX/sNH2IiEmsxw7lqYiAwrdHMjz1FctOsyDQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ky": "^1.2.0",
+ "registry-auth-token": "^5.0.2",
+ "registry-url": "^6.0.1",
+ "semver": "^7.6.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "dev": true,
+ "license": "(MIT AND Zlib)"
+ },
+ "node_modules/parse-json": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz",
+ "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.21.4",
+ "error-ex": "^1.3.2",
+ "json-parse-even-better-errors": "^3.0.0",
+ "lines-and-columns": "^2.0.3",
+ "type-fest": "^3.8.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parse-json/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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/parse-json/node_modules/lines-and-columns": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz",
+ "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/parse-json/node_modules/type-fest": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz",
+ "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parse-png": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/parse-png/-/parse-png-2.1.0.tgz",
+ "integrity": "sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ==",
+ "license": "MIT",
+ "dependencies": {
+ "pngjs": "^3.3.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "BlueOak-1.0.0",
+ "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==",
+ "license": "ISC"
+ },
+ "node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/perfect-debounce": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.0.0.tgz",
+ "integrity": "sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pidtree": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz",
+ "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "pidtree": "bin/pidtree.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pino": {
+ "version": "9.7.0",
+ "resolved": "https://registry.npmjs.org/pino/-/pino-9.7.0.tgz",
+ "integrity": "sha512-vnMCM6xZTb1WDmLvtG2lE/2p+t9hDEIvTWJsu6FejkE62vB7gDhvzrpFR4Cw2to+9JNQxVnkAKVPA1KPB98vWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "atomic-sleep": "^1.0.0",
+ "fast-redact": "^3.1.1",
+ "on-exit-leak-free": "^2.1.0",
+ "pino-abstract-transport": "^2.0.0",
+ "pino-std-serializers": "^7.0.0",
+ "process-warning": "^5.0.0",
+ "quick-format-unescaped": "^4.0.3",
+ "real-require": "^0.2.0",
+ "safe-stable-stringify": "^2.3.1",
+ "sonic-boom": "^4.0.1",
+ "thread-stream": "^3.0.0"
+ },
+ "bin": {
+ "pino": "bin.js"
+ }
+ },
+ "node_modules/pino-abstract-transport": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz",
+ "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "split2": "^4.0.0"
+ }
+ },
+ "node_modules/pino-std-serializers": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz",
+ "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/pkg-types": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz",
+ "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "confbox": "^0.2.2",
+ "exsolve": "^1.0.7",
+ "pathe": "^2.0.3"
+ }
+ },
+ "node_modules/plist": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz",
+ "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@xmldom/xmldom": "^0.8.8",
+ "base64-js": "^1.5.1",
+ "xmlbuilder": "^15.1.1"
+ },
+ "engines": {
+ "node": ">=10.4.0"
+ }
+ },
+ "node_modules/pngjs": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
+ "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.4.49",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
+ "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-import": {
+ "version": "15.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
+ "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.0.0",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.0"
+ }
+ },
+ "node_modules/postcss-js": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz",
+ "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "camelcase-css": "^2.0.1"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >= 16"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.21"
+ }
+ },
+ "node_modules/postcss-load-config": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
+ "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "lilconfig": "^3.1.1"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "jiti": ">=1.21.0",
+ "postcss": ">=8.0.9",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/postcss-nested": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
+ "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "postcss-selector-parser": "^6.1.1"
+ },
+ "engines": {
+ "node": ">=12.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.14"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "license": "MIT"
+ },
+ "node_modules/prettier": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
+ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/prettier-plugin-tailwindcss": {
+ "version": "0.5.14",
+ "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.5.14.tgz",
+ "integrity": "sha512-Puaz+wPUAhFp8Lo9HuciYKM2Y2XExESjeT+9NQoVFXZsPPnc9VYss2SpxdQ6vbatmt8/4+SN0oe0I1cPDABg9Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.21.3"
+ },
+ "peerDependencies": {
+ "@ianvs/prettier-plugin-sort-imports": "*",
+ "@prettier/plugin-pug": "*",
+ "@shopify/prettier-plugin-liquid": "*",
+ "@trivago/prettier-plugin-sort-imports": "*",
+ "@zackad/prettier-plugin-twig-melody": "*",
+ "prettier": "^3.0",
+ "prettier-plugin-astro": "*",
+ "prettier-plugin-css-order": "*",
+ "prettier-plugin-import-sort": "*",
+ "prettier-plugin-jsdoc": "*",
+ "prettier-plugin-marko": "*",
+ "prettier-plugin-organize-attributes": "*",
+ "prettier-plugin-organize-imports": "*",
+ "prettier-plugin-sort-imports": "*",
+ "prettier-plugin-style-order": "*",
+ "prettier-plugin-svelte": "*"
+ },
+ "peerDependenciesMeta": {
+ "@ianvs/prettier-plugin-sort-imports": {
+ "optional": true
+ },
+ "@prettier/plugin-pug": {
+ "optional": true
+ },
+ "@shopify/prettier-plugin-liquid": {
+ "optional": true
+ },
+ "@trivago/prettier-plugin-sort-imports": {
+ "optional": true
+ },
+ "@zackad/prettier-plugin-twig-melody": {
+ "optional": true
+ },
+ "prettier-plugin-astro": {
+ "optional": true
+ },
+ "prettier-plugin-css-order": {
+ "optional": true
+ },
+ "prettier-plugin-import-sort": {
+ "optional": true
+ },
+ "prettier-plugin-jsdoc": {
+ "optional": true
+ },
+ "prettier-plugin-marko": {
+ "optional": true
+ },
+ "prettier-plugin-organize-attributes": {
+ "optional": true
+ },
+ "prettier-plugin-organize-imports": {
+ "optional": true
+ },
+ "prettier-plugin-sort-imports": {
+ "optional": true
+ },
+ "prettier-plugin-style-order": {
+ "optional": true
+ },
+ "prettier-plugin-svelte": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/pretty-bytes": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
+ "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/proc-log": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",
+ "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==",
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/process-warning": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz",
+ "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "asap": "~2.0.6"
+ }
+ },
+ "node_modules/promise-toolbox": {
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/promise-toolbox/-/promise-toolbox-0.21.0.tgz",
+ "integrity": "sha512-NV8aTmpwrZv+Iys54sSFOBx3tuVaOBvvrft5PNppnxy9xpU/akHbaWIril22AB22zaPgrgwKdD0KsrM0ptUtpg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "make-error": "^1.3.2"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/prompts": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
+ "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
+ "license": "MIT",
+ "dependencies": {
+ "kleur": "^3.0.3",
+ "sisteransi": "^1.0.5"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/publish-browser-extension": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/publish-browser-extension/-/publish-browser-extension-3.0.3.tgz",
+ "integrity": "sha512-cBINZCkLo7YQaGoUvEHthZ0sDzgJQht28IS+SFMT2omSNhGsPiVNRkWir3qLiTrhGhW9Ci2KVHpA1QAMoBdL2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cac": "^6.7.14",
+ "consola": "^3.4.2",
+ "dotenv": "^17.2.3",
+ "form-data-encoder": "^4.1.0",
+ "formdata-node": "^6.0.3",
+ "listr2": "^8.3.3",
+ "ofetch": "^1.4.1",
+ "zod": "^3.25.76 || ^4.0.0"
+ },
+ "bin": {
+ "publish-extension": "bin/publish-extension.cjs"
+ }
+ },
+ "node_modules/publish-browser-extension/node_modules/dotenv": {
+ "version": "17.2.3",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz",
+ "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pupa": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.3.0.tgz",
+ "integrity": "sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "escape-goat": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/qrcode-terminal": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz",
+ "integrity": "sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==",
+ "bin": {
+ "qrcode-terminal": "bin/qrcode-terminal.js"
+ }
+ },
+ "node_modules/quansync": {
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
+ "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/antfu"
+ },
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ ],
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "~2.0.3"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/quick-format-unescaped": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
+ "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
+ "dependencies": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "bin": {
+ "rc": "cli.js"
+ }
+ },
+ "node_modules/rc9": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz",
+ "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "defu": "^6.1.4",
+ "destr": "^2.0.3"
+ }
+ },
+ "node_modules/react": {
+ "version": "19.1.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
+ "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-devtools-core": {
+ "version": "6.1.5",
+ "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-6.1.5.tgz",
+ "integrity": "sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==",
+ "license": "MIT",
+ "dependencies": {
+ "shell-quote": "^1.6.1",
+ "ws": "^7"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "19.1.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
+ "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
+ "license": "MIT",
+ "dependencies": {
+ "scheduler": "^0.26.0"
+ },
+ "peerDependencies": {
+ "react": "^19.1.0"
+ }
+ },
+ "node_modules/react-fast-compare": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
+ "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/react-native": {
+ "version": "0.81.5",
+ "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.81.5.tgz",
+ "integrity": "sha512-1w+/oSjEXZjMqsIvmkCRsOc8UBYv163bTWKTI8+1mxztvQPhCRYGTvZ/PL1w16xXHneIj/SLGfxWg2GWN2uexw==",
+ "license": "MIT",
+ "dependencies": {
+ "@jest/create-cache-key-function": "^29.7.0",
+ "@react-native/assets-registry": "0.81.5",
+ "@react-native/codegen": "0.81.5",
+ "@react-native/community-cli-plugin": "0.81.5",
+ "@react-native/gradle-plugin": "0.81.5",
+ "@react-native/js-polyfills": "0.81.5",
+ "@react-native/normalize-colors": "0.81.5",
+ "@react-native/virtualized-lists": "0.81.5",
+ "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.29.1",
+ "base64-js": "^1.5.1",
+ "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.83.1",
+ "metro-source-map": "^0.83.1",
+ "nullthrows": "^1.1.1",
+ "pretty-format": "^29.7.0",
+ "promise": "^8.3.0",
+ "react-devtools-core": "^6.1.5",
+ "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": ">= 20.19.4"
+ },
+ "peerDependencies": {
+ "@types/react": "^19.1.0",
+ "react": "^19.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-native-context-menu-view": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/react-native-context-menu-view/-/react-native-context-menu-view-1.20.0.tgz",
+ "integrity": "sha512-g1EYZiPaJWjeq7GWeL9TaYSnKmL9/hiDE7Arvj8r8fLip/l+BvS+BRtblX9qk9VpQdDWyd6L6A4yL2sz6+ohQw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.1 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-native": ">=0.60.0-rc.0 <1.0.x"
+ }
+ },
+ "node_modules/react-native-css-interop": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/react-native-css-interop/-/react-native-css-interop-0.2.1.tgz",
+ "integrity": "sha512-B88f5rIymJXmy1sNC/MhTkb3xxBej1KkuAt7TiT9iM7oXz3RM8Bn+7GUrfR02TvSgKm4cg2XiSuLEKYfKwNsjA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.22.15",
+ "@babel/traverse": "^7.23.0",
+ "@babel/types": "^7.23.0",
+ "debug": "^4.3.7",
+ "lightningcss": "~1.27.0",
+ "semver": "^7.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-native": "*",
+ "react-native-reanimated": ">=3.6.2",
+ "tailwindcss": "~3"
+ },
+ "peerDependenciesMeta": {
+ "react-native-safe-area-context": {
+ "optional": true
+ },
+ "react-native-svg": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-native-css-interop/node_modules/detect-libc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+ "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
+ "license": "Apache-2.0",
+ "bin": {
+ "detect-libc": "bin/detect-libc.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/react-native-css-interop/node_modules/lightningcss": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.27.0.tgz",
+ "integrity": "sha512-8f7aNmS1+etYSLHht0fQApPc2kNO8qGRutifN5rVIc6Xo6ABsEbqOr758UwI7ALVbTt4x1fllKt0PYgzD9S3yQ==",
+ "license": "MPL-2.0",
+ "dependencies": {
+ "detect-libc": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-darwin-arm64": "1.27.0",
+ "lightningcss-darwin-x64": "1.27.0",
+ "lightningcss-freebsd-x64": "1.27.0",
+ "lightningcss-linux-arm-gnueabihf": "1.27.0",
+ "lightningcss-linux-arm64-gnu": "1.27.0",
+ "lightningcss-linux-arm64-musl": "1.27.0",
+ "lightningcss-linux-x64-gnu": "1.27.0",
+ "lightningcss-linux-x64-musl": "1.27.0",
+ "lightningcss-win32-arm64-msvc": "1.27.0",
+ "lightningcss-win32-x64-msvc": "1.27.0"
+ }
+ },
+ "node_modules/react-native-css-interop/node_modules/lightningcss-darwin-arm64": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.27.0.tgz",
+ "integrity": "sha512-Gl/lqIXY+d+ySmMbgDf0pgaWSqrWYxVHoc88q+Vhf2YNzZ8DwoRzGt5NZDVqqIW5ScpSnmmjcgXP87Dn2ylSSQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/react-native-css-interop/node_modules/lightningcss-darwin-x64": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.27.0.tgz",
+ "integrity": "sha512-0+mZa54IlcNAoQS9E0+niovhyjjQWEMrwW0p2sSdLRhLDc8LMQ/b67z7+B5q4VmjYCMSfnFi3djAAQFIDuj/Tg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/react-native-css-interop/node_modules/lightningcss-freebsd-x64": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.27.0.tgz",
+ "integrity": "sha512-n1sEf85fePoU2aDN2PzYjoI8gbBqnmLGEhKq7q0DKLj0UTVmOTwDC7PtLcy/zFxzASTSBlVQYJUhwIStQMIpRA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/react-native-css-interop/node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.27.0.tgz",
+ "integrity": "sha512-MUMRmtdRkOkd5z3h986HOuNBD1c2lq2BSQA1Jg88d9I7bmPGx08bwGcnB75dvr17CwxjxD6XPi3Qh8ArmKFqCA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/react-native-css-interop/node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.27.0.tgz",
+ "integrity": "sha512-cPsxo1QEWq2sfKkSq2Bq5feQDHdUEwgtA9KaB27J5AX22+l4l0ptgjMZZtYtUnteBofjee+0oW1wQ1guv04a7A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/react-native-css-interop/node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.27.0.tgz",
+ "integrity": "sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/react-native-css-interop/node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.27.0.tgz",
+ "integrity": "sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/react-native-css-interop/node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.27.0.tgz",
+ "integrity": "sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/react-native-css-interop/node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.27.0.tgz",
+ "integrity": "sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/react-native-css-interop/node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.27.0.tgz",
+ "integrity": "sha512-/OJLj94Zm/waZShL8nB5jsNj3CfNATLCTyFxZyouilfTmSoLDX7VlVAmhPHoZWVFp4vdmoiEbPEYC8HID3m6yw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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-is-edge-to-edge": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.2.1.tgz",
+ "integrity": "sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/react-native-reanimated": {
+ "version": "3.17.5",
+ "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.17.5.tgz",
+ "integrity": "sha512-SxBK7wQfJ4UoWoJqQnmIC7ZjuNgVb9rcY5Xc67upXAFKftWg0rnkknTw6vgwnjRcvYThrjzUVti66XoZdDJGtw==",
+ "license": "MIT",
+ "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-reanimated/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==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/react-native-safe-area-context": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.4.0.tgz",
+ "integrity": "sha512-JaEThVyJcLhA+vU0NU8bZ0a1ih6GiF4faZ+ArZLqpYbL6j7R3caRqj+mE3lEtKCuHgwjLg3bCxLL1GPUJZVqUA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/react-native-screens": {
+ "version": "4.16.0",
+ "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.16.0.tgz",
+ "integrity": "sha512-yIAyh7F/9uWkOzCi1/2FqvNvK6Wb9Y1+Kzn16SuGfN9YFJDTbwlzGRvePCNTOX0recpLQF3kc2FmvMUhyTCH1Q==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "react-freeze": "^1.0.0",
+ "react-native-is-edge-to-edge": "^1.2.1",
+ "warn-once": "^0.1.0"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/react-native-svg": {
+ "version": "15.15.0",
+ "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.15.0.tgz",
+ "integrity": "sha512-/Wx6F/IZ88B/GcF88bK8K7ZseJDYt+7WGaiggyzLvTowChQ8BM5idmcd4pK+6QJP6a6DmzL2sfOMukFUn/NArg==",
+ "license": "MIT",
+ "dependencies": {
+ "css-select": "^5.1.0",
+ "css-tree": "^1.1.3",
+ "warn-once": "0.1.1"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/react-native-web": {
+ "version": "0.21.2",
+ "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.21.2.tgz",
+ "integrity": "sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.18.6",
+ "@react-native/normalize-colors": "^0.74.1",
+ "fbjs": "^3.0.4",
+ "inline-style-prefixer": "^7.0.1",
+ "memoize-one": "^6.0.0",
+ "nullthrows": "^1.1.1",
+ "postcss-value-parser": "^4.2.0",
+ "styleq": "^0.1.3"
+ },
+ "peerDependencies": {
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/react-native-web/node_modules/@react-native/normalize-colors": {
+ "version": "0.74.89",
+ "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.89.tgz",
+ "integrity": "sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg==",
+ "license": "MIT"
+ },
+ "node_modules/react-native-web/node_modules/memoize-one": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
+ "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
+ "license": "MIT"
+ },
+ "node_modules/react-native-worklets": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.6.1.tgz",
+ "integrity": "sha512-URca8l7c7Uog7gv4mcg9KILdJlnbvwdS5yfXQYf5TDkD2W1VY1sduEKrD+sA3lUPXH/TG1vmXAvNxCNwPMYgGg==",
+ "license": "MIT",
+ "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",
+ "semver": "7.7.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0",
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/react-native-worklets/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==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/react-native/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==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/react-native/node_modules/commander": {
+ "version": "12.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
+ "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/react-native/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/react-native/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/react-native/node_modules/ws": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
+ "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
+ "license": "MIT",
+ "dependencies": {
+ "async-limiter": "~1.0.0"
+ }
+ },
+ "node_modules/react-refresh": {
+ "version": "0.14.2",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
+ "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-remove-scroll": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz",
+ "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==",
+ "license": "MIT",
+ "dependencies": {
+ "react-remove-scroll-bar": "^2.3.7",
+ "react-style-singleton": "^2.2.3",
+ "tslib": "^2.1.0",
+ "use-callback-ref": "^1.3.3",
+ "use-sidecar": "^1.1.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-remove-scroll-bar": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",
+ "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",
+ "license": "MIT",
+ "dependencies": {
+ "react-style-singleton": "^2.2.2",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-style-singleton": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
+ "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",
+ "license": "MIT",
+ "dependencies": {
+ "get-nonce": "^1.0.0",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
+ "license": "MIT",
+ "dependencies": {
+ "pify": "^2.3.0"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/readable-stream/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/readdirp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/real-require": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz",
+ "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12.13.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==",
+ "license": "MIT"
+ },
+ "node_modules/regenerate-unicode-properties": {
+ "version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz",
+ "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/regexpu-core": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz",
+ "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==",
+ "license": "MIT",
+ "dependencies": {
+ "regenerate": "^1.4.2",
+ "regenerate-unicode-properties": "^10.2.2",
+ "regjsgen": "^0.8.0",
+ "regjsparser": "^0.13.0",
+ "unicode-match-property-ecmascript": "^2.0.0",
+ "unicode-match-property-value-ecmascript": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/registry-auth-token": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.0.tgz",
+ "integrity": "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@pnpm/npm-conf": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/registry-url": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz",
+ "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "rc": "1.2.8"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/regjsgen": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz",
+ "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
+ "license": "MIT"
+ },
+ "node_modules/regjsparser": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz",
+ "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "jsesc": "~3.1.0"
+ },
+ "bin": {
+ "regjsparser": "bin/parser"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/requireg": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/requireg/-/requireg-0.2.2.tgz",
+ "integrity": "sha512-nYzyjnFcPNGR3lx9lwPPPnuQxv6JWEZd2Ci0u9opN7N5zUEPIhY/GbL3vMGOr2UXwEg9WwSyV9X9Y/kLFgPsOg==",
+ "dependencies": {
+ "nested-error-stacks": "~2.0.1",
+ "rc": "~1.2.7",
+ "resolve": "~1.7.1"
+ },
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/requireg/node_modules/resolve": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz",
+ "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==",
+ "license": "MIT",
+ "dependencies": {
+ "path-parse": "^1.0.5"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.11",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
+ "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==",
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.16.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-global": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz",
+ "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==",
+ "license": "MIT",
+ "dependencies": {
+ "global-dirs": "^0.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-workspace-root": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-workspace-root/-/resolve-workspace-root-2.0.0.tgz",
+ "integrity": "sha512-IsaBUZETJD5WsI11Wt8PKHwaIe45or6pwNc8yflvLJ4DWtImK9kuLoH5kUva/2Mmx/RdIyr4aONNSa2v9LTJsw==",
+ "license": "MIT"
+ },
+ "node_modules/resolve.exports": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz",
+ "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==",
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/restore-cursor/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==",
+ "license": "ISC"
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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",
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rimraf/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==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/rimraf/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rimraf/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.53.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.1.tgz",
+ "integrity": "sha512-n2I0V0lN3E9cxxMqBCT3opWOiQBzRN7UG60z/WDKqdX2zHUS/39lezBcsckZFsV6fUTSnfqI7kHf60jDAPGKug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.8"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.53.1",
+ "@rollup/rollup-android-arm64": "4.53.1",
+ "@rollup/rollup-darwin-arm64": "4.53.1",
+ "@rollup/rollup-darwin-x64": "4.53.1",
+ "@rollup/rollup-freebsd-arm64": "4.53.1",
+ "@rollup/rollup-freebsd-x64": "4.53.1",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.53.1",
+ "@rollup/rollup-linux-arm-musleabihf": "4.53.1",
+ "@rollup/rollup-linux-arm64-gnu": "4.53.1",
+ "@rollup/rollup-linux-arm64-musl": "4.53.1",
+ "@rollup/rollup-linux-loong64-gnu": "4.53.1",
+ "@rollup/rollup-linux-ppc64-gnu": "4.53.1",
+ "@rollup/rollup-linux-riscv64-gnu": "4.53.1",
+ "@rollup/rollup-linux-riscv64-musl": "4.53.1",
+ "@rollup/rollup-linux-s390x-gnu": "4.53.1",
+ "@rollup/rollup-linux-x64-gnu": "4.53.1",
+ "@rollup/rollup-linux-x64-musl": "4.53.1",
+ "@rollup/rollup-openharmony-arm64": "4.53.1",
+ "@rollup/rollup-win32-arm64-msvc": "4.53.1",
+ "@rollup/rollup-win32-ia32-msvc": "4.53.1",
+ "@rollup/rollup-win32-x64-gnu": "4.53.1",
+ "@rollup/rollup-win32-x64-msvc": "4.53.1",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/run-applescript": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
+ "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safe-stable-stringify": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
+ "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/sax": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.3.tgz",
+ "integrity": "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==",
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/scheduler": {
+ "version": "0.26.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
+ "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
+ "license": "MIT"
+ },
+ "node_modules/scule": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz",
+ "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "license": "ISC",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/server-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz",
+ "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==",
+ "license": "MIT"
+ },
+ "node_modules/set-value": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-4.1.0.tgz",
+ "integrity": "sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/jonschlinkert",
+ "https://paypal.me/jonathanschlinkert",
+ "https://jonschlinkert.dev/sponsor"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4",
+ "is-primitive": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=11.0"
+ }
+ },
+ "node_modules/setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+ "license": "MIT"
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "license": "ISC"
+ },
+ "node_modules/sf-symbols-typescript": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/sf-symbols-typescript/-/sf-symbols-typescript-2.1.0.tgz",
+ "integrity": "sha512-ezT7gu/SHTPIOEEoG6TF+O0m5eewl0ZDAO4AtdBi5HjsrUI6JdCG17+Q8+aKp0heM06wZKApRCn5olNbs0Wb/A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shallowequal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
+ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/shellwords": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
+ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/simple-plist": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.1.tgz",
+ "integrity": "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/sisteransi": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+ "license": "MIT"
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/slice-ansi": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz",
+ "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.0.0",
+ "is-fullwidth-code-point": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/slice-ansi/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
+ "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/sonic-boom": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.0.tgz",
+ "integrity": "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "atomic-sleep": "^1.0.0"
+ }
+ },
+ "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==",
+ "license": "BSD-3-Clause",
+ "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==",
+ "license": "BSD-3-Clause",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/spawn-sync": {
+ "version": "1.0.15",
+ "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz",
+ "integrity": "sha512-9DWBgrgYZzNghseho0JOuh+5fg9u6QWhAWa51QC7+U5rCheZ/j1DrEZnyE0RBBRqZ9uEXGPgSSM0nky6burpVw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "concat-stream": "^1.4.7",
+ "os-shim": "^0.1.2"
+ }
+ },
+ "node_modules/split": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
+ "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "through": "2"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 10.x"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "license": "BSD-3-Clause"
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/stdin-discarder": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz",
+ "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "Unlicense",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/string_decoder/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-argv": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
+ "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6.19"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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/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==",
+ "license": "MIT",
+ "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/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==",
+ "license": "MIT"
+ },
+ "node_modules/string-width-cjs/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==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
+ "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi/node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-5.0.0.tgz",
+ "integrity": "sha512-p+byADHF7SzEcVnLvc/r3uognM1hUhObuHXxJcgLCfD194XAkaLbjq3Wzb0N5G2tgIjH0dgT708Z51QxMeu60A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
+ "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-literal": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz",
+ "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^9.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/strip-literal/node_modules/js-tokens": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
+ "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/structured-headers": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/structured-headers/-/structured-headers-0.4.1.tgz",
+ "integrity": "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==",
+ "license": "MIT"
+ },
+ "node_modules/stubborn-fs": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/stubborn-fs/-/stubborn-fs-2.0.0.tgz",
+ "integrity": "sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "stubborn-utils": "^1.0.1"
+ }
+ },
+ "node_modules/stubborn-utils": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/stubborn-utils/-/stubborn-utils-1.0.2.tgz",
+ "integrity": "sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/styleq": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/styleq/-/styleq-0.1.3.tgz",
+ "integrity": "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA==",
+ "license": "MIT"
+ },
+ "node_modules/sucrase": {
+ "version": "3.35.0",
+ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
+ "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "commander": "^4.0.0",
+ "glob": "^10.3.10",
+ "lines-and-columns": "^1.1.6",
+ "mz": "^2.7.0",
+ "pirates": "^4.0.1",
+ "ts-interface-checker": "^0.1.9"
+ },
+ "bin": {
+ "sucrase": "bin/sucrase",
+ "sucrase-node": "bin/sucrase-node"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/sucrase/node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/supports-hyperlinks": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz",
+ "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-hyperlinks/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-hyperlinks/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==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/tailwindcss": {
+ "version": "3.4.18",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.18.tgz",
+ "integrity": "sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@alloc/quick-lru": "^5.2.0",
+ "arg": "^5.0.2",
+ "chokidar": "^3.6.0",
+ "didyoumean": "^1.2.2",
+ "dlv": "^1.1.3",
+ "fast-glob": "^3.3.2",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "jiti": "^1.21.7",
+ "lilconfig": "^3.1.3",
+ "micromatch": "^4.0.8",
+ "normalize-path": "^3.0.0",
+ "object-hash": "^3.0.0",
+ "picocolors": "^1.1.1",
+ "postcss": "^8.4.47",
+ "postcss-import": "^15.1.0",
+ "postcss-js": "^4.0.1",
+ "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0",
+ "postcss-nested": "^6.2.0",
+ "postcss-selector-parser": "^6.1.2",
+ "resolve": "^1.22.8",
+ "sucrase": "^3.35.0"
+ },
+ "bin": {
+ "tailwind": "lib/cli.js",
+ "tailwindcss": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/tailwindcss/node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/tailwindcss/node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/tailwindcss/node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/tailwindcss/node_modules/jiti": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
+ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
+ "license": "MIT",
+ "bin": {
+ "jiti": "bin/jiti.js"
+ }
+ },
+ "node_modules/tailwindcss/node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/tar": {
+ "version": "7.5.2",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.2.tgz",
+ "integrity": "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/fs-minipass": "^4.0.0",
+ "chownr": "^3.0.0",
+ "minipass": "^7.1.2",
+ "minizlib": "^3.1.0",
+ "yallist": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tar/node_modules/yallist": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
+ "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/temp-dir": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz",
+ "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/terminal-link": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
+ "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-escapes": "^4.2.1",
+ "supports-hyperlinks": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.44.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz",
+ "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.15.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==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "ISC",
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/test-exclude/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==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/test-exclude/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/test-exclude/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "node_modules/thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "license": "MIT",
+ "dependencies": {
+ "thenify": ">= 3.1.0 < 4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/thread-stream": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz",
+ "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "real-require": "^0.2.0"
+ }
+ },
+ "node_modules/throat": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz",
+ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==",
+ "license": "MIT"
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyexec": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz",
+ "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tinyglobby/node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tinyglobby/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/tmp": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
+ "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/tmpl": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
+ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
+ "license": "BSD-3-Clause"
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "license": "MIT"
+ },
+ "node_modules/ts-interface-checker": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
+ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
+ "license": "Apache-2.0"
+ },
+ "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==",
+ "license": "0BSD"
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ua-parser-js": {
+ "version": "1.0.41",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.41.tgz",
+ "integrity": "sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/ua-parser-js"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/faisalman"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/faisalman"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "ua-parser-js": "script/cli.js"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ufo": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz",
+ "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/uhyphen": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/uhyphen/-/uhyphen-0.2.0.tgz",
+ "integrity": "sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/undici": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-6.22.0.tgz",
+ "integrity": "sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.17"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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.1",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz",
+ "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-property-aliases-ecmascript": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz",
+ "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unimport": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/unimport/-/unimport-5.5.0.tgz",
+ "integrity": "sha512-/JpWMG9s1nBSlXJAQ8EREFTFy3oy6USFd8T6AoBaw1q2GGcF4R9yp3ofg32UODZlYEO5VD0EWE1RpI9XDWyPYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "escape-string-regexp": "^5.0.0",
+ "estree-walker": "^3.0.3",
+ "local-pkg": "^1.1.2",
+ "magic-string": "^0.30.19",
+ "mlly": "^1.8.0",
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.3",
+ "pkg-types": "^2.3.0",
+ "scule": "^1.3.0",
+ "strip-literal": "^3.1.0",
+ "tinyglobby": "^0.2.15",
+ "unplugin": "^2.3.10",
+ "unplugin-utils": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ }
+ },
+ "node_modules/unimport/node_modules/escape-string-regexp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/unimport/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/unique-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
+ "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==",
+ "license": "MIT",
+ "dependencies": {
+ "crypto-random-string": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/unplugin": {
+ "version": "2.3.10",
+ "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.10.tgz",
+ "integrity": "sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/remapping": "^2.3.5",
+ "acorn": "^8.15.0",
+ "picomatch": "^4.0.3",
+ "webpack-virtual-modules": "^0.6.2"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ }
+ },
+ "node_modules/unplugin-utils": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.3.1.tgz",
+ "integrity": "sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "node_modules/unplugin-utils/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/unplugin/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz",
+ "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==",
+ "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"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/update-notifier": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-7.3.1.tgz",
+ "integrity": "sha512-+dwUY4L35XFYEzE+OAL3sarJdUioVovq+8f7lcIJ7wnmnYQV5UD1Y/lcwaMSyaQ6Bj3JMj1XSTjZbNLHn/19yA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boxen": "^8.0.1",
+ "chalk": "^5.3.0",
+ "configstore": "^7.0.0",
+ "is-in-ci": "^1.0.0",
+ "is-installed-globally": "^1.0.0",
+ "is-npm": "^6.0.0",
+ "latest-version": "^9.0.0",
+ "pupa": "^3.1.0",
+ "semver": "^7.6.3",
+ "xdg-basedir": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/yeoman/update-notifier?sponsor=1"
+ }
+ },
+ "node_modules/update-notifier/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/use-callback-ref": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz",
+ "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/use-sidecar": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
+ "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "detect-node-es": "^1.1.0",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/validate-npm-package-name": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz",
+ "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==",
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/vaul": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz",
+ "integrity": "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-dialog": "^1.1.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc"
+ }
+ },
+ "node_modules/vite": {
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
+ "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.25.0",
+ "fdir": "^6.4.4",
+ "picomatch": "^4.0.2",
+ "postcss": "^8.5.3",
+ "rollup": "^4.34.9",
+ "tinyglobby": "^0.2.13"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "jiti": ">=1.21.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-node": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz",
+ "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cac": "^6.7.14",
+ "debug": "^4.4.1",
+ "es-module-lexer": "^1.7.0",
+ "pathe": "^2.0.3",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
+ },
+ "bin": {
+ "vite-node": "vite-node.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/vite/node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/vite/node_modules/postcss": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/vlq": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz",
+ "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==",
+ "license": "MIT"
+ },
+ "node_modules/walker": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
+ "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
+ "license": "Apache-2.0",
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/watchpack": {
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz",
+ "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/wcwidth": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+ "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
+ "license": "MIT",
+ "dependencies": {
+ "defaults": "^1.0.3"
+ }
+ },
+ "node_modules/web-ext-run": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/web-ext-run/-/web-ext-run-0.2.4.tgz",
+ "integrity": "sha512-rQicL7OwuqWdQWI33JkSXKcp7cuv1mJG8u3jRQwx/8aDsmhbTHs9ZRmNYOL+LX0wX8edIEQX8jj4bB60GoXtKA==",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "@babel/runtime": "7.28.2",
+ "@devicefarmer/adbkit": "3.3.8",
+ "chrome-launcher": "1.2.0",
+ "debounce": "1.2.1",
+ "es6-error": "4.1.1",
+ "firefox-profile": "4.7.0",
+ "fx-runner": "1.4.0",
+ "multimatch": "6.0.0",
+ "node-notifier": "10.0.1",
+ "parse-json": "7.1.1",
+ "pino": "9.7.0",
+ "promise-toolbox": "0.21.0",
+ "set-value": "4.1.0",
+ "source-map-support": "0.5.21",
+ "strip-bom": "5.0.0",
+ "strip-json-comments": "5.0.2",
+ "tmp": "0.2.5",
+ "update-notifier": "7.3.1",
+ "watchpack": "2.4.4",
+ "zip-dir": "2.0.0"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ }
+ },
+ "node_modules/web-ext-run/node_modules/@babel/runtime": {
+ "version": "7.28.2",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz",
+ "integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/web-ext-run/node_modules/chrome-launcher": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.2.0.tgz",
+ "integrity": "sha512-JbuGuBNss258bvGil7FT4HKdC3SC2K7UAEUqiPy3ACS3Yxo3hAW6bvFpCu2HsIJLgTqxgEX6BkujvzZfLpUD0Q==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/node": "*",
+ "escape-string-regexp": "^4.0.0",
+ "is-wsl": "^2.2.0",
+ "lighthouse-logger": "^2.0.1"
+ },
+ "bin": {
+ "print-chrome-path": "bin/print-chrome-path.cjs"
+ },
+ "engines": {
+ "node": ">=12.13.0"
+ }
+ },
+ "node_modules/web-ext-run/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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/web-ext-run/node_modules/lighthouse-logger": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-2.0.2.tgz",
+ "integrity": "sha512-vWl2+u5jgOQuZR55Z1WM0XDdrJT6mzMP8zHUct7xTlWhuQs+eV0g+QL0RQdFjT54zVmbhLCP8vIVpy1wGn/gCg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "debug": "^4.4.1",
+ "marky": "^1.2.2"
+ }
+ },
+ "node_modules/web-ext-run/node_modules/strip-json-comments": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.2.tgz",
+ "integrity": "sha512-4X2FR3UwhNUE9G49aIsJW5hRRR3GXGTBTZRMfv568O60ojM8HcWjV/VxAxCDW3SUND33O6ZY66ZuRcdkj73q2g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
+ "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/webpack-virtual-modules": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
+ "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/whatwg-url-without-unicode": {
+ "version": "8.0.0-3",
+ "resolved": "https://registry.npmjs.org/whatwg-url-without-unicode/-/whatwg-url-without-unicode-8.0.0-3.tgz",
+ "integrity": "sha512-HoKuzZrUlgpz35YO27XgD28uh/WJH4B0+3ttFqRo//lmq+9T/mIOJ6kqmINI9HpUpz1imRC/nR/lxKpJiv0uig==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer": "^5.4.3",
+ "punycode": "^2.1.1",
+ "webidl-conversions": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/whatwg-url/node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/when": {
+ "version": "3.7.7",
+ "resolved": "https://registry.npmjs.org/when/-/when-3.7.7.tgz",
+ "integrity": "sha512-9lFZp/KHoqH6bPKjbWqa+3Dg/K/r2v0X/3/G2x4DBGchVS2QX2VXL3cZV994WQVnTM1/PD71Az25nAzryEUugw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/when-exit": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/when-exit/-/when-exit-2.1.5.tgz",
+ "integrity": "sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/widest-line": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz",
+ "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "string-width": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/widest-line/node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/widest-line/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/winreg": {
+ "version": "0.0.12",
+ "resolved": "https://registry.npmjs.org/winreg/-/winreg-0.0.12.tgz",
+ "integrity": "sha512-typ/+JRmi7RqP1NanzFULK36vczznSNN8kWVA9vIqXyv8GhghUlwhGp1Xj3Nms1FsPcNnsQrJOR10N58/nQ9hQ==",
+ "dev": true,
+ "license": "BSD"
+ },
+ "node_modules/wonka": {
+ "version": "6.3.5",
+ "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.5.tgz",
+ "integrity": "sha512-SSil+ecw6B4/Dm7Pf2sAshKQ5hWFvfyGlfPbEd6A14dOH6VDjrmbY86u6nZvy9omGwwIPFR8V41+of1EezgoUw==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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/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==",
+ "license": "MIT",
+ "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/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/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==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/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==",
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi-cjs/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==",
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi-cjs/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==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/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==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?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==",
+ "license": "ISC"
+ },
+ "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==",
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^3.0.7"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/write-file-atomic/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==",
+ "license": "ISC"
+ },
+ "node_modules/ws": {
+ "version": "7.5.10",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
+ "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
+ "license": "MIT",
+ "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/wsl-utils": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz",
+ "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-wsl": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wsl-utils/node_modules/is-wsl": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz",
+ "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-inside-container": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wxt": {
+ "version": "0.20.11",
+ "resolved": "https://registry.npmjs.org/wxt/-/wxt-0.20.11.tgz",
+ "integrity": "sha512-DqqHc/5COs8GR21ii99bANXf/mu6zuDpiXFV1YKNsqO5/PvkrCx5arY0aVPL5IATsuacAnNzdj4eMc1qbzS53Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@1natsu/wait-element": "^4.1.2",
+ "@aklinker1/rollup-plugin-visualizer": "5.12.0",
+ "@webext-core/fake-browser": "^1.3.2",
+ "@webext-core/isolated-element": "^1.1.2",
+ "@webext-core/match-patterns": "^1.0.3",
+ "@wxt-dev/browser": "^0.1.4",
+ "@wxt-dev/storage": "^1.0.0",
+ "async-mutex": "^0.5.0",
+ "c12": "^3.2.0",
+ "cac": "^6.7.14",
+ "chokidar": "^4.0.3",
+ "ci-info": "^4.3.0",
+ "consola": "^3.4.2",
+ "defu": "^6.1.4",
+ "dotenv": "^17.2.2",
+ "dotenv-expand": "^12.0.3",
+ "esbuild": "^0.25.0",
+ "fast-glob": "^3.3.3",
+ "filesize": "^11.0.2",
+ "fs-extra": "^11.3.1",
+ "get-port-please": "^3.2.0",
+ "giget": "^1.2.3 || ^2.0.0",
+ "hookable": "^5.5.3",
+ "import-meta-resolve": "^4.2.0",
+ "is-wsl": "^3.1.0",
+ "json5": "^2.2.3",
+ "jszip": "^3.10.1",
+ "linkedom": "^0.18.12",
+ "magicast": "^0.3.5",
+ "minimatch": "^10.0.3",
+ "nano-spawn": "^1.0.2",
+ "normalize-path": "^3.0.0",
+ "nypm": "^0.6.1",
+ "ohash": "^2.0.11",
+ "open": "^10.2.0",
+ "ora": "^8.2.0",
+ "perfect-debounce": "^2.0.0",
+ "picocolors": "^1.1.1",
+ "prompts": "^2.4.2",
+ "publish-browser-extension": "^2.3.0 || ^3.0.2",
+ "scule": "^1.3.0",
+ "unimport": "^3.13.1 || ^4.0.0 || ^5.0.0",
+ "vite": "^5.4.19 || ^6.3.4 || ^7.0.0",
+ "vite-node": "^2.1.4 || ^3.1.2",
+ "web-ext-run": "^0.2.4"
+ },
+ "bin": {
+ "wxt": "bin/wxt.mjs",
+ "wxt-publish-extension": "bin/wxt-publish-extension.cjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/wxt-dev"
+ }
+ },
+ "node_modules/wxt/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/wxt/node_modules/ci-info": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz",
+ "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wxt/node_modules/cli-cursor": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
+ "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "restore-cursor": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wxt/node_modules/define-lazy-prop": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
+ "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wxt/node_modules/dotenv": {
+ "version": "17.2.3",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz",
+ "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/wxt/node_modules/dotenv-expand": {
+ "version": "12.0.3",
+ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-12.0.3.tgz",
+ "integrity": "sha512-uc47g4b+4k/M/SeaW1y4OApx+mtLWl92l5LMPP0GNXctZqELk+YGgOPIIC5elYmUH4OuoK3JLhuRUYegeySiFA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dotenv": "^16.4.5"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/wxt/node_modules/dotenv-expand/node_modules/dotenv": {
+ "version": "16.6.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/wxt/node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wxt/node_modules/is-wsl": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz",
+ "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-inside-container": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wxt/node_modules/log-symbols": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz",
+ "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^5.3.0",
+ "is-unicode-supported": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wxt/node_modules/log-symbols/node_modules/is-unicode-supported": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz",
+ "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wxt/node_modules/minimatch": {
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz",
+ "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/brace-expansion": "^5.0.0"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/wxt/node_modules/onetime": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
+ "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-function": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wxt/node_modules/open": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz",
+ "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "default-browser": "^5.2.1",
+ "define-lazy-prop": "^3.0.0",
+ "is-inside-container": "^1.0.0",
+ "wsl-utils": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wxt/node_modules/ora": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz",
+ "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^5.3.0",
+ "cli-cursor": "^5.0.0",
+ "cli-spinners": "^2.9.2",
+ "is-interactive": "^2.0.0",
+ "is-unicode-supported": "^2.0.0",
+ "log-symbols": "^6.0.0",
+ "stdin-discarder": "^0.2.2",
+ "string-width": "^7.2.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wxt/node_modules/restore-cursor": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
+ "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^7.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wxt/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/xcode": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz",
+ "integrity": "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "simple-plist": "^1.1.0",
+ "uuid": "^7.0.3"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/xdg-basedir": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz",
+ "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/xml2js": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.0.tgz",
+ "integrity": "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "ISC",
+ "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==",
+ "license": "ISC"
+ },
+ "node_modules/yaml": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
+ "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
+ "license": "ISC",
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14.6"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "license": "MIT",
+ "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==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs/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==",
+ "license": "MIT"
+ },
+ "node_modules/yargs/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==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/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==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/zip-dir": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/zip-dir/-/zip-dir-2.0.0.tgz",
+ "integrity": "sha512-uhlsJZWz26FLYXOD6WVuq+fIcZ3aBPGo/cFdiLlv3KNwpa52IF3ISV8fLhQLiqVu5No3VhlqlgthN6gehil1Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async": "^3.2.0",
+ "jszip": "^3.2.2"
+ }
+ },
+ "node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/zod-to-json-schema": {
+ "version": "3.24.6",
+ "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz",
+ "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==",
+ "license": "ISC",
+ "peerDependencies": {
+ "zod": "^3.24.1"
+ }
+ }
+ }
+}
diff --git a/companion/package.json b/companion/package.json
new file mode 100644
index 0000000000..bdc0411304
--- /dev/null
+++ b/companion/package.json
@@ -0,0 +1,64 @@
+{
+ "name": "cal-companion",
+ "displayName": "Cal.com Companion",
+ "version": "1.7.0",
+ "main": "index.js",
+ "scripts": {
+ "start": "expo start",
+ "android": "expo start --android",
+ "ios": "expo start --ios",
+ "web": "expo start --web",
+ "ext:build": "wxt build",
+ "ext": "wxt",
+ "ext:zip": "wxt zip",
+ "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,md}\"",
+ "format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,css,md}\"",
+ "prepare": "cd .. && husky companion/.husky"
+ },
+ "dependencies": {
+ "@expo/ui": "^0.2.0-beta.7",
+ "@expo/vector-icons": "^15.0.3",
+ "@react-native-segmented-control/segmented-control": "^2.5.7",
+ "@types/react": "~19.1.10",
+ "@types/react-dom": "~19.1.7",
+ "base64-js": "^1.5.1",
+ "expo": "~54.0.0",
+ "expo-auth-session": "^7.0.9",
+ "expo-constants": "~18.0.10",
+ "expo-crypto": "^15.0.7",
+ "expo-device": "^8.0.9",
+ "expo-glass-effect": "~0.1.6",
+ "expo-linking": "~8.0.8",
+ "expo-router": "~6.0.14",
+ "expo-secure-store": "^15.0.7",
+ "expo-status-bar": "~3.0.8",
+ "expo-web-browser": "^15.0.9",
+ "nativewind": "^4.2.1",
+ "react": "^19.1.0",
+ "react-dom": "^19.1.0",
+ "react-native": "0.81.5",
+ "react-native-context-menu-view": "^1.20.0",
+ "react-native-gesture-handler": "^2.29.1",
+ "react-native-reanimated": "~3.17.4",
+ "react-native-safe-area-context": "5.4.0",
+ "react-native-svg": "^15.15.0",
+ "react-native-web": "^0.21.2",
+ "react-native-worklets": "^0.6.1"
+ },
+ "private": true,
+ "devDependencies": {
+ "@types/chrome": "^0.1.31",
+ "babel-preset-expo": "^54.0.7",
+ "husky": "^9.0.11",
+ "lint-staged": "^15.2.0",
+ "prettier": "^3.2.5",
+ "prettier-plugin-tailwindcss": "^0.5.11",
+ "tailwindcss": "^3.4.17",
+ "wxt": "^0.20.11"
+ },
+ "lint-staged": {
+ "**/*.{js,jsx,ts,tsx,json,css,md}": [
+ "prettier --write"
+ ]
+ }
+}
diff --git a/companion/services/calcom.ts b/companion/services/calcom.ts
new file mode 100644
index 0000000000..02692a1917
--- /dev/null
+++ b/companion/services/calcom.ts
@@ -0,0 +1,1146 @@
+import type {
+ EventType,
+ CreateEventTypeInput,
+ GetEventTypesResponse,
+ Booking,
+ GetBookingsResponse,
+ BookingParticipationResult,
+ Schedule,
+ GetSchedulesResponse,
+ GetScheduleResponse,
+ UserProfile,
+ ConferencingOption,
+ Webhook,
+ CreateWebhookInput,
+ UpdateWebhookInput,
+ PrivateLink,
+ CreatePrivateLinkInput,
+ UpdatePrivateLinkInput,
+} from "./types";
+
+const API_BASE_URL = "https://api.cal.com/v2";
+
+// Authentication configuration
+interface AuthConfig {
+ accessToken?: string;
+ refreshToken?: string;
+}
+
+// Global auth state
+const authConfig: AuthConfig = {};
+
+// Token refresh callback - will be set by AuthContext
+let tokenRefreshCallback: ((accessToken: string, refreshToken?: string) => Promise) | null =
+ null;
+
+// Refresh token function - will be set by AuthContext
+let refreshTokenFunction:
+ | ((refreshToken: string) => Promise<{ accessToken: string; refreshToken?: string }>)
+ | null = null;
+
+// Re-export types for backward compatibility
+export type {
+ EventType,
+ CreateEventTypeInput,
+ Booking,
+ BookingParticipationResult,
+ Schedule,
+ UserProfile,
+ ConferencingOption,
+ Webhook,
+ CreateWebhookInput,
+ UpdateWebhookInput,
+ PrivateLink,
+ CreatePrivateLinkInput,
+ UpdatePrivateLinkInput,
+};
+
+export const getBookingParticipation = (
+ booking: Booking,
+ userId?: number,
+ userEmail?: string
+): BookingParticipationResult => {
+ const normalizedUserEmail = userEmail?.toLowerCase();
+ const emailEq = (a?: string, b?: string) => a?.toLowerCase() === b?.toLowerCase();
+ const idEq = (a?: string | number, b?: string | number) =>
+ a !== undefined && b !== undefined && String(a) === String(b);
+
+ const isOrganizer =
+ !!booking.user &&
+ (idEq(booking.user.id, userId) || emailEq(booking.user.email, normalizedUserEmail));
+
+ const isHost =
+ Array.isArray(booking.hosts) &&
+ booking.hosts.some((host) => idEq(host.id, userId) || emailEq(host.email, normalizedUserEmail));
+
+ const isAttendee =
+ Array.isArray(booking.attendees) &&
+ booking.attendees.some(
+ (attendee) => idEq(attendee.id, userId) || emailEq(attendee.email, normalizedUserEmail)
+ );
+
+ const isParticipating = isOrganizer || isHost || isAttendee;
+
+ return { isOrganizer, isHost, isAttendee, isParticipating };
+};
+
+export class CalComAPIService {
+ private static userProfile: UserProfile | null = null;
+
+ /**
+ * Set OAuth access token for authentication
+ */
+ static setAccessToken(accessToken: string, refreshToken?: string): void {
+ authConfig.accessToken = accessToken;
+ if (refreshToken) {
+ authConfig.refreshToken = refreshToken;
+ }
+ }
+
+ /**
+ * Set refresh token function for automatic token refresh
+ */
+ static setRefreshTokenFunction(
+ refreshFn: (refreshToken: string) => Promise<{ accessToken: string; refreshToken?: string }>
+ ): void {
+ refreshTokenFunction = refreshFn;
+ }
+
+ /**
+ * Clear all authentication
+ */
+ static clearAuth(): void {
+ authConfig.accessToken = undefined;
+ authConfig.refreshToken = undefined;
+ tokenRefreshCallback = null;
+ refreshTokenFunction = null;
+ }
+
+ /**
+ * Set token refresh callback for OAuth token refresh
+ */
+ static setTokenRefreshCallback(
+ callback: (accessToken: string, refreshToken?: string) => Promise
+ ): void {
+ tokenRefreshCallback = callback;
+ }
+
+ /**
+ * Get current authentication header
+ */
+ private static getAuthHeader(): string {
+ if (authConfig.accessToken) {
+ return `Bearer ${authConfig.accessToken}`;
+ } else {
+ throw new Error("No authentication configured. Please sign in with OAuth.");
+ }
+ }
+
+ // Get current user profile
+ static async getCurrentUser(): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: UserProfile }>(
+ "/me",
+ {
+ headers: {
+ "cal-api-version": "2024-06-11",
+ },
+ },
+ "2024-06-11"
+ );
+ return response.data;
+ } catch (error) {
+ throw error;
+ }
+ }
+
+ // Update current user profile
+ static async updateUserProfile(updates: {
+ email?: string;
+ name?: string;
+ timeFormat?: number;
+ defaultScheduleId?: number;
+ weekStart?: string;
+ timeZone?: string;
+ locale?: string;
+ avatarUrl?: string;
+ bio?: string;
+ metadata?: Record;
+ }): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: UserProfile }>(
+ "/me",
+ {
+ method: "PATCH",
+ headers: {
+ "Content-Type": "application/json",
+ "cal-api-version": "2024-06-11",
+ },
+ body: JSON.stringify(updates),
+ },
+ "2024-06-11"
+ );
+
+ if (response && response.data) {
+ // Update cached profile
+ this.userProfile = response.data;
+ return response.data;
+ }
+
+ throw new Error("Invalid response from update user profile API");
+ } catch (error) {
+ console.error("updateUserProfile error:", error);
+ throw error;
+ }
+ }
+
+ // Get and cache user profile
+ static async getUserProfile(): Promise {
+ if (this.userProfile) {
+ return this.userProfile;
+ }
+
+ this.userProfile = await this.getCurrentUser();
+ return this.userProfile;
+ }
+
+ // Get cached username or fetch if not available
+ static async getUsername(): Promise {
+ const profile = await this.getUserProfile();
+ return profile.username;
+ }
+
+ // Build shareable link for event type
+ static async buildEventTypeLink(eventTypeSlug: string): Promise {
+ const username = await this.getUsername();
+ return `https://cal.com/${username}/${eventTypeSlug}`;
+ }
+
+ // Clear cached profile (useful for logout)
+ static clearUserProfile(): void {
+ this.userProfile = null;
+ }
+
+ // Test function for bookings API specifically
+ static async testRawBookingsAPI(): Promise {
+ try {
+ const url = `${API_BASE_URL}/bookings?status=upcoming&status=unconfirmed&limit=50`;
+
+ const response = await fetch(url, {
+ headers: {
+ Authorization: this.getAuthHeader(),
+ "Content-Type": "application/json",
+ "cal-api-version": "2024-08-13",
+ },
+ });
+
+ const responseText = await response.text();
+
+ try {
+ const responseJson = JSON.parse(responseText);
+ } catch (parseError) {}
+ } catch (error) {}
+ }
+
+ private static async makeRequest(
+ endpoint: string,
+ options: RequestInit = {},
+ apiVersion: string = "2024-08-13",
+ isRetry: boolean = false
+ ): Promise {
+ const url = `${API_BASE_URL}${endpoint}`;
+
+ const response = await fetch(url, {
+ ...options,
+ headers: {
+ Authorization: this.getAuthHeader(),
+ "Content-Type": "application/json",
+ "cal-api-version": apiVersion,
+ ...options.headers,
+ },
+ });
+
+ if (!response.ok) {
+ const errorBody = await response.text();
+
+ // Parse error for better user messages
+ let errorMessage = response.statusText;
+
+ try {
+ const errorJson = JSON.parse(errorBody);
+ errorMessage = errorJson?.error?.message || errorJson?.message || response.statusText;
+ } catch (parseError) {
+ // If JSON parsing fails, use the raw error body
+ errorMessage = errorBody || response.statusText;
+ }
+
+ // Handle specific error cases
+ if (response.status === 401) {
+ if (!isRetry && authConfig.refreshToken && refreshTokenFunction && tokenRefreshCallback) {
+ try {
+ const newTokens = await refreshTokenFunction(authConfig.refreshToken);
+
+ authConfig.accessToken = newTokens.accessToken;
+ if (newTokens.refreshToken) {
+ authConfig.refreshToken = newTokens.refreshToken;
+ }
+
+ // Notify AuthContext to update stored tokens
+ await tokenRefreshCallback(newTokens.accessToken, newTokens.refreshToken);
+
+ // Retry the original request with the new token
+ return this.makeRequest(endpoint, options, apiVersion, true);
+ } catch (refreshError) {
+ console.error("Token refresh failed:", refreshError);
+ this.clearAuth();
+ throw new Error("Authentication failed. Please sign in again.");
+ }
+ }
+
+ if (errorMessage.includes("expired")) {
+ throw new Error("Your authentication has expired. Please sign in again.");
+ }
+ throw new Error("Authentication failed. Please check your credentials.");
+ }
+
+ throw new Error(`API Error: ${errorMessage}`);
+ }
+
+ return response.json();
+ }
+
+ // Delete an event type
+ static async deleteEventType(eventTypeId: number): Promise {
+ try {
+ console.log(`Deleting event type with ID: ${eventTypeId}`);
+ await this.makeRequest(
+ `/event-types/${eventTypeId}`,
+ {
+ method: "DELETE",
+ },
+ "2024-06-14"
+ );
+ console.log("Delete completed");
+ } catch (error) {
+ console.error("Delete API error:", error);
+ throw error;
+ }
+ }
+
+ // Create an event type
+ static async createEventType(input: CreateEventTypeInput): Promise {
+ try {
+ console.log("Creating event type with input:", JSON.stringify(input, null, 2));
+
+ const response = await this.makeRequest<{ status: string; data: EventType }>(
+ "/event-types",
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ "cal-api-version": "2024-06-14",
+ },
+ body: JSON.stringify(input),
+ },
+ "2024-06-14"
+ );
+
+ if (response && response.data) {
+ console.log("Event type created successfully:", response.data);
+ return response.data;
+ }
+
+ throw new Error("Invalid response from create event type API");
+ } catch (error) {
+ console.error("createEventType error:", error);
+ throw error;
+ }
+ }
+
+ // Cancel a booking
+ static async cancelBooking(bookingUid: string, reason?: string): Promise {
+ try {
+ const body: { reason?: string } = {};
+ if (reason) {
+ body.reason = reason;
+ }
+
+ await this.makeRequest(`/bookings/${bookingUid}/cancel`, {
+ method: "POST",
+ body: JSON.stringify(body),
+ });
+ } catch (error) {
+ throw error;
+ }
+ }
+
+ // Reschedule a booking
+ static async rescheduleBooking(
+ bookingUid: string,
+ input: {
+ start: string; // ISO 8601 datetime string
+ reschedulingReason?: string;
+ }
+ ): Promise {
+ try {
+ console.log(`Rescheduling booking ${bookingUid} to:`, input.start);
+
+ const response = await this.makeRequest<{ status: string; data: Booking }>(
+ `/bookings/${bookingUid}/reschedule`,
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ "cal-api-version": "2024-08-13",
+ },
+ body: JSON.stringify(input),
+ },
+ "2024-08-13"
+ );
+
+ if (response && response.data) {
+ console.log("Booking rescheduled successfully:", response.data);
+ return response.data;
+ }
+
+ throw new Error("Invalid response from reschedule booking API");
+ } catch (error) {
+ console.error("rescheduleBooking error:", error);
+ throw error;
+ }
+ }
+
+ static async getEventTypes(): Promise {
+ try {
+ // Get current user to extract username
+ let username: string | undefined;
+ try {
+ const currentUser = await this.getCurrentUser();
+ // Extract username from response
+ if (currentUser?.username) {
+ username = currentUser.username;
+ }
+ } catch (error) {}
+
+ // Build query string with username if available
+ const params = new URLSearchParams();
+ if (username) {
+ params.append("username", username);
+ }
+
+ const queryString = params.toString();
+ const endpoint = `/event-types${queryString ? `?${queryString}` : ""}`;
+
+ const response = await this.makeRequest(endpoint, {}, "2024-06-14");
+
+ // Handle different possible response structures
+ let eventTypesArray: EventType[] = [];
+
+ if (Array.isArray(response)) {
+ eventTypesArray = response;
+ } else if (response && typeof response === "object") {
+ if (response.data && Array.isArray(response.data)) {
+ eventTypesArray = response.data;
+ } else if (response.eventTypes && Array.isArray(response.eventTypes)) {
+ eventTypesArray = response.eventTypes;
+ } else if (response.items && Array.isArray(response.items)) {
+ eventTypesArray = response.items;
+ } else if (response.data && typeof response.data === "object") {
+ if (response.data.eventTypes && Array.isArray(response.data.eventTypes)) {
+ eventTypesArray = response.data.eventTypes;
+ } else if (response.data.items && Array.isArray(response.data.items)) {
+ eventTypesArray = response.data.items;
+ } else {
+ const keys = Object.keys(response.data);
+ if (keys.length > 0) {
+ eventTypesArray = Object.values(response.data).filter(
+ (item): item is EventType => item && typeof item === "object" && "id" in item
+ ) as EventType[];
+ }
+ }
+ } else {
+ const possibleArrays = Object.values(response).filter((val) => Array.isArray(val));
+ if (possibleArrays.length > 0) {
+ eventTypesArray = possibleArrays[0] as EventType[];
+ }
+ }
+ }
+
+ return eventTypesArray;
+ } catch (error) {
+ throw error;
+ }
+ }
+
+ static async getBookingByUid(bookingUid: string): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: Booking }>(
+ `/bookings/${bookingUid}`,
+ {
+ headers: {
+ "cal-api-version": "2024-08-13",
+ },
+ },
+ "2024-08-13"
+ );
+ console.log("getBookingByUid raw response:", JSON.stringify(response, null, 2));
+ if (response && response.data) {
+ console.log("getBookingByUid booking data:", JSON.stringify(response.data, null, 2));
+ console.log("getBookingByUid user field:", response.data.user);
+ console.log("getBookingByUid hosts field:", response.data.hosts);
+ console.log("getBookingByUid attendees field:", response.data.attendees);
+ return response.data;
+ }
+ throw new Error("Invalid response from get booking API");
+ } catch (error) {
+ console.error("getBookingByUid error:", error);
+ throw error;
+ }
+ }
+
+ static async getBookings(filters?: {
+ status?: string[];
+ fromDate?: string;
+ toDate?: string;
+ eventTypeId?: number;
+ limit?: number;
+ offset?: number;
+ }): Promise {
+ try {
+ // Build query parameters
+ const params = new URLSearchParams();
+
+ if (filters?.status?.length) {
+ filters.status.forEach((status) => params.append("status", status));
+ }
+ if (filters?.fromDate) {
+ params.append("fromDate", filters.fromDate);
+ }
+ if (filters?.toDate) {
+ params.append("toDate", filters.toDate);
+ }
+ if (filters?.eventTypeId) {
+ params.append("eventTypeId", filters.eventTypeId.toString());
+ }
+ if (filters?.limit) {
+ params.append("limit", filters.limit.toString());
+ }
+ if (filters?.offset) {
+ params.append("offset", filters.offset.toString());
+ }
+
+ const queryString = params.toString();
+ const endpoint = `/bookings${queryString ? `?${queryString}` : ""}`;
+
+ const response = await this.makeRequest(endpoint);
+
+ // Handle different possible response structures (same logic as event types)
+ let bookingsArray: Booking[] = [];
+
+ if (Array.isArray(response)) {
+ bookingsArray = response;
+ } else if (response && typeof response === "object") {
+ if (response.data && Array.isArray(response.data)) {
+ bookingsArray = response.data;
+ } else if (response.bookings && Array.isArray(response.bookings)) {
+ bookingsArray = response.bookings;
+ } else if (response.items && Array.isArray(response.items)) {
+ bookingsArray = response.items;
+ } else if (response.data && typeof response.data === "object") {
+ if (response.data.bookings && Array.isArray(response.data.bookings)) {
+ bookingsArray = response.data.bookings;
+ } else if (response.data.items && Array.isArray(response.data.items)) {
+ bookingsArray = response.data.items;
+ } else {
+ // Convert object values to array as last resort
+ const keys = Object.keys(response.data);
+ if (keys.length > 0) {
+ bookingsArray = Object.values(response.data).filter(
+ (item): item is Booking =>
+ item && typeof item === "object" && ("id" in item || "uid" in item)
+ ) as Booking[];
+ }
+ }
+ } else {
+ // Try to extract any arrays from the response
+ const possibleArrays = Object.values(response).filter((val) => Array.isArray(val));
+ if (possibleArrays.length > 0) {
+ bookingsArray = possibleArrays[0] as Booking[];
+ }
+ }
+ }
+
+ // Get current user to filter bookings
+ let currentUser;
+ try {
+ currentUser = await this.getCurrentUser();
+ } catch (error) {
+ return bookingsArray;
+ }
+
+ // Extract user info from response
+ let userId: number | undefined;
+ let userEmail: string | undefined;
+
+ if (currentUser) {
+ userId = currentUser.id;
+ userEmail = currentUser.email;
+ }
+
+ // Filter bookings to only show ones where the current user is participating
+ const userBookings = bookingsArray.filter((booking) => {
+ const { isOrganizer, isHost, isAttendee, isParticipating } = getBookingParticipation(
+ booking,
+ userId,
+ userEmail
+ );
+
+ return isParticipating;
+ });
+
+ return userBookings;
+ } catch (error) {
+ throw error;
+ }
+ }
+
+ // Get all schedules
+ static async getSchedules(): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: Schedule[] }>(
+ "/schedules",
+ {
+ headers: {
+ "cal-api-version": "2024-06-11", // Override version for schedules
+ },
+ },
+ "2024-06-11"
+ );
+
+ let schedulesArray: Schedule[] = [];
+
+ // Handle response structure: { status: "success", data: [...] }
+ if (
+ response &&
+ response.status === "success" &&
+ response.data &&
+ Array.isArray(response.data)
+ ) {
+ schedulesArray = response.data;
+ } else if (Array.isArray(response)) {
+ // Fallback: response might be array directly
+ schedulesArray = response;
+ } else if (response && response.data && Array.isArray(response.data)) {
+ // Fallback: response.data might be array
+ schedulesArray = response.data;
+ }
+
+ return schedulesArray;
+ } catch (error) {
+ throw error;
+ }
+ }
+
+ // Create a new schedule
+ static async createSchedule(input: {
+ name: string;
+ timeZone: string;
+ isDefault?: boolean;
+ availability?: Array<{
+ days: string[]; // e.g., ["Monday", "Tuesday"]
+ startTime: string; // e.g., "09:00"
+ endTime: string; // e.g., "17:00"
+ }>;
+ overrides?: Array<{
+ date: string; // e.g., "2024-05-20"
+ startTime: string; // e.g., "12:00"
+ endTime: string; // e.g., "14:00"
+ }>;
+ }): Promise {
+ try {
+ console.log("Creating schedule with input:", JSON.stringify(input, null, 2));
+
+ const response = await this.makeRequest<{ status: string; data: Schedule }>(
+ "/schedules",
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ "cal-api-version": "2024-06-11",
+ },
+ body: JSON.stringify(input),
+ },
+ "2024-06-11"
+ );
+
+ if (response && response.data) {
+ console.log("Schedule created successfully:", response.data);
+ return response.data;
+ }
+
+ throw new Error("Invalid response from create schedule API");
+ } catch (error) {
+ console.error("createSchedule error:", error);
+ throw error;
+ }
+ }
+
+ // Get specific schedule by ID
+ static async getScheduleById(scheduleId: number): Promise {
+ try {
+ const response = await this.makeRequest(
+ `/schedules/${scheduleId}`,
+ {
+ headers: {
+ "cal-api-version": "2024-06-11", // Override version for schedules
+ },
+ },
+ "2024-06-11"
+ );
+
+ console.log("getScheduleById raw response:", JSON.stringify(response, null, 2));
+
+ if (response && response.data) {
+ console.log("Returning schedule data:", response.data);
+ return response.data;
+ }
+
+ // Sometimes the response might be the schedule directly
+ if (response && response.id) {
+ console.log("Returning schedule directly:", response);
+ return response;
+ }
+
+ console.log("No schedule data found in response");
+ return null;
+ } catch (error) {
+ console.error("getScheduleById error:", error);
+ throw error;
+ }
+ }
+
+ // Get conferencing options
+ static async getConferencingOptions(): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: ConferencingOption[] }>(
+ "/conferencing"
+ );
+
+ if (response && response.data && Array.isArray(response.data)) {
+ return response.data;
+ }
+
+ return [];
+ } catch (error) {
+ console.error("getConferencingOptions error:", error);
+ throw error;
+ }
+ }
+
+ // Get a single event type by ID
+ static async getEventTypeById(eventTypeId: number): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: EventType }>(
+ `/event-types/${eventTypeId}`,
+ {},
+ "2024-06-14"
+ );
+
+ if (response && response.data) {
+ return response.data;
+ }
+
+ return null;
+ } catch (error) {
+ // Handle 404 errors gracefully - resource doesn't exist or user doesn't have access
+ if (error instanceof Error) {
+ // Check if error message contains 404 status code
+ const statusMatch = error.message.match(/API Error: (\d+)/);
+ if (statusMatch && statusMatch[1] === "404") {
+ console.warn(`Event type ${eventTypeId} not found`);
+ return null;
+ }
+ }
+ console.error("getEventTypeById error:", error);
+ throw error;
+ }
+ }
+
+ // Update an event type
+ static async updateEventType(
+ eventTypeId: number,
+ updates: Partial
+ ): Promise {
+ try {
+ console.log(`Updating event type ${eventTypeId} with:`, JSON.stringify(updates, null, 2));
+
+ const response = await this.makeRequest<{ status: string; data: EventType }>(
+ `/event-types/${eventTypeId}`,
+ {
+ method: "PATCH",
+ headers: {
+ "Content-Type": "application/json",
+ "cal-api-version": "2024-06-14",
+ },
+ body: JSON.stringify(updates),
+ },
+ "2024-06-14"
+ );
+
+ if (response && response.data) {
+ console.log("Event type updated successfully:", response.data);
+ return response.data;
+ }
+
+ throw new Error("Invalid response from update event type API");
+ } catch (error) {
+ console.error("updateEventType error:", error);
+ throw error;
+ }
+ }
+
+ // Update a schedule
+ static async updateSchedule(
+ scheduleId: number,
+ updates: {
+ isDefault?: boolean;
+ name?: string;
+ timeZone?: string;
+ availability?: Array<{
+ days: string[]; // Day names like "Monday", "Tuesday"
+ startTime: string; // Format: "09:00"
+ endTime: string; // Format: "10:00"
+ }>;
+ overrides?: Array<{
+ date: string; // Format: "2024-05-20"
+ startTime: string; // Format: "12:00"
+ endTime: string; // Format: "14:00"
+ }>;
+ }
+ ): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: Schedule }>(
+ `/schedules/${scheduleId}`,
+ {
+ method: "PATCH",
+ headers: {
+ "Content-Type": "application/json",
+ "cal-api-version": "2024-06-11",
+ },
+ body: JSON.stringify(updates),
+ },
+ "2024-06-11"
+ );
+
+ if (response && response.data) {
+ return response.data;
+ }
+
+ throw new Error("Invalid response from update schedule API");
+ } catch (error) {
+ console.error("updateSchedule error:", error);
+ throw error;
+ }
+ }
+
+ // Duplicate a schedule
+ static async duplicateSchedule(scheduleId: number): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: Schedule }>(
+ `/atoms/schedules/${scheduleId}/duplicate`,
+ {
+ method: "POST",
+ headers: {
+ "cal-api-version": "2024-06-11",
+ },
+ },
+ "2024-06-11"
+ );
+
+ if (response && response.data) {
+ return response.data;
+ }
+
+ throw new Error("Invalid response from duplicate schedule API");
+ } catch (error) {
+ console.error("duplicateSchedule error:", error);
+ throw error;
+ }
+ }
+
+ // Delete a schedule
+ static async deleteSchedule(scheduleId: number): Promise {
+ try {
+ await this.makeRequest<{ status: string }>(
+ `/schedules/${scheduleId}`,
+ {
+ method: "DELETE",
+ headers: {
+ "cal-api-version": "2024-06-11",
+ },
+ },
+ "2024-06-11"
+ );
+ } catch (error) {
+ console.error("deleteSchedule error:", error);
+ throw error;
+ }
+ }
+
+ // ============================================
+ // WEBHOOKS
+ // ============================================
+
+ // Get all global webhooks
+ static async getWebhooks(): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: Webhook[] }>("/webhooks");
+
+ if (response && response.data && Array.isArray(response.data)) {
+ return response.data;
+ }
+
+ return [];
+ } catch (error) {
+ console.error("getWebhooks error:", error);
+ throw error;
+ }
+ }
+
+ // Create a global webhook
+ static async createWebhook(input: CreateWebhookInput): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: Webhook }>("/webhooks", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(input),
+ });
+
+ if (response && response.data) {
+ return response.data;
+ }
+
+ throw new Error("Invalid response from create webhook API");
+ } catch (error) {
+ console.error("createWebhook error:", error);
+ throw error;
+ }
+ }
+
+ // Update a global webhook
+ static async updateWebhook(webhookId: string, updates: UpdateWebhookInput): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: Webhook }>(
+ `/webhooks/${webhookId}`,
+ {
+ method: "PATCH",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(updates),
+ }
+ );
+
+ if (response && response.data) {
+ return response.data;
+ }
+
+ throw new Error("Invalid response from update webhook API");
+ } catch (error) {
+ console.error("updateWebhook error:", error);
+ throw error;
+ }
+ }
+
+ // Delete a global webhook
+ static async deleteWebhook(webhookId: string): Promise {
+ try {
+ await this.makeRequest(`/webhooks/${webhookId}`, {
+ method: "DELETE",
+ });
+ } catch (error) {
+ console.error("deleteWebhook error:", error);
+ throw error;
+ }
+ }
+
+ // Get webhooks for a specific event type
+ static async getEventTypeWebhooks(eventTypeId: number): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: Webhook[] }>(
+ `/event-types/${eventTypeId}/webhooks`
+ );
+
+ if (response && response.data && Array.isArray(response.data)) {
+ return response.data;
+ }
+
+ return [];
+ } catch (error) {
+ console.error("getEventTypeWebhooks error:", error);
+ throw error;
+ }
+ }
+
+ // Create a webhook for a specific event type
+ static async createEventTypeWebhook(
+ eventTypeId: number,
+ input: CreateWebhookInput
+ ): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: Webhook }>(
+ `/event-types/${eventTypeId}/webhooks`,
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(input),
+ }
+ );
+
+ if (response && response.data) {
+ return response.data;
+ }
+
+ throw new Error("Invalid response from create event type webhook API");
+ } catch (error) {
+ console.error("createEventTypeWebhook error:", error);
+ throw error;
+ }
+ }
+
+ // Update an event type webhook
+ static async updateEventTypeWebhook(
+ eventTypeId: number,
+ webhookId: string,
+ updates: UpdateWebhookInput
+ ): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: Webhook }>(
+ `/event-types/${eventTypeId}/webhooks/${webhookId}`,
+ {
+ method: "PATCH",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(updates),
+ }
+ );
+
+ if (response && response.data) {
+ return response.data;
+ }
+
+ throw new Error("Invalid response from update event type webhook API");
+ } catch (error) {
+ console.error("updateEventTypeWebhook error:", error);
+ throw error;
+ }
+ }
+
+ // Delete an event type webhook
+ static async deleteEventTypeWebhook(eventTypeId: number, webhookId: string): Promise {
+ try {
+ await this.makeRequest(`/event-types/${eventTypeId}/webhooks/${webhookId}`, {
+ method: "DELETE",
+ });
+ } catch (error) {
+ console.error("deleteEventTypeWebhook error:", error);
+ throw error;
+ }
+ }
+
+ // ============================================
+ // PRIVATE LINKS
+ // ============================================
+
+ // Get all private links for an event type
+ static async getEventTypePrivateLinks(eventTypeId: number): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: PrivateLink[] }>(
+ `/event-types/${eventTypeId}/private-links`
+ );
+
+ if (response && response.data && Array.isArray(response.data)) {
+ return response.data;
+ }
+
+ return [];
+ } catch (error) {
+ console.error("getEventTypePrivateLinks error:", error);
+ throw error;
+ }
+ }
+
+ // Create a private link for an event type
+ static async createEventTypePrivateLink(
+ eventTypeId: number,
+ input: CreatePrivateLinkInput = {}
+ ): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: PrivateLink }>(
+ `/event-types/${eventTypeId}/private-links`,
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(input),
+ }
+ );
+
+ if (response && response.data) {
+ return response.data;
+ }
+
+ throw new Error("Invalid response from create private link API");
+ } catch (error) {
+ console.error("createEventTypePrivateLink error:", error);
+ throw error;
+ }
+ }
+
+ // Update a private link
+ static async updateEventTypePrivateLink(
+ eventTypeId: number,
+ linkId: number,
+ updates: UpdatePrivateLinkInput
+ ): Promise {
+ try {
+ const response = await this.makeRequest<{ status: string; data: PrivateLink }>(
+ `/event-types/${eventTypeId}/private-links/${linkId}`,
+ {
+ method: "PATCH",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(updates),
+ }
+ );
+
+ if (response && response.data) {
+ return response.data;
+ }
+
+ throw new Error("Invalid response from update private link API");
+ } catch (error) {
+ console.error("updateEventTypePrivateLink error:", error);
+ throw error;
+ }
+ }
+
+ // Delete a private link
+ static async deleteEventTypePrivateLink(eventTypeId: number, linkId: number): Promise {
+ try {
+ await this.makeRequest(`/event-types/${eventTypeId}/private-links/${linkId}`, {
+ method: "DELETE",
+ });
+ } catch (error) {
+ console.error("deleteEventTypePrivateLink error:", error);
+ throw error;
+ }
+ }
+}
diff --git a/companion/services/oauthService.ts b/companion/services/oauthService.ts
new file mode 100644
index 0000000000..40d68757e5
--- /dev/null
+++ b/companion/services/oauthService.ts
@@ -0,0 +1,496 @@
+///
+
+import * as AuthSession from "expo-auth-session";
+import * as WebBrowser from "expo-web-browser";
+import * as Crypto from "expo-crypto";
+import { Platform } from "react-native";
+import { fromByteArray } from "base64-js";
+
+// Complete warm up for WebBrowser on mobile
+WebBrowser.maybeCompleteAuthSession();
+
+export interface OAuthTokens {
+ accessToken: string;
+ refreshToken?: string;
+ tokenType: string;
+ expiresAt?: number;
+ scope?: string;
+}
+
+export interface OAuthConfig {
+ clientId: string;
+ redirectUri: string;
+ calcomBaseUrl: string;
+}
+
+export class CalComOAuthService {
+ private config: OAuthConfig;
+ private codeVerifier: string | null = null;
+ private state: string | null = null;
+
+ constructor(config: OAuthConfig) {
+ this.config = config;
+ }
+
+ private async generatePKCEParams(): Promise<{
+ codeVerifier: string;
+ codeChallenge: string;
+ state: string;
+ }> {
+ const codeVerifier = this.generateRandomBase64Url();
+ const codeChallenge = await this.generateCodeChallenge(codeVerifier);
+ const state = this.generateRandomBase64Url();
+
+ this.codeVerifier = codeVerifier;
+ this.state = state;
+
+ return { codeVerifier, codeChallenge, state };
+ }
+
+ private async generateCodeChallenge(codeVerifier: string): Promise {
+ try {
+ const base64Hash = await Crypto.digestStringAsync(
+ Crypto.CryptoDigestAlgorithm.SHA256,
+ codeVerifier,
+ { encoding: Crypto.CryptoEncoding.BASE64 }
+ );
+
+ return base64Hash.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
+ } catch (error) {
+ console.error("Failed to generate code challenge:", error);
+ throw new Error("Failed to generate OAuth code challenge");
+ }
+ }
+
+ private generateRandomBase64Url(): string {
+ const bytes = new Uint8Array(Crypto.getRandomBytes(32));
+
+ const base64 =
+ typeof btoa !== "undefined" ? btoa(String.fromCharCode(...bytes)) : fromByteArray(bytes);
+
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
+ }
+
+ private buildAuthorizationUrl(codeChallenge: string, state: string): string {
+ const params = new URLSearchParams({
+ client_id: this.config.clientId,
+ response_type: "code",
+ redirect_uri: this.config.redirectUri,
+ state: state,
+ code_challenge: codeChallenge,
+ code_challenge_method: "S256",
+ });
+
+ return `${this.config.calcomBaseUrl}/auth/oauth2/authorize?${params.toString()}`;
+ }
+
+ async startAuthorizationFlow(): Promise {
+ try {
+ const { codeChallenge, state } = await this.generatePKCEParams();
+
+ // Web only: check for stored callback with state-specific keys to prevent race conditions
+ if (Platform.OS === "web" && typeof window !== "undefined") {
+ const storedCode = window.localStorage.getItem(`oauth_callback_code_${state}`);
+ const storedState = window.localStorage.getItem(`oauth_callback_state_${state}`);
+
+ if (storedCode && storedState) {
+ // CSRF protection: verify state matches
+ if (storedState !== state) {
+ window.localStorage.removeItem(`oauth_callback_code_${state}`);
+ window.localStorage.removeItem(`oauth_callback_state_${state}`);
+ throw new Error("Invalid state parameter - possible CSRF attack");
+ }
+
+ window.localStorage.removeItem(`oauth_callback_code_${state}`);
+ window.localStorage.removeItem(`oauth_callback_state_${state}`);
+
+ return await this.exchangeCodeForTokens(storedCode, state);
+ }
+ }
+
+ // Note: State stored in background script (iframe may not have chrome.storage access)
+
+ const authResult = await this.getAuthorizationResult(codeChallenge, state);
+ if (authResult.type === "success") {
+ const code = authResult.params?.code || authResult.params?.authorizationCode;
+ const returnedState = authResult.params?.state;
+
+ if (returnedState !== state) {
+ throw new Error("Invalid state parameter - possible CSRF attack");
+ }
+
+ if (!code) {
+ throw new Error("No authorization code received");
+ }
+
+ return await this.exchangeCodeForTokens(code, state);
+ }
+
+ if (authResult.type === "error") {
+ const errorDescription =
+ authResult.params?.error_description ||
+ ("error" in authResult ? authResult.error?.message : undefined) ||
+ "Unknown error";
+ throw new Error(`OAuth error: ${errorDescription}`);
+ }
+
+ if (authResult.type === "cancel") {
+ throw new Error("OAuth flow was cancelled by user");
+ }
+
+ throw new Error("OAuth flow failed or was dismissed");
+ } catch (error) {
+ console.error("OAuth authorization error:", error);
+ throw error;
+ }
+ }
+
+ // Detect browser extension environment using reliable indicators
+ private isBrowserExtension(): boolean {
+ if (Platform.OS !== "web" || typeof window === "undefined") {
+ return false;
+ }
+
+ if (typeof chrome !== "undefined" && chrome.runtime?.id) {
+ return true;
+ }
+
+ if (window.location.protocol === "chrome-extension:") {
+ return true;
+ }
+
+ // Extension content script injects companion app as iframe
+ if (window.parent !== window) {
+ try {
+ const parentOrigin = window.parent.location.origin;
+ const currentOrigin = window.location.origin;
+
+ if (parentOrigin !== currentOrigin && window.location.hostname === "localhost") {
+ return true;
+ }
+ } catch {
+ // Cross-origin access blocked - expected for extension iframes
+ if (window.location.hostname === "localhost") {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private async launchExtensionAuthFlow(authUrl: string): Promise {
+ return new Promise((resolve, reject) => {
+ if (typeof chrome !== "undefined" && chrome.identity) {
+ chrome.identity.launchWebAuthFlow(
+ {
+ url: authUrl,
+ interactive: true,
+ },
+ (responseUrl) => {
+ if (chrome.runtime.lastError) {
+ reject(new Error(`OAuth flow failed: ${chrome.runtime.lastError.message}`));
+ } else if (responseUrl) {
+ resolve(responseUrl);
+ } else {
+ reject(new Error("OAuth flow cancelled or failed"));
+ }
+ }
+ );
+ return;
+ }
+
+ // Iframe: communicate with parent window
+ if (window.parent !== window) {
+ let timeoutId: NodeJS.Timeout | null = null;
+
+ const messageHandler = (event: MessageEvent) => {
+ // Security: only accept messages from parent
+ if (event.source !== window.parent) {
+ return;
+ }
+
+ if (event.data.type === "cal-extension-oauth-result") {
+ window.removeEventListener("message", messageHandler);
+ if (timeoutId) {
+ clearTimeout(timeoutId);
+ }
+
+ if (event.data.success) {
+ resolve(event.data.responseUrl);
+ } else {
+ console.error("OAuth flow failed:", event.data.error);
+ reject(new Error(event.data.error || "OAuth flow failed"));
+ }
+ }
+ };
+
+ window.addEventListener("message", messageHandler);
+
+ window.parent.postMessage(
+ {
+ type: "cal-extension-oauth-request",
+ authUrl: authUrl,
+ },
+ "*"
+ );
+
+ timeoutId = setTimeout(() => {
+ console.error("OAuth flow timeout - no response from extension");
+ window.removeEventListener("message", messageHandler);
+ reject(new Error("OAuth flow timeout - no response from extension"));
+ }, 30000);
+ } else {
+ reject(new Error("Chrome extension context not detected"));
+ }
+ });
+ }
+
+ private async getAuthorizationResult(
+ codeChallenge: string,
+ state: string
+ ): Promise }> {
+ const authUrl = this.buildAuthorizationUrl(codeChallenge, state);
+
+ const isExtension = this.isBrowserExtension();
+
+ if (isExtension) {
+ try {
+ const responseUrl = await this.launchExtensionAuthFlow(authUrl);
+ const params = this.parseCallbackUrl(responseUrl);
+ return { type: "success" as const, params };
+ } catch (error) {
+ console.error("Extension OAuth flow failed:", error);
+ return { type: "error", params: { error: error.message } } as {
+ type: string;
+ params: Record;
+ };
+ }
+ } else if (Platform.OS === "web") {
+ const discovery = await this.getDiscoveryEndpoints();
+ const request = new AuthSession.AuthRequest({
+ clientId: this.config.clientId,
+ redirectUri: this.config.redirectUri,
+ responseType: AuthSession.ResponseType.Code,
+ state: state,
+ codeChallenge: codeChallenge,
+ codeChallengeMethod: AuthSession.CodeChallengeMethod.S256,
+ });
+
+ return await request.promptAsync(discovery);
+ } else {
+ const result = await WebBrowser.openAuthSessionAsync(authUrl, this.config.redirectUri);
+
+ if (result.type === "success") {
+ const params = this.parseCallbackUrl(result.url);
+ return { type: "success" as const, params };
+ }
+
+ return { type: result.type, params: {} } as { type: string; params: Record };
+ }
+ }
+
+ private async getDiscoveryEndpoints(): Promise {
+ try {
+ const discovery = await AuthSession.fetchDiscoveryAsync(
+ `${this.config.calcomBaseUrl}/.well-known/openid_configuration`
+ );
+ return discovery;
+ } catch {
+ return {
+ authorizationEndpoint: `${this.config.calcomBaseUrl}/auth/oauth2/authorize`,
+ tokenEndpoint: `${this.config.calcomBaseUrl}/api/auth/oauth/token`,
+ } as AuthSession.DiscoveryDocument;
+ }
+ }
+
+ private parseCallbackUrl(url: string): Record {
+ const urlObj = new URL(url);
+ const params: Record = {};
+
+ urlObj.searchParams.forEach((value, key) => {
+ params[key] = value;
+ });
+
+ if (Object.keys(params).length === 0 && urlObj.hash) {
+ const hashParams = new URLSearchParams(urlObj.hash.substring(1));
+ hashParams.forEach((value, key) => {
+ params[key] = value;
+ });
+ }
+
+ return params;
+ }
+
+ private async exchangeCodeForTokens(code: string, state?: string): Promise {
+ if (!this.codeVerifier) {
+ throw new Error("No code verifier available");
+ }
+
+ // Extension: use APIs to avoid CORS
+ if (this.isBrowserExtension() && window.parent !== window) {
+ return await this.exchangeTokensViaExtension(code, state);
+ }
+
+ const tokenEndpoint = `${this.config.calcomBaseUrl}/api/auth/oauth/token`;
+
+ const body = new URLSearchParams();
+ body.append("grant_type", "authorization_code");
+ body.append("client_id", this.config.clientId);
+ body.append("code", code);
+ body.append("redirect_uri", this.config.redirectUri);
+ body.append("code_verifier", this.codeVerifier);
+
+ const response = await fetch(tokenEndpoint, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ Accept: "application/json",
+ },
+ body: body.toString(),
+ });
+
+ if (!response.ok) {
+ const errorData = await response.text();
+ console.error("Token exchange error response:", errorData);
+
+ try {
+ const errorJson = JSON.parse(errorData);
+ console.error("Parsed error:", errorJson);
+ } catch {
+ console.error("Could not parse error response as JSON");
+ }
+
+ throw new Error(`Token exchange failed: ${response.status} ${errorData}`);
+ }
+
+ const tokenData = await response.json();
+
+ const tokens: OAuthTokens = {
+ accessToken: tokenData.access_token,
+ refreshToken: tokenData.refresh_token,
+ tokenType: tokenData.token_type || "Bearer",
+ expiresAt: tokenData.expires_in ? Date.now() + tokenData.expires_in * 1000 : undefined,
+ scope: tokenData.scope,
+ };
+
+ return tokens;
+ }
+
+ private async exchangeTokensViaExtension(code: string, state?: string): Promise {
+ return new Promise((resolve, reject) => {
+ let timeoutId: NodeJS.Timeout | null = null;
+
+ const messageHandler = (event: MessageEvent) => {
+ // Security: only accept messages from parent
+ if (event.source !== window.parent) {
+ return;
+ }
+
+ if (event.data.type === "cal-extension-token-exchange-result") {
+ window.removeEventListener("message", messageHandler);
+ if (timeoutId) {
+ clearTimeout(timeoutId);
+ }
+
+ if (event.data.success) {
+ resolve(event.data.tokens);
+ } else {
+ console.error("Token exchange failed via extension:", event.data.error);
+ reject(new Error(event.data.error || "Token exchange failed"));
+ }
+ }
+ };
+
+ window.addEventListener("message", messageHandler);
+
+ window.parent.postMessage(
+ {
+ type: "cal-extension-token-exchange-request",
+ tokenRequest: {
+ grant_type: "authorization_code",
+ client_id: this.config.clientId,
+ code: code,
+ redirect_uri: this.config.redirectUri,
+ code_verifier: this.codeVerifier,
+ },
+ state: state, // CSRF validation in background script
+ tokenEndpoint: `${this.config.calcomBaseUrl}/api/auth/oauth/token`,
+ },
+ "*"
+ );
+
+ timeoutId = setTimeout(() => {
+ window.removeEventListener("message", messageHandler);
+ reject(new Error("Token exchange timeout"));
+ }, 30000);
+ });
+ }
+
+ async refreshAccessToken(refreshToken: string): Promise {
+ const tokenEndpoint = `${this.config.calcomBaseUrl}/api/auth/oauth/refreshToken`;
+
+ const body = new URLSearchParams({
+ grant_type: "refresh_token",
+ client_id: this.config.clientId,
+ refresh_token: refreshToken,
+ });
+
+ const response = await fetch(tokenEndpoint, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ Accept: "application/json",
+ },
+ body: body.toString(),
+ });
+
+ if (!response.ok) {
+ const errorData = await response.text();
+ throw new Error(`Token refresh failed: ${response.status} ${errorData}`);
+ }
+
+ const tokenData = await response.json();
+
+ const tokens: OAuthTokens = {
+ accessToken: tokenData.access_token,
+ refreshToken: tokenData.refresh_token || refreshToken,
+ tokenType: tokenData.token_type || "Bearer",
+ expiresAt: tokenData.expires_in ? Date.now() + tokenData.expires_in * 1000 : undefined,
+ scope: tokenData.scope,
+ };
+
+ return tokens;
+ }
+
+ isTokenExpired(tokens: OAuthTokens): boolean {
+ if (!tokens.expiresAt) {
+ return false;
+ }
+ // 5-minute buffer before expiry
+ return Date.now() >= tokens.expiresAt - 5 * 60 * 1000;
+ }
+ clearPKCEParams(): void {
+ this.codeVerifier = null;
+ this.state = null;
+ }
+}
+
+export function createCalComOAuthService(overrides: Partial = {}): CalComOAuthService {
+ let defaultRedirectUri: string;
+
+ const defaultConfig: OAuthConfig = {
+ clientId: process.env.EXPO_PUBLIC_CALCOM_OAUTH_CLIENT_ID || "",
+ redirectUri: process.env.EXPO_PUBLIC_CALCOM_OAUTH_REDIRECT_URI,
+ calcomBaseUrl: "https://app.cal.com",
+ ...overrides,
+ };
+
+ if (!defaultConfig.clientId) {
+ throw new Error(
+ "OAuth client ID is required. Set EXPO_PUBLIC_CALCOM_OAUTH_CLIENT_ID environment variable."
+ );
+ }
+
+ return new CalComOAuthService(defaultConfig);
+}
diff --git a/companion/services/types/bookings.types.ts b/companion/services/types/bookings.types.ts
new file mode 100644
index 0000000000..69eddfd0ab
--- /dev/null
+++ b/companion/services/types/bookings.types.ts
@@ -0,0 +1,64 @@
+export interface Booking {
+ id: number;
+ uid: string;
+ title: string;
+ description?: string;
+ startTime: string;
+ endTime: string;
+ start?: string;
+ end?: string;
+ eventTypeId: number;
+ eventType?: {
+ id: number;
+ title: string;
+ slug: string;
+ };
+ hosts?: Array<{
+ id?: number | string;
+ name?: string;
+ email?: string;
+ username?: string;
+ timeZone?: string;
+ }>;
+ user?: {
+ id: number;
+ email: string;
+ name: string;
+ timeZone: string;
+ };
+ attendees?: Array<{
+ id?: number | string;
+ email: string;
+ name: string;
+ timeZone: string;
+ noShow?: boolean;
+ }>;
+ status: "ACCEPTED" | "PENDING" | "CANCELLED" | "REJECTED";
+ paid?: boolean;
+ payment?: Array<{
+ id: number;
+ success: boolean;
+ paymentOption: string;
+ }>;
+ rescheduled?: boolean;
+ fromReschedule?: string;
+ recurringEventId?: string;
+ recurringBookingUid?: string;
+ smsReminderNumber?: string;
+ location?: string;
+ cancellationReason?: string;
+ rejectionReason?: string;
+ responses?: Record;
+}
+
+export interface GetBookingsResponse {
+ status: "success";
+ data: Booking[];
+}
+
+export interface BookingParticipationResult {
+ isOrganizer: boolean;
+ isHost: boolean;
+ isAttendee: boolean;
+ isParticipating: boolean;
+}
diff --git a/companion/services/types/event-types.types.ts b/companion/services/types/event-types.types.ts
new file mode 100644
index 0000000000..a83610c03c
--- /dev/null
+++ b/companion/services/types/event-types.types.ts
@@ -0,0 +1,288 @@
+// Event Type Creation/Update Types
+export interface BookingLimitsCount {
+ day?: number;
+ week?: number;
+ month?: number;
+ year?: number;
+}
+
+export interface BookingLimitsDuration {
+ day?: number;
+ week?: number;
+ month?: number;
+ year?: number;
+}
+
+export interface BookerActiveBookingsLimit {
+ count: number;
+}
+
+export interface BusinessDaysWindow {
+ type: "businessDays";
+ value: number;
+ rolling?: boolean;
+ rollingWindow?: number;
+}
+
+export interface CalendarDaysWindow {
+ type: "calendarDays";
+ value: number;
+ rolling?: boolean;
+ rollingWindow?: number;
+}
+
+export interface RangeWindow {
+ type: "range";
+ value: [string, string]; // ISO date strings
+}
+
+export type BookingWindow =
+ | BusinessDaysWindow
+ | CalendarDaysWindow
+ | RangeWindow
+ | { disabled: true };
+
+export interface BookerLayouts {
+ enabledLayouts: Array<"month_view" | "week_view" | "column_view">;
+ defaultLayout: "month_view" | "week_view" | "column_view";
+}
+
+export interface ConfirmationPolicy {
+ noticeThreshold?: {
+ count: number;
+ unit: "hours" | "minutes";
+ };
+}
+
+export interface Recurrence {
+ interval: number;
+ occurrences: number;
+ frequency: "daily" | "weekly" | "monthly" | "yearly";
+}
+
+export interface Seats {
+ seatsPerTimeSlot?: number;
+ showAttendeeInfo?: boolean;
+ showAvailabilityCount?: boolean;
+ seatsShowAvailabilityCount?: boolean;
+}
+
+export interface EventTypeColor {
+ lightEventTypeColor?: string;
+ darkEventTypeColor?: string;
+}
+
+export interface EmailSettings {
+ additionalGuestsEmails?: string[];
+}
+
+// Booking Field Types
+export interface BaseBookingField {
+ name: string;
+ type: string;
+ label?: string;
+ placeholder?: string;
+ required?: boolean;
+ hidden?: boolean;
+}
+
+export interface NameDefaultField extends BaseBookingField {
+ type: "name";
+ variant?: "fullName" | "firstAndLastName";
+}
+
+export interface EmailDefaultField extends BaseBookingField {
+ type: "email";
+}
+
+export interface PhoneField extends BaseBookingField {
+ type: "phone";
+}
+
+export interface AddressField extends BaseBookingField {
+ type: "address";
+}
+
+export interface TextField extends BaseBookingField {
+ type: "text";
+}
+
+export interface NumberField extends BaseBookingField {
+ type: "number";
+}
+
+export interface TextAreaField extends BaseBookingField {
+ type: "textarea";
+}
+
+export interface SelectField extends BaseBookingField {
+ type: "select" | "multiselect";
+ options?: Array<{ label: string; value: string }>;
+}
+
+export interface CheckboxField extends BaseBookingField {
+ type: "checkbox";
+}
+
+export interface RadioField extends BaseBookingField {
+ type: "radio" | "radioInput";
+ options?: Array<{ label: string; value: string }>;
+}
+
+export interface BooleanField extends BaseBookingField {
+ type: "boolean";
+}
+
+export type BookingField =
+ | NameDefaultField
+ | EmailDefaultField
+ | PhoneField
+ | AddressField
+ | TextField
+ | NumberField
+ | TextAreaField
+ | SelectField
+ | CheckboxField
+ | RadioField
+ | BooleanField;
+
+export interface EventType {
+ id: number;
+ title: string;
+ slug: string;
+ description?: string;
+ length: number; // Deprecated: use lengthInMinutes instead
+ lengthInMinutes?: number; // API returns this field
+ lengthInMinutesOptions?: number[];
+
+ // Locations
+ locations?: Array<{
+ type: string;
+ address?: string;
+ link?: string;
+ phone?: string;
+ integration?: string;
+ credentialId?: number;
+ public?: boolean;
+ }>;
+
+ // Pricing
+ price?: number;
+ currency?: string;
+
+ // Basic settings
+ disableGuests?: boolean;
+ lockTimeZoneToggleOnBookingPage?: boolean;
+ requiresConfirmation?: boolean;
+ requiresBookerEmailVerification?: boolean;
+ hideCalendarNotes?: boolean;
+ successRedirectUrl?: string;
+ forwardParamsSuccessRedirect?: boolean;
+
+ // Schedule and buffers
+ scheduleId?: number;
+ slotInterval?: number;
+ minimumBookingNotice?: number;
+ beforeEventBuffer?: number;
+ afterEventBuffer?: number;
+
+ // Limits
+ bookingLimitsCount?: BookingLimitsCount | { disabled: true };
+ bookingLimitsDuration?: BookingLimitsDuration | { disabled: true };
+ bookerActiveBookingsLimit?: BookerActiveBookingsLimit | { disabled: true };
+ onlyShowFirstAvailableSlot?: boolean;
+ bookingWindow?: BookingWindow;
+ offsetStart?: number;
+
+ // Advanced
+ bookerLayouts?: BookerLayouts;
+ confirmationPolicy?: ConfirmationPolicy | { disabled: true };
+
+ // Recurring
+ recurrence?: Recurrence | { disabled: true };
+
+ // Seats
+ seats?: Seats | { disabled: true };
+
+ // Customization
+ bookingFields?: BookingField[];
+ hidden?: boolean;
+ eventTypeColor?: EventTypeColor;
+
+ // Ownership
+ userId?: number;
+ teamId?: number;
+ hosts?: Array<{
+ userId: number;
+ isFixed: boolean;
+ }>;
+
+ // Metadata
+ metadata?: Record;
+}
+
+export interface CreateEventTypeInput {
+ // Basic fields
+ title: string;
+ slug: string;
+ description?: string;
+ lengthInMinutes: number;
+ lengthInMinutesOptions?: number[];
+
+ // Locations
+ locations?: Array<{
+ type: string;
+ address?: string;
+ link?: string;
+ phone?: string;
+ integration?: string;
+ credentialId?: number;
+ public?: boolean;
+ }>;
+
+ // Schedule
+ scheduleId?: number;
+
+ // Booking settings
+ disableGuests?: boolean;
+ slotInterval?: number;
+ minimumBookingNotice?: number;
+ beforeEventBuffer?: number;
+ afterEventBuffer?: number;
+
+ // Limits
+ bookingLimitsCount?: BookingLimitsCount | { disabled: true };
+ bookingLimitsDuration?: BookingLimitsDuration | { disabled: true };
+ bookerActiveBookingsLimit?: BookerActiveBookingsLimit | { disabled: true };
+ onlyShowFirstAvailableSlot?: boolean;
+
+ // Booking window
+ bookingWindow?: BookingWindow;
+
+ // Advanced settings
+ offsetStart?: number;
+ bookerLayouts?: BookerLayouts;
+ confirmationPolicy?: ConfirmationPolicy | { disabled: true };
+ recurrence?: Recurrence | { disabled: true };
+ seats?: Seats | { disabled: true };
+
+ // Customization
+ bookingFields?: BookingField[];
+ hidden?: boolean;
+ eventTypeColor?: EventTypeColor;
+ emailSettings?: EmailSettings;
+
+ // Additional fields
+ requiresConfirmation?: boolean;
+ requiresBookerEmailVerification?: boolean;
+ hideCalendarNotes?: boolean;
+ lockTimeZoneToggleOnBookingPage?: boolean;
+ successRedirectUrl?: string;
+ forwardParamsSuccessRedirect?: boolean;
+ metadata?: Record;
+}
+
+export interface GetEventTypesResponse {
+ status: "success";
+ data: EventType[];
+}
diff --git a/companion/services/types/index.ts b/companion/services/types/index.ts
new file mode 100644
index 0000000000..29169f1296
--- /dev/null
+++ b/companion/services/types/index.ts
@@ -0,0 +1,7 @@
+// Re-export all types for easy importing
+export * from "./event-types.types";
+export * from "./bookings.types";
+export * from "./schedules.types";
+export * from "./users.types";
+export * from "./webhooks.types";
+export * from "./private-links.types";
diff --git a/companion/services/types/private-links.types.ts b/companion/services/types/private-links.types.ts
new file mode 100644
index 0000000000..1b224f8701
--- /dev/null
+++ b/companion/services/types/private-links.types.ts
@@ -0,0 +1,25 @@
+// Private Link Types
+export interface PrivateLink {
+ id: number;
+ link: string;
+ enabled: boolean;
+ eventTypeId: number;
+}
+
+export interface CreatePrivateLinkInput {
+ enabled?: boolean;
+}
+
+export interface UpdatePrivateLinkInput {
+ enabled?: boolean;
+}
+
+export interface GetPrivateLinksResponse {
+ status: string;
+ data: PrivateLink[];
+}
+
+export interface GetPrivateLinkResponse {
+ status: string;
+ data: PrivateLink;
+}
diff --git a/companion/services/types/schedules.types.ts b/companion/services/types/schedules.types.ts
new file mode 100644
index 0000000000..be64af6f53
--- /dev/null
+++ b/companion/services/types/schedules.types.ts
@@ -0,0 +1,31 @@
+export interface ScheduleAvailability {
+ days: string[];
+ startTime: string;
+ endTime: string;
+}
+
+export interface ScheduleOverride {
+ date: string;
+ startTime: string;
+ endTime: string;
+}
+
+export interface Schedule {
+ id: number;
+ ownerId: number;
+ name: string;
+ timeZone: string;
+ availability: ScheduleAvailability[];
+ isDefault: boolean;
+ overrides: ScheduleOverride[];
+}
+
+export interface GetSchedulesResponse {
+ status: "success";
+ data: Schedule[];
+}
+
+export interface GetScheduleResponse {
+ status: "success";
+ data: Schedule | null;
+}
diff --git a/companion/services/types/users.types.ts b/companion/services/types/users.types.ts
new file mode 100644
index 0000000000..aa1b92896f
--- /dev/null
+++ b/companion/services/types/users.types.ts
@@ -0,0 +1,35 @@
+export interface UserProfile {
+ id: number;
+ username: string;
+ name: string;
+ email: string;
+ bio?: string;
+ avatarUrl?: string;
+ timeZone?: string;
+ weekStart?: string;
+ timeFormat?: number;
+ defaultScheduleId?: number;
+ locale?: string;
+ organizationId?: number;
+ organization?: {
+ id: number;
+ isPlatform: boolean;
+ };
+ metadata?: Record;
+ brandColor?: string;
+ darkBrandColor?: string;
+ theme?: string;
+}
+
+export interface ConferencingOption {
+ id: number;
+ type: string;
+ userId: number | null;
+ teamId: number | null;
+ appId: string | null;
+ subscriptionId: number | null;
+ paymentStatus: string | null;
+ billingCycleStart: string | null;
+ invalid: boolean;
+ delegationCredentialId: string | null;
+}
diff --git a/companion/services/types/webhooks.types.ts b/companion/services/types/webhooks.types.ts
new file mode 100644
index 0000000000..30b47e673b
--- /dev/null
+++ b/companion/services/types/webhooks.types.ts
@@ -0,0 +1,36 @@
+// Webhook Types
+export interface Webhook {
+ id: string;
+ subscriberUrl: string;
+ eventTriggers: string[];
+ active: boolean;
+ payloadTemplate?: string;
+ secret?: string;
+ eventTypeId?: number;
+}
+
+export interface CreateWebhookInput {
+ subscriberUrl: string;
+ eventTriggers: string[];
+ active?: boolean;
+ payloadTemplate?: string;
+ secret?: string;
+}
+
+export interface UpdateWebhookInput {
+ subscriberUrl?: string;
+ eventTriggers?: string[];
+ active?: boolean;
+ payloadTemplate?: string;
+ secret?: string;
+}
+
+export interface GetWebhooksResponse {
+ status: string;
+ data: Webhook[];
+}
+
+export interface GetWebhookResponse {
+ status: string;
+ data: Webhook;
+}
diff --git a/companion/services/webAuth.ts b/companion/services/webAuth.ts
new file mode 100644
index 0000000000..0f05dd13b4
--- /dev/null
+++ b/companion/services/webAuth.ts
@@ -0,0 +1,192 @@
+import { Platform } from "react-native";
+
+export interface WebSessionInfo {
+ isLoggedIn: boolean;
+ accessToken?: string;
+ refreshToken?: string;
+ userInfo?: any;
+}
+
+export class WebAuthService {
+ // Check if running on web
+ static isWeb(): boolean {
+ return Platform.OS === "web";
+ }
+
+ // Get cookies from the browser
+ static getCookies(): { [key: string]: string } {
+ if (!this.isWeb()) return {};
+
+ const cookies: { [key: string]: string } = {};
+ if (typeof document !== "undefined") {
+ document.cookie.split(";").forEach((cookie) => {
+ const [name, value] = cookie.trim().split("=");
+ if (name && value) {
+ cookies[name] = decodeURIComponent(value);
+ }
+ });
+ }
+ return cookies;
+ }
+
+ // Check for Cal.com session cookies
+ static async checkCalComSession(): Promise {
+ if (!this.isWeb()) {
+ return { isLoggedIn: false };
+ }
+
+ try {
+ // Check for common Cal.com session cookies
+ const cookies = this.getCookies();
+
+ // Look for Cal.com authentication cookies
+ // Common patterns: next-auth.session-token, __Secure-next-auth.session-token, etc.
+ const sessionCookieNames = [
+ "next-auth.session-token",
+ "__Secure-next-auth.session-token",
+ "__Host-next-auth.session-token",
+ "next-auth.csrf-token",
+ "cal-session",
+ "session-token",
+ ];
+
+ const foundSessionCookie = sessionCookieNames.find((name) => cookies[name]);
+
+ if (foundSessionCookie) {
+ // Try to validate the session with Cal.com API
+ const sessionInfo = await this.validateWebSession();
+ return sessionInfo;
+ }
+
+ return { isLoggedIn: false };
+ } catch (error) {
+ return { isLoggedIn: false };
+ }
+ }
+
+ // Validate web session by calling Cal.com API with cookies
+ static async validateWebSession(): Promise {
+ if (!this.isWeb()) {
+ return { isLoggedIn: false };
+ }
+
+ try {
+ // First try to call the NextAuth session endpoint
+ const sessionResponse = await fetch("https://app.cal.com/api/auth/session", {
+ method: "GET",
+ credentials: "include", // Include cookies
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+
+ if (sessionResponse.ok) {
+ const sessionData = await sessionResponse.json();
+
+ if (sessionData && sessionData.user) {
+ // User is logged in via web session
+ return {
+ isLoggedIn: true,
+ userInfo: sessionData.user,
+ };
+ }
+ }
+
+ // Try the internal Cal.com me endpoint (this might work with cookies)
+ const meResponse = await fetch("https://app.cal.com/api/me", {
+ method: "GET",
+ credentials: "include",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+
+ if (meResponse.ok) {
+ const userData = await meResponse.json();
+
+ if (userData && (userData.id || userData.user || userData.data)) {
+ return {
+ isLoggedIn: true,
+ userInfo: userData.user || userData.data || userData,
+ };
+ }
+ }
+
+ // Try to check if user is logged in by attempting to access a protected page
+ const dashboardResponse = await fetch("https://app.cal.com/api/trpc/viewer.me", {
+ method: "GET",
+ credentials: "include",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+
+ if (dashboardResponse.ok) {
+ const dashboardData = await dashboardResponse.json();
+
+ if (dashboardData && dashboardData.result && dashboardData.result.data) {
+ return {
+ isLoggedIn: true,
+ userInfo: dashboardData.result.data,
+ };
+ }
+ }
+
+ return { isLoggedIn: false };
+ } catch (error) {
+ return { isLoggedIn: false };
+ }
+ }
+
+ // Try to get API tokens from web session
+ static async getTokensFromWebSession(): Promise<{ accessToken?: string; refreshToken?: string }> {
+ if (!this.isWeb()) {
+ return {};
+ }
+
+ try {
+ // Some Cal.com implementations might expose tokens via specific endpoints
+ // This is a fallback approach - in practice, web sessions might not expose tokens directly
+
+ // Check localStorage/sessionStorage for any stored tokens
+ if (typeof window !== "undefined") {
+ const localStorage = window.localStorage;
+ const sessionStorage = window.sessionStorage;
+
+ const possibleTokenKeys = [
+ "cal-access-token",
+ "cal-auth-token",
+ "next-auth.token",
+ "auth-token",
+ "access-token",
+ ];
+
+ for (const key of possibleTokenKeys) {
+ const localToken = localStorage.getItem(key);
+ const sessionToken = sessionStorage.getItem(key);
+
+ if (localToken || sessionToken) {
+ return {
+ accessToken: localToken || sessionToken || undefined,
+ };
+ }
+ }
+ }
+
+ return {};
+ } catch (error) {
+ return {};
+ }
+ }
+
+ // Redirect to Cal.com web login instead of using WebView
+ static redirectToWebLogin(): void {
+ if (!this.isWeb()) return;
+
+ // For web, redirect directly to Cal.com login
+ const currentUrl = window.location.href;
+ const loginUrl = `https://app.cal.com/auth/signin?callbackUrl=${encodeURIComponent(currentUrl)}`;
+
+ window.location.href = loginUrl;
+ }
+}
diff --git a/companion/tailwind.config.js b/companion/tailwind.config.js
new file mode 100644
index 0000000000..6288219191
--- /dev/null
+++ b/companion/tailwind.config.js
@@ -0,0 +1,9 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: ["./app/**/*.{js,jsx,ts,tsx}", "./components/**/*.{js,jsx,ts,tsx}"],
+ presets: [require("nativewind/preset")],
+ theme: {
+ extend: {},
+ },
+ plugins: [],
+};
diff --git a/companion/tsconfig.json b/companion/tsconfig.json
new file mode 100644
index 0000000000..b365f86f06
--- /dev/null
+++ b/companion/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "compilerOptions": {
+ "types": ["nativewind/types"]
+ },
+ "extends": "expo/tsconfig.base"
+}
diff --git a/companion/utils/defaultLocations.ts b/companion/utils/defaultLocations.ts
new file mode 100644
index 0000000000..94e99129cf
--- /dev/null
+++ b/companion/utils/defaultLocations.ts
@@ -0,0 +1,97 @@
+/**
+ * Default location types that are available alongside conferencing apps
+ * These match the pattern from packages/app-store/locations.ts
+ */
+
+export enum DefaultLocationType {
+ AttendeeInPerson = "attendeeInPerson",
+ InPerson = "inPerson",
+ Phone = "phone",
+ UserPhone = "userPhone",
+ Link = "link",
+ Conferencing = "conferencing",
+ SomewhereElse = "somewhereElse",
+}
+
+export type DefaultLocation = {
+ type: DefaultLocationType;
+ label: string;
+ iconUrl: string;
+ category: "in person" | "conferencing" | "other" | "phone";
+ organizerInputType?: "text" | "phone" | null;
+ organizerInputPlaceholder?: string;
+ organizerInputLabel?: string;
+ messageForOrganizer?: string;
+};
+
+/**
+ * Default locations available in Cal.com
+ * Icons are served from https://app.cal.com/{iconPath}
+ */
+export const defaultLocations: DefaultLocation[] = [
+ {
+ type: DefaultLocationType.AttendeeInPerson,
+ label: "In Person (Attendee Address)",
+ iconUrl: "https://app.cal.com/map-pin-dark.svg",
+ category: "in person",
+ },
+ {
+ type: DefaultLocationType.SomewhereElse,
+ label: "Custom Attendee Location",
+ iconUrl: "https://app.cal.com/message-pin.svg",
+ category: "other",
+ },
+ {
+ type: DefaultLocationType.InPerson,
+ label: "In Person (Organizer Address)",
+ iconUrl: "https://app.cal.com/map-pin-dark.svg",
+ category: "in person",
+ organizerInputType: "text",
+ organizerInputPlaceholder: "Enter address or place",
+ organizerInputLabel: "Address",
+ messageForOrganizer: "Provide an Address or Place",
+ },
+ {
+ type: DefaultLocationType.Link,
+ label: "Link Meeting",
+ iconUrl: "https://app.cal.com/link.svg",
+ category: "other",
+ organizerInputType: "text",
+ organizerInputPlaceholder: "https://meet.example.com/join/123456",
+ organizerInputLabel: "Meeting Link",
+ messageForOrganizer: "Provide a Meeting Link",
+ },
+ {
+ type: DefaultLocationType.Phone,
+ label: "Attendee Phone Number",
+ iconUrl: "https://app.cal.com/phone.svg",
+ category: "phone",
+ organizerInputType: null,
+ messageForOrganizer: "Cal will ask your invitee to enter a phone number before scheduling.",
+ },
+ {
+ type: DefaultLocationType.UserPhone,
+ label: "Organizer Phone Number",
+ iconUrl: "https://app.cal.com/phone.svg",
+ category: "phone",
+ organizerInputType: "phone",
+ organizerInputPlaceholder: "Enter phone number",
+ organizerInputLabel: "Phone Number",
+ messageForOrganizer: "Provide your phone number with country code",
+ },
+];
+
+/**
+ * Get icon URL for a default location type
+ */
+export function getDefaultLocationIconUrl(locationType: string): string | null {
+ const location = defaultLocations.find((loc) => loc.type === locationType);
+ return location ? location.iconUrl : null;
+}
+
+/**
+ * Check if a location type is a default location (not a conferencing app)
+ */
+export function isDefaultLocation(locationType: string): boolean {
+ return defaultLocations.some((loc) => loc.type === locationType);
+}
diff --git a/companion/utils/getAppIconUrl.ts b/companion/utils/getAppIconUrl.ts
new file mode 100644
index 0000000000..21d316c794
--- /dev/null
+++ b/companion/utils/getAppIconUrl.ts
@@ -0,0 +1,123 @@
+/**
+ * Maps conferencing app types or appIds to their icon URLs.
+ * Icons are publicly accessible at: https://app.cal.com/app-store/{dirName}/icon.svg
+ */
+
+const APP_TYPE_TO_DIR_NAME: Record = {
+ // Video conferencing apps
+ zoom_video: "zoomvideo",
+ google_video: "googlevideo",
+ office365_video: "office365video",
+ teams_video: "office365video",
+ daily_video: "dailyvideo",
+ jitsi_video: "jitsivideo",
+ huddle01_video: "huddle01video",
+ tandem_video: "tandemvideo",
+ whereby_video: "whereby",
+ webex_video: "webex",
+ sylapsvideo_video: "sylapsvideo",
+ shimmervideo_video: "shimmervideo",
+ riverside_video: "riverside",
+ roam_video: "roam",
+ ping_video: "ping",
+ mirotalk_video: "mirotalk",
+ nextcloudtalk_conferencing: "nextcloudtalk",
+ jelly_conferencing: "jelly",
+ "horizon-workrooms_video": "horizon-workrooms",
+ "element-call_conferencing": "element-call",
+ eightxeight_video: "eightxeight",
+ discord_video: "discord",
+ dialpad_video: "dialpad",
+ demodesk_video: "demodesk",
+ campfire_video: "campfire",
+ facetime_video: "facetime",
+ whatsapp_video: "whatsapp",
+ telegram_video: "telegram",
+ skype_video: "skype",
+ signal_video: "signal",
+ sirius_video: "sirius_video",
+ sirius_video_video: "sirius_video", // Handle double _video suffix
+ salesroom_video: "salesroom",
+};
+
+const APP_ID_TO_DIR_NAME: Record = {
+ zoom: "zoomvideo",
+ "google-meet": "googlevideo",
+ msteams: "office365video",
+ office365: "office365video",
+ teams: "office365video",
+ "cal-video": "dailyvideo",
+ "daily-video": "dailyvideo",
+ daily: "dailyvideo",
+ jitsi: "jitsivideo",
+ huddle01: "huddle01video",
+ tandem: "tandemvideo",
+ whereby: "whereby",
+ webex: "webex",
+ sylapsvideo: "sylapsvideo",
+ shimmervideo: "shimmervideo",
+ riverside: "riverside",
+ roam: "roam",
+ ping: "ping",
+ mirotalk: "mirotalk",
+ nextcloudtalk: "nextcloudtalk",
+ jelly: "jelly",
+ "horizon-workrooms": "horizon-workrooms",
+ "element-call": "element-call",
+ eightxeight: "eightxeight",
+ discord: "discord",
+ dialpad: "dialpad",
+ demodesk: "demodesk",
+ campfire: "campfire",
+ facetime: "facetime",
+ whatsapp: "whatsapp",
+ telegram: "telegram",
+ skype: "skype",
+ signal: "signal",
+ sirius_video: "sirius_video",
+ salesroom: "salesroom",
+};
+
+/**
+ * Generates the icon URL for a conferencing app based on its type or appId.
+ * Uses publicly available icons from https://app.cal.com/app-store/{dirName}/icon.svg
+ * Special cases are handled (e.g., Google Meet uses logo.webp)
+ *
+ * @param type - The credential type (e.g., "zoom_video", "google_video")
+ * @param appId - The app identifier (e.g., "zoom", "google-meet")
+ * @returns The full icon URL or null if the app is not found
+ *
+ * @example
+ * getAppIconUrl("zoom_video", "zoom") // "https://app.cal.com/app-store/zoomvideo/icon.svg"
+ * getAppIconUrl("google_video", "google-meet") // "https://app.cal.com/app-store/googlevideo/logo.webp"
+ */
+export function getAppIconUrl(type: string, appId: string | null): string | null {
+ let dirName: string | null = null;
+ let iconFileName = "icon.svg";
+
+ // Try to find by appId first (more specific)
+ if (appId && APP_ID_TO_DIR_NAME[appId]) {
+ dirName = APP_ID_TO_DIR_NAME[appId];
+ } else if (APP_TYPE_TO_DIR_NAME[type]) {
+ // Fallback to type
+ dirName = APP_TYPE_TO_DIR_NAME[type];
+ }
+
+ if (!dirName) {
+ return null;
+ }
+
+ // Special cases for icon file names
+ if (appId === "google-meet" || type === "google_video") {
+ // Google Meet uses logo.webp instead of icon.svg
+ iconFileName = "logo.webp";
+ } else if (appId === "riverside" || type === "riverside_video") {
+ // Riverside uses icon-dark.svg
+ iconFileName = "icon-dark.svg";
+ } else if (appId === "sirius_video" || type === "sirius_video" || type === "sirius_video_video") {
+ // Sirius Video uses icon-dark.svg
+ iconFileName = "icon-dark.svg";
+ }
+
+ return `https://app.cal.com/app-store/${dirName}/${iconFileName}`;
+}
diff --git a/companion/utils/gmail-google-chip-parser.ts b/companion/utils/gmail-google-chip-parser.ts
new file mode 100644
index 0000000000..1989103b80
--- /dev/null
+++ b/companion/utils/gmail-google-chip-parser.ts
@@ -0,0 +1,155 @@
+/**
+ * Parser for Google Calendar scheduling chips in Gmail
+ * Extracts time slots from the Gmail ad-hoc scheduling chip
+ */
+
+export interface GoogleTimeSlot {
+ date: string; // "Wed, 26 November"
+ startTime: string; // "3:30 pm"
+ endTime: string; // "4:30 pm"
+ durationMinutes: number; // 60
+ isoDate: string; // "2025-11-27"
+ isoTimestamp: string; // "2025-11-27T05:30:00.000Z"
+ googleUrl: string; // Original Google Calendar URL
+}
+
+export interface ParsedGoogleChip {
+ scheduleId: string;
+ timezone: string; // "Asia/Kolkata"
+ timezoneOffset: string; // "GMT+05:30"
+ slots: GoogleTimeSlot[];
+ detectedDuration: number; // 15, 30, 45, or 60
+}
+
+/**
+ * Parse Google Calendar scheduling chip from Gmail
+ */
+export function parseGoogleChip(chipElement: HTMLElement): ParsedGoogleChip | null {
+ try {
+ // 1. Get schedule ID from data attribute
+ const scheduleId = chipElement.getAttribute("data-ad-hoc-schedule-id");
+ if (!scheduleId) {
+ console.warn("No schedule ID found in Google chip");
+ return null;
+ }
+
+ // 2. Parse timezone - first try to get IANA timezone from data attribute
+ let timezone = "UTC";
+ let timezoneOffset = "GMT+00:00";
+
+ // Try to get IANA timezone from data-ad-hoc-v2-params
+ const paramsAttr = chipElement.getAttribute("data-ad-hoc-v2-params");
+ if (paramsAttr) {
+ // The timezone is at the end of the params string, like: "Asia/Kolkata"
+ // Try multiple patterns as Gmail might format it differently
+ let tzMatch = paramsAttr.match(/"([^&]+)"\]/);
+
+ // Also try without HTML entities
+ if (!tzMatch) {
+ tzMatch = paramsAttr.match(/"([^"]+)"\]/);
+ }
+
+ // Also try with escaped quotes
+ if (!tzMatch) {
+ tzMatch = paramsAttr.match(/\\"([^\\]+)\\"\]/);
+ }
+
+ if (tzMatch && tzMatch[1]) {
+ timezone = tzMatch[1]; // e.g., "Asia/Kolkata"
+ }
+ }
+
+ // Also get the display timezone offset from the UI text
+ const timezoneText = chipElement.querySelector("td")?.textContent?.trim() || "";
+ const timezoneMatch = timezoneText.match(/^(.+?)\s*-\s*(.+?)\s*\((.+?)\)$/);
+
+ if (timezoneMatch) {
+ timezoneOffset = timezoneMatch[3].trim(); // e.g., "GMT+05:30"
+ }
+
+ // 3. Find all time slot links
+ const slotLinks = Array.from(chipElement.querySelectorAll("a[href*='slotStartTime']"));
+
+ if (slotLinks.length === 0) {
+ console.warn("No time slot links found in Google chip");
+ return null;
+ }
+
+ const slots: GoogleTimeSlot[] = [];
+ let detectedDuration = 60; // Default
+
+ slotLinks.forEach((link) => {
+ const href = (link as HTMLAnchorElement).href;
+ const url = new URL(href);
+
+ // Extract parameters
+ const slotStartTime = url.searchParams.get("slotStartTime");
+ const slotDurationMinutes = url.searchParams.get("slotDurationMinutes");
+
+ if (!slotStartTime || !slotDurationMinutes) {
+ return;
+ }
+
+ const durationMinutes = parseInt(slotDurationMinutes, 10);
+ detectedDuration = durationMinutes; // Use the duration from slots
+
+ // Convert Unix timestamp (milliseconds) to Date
+ const startDate = new Date(parseInt(slotStartTime, 10));
+ const endDate = new Date(startDate.getTime() + durationMinutes * 60 * 1000);
+
+ // Format date and time using the chip's timezone for consistency
+ const dateOptions: Intl.DateTimeFormatOptions = {
+ weekday: "short",
+ day: "numeric",
+ month: "long",
+ timeZone: timezone, // Use chip's timezone
+ };
+ const timeOptions: Intl.DateTimeFormatOptions = {
+ hour: "numeric",
+ minute: "2-digit",
+ hour12: true,
+ timeZone: timezone, // Use chip's timezone
+ };
+
+ const date = startDate.toLocaleDateString("en-US", dateOptions);
+ const startTime = startDate
+ .toLocaleTimeString("en-US", timeOptions)
+ .toLowerCase()
+ .replace(/\s/g, " ");
+ const endTime = endDate
+ .toLocaleTimeString("en-US", timeOptions)
+ .toLowerCase()
+ .replace(/\s/g, " ");
+
+ // ISO format for Cal.com
+ const isoDate = startDate.toISOString().split("T")[0]; // "2025-11-27"
+ const isoTimestamp = startDate.toISOString(); // "2025-11-27T05:30:00.000Z"
+
+ slots.push({
+ date,
+ startTime,
+ endTime,
+ durationMinutes,
+ isoDate,
+ isoTimestamp,
+ googleUrl: href,
+ });
+ });
+
+ if (slots.length === 0) {
+ console.warn("No valid slots parsed from Google chip");
+ return null;
+ }
+
+ return {
+ scheduleId,
+ timezone,
+ timezoneOffset,
+ slots,
+ detectedDuration,
+ };
+ } catch (error) {
+ console.error("Error parsing Google chip:", error);
+ return null;
+ }
+}
diff --git a/companion/utils/parsers/event-type-parsers.ts b/companion/utils/parsers/event-type-parsers.ts
new file mode 100644
index 0000000000..61d30a6e05
--- /dev/null
+++ b/companion/utils/parsers/event-type-parsers.ts
@@ -0,0 +1,29 @@
+/**
+ * Helper functions to parse form values into API-compatible formats
+ */
+
+export const parseBufferTime = (buffer: string): number => {
+ const match = buffer.match(/(\d+)/);
+ return match ? parseInt(match[1]) : 0;
+};
+
+export const parseMinimumNotice = (value: string, unit: string): number => {
+ const val = parseInt(value) || 0;
+ if (unit === "Hours") return val * 60;
+ if (unit === "Days") return val * 24 * 60;
+ return val; // Minutes
+};
+
+export const parseFrequencyUnit = (unit: string): string | null => {
+ const normalized = unit.toLowerCase();
+ if (normalized.includes("day")) return "day";
+ if (normalized.includes("week")) return "week";
+ if (normalized.includes("month")) return "month";
+ if (normalized.includes("year")) return "year";
+ return null;
+};
+
+export const parseSlotInterval = (interval: string): number => {
+ const match = interval.match(/(\d+)/);
+ return match ? parseInt(match[1]) : 0;
+};
diff --git a/companion/utils/slugify.ts b/companion/utils/slugify.ts
new file mode 100644
index 0000000000..26704f4077
--- /dev/null
+++ b/companion/utils/slugify.ts
@@ -0,0 +1,33 @@
+// forDisplayingInput is used to allow user to type "-" at the end and not replace with empty space.
+// For eg:- "test-slug" is the slug user wants to set but while typing "test-" would get replace to "test" because of replace(/-+$/, "")
+
+export const slugify = (str: string, forDisplayingInput?: boolean) => {
+ if (!str) {
+ return "";
+ }
+
+ const s = str
+ .toLowerCase() // Convert to lowercase
+ .trim() // Remove whitespace from both sides
+ .normalize("NFD") // Normalize to decomposed form for handling accents
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ .replace(/\p{Diacritic}/gu, "") // Remove any diacritics (accents) from characters
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ .replace(/[^.\p{L}\p{N}\p{Zs}\p{Emoji}]+/gu, "-") // Replace any non-alphanumeric characters (including Unicode and except "." period) with a dash
+ .replace(/[\s_#]+/g, "-") // Replace whitespace, # and underscores with a single dash
+ .replace(/^-+/, "") // Remove dashes from start
+ .replace(/\.{2,}/g, ".") // Replace consecutive periods with a single period
+ .replace(/^\.+/, "") // Remove periods from the start
+ .replace(
+ /([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g,
+ ""
+ ) // Removes emojis
+ .replace(/\s+/g, " ")
+ .replace(/-+/g, "-"); // Replace consecutive dashes with a single dash
+
+ return forDisplayingInput ? s : s.replace(/-+$/, "").replace(/\.*$/, ""); // Remove dashes and period from end
+};
+
+export default slugify;
diff --git a/companion/wxt.config.ts b/companion/wxt.config.ts
new file mode 100644
index 0000000000..f93e8dea94
--- /dev/null
+++ b/companion/wxt.config.ts
@@ -0,0 +1,63 @@
+import { defineConfig } from "wxt";
+
+export default defineConfig({
+ srcDir: "extension",
+ entrypointsDir: "entrypoints",
+ publicDir: "extension/public",
+ outDir: ".output",
+ manifest: {
+ name: "Cal.com Companion",
+ version: "1.7.0",
+ description: "Your calendar companion for quick booking and scheduling",
+ permissions: ["activeTab", "storage", "identity"],
+ host_permissions: [
+ "http://localhost:8081/*",
+ "https://api.cal.com/*",
+ "https://app.cal.com/*",
+ "https://mail.google.com/*",
+ ],
+ content_security_policy: {
+ extension_pages:
+ "script-src 'self'; object-src 'self'; frame-src 'self' http://localhost:8081;",
+ },
+ action: {
+ default_title: "Cal.com Companion",
+ default_icon: {
+ "16": "icon-16.png",
+ "48": "icon-48.png",
+ "128": "icon-128.png",
+ },
+ },
+ icons: {
+ "16": "icon-16.png",
+ "48": "icon-48.png",
+ "128": "icon-128.png",
+ },
+ },
+ vite: () => ({
+ resolve: {
+ alias: {
+ "react-native": "react-native-web",
+ },
+ },
+ define: {
+ global: "globalThis",
+ __DEV__: JSON.stringify(false),
+ // Expose environment variables to the extension
+ "import.meta.env.EXPO_PUBLIC_CALCOM_OAUTH_CLIENT_ID": JSON.stringify(
+ process.env.EXPO_PUBLIC_CALCOM_OAUTH_CLIENT_ID
+ ),
+ "import.meta.env.EXPO_PUBLIC_CALCOM_OAUTH_REDIRECT_URI": JSON.stringify(
+ process.env.EXPO_PUBLIC_CALCOM_OAUTH_REDIRECT_URI
+ ),
+ },
+ optimizeDeps: {
+ include: ["react-native-web"],
+ esbuildOptions: {
+ loader: {
+ ".js": "jsx",
+ },
+ },
+ },
+ }),
+});