diff --git a/package-lock.json b/package-lock.json index 55d3018..9c322ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6592,20 +6592,6 @@ "node": ">=18" } }, - "node_modules/yaml": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", - "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", - "license": "ISC", - "optional": true, - "peer": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/src/pages/MapPage/index.tsx b/src/pages/MapPage/index.tsx index a7ef7ec..930d01d 100644 --- a/src/pages/MapPage/index.tsx +++ b/src/pages/MapPage/index.tsx @@ -73,7 +73,8 @@ if (typeof document !== "undefined") { import { languageInstance } from "@shared"; import { makeAutoObservable } from "mobx"; -import { stationsStore, routeStore, sightsStore } from "@shared"; +import { stationsStore, routeStore, sightsStore, menuStore } from "@shared"; +import { Token } from "@mui/icons-material"; // Функция для сброса кешей карты export const clearMapCaches = () => { @@ -101,6 +102,7 @@ interface ApiStation { name: string; latitude: number; longitude: number; + created_at?: string; } interface ApiSight { @@ -109,8 +111,12 @@ interface ApiSight { description: string; latitude: number; longitude: number; + created_at?: string; } +export type SortType = "name_asc" | "name_desc" | "date_asc" | "date_desc"; + + class MapStore { constructor() { makeAutoObservable(this); @@ -120,6 +126,61 @@ class MapStore { stations: ApiStation[] = []; sights: ApiSight[] = []; + // НОВЫЕ ПОЛЯ ДЛЯ СОРТИРОВКИ + stationSort: SortType = "name_asc"; + sightSort: SortType = "name_asc"; + + // НОВЫЕ МЕТОДЫ-СЕТТЕРЫ + setStationSort = (sortType: SortType) => { + this.stationSort = sortType; + }; + + setSightSort = (sortType: SortType) => { + this.sightSort = sortType; + }; + + // ПРИВАТНЫЙ МЕТОД ДЛЯ ОБЩЕЙ ЛОГИКИ СОРТИРОВКИ + private sortFeatures( + features: T[], + sortType: SortType + ): T[] { + const sorted = [...features]; + switch (sortType) { + case "name_asc": + return sorted.sort((a, b) => a.name.localeCompare(b.name)); + case "name_desc": + return sorted.sort((a, b) => b.name.localeCompare(a.name)); + case "date_asc": + return sorted.sort((a, b) => { + if ('created_at' in a && 'created_at' in b && a.created_at && b.created_at) { + return new Date(a.created_at).getTime() - new Date(b.created_at).getTime(); + } + // Фоллбэк: сортировка по ID, если дата недоступна + return a.id - b.id; + }); + case "date_desc": + return sorted.sort((a, b) => { + if ('created_at' in a && 'created_at' in b && a.created_at && b.created_at) { + return new Date(b.created_at).getTime() - new Date(a.created_at).getTime(); + } + // Фоллбэк: сортировка по ID, если дата недоступна + return b.id - a.id; + }); + default: + return sorted; + } + } + + // НОВЫЕ ГЕТТЕРЫ, ВОЗВРАЩАЮЩИЕ ОТСОРТИРОВАННЫЕ СПИСКИ + get sortedStations(): ApiStation[] { + return this.sortFeatures(this.stations, this.stationSort); + } + + get sortedSights(): ApiSight[] { + return this.sortFeatures(this.sights, this.sightSort); + } + + getRoutes = async () => { const response = await languageInstance("ru").get("/route"); const routesIds = response.data.map((route: any) => route.id); @@ -2116,6 +2177,8 @@ const MapControls: React.FC = ({ ); }; +import {observer} from "mobx-react-lite"; + // --- MAP SIGHTBAR COMPONENT --- interface MapSightbarProps { mapService: MapService | null; @@ -2126,8 +2189,7 @@ interface MapSightbarProps { activeSection: string | null; setActiveSection: (section: string | null) => void; } - -const MapSightbar: React.FC = ({ +const MapSightbar: React.FC = observer(({ mapService, mapFeatures, selectedFeature, @@ -2138,50 +2200,50 @@ const MapSightbar: React.FC = ({ }) => { const navigate = useNavigate(); const [searchQuery, setSearchQuery] = useState(""); + const [stationSort, setStationSort] = useState("name_asc"); + const [sightSort, setSightSort] = useState("name_asc"); - const actualFeatures = useMemo(() => { - return mapFeatures.filter((feature) => !feature.get("isProxy")); - }, [mapFeatures]); + const { isOpen } = menuStore; + + + const actualFeatures = useMemo( + () => mapFeatures.filter((f) => !f.get("isProxy")), + [mapFeatures] + ); const filteredFeatures = useMemo(() => { if (!searchQuery.trim()) return actualFeatures; - return actualFeatures.filter((feature) => - ((feature.get("name") as string) || "") + return actualFeatures.filter((f) => + ((f.get("name") as string) || "") .toLowerCase() .includes(searchQuery.toLowerCase()) ); }, [actualFeatures, searchQuery]); const handleFeatureClick = useCallback( - (id: string | number | undefined) => { - if (!id || !mapService) return; + (id: string | number) => { + if (!mapService) return; mapService.selectFeature(id); }, [mapService] ); const handleDeleteFeature = useCallback( - // @ts-ignore - (id, recourse) => { - if ( - mapService && - window.confirm("Вы действительно хотите удалить этот объект?") - ) { - mapService.deleteFeature(id, recourse); + (id: string | number, resource: string) => { + if (!mapService) return; + if (window.confirm("Вы действительно хотите удалить этот объект?")) { + mapService.deleteFeature(id, resource); } }, [mapService] ); const handleCheckboxChange = useCallback( - (id: string | number | undefined) => { - if (!id || !mapService) return; + (id: string | number) => { + if (!mapService) return; const newSet = new Set(selectedIds); - if (newSet.has(id)) { - newSet.delete(id); - } else { - newSet.add(id); - } + if (newSet.has(id)) newSet.delete(id); + else newSet.add(id); setSelectedIds(newSet); mapService.setSelectedIds(newSet); }, @@ -2200,69 +2262,68 @@ const MapSightbar: React.FC = ({ } }, [mapService, selectedIds, setSelectedIds]); - // @ts-ignore const handleEditFeature = useCallback( - // @ts-ignore - (featureType, fullId) => { - if (!featureType || !fullId) return; + (featureType: string, fullId: string | number) => { const numericId = String(fullId).split("-")[1]; - if (numericId) navigate(`/${featureType}/${numericId}/edit`); + if (!featureType || !numericId) return; + navigate(`/${featureType}/${numericId}/edit`); }, [navigate] ); - const sortFeatures = ( - features: Feature[], - currentSelectedIds: Set, - currentSelectedFeature: Feature | null - ) => { - const selectedId = currentSelectedFeature?.getId(); - return [...features].sort((a, b) => { - const aId = a.getId(); - const bId = b.getId(); - - if (selectedId) { - if (aId === selectedId) return -1; - if (bId === selectedId) return 1; - } - - const aIsChecked = aId !== undefined && currentSelectedIds.has(aId); - const bIsChecked = bId !== undefined && currentSelectedIds.has(bId); - if (aIsChecked && !bIsChecked) return -1; - if (!aIsChecked && bIsChecked) return 1; - - const aNumericId = aId ? parseInt(String(aId).split("-")[1], 10) : 0; - const bNumericId = bId ? parseInt(String(bId).split("-")[1], 10) : 0; - if ( - !isNaN(aNumericId) && - !isNaN(bNumericId) && - aNumericId !== bNumericId - ) { - return aNumericId - bNumericId; - } - - const aName = (a.get("name") as string) || ""; - const bName = (b.get("name") as string) || ""; - return aName.localeCompare(bName, "ru"); - }); + const sortFeaturesByType = >( + features: T[], + sortType: SortType + ): T[] => { + const sorted = [...features]; + switch (sortType) { + case "name_asc": + return sorted.sort((a, b) => + ((a.get("name") as string) || "").localeCompare( + ((b.get("name") as string) || "") + ) + ); + case "name_desc": + return sorted.sort((a, b) => + ((b.get("name") as string) || "").localeCompare( + ((a.get("name") as string) || "") + ) + ); + case "date_asc": + return sorted.sort((a, b) => { + const aDate = a.get("created_at") + ? new Date(a.get("created_at")) + : new Date(0); + const bDate = b.get("created_at") + ? new Date(b.get("created_at")) + : new Date(0); + return aDate.getTime() - bDate.getTime(); + }); + case "date_desc": + return sorted.sort((a, b) => { + const aDate = a.get("created_at") + ? new Date(a.get("created_at")) + : new Date(0); + const bDate = b.get("created_at") + ? new Date(b.get("created_at")) + : new Date(0); + return bDate.getTime() - aDate.getTime(); + }); + default: + return sorted; + } }; - const toggleSection = (id: string) => - setActiveSection(activeSection === id ? null : id); - const stations = filteredFeatures.filter( (f) => f.get("featureType") === "station" ); - const lines = filteredFeatures.filter( - (f) => f.get("featureType") === "route" - ); + const lines = filteredFeatures.filter((f) => f.get("featureType") === "route"); const sights = filteredFeatures.filter( (f) => f.get("featureType") === "sight" ); - const sortedStations = sortFeatures(stations, selectedIds, selectedFeature); - const sortedLines = sortFeatures(lines, selectedIds, selectedFeature); - const sortedSights = sortFeatures(sights, selectedIds, selectedFeature); + const sortedStations = sortFeaturesByType(stations, stationSort); + const sortedSights = sortFeaturesByType(sights, sightSort); const renderFeatureList = ( features: Feature[], @@ -2273,9 +2334,11 @@ const MapSightbar: React.FC = ({ {features.length > 0 ? ( features.map((feature) => { const fId = feature.getId(); + if (fId === undefined) return null; // TypeScript-safe const fName = (feature.get("name") as string) || "Без названия"; const isSelected = selectedFeature?.getId() === fId; - const isChecked = fId !== undefined && selectedIds.has(fId); + const isChecked = selectedIds.has(fId); + return (
= ({ size={16} /> {fName} @@ -2331,7 +2391,8 @@ const MapSightbar: React.FC = ({
); + const toggleSection = (id: string) => + setActiveSection(activeSection === id ? null : id); + const sections = [ { id: "layers", title: `Остановки (${sortedStations.length})`, icon: , count: sortedStations.length, - content: renderFeatureList(sortedStations, "station", MapPin), + content: ( + <> +
+ + +
+ {renderFeatureList(sortedStations, "station", MapPin)} + + ), }, { id: "lines", - title: `Маршруты (${sortedLines.length})`, + title: `Маршруты (${lines.length})`, icon: , - count: sortedLines.length, - content: renderFeatureList(sortedLines, "route", ArrowRightLeft), + count: lines.length, + content: renderFeatureList(lines, "route", ArrowRightLeft), }, { id: "sights", title: `Достопримечательности (${sortedSights.length})`, icon: , count: sortedSights.length, - content: renderFeatureList(sortedSights, "sight", Landmark), + content: ( + <> +
+ + +
+ {renderFeatureList(sortedSights, "sight", Landmark)} + + ), }, ]; + React.useEffect(() => { + console.log("isOpen changed:", isOpen); + }, [isOpen]); + return ( -
+

Панель управления

@@ -2396,8 +2494,7 @@ const MapSightbar: React.FC = ({ className="w-full px-3 py-2 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" />
- -
+
{filteredFeatures.length === 0 && searchQuery ? (
Ничего не найдено. @@ -2452,7 +2549,6 @@ const MapSightbar: React.FC = ({ ) )}
- {selectedIds.size > 0 && (
); -}; +}); // --- MAP PAGE COMPONENT --- export const MapPage: React.FC = () => { const mapRef = useRef(null); diff --git a/src/pages/Route/RouteCreatePage/index.tsx b/src/pages/Route/RouteCreatePage/index.tsx index 44f6963..bc9848c 100644 --- a/src/pages/Route/RouteCreatePage/index.tsx +++ b/src/pages/Route/RouteCreatePage/index.tsx @@ -301,10 +301,10 @@ export const RouteCreatePage = observer(() => { - {/* Селектор видео превью */} + {/* Селектор видеозаставки */} { - {/* Селектор видео превью */} + {/* Селектор видеозаставки */} { const navigate = useNavigate(); @@ -28,6 +30,8 @@ export const StationCreatePage = observer(() => { } = stationsStore; const { cities, getCities } = cityStore; const [coordinates, setCoordinates] = useState(""); + // НОВОЕ СОСТОЯНИЕ ДЛЯ ПРЕДУПРЕЖДАЮЩЕГО ОКНА + const [isSaveWarningOpen, setIsSaveWarningOpen] = useState(false); useEffect(() => { if ( @@ -40,7 +44,8 @@ export const StationCreatePage = observer(() => { } }, [createStationData.common.latitude, createStationData.common.longitude]); - const handleCreate = async () => { + // НОВАЯ ФУНКЦИЯ: Фактическое создание (вызывается после подтверждения) + const executeCreate = async () => { try { setIsLoading(true); await createStation(); @@ -54,6 +59,30 @@ export const StationCreatePage = observer(() => { } }; + // ОБНОВЛЕННАЯ ФУНКЦИЯ: Проверка и вызов окна или создания + const handleCreate = async () => { + const isCityMissing = !createStationData.common.city_id; + const isNameMissing = !createStationData[language].name; + + if (isCityMissing || isNameMissing) { + setIsSaveWarningOpen(true); + return; + } + + await executeCreate(); + }; + + // Обработчик "Да" в предупреждающем окне + const handleConfirmCreate = async () => { + setIsSaveWarningOpen(false); + await executeCreate(); + }; + + // Обработчик "Нет" в предупреждающем окне + const handleCancelCreate = () => { + setIsSaveWarningOpen(false); + }; + useEffect(() => { const fetchCities = async () => { await getCities("ru"); @@ -192,7 +221,7 @@ export const StationCreatePage = observer(() => { className="w-min flex gap-2 items-center" startIcon={} onClick={handleCreate} - disabled={isLoading || !createStationData[language]?.name} + disabled={isLoading} // Убрал проверку name/city_id отсюда, чтобы ее обрабатывал handleCreate > {isLoading ? ( @@ -201,6 +230,16 @@ export const StationCreatePage = observer(() => { )}
+ + {/* ИНТЕГРИРОВАННОЕ ПРЕДУПРЕЖДАЮЩЕЕ ОКНО */} + {isSaveWarningOpen && ( + + )} ); -}); +}); \ No newline at end of file diff --git a/src/pages/Station/StationEditPage/index.tsx b/src/pages/Station/StationEditPage/index.tsx index a191da1..040e8ad 100644 --- a/src/pages/Station/StationEditPage/index.tsx +++ b/src/pages/Station/StationEditPage/index.tsx @@ -16,6 +16,7 @@ import { stationsStore, languageStore, cityStore } from "@shared"; import { useEffect, useState } from "react"; import { LanguageSwitcher } from "@widgets"; import { LinkedSights } from "../LinkedSights"; +import { SaveWithoutCityAgree } from "@widgets"; export const StationEditPage = observer(() => { const navigate = useNavigate(); @@ -31,9 +32,10 @@ export const StationEditPage = observer(() => { } = stationsStore; const { cities, getCities } = cityStore; const [coordinates, setCoordinates] = useState(""); + // НОВОЕ СОСТОЯНИЕ ДЛЯ ПРЕДУПРЕЖДАЮЩЕГО ОКНА + const [isSaveWarningOpen, setIsSaveWarningOpen] = useState(false); useEffect(() => { - // Устанавливаем русский язык при загрузке страницы languageStore.setLanguage("ru"); }, []); @@ -48,7 +50,8 @@ export const StationEditPage = observer(() => { } }, [editStationData.common.latitude, editStationData.common.longitude]); - const handleEdit = async () => { + // НОВАЯ ФУНКЦИЯ: Фактическое редактирование (вызывается после подтверждения) + const executeEdit = async () => { try { setIsLoading(true); await editStation(Number(id)); @@ -61,6 +64,30 @@ export const StationEditPage = observer(() => { } }; + // ОБНОВЛЕННАЯ ФУНКЦИЯ: Проверка и вызов окна или редактирования + const handleEdit = async () => { + const isCityMissing = !editStationData.common.city_id; + const isNameMissing = !editStationData[language].name; + + if (isCityMissing || isNameMissing) { + setIsSaveWarningOpen(true); + return; + } + + await executeEdit(); + }; + + // Обработчик "Да" в предупреждающем окне + const handleConfirmEdit = async () => { + setIsSaveWarningOpen(false); + await executeEdit(); + }; + + // Обработчик "Нет" в предупреждающем окне + const handleCancelEdit = () => { + setIsSaveWarningOpen(false); + }; + useEffect(() => { const fetchAndSetStationData = async () => { if (!id) return; @@ -211,7 +238,7 @@ export const StationEditPage = observer(() => { className="w-min flex gap-2 items-center" startIcon={} onClick={handleEdit} - disabled={isLoading || !editStationData[language]?.name} + disabled={isLoading} // Убрал проверку name/city_id отсюда, чтобы ее обрабатывал handleEdit > {isLoading ? ( @@ -220,6 +247,16 @@ export const StationEditPage = observer(() => { )}
+ + {/* ИНТЕГРИРОВАННОЕ ПРЕДУПРЕЖДАЮЩЕЕ ОКНО */} + {isSaveWarningOpen && ( + + )} ); -}); +}); \ No newline at end of file diff --git a/src/shared/store/MenuStore/index.ts b/src/shared/store/MenuStore/index.ts new file mode 100644 index 0000000..2844b36 --- /dev/null +++ b/src/shared/store/MenuStore/index.ts @@ -0,0 +1,15 @@ +import { makeAutoObservable } from "mobx"; + +class MenuStore { + isOpen: boolean = true; + + constructor() { + makeAutoObservable(this); + } + + setIsMenuOpen = (isOpen: boolean) => { + this.isOpen = isOpen; + }; +} + +export const menuStore = new MenuStore(); diff --git a/src/shared/store/index.ts b/src/shared/store/index.ts index bddc885..9154594 100644 --- a/src/shared/store/index.ts +++ b/src/shared/store/index.ts @@ -14,3 +14,4 @@ export * from "./RouteStore"; export * from "./UserStore"; export * from "./CarrierStore"; export * from "./StationsStore"; +export * from "./MenuStore" diff --git a/src/widgets/Layout/index.tsx b/src/widgets/Layout/index.tsx index 1b4c982..f54d9f8 100644 --- a/src/widgets/Layout/index.tsx +++ b/src/widgets/Layout/index.tsx @@ -8,7 +8,7 @@ import { AppBar } from "./ui/AppBar"; import { Drawer } from "./ui/Drawer"; import { DrawerHeader } from "./ui/DrawerHeader"; import { NavigationList } from "@features"; -import { authStore, userStore } from "@shared"; +import { authStore, userStore, menuStore } from "@shared"; import { observer } from "mobx-react-lite"; import { useEffect } from "react"; import { Typography } from "@mui/material"; @@ -20,6 +20,14 @@ interface LayoutProps { export const Layout: React.FC = observer(({ children }) => { const theme = useTheme(); const [open, setOpen] = React.useState(true); + const { setIsMenuOpen } = menuStore; + + React.useEffect(() => { + setIsMenuOpen(open); + }, [open]); + + + const { getUsers, users } = userStore; useEffect(() => { diff --git a/src/widgets/SaveWithoutCityAgree/index.tsx b/src/widgets/SaveWithoutCityAgree/index.tsx new file mode 100644 index 0000000..488b5d6 --- /dev/null +++ b/src/widgets/SaveWithoutCityAgree/index.tsx @@ -0,0 +1,23 @@ +import { Button } from "@mui/material"; + +export const SaveWithoutCityAgree = ({ blocker }: { blocker: any }) => { + return ( +
+
+

+ Вы не указали город и/или не заполнили названия на всех языках. +
+ Сохранить достопримечательность без этой информации? +

+
+ + +
+
+
+ ); +}; diff --git a/src/widgets/SightTabs/CreateInformationTab/index.tsx b/src/widgets/SightTabs/CreateInformationTab/index.tsx index 106ef98..119e70b 100644 --- a/src/widgets/SightTabs/CreateInformationTab/index.tsx +++ b/src/widgets/SightTabs/CreateInformationTab/index.tsx @@ -35,8 +35,7 @@ import { Save } from "lucide-react"; import { observer } from "mobx-react-lite"; import { useEffect, useState } from "react"; import { toast } from "react-toastify"; - -// Мокап для всплывающей подсказки +import { SaveWithoutCityAgree } from "@widgets"; export const CreateInformationTab = observer( ({ value, index }: { value: number; index: number }) => { @@ -51,7 +50,6 @@ export const CreateInformationTab = observer( const [, setCity] = useState(sight.city_id ?? 0); const [coordinates, setCoordinates] = useState(`0, 0`); - // Menu state for each media button const [menuAnchorEl, setMenuAnchorEl] = useState(null); const [activeMenuType, setActiveMenuType] = useState< "thumbnail" | "watermark_lu" | "watermark_rd" | "video_preview" | null @@ -62,21 +60,15 @@ export const CreateInformationTab = observer( "thumbnail" | "watermark_lu" | "watermark_rd" | "video_preview" | null >(null); + // НОВОЕ СОСТОЯНИЕ ДЛЯ ПРЕДУПРЕЖДАЮЩЕГО ОКНА + const [isSaveWarningOpen, setIsSaveWarningOpen] = useState(false); + useEffect(() => {}, [hardcodeType]); - // const handleMenuOpen = ( - // event: React.MouseEvent, - // type: "thumbnail" | "watermark_lu" | "watermark_rd" - // ) => { - // setMenuAnchorEl(event.currentTarget); - // setActiveMenuType(type); - // }; useEffect(() => { - // Показывать только при инициализации (не менять при ошибках пользователя) if (sight.latitude !== 0 || sight.longitude !== 0) { setCoordinates(`${sight.latitude}, ${sight.longitude}`); } - // если координаты обнулились — оставить поле как есть }, [sight.latitude, sight.longitude]); const handleMenuClose = () => { @@ -125,6 +117,29 @@ export const CreateInformationTab = observer( } }; + const handleSave = async () => { + const isCityMissing = !sight.city_id; + const isNameMissing = !sight[language].name; + + if (isCityMissing || isNameMissing) { + setIsSaveWarningOpen(true); + return; + } + + await createSight(language); + toast.success("Достопримечательность создана"); + }; + + const handleConfirmSave = async () => { + setIsSaveWarningOpen(false); + await createSight(language); + toast.success("Достопримечательность создана"); + }; + + const handleCancelSave = () => { + setIsSaveWarningOpen(false); + }; + return ( <> @@ -134,7 +149,7 @@ export const CreateInformationTab = observer( flexDirection: "column", gap: 3, position: "relative", - paddingBottom: "70px" /* Space for save button */, + paddingBottom: "70px", }} >
@@ -146,12 +161,11 @@ export const CreateInformationTab = observer( sx={{ display: "flex", - gap: 4, // Added gap between the two main columns + gap: 4, width: "100%", flexDirection: "column", }} > - {/* Left column with main fields */} { const input = e.target.value; - setCoordinates(input); // показываем как есть + setCoordinates(input); - const [latStr, lonStr] = input.split(/\s+/); // учитываем любые пробелы + const [latStr, lonStr] = input.split(/\s+/); const lat = parseFloat(latStr); const lon = parseFloat(lonStr); - // Проверка, что обе координаты валидные числа const isValidLat = !isNaN(lat); const isValidLon = !isNaN(lon); @@ -260,7 +273,7 @@ export const CreateInformationTab = observer( justifyContent: "space-around", width: "80%", gap: 2, - flexDirection: { xs: "column", sm: "row" }, // Stack on extra small, side-by-side on small and up + flexDirection: { xs: "column", sm: "row" }, }} > { @@ -358,12 +371,10 @@ export const CreateInformationTab = observer( }} onSelectVideoClick={(file) => { if (file) { - // Если передан файл, открываем диалог загрузки медиа createSightStore.setFileToUpload(file); setActiveMenuType("video_preview"); setIsUploadMediaOpen(true); } else { - // Если файл не передан, открываем диалог выбора существующих медиа setActiveMenuType("video_preview"); setIsAddMediaOpen(true); } @@ -373,31 +384,25 @@ export const CreateInformationTab = observer( - {/* LanguageSwitcher positioned at the top right */} - - {/* Save Button fixed at the bottom right */} @@ -405,7 +410,6 @@ export const CreateInformationTab = observer( - {/* Media Menu */} - {/* Модальное окно предпросмотра видео */} {sight.video_preview && sight.video_preview !== "" && ( )} + + {/* ИНТЕГРИРОВАННОЕ ПРЕДУПРЕЖДАЮЩЕЕ ОКНО */} + {isSaveWarningOpen && ( + + )} ); } -); +); \ No newline at end of file diff --git a/src/widgets/SightTabs/InformationTab/index.tsx b/src/widgets/SightTabs/InformationTab/index.tsx index fbd2cb5..2773b04 100644 --- a/src/widgets/SightTabs/InformationTab/index.tsx +++ b/src/widgets/SightTabs/InformationTab/index.tsx @@ -37,7 +37,8 @@ import { useEffect, useState } from "react"; import { toast } from "react-toastify"; -// Мокап для всплывающей подсказки +// Компонент предупреждающего окна (перенесен сюда) +import { SaveWithoutCityAgree } from "@widgets"; export const InformationTab = observer( ({ value, index }: { value: number; index: number }) => { @@ -51,7 +52,6 @@ export const InformationTab = observer( const [, setCity] = useState(sight.common.city_id ?? 0); const [coordinates, setCoordinates] = useState(`0, 0`); - // Menu state for each media button const [menuAnchorEl, setMenuAnchorEl] = useState(null); const [activeMenuType, setActiveMenuType] = useState< "thumbnail" | "watermark_lu" | "watermark_rd" | "video_preview" | null @@ -62,15 +62,15 @@ export const InformationTab = observer( "thumbnail" | "watermark_lu" | "watermark_rd" | "video_preview" | null >(null); const { cities } = cityStore; + // НОВОЕ СОСТОЯНИЕ ДЛЯ ПРЕДУПРЕЖДАЮЩЕГО ОКНА + const [isSaveWarningOpen, setIsSaveWarningOpen] = useState(false); useEffect(() => {}, [hardcodeType]); useEffect(() => { - // Показывать только при инициализации (не менять при ошибках пользователя) if (sight.common.latitude !== 0 || sight.common.longitude !== 0) { setCoordinates(`${sight.common.latitude}, ${sight.common.longitude}`); } - // если координаты обнулились — оставить поле как есть }, [sight.common.latitude, sight.common.longitude]); const handleMenuClose = () => { @@ -119,6 +119,36 @@ export const InformationTab = observer( updateSightInfo(language, content, common); }; + // НОВАЯ ФУНКЦИЯ: Фактическое сохранение (вызывается после подтверждения) + const executeSave = async () => { + await updateSight(); + toast.success("Достопримечательность сохранена"); + }; + + // ОБНОВЛЕННАЯ ФУНКЦИЯ: Проверка и вызов окна или сохранения + const handleSave = async () => { + const isCityMissing = !sight.common.city_id; + const isNameMissing = !sight[language].name; + + if (isCityMissing || isNameMissing) { + setIsSaveWarningOpen(true); + return; + } + + await executeSave(); + }; + + // Обработчик "Да" в предупреждающем окне + const handleConfirmSave = async () => { + setIsSaveWarningOpen(false); + await executeSave(); + }; + + // Обработчик "Нет" в предупреждающем окне + const handleCancelSave = () => { + setIsSaveWarningOpen(false); + }; + return ( <> @@ -128,7 +158,7 @@ export const InformationTab = observer( flexDirection: "column", gap: 3, position: "relative", - paddingBottom: "70px" /* Space for save button */, + paddingBottom: "70px", }} >
@@ -141,12 +171,11 @@ export const InformationTab = observer( sx={{ display: "flex", - gap: 4, // Added gap between the two main columns + gap: 4, width: "100%", flexDirection: "column", }} > - {/* Left column with main fields */} { const newValue = e.target.value; - setCoordinates(newValue); // сохраняем ввод пользователя как есть + setCoordinates(newValue); - // Обрабатываем значение для сохранения const input = newValue.replace(/,/g, " ").trim(); const [latStr, lonStr] = input.split(/\s+/); const lat = parseFloat(latStr); const lon = parseFloat(lonStr); - // Проверка, что обе координаты валидные числа const isValidLat = !isNaN(lat); const isValidLon = !isNaN(lon); @@ -260,7 +287,7 @@ export const InformationTab = observer( justifyContent: "space-around", width: "80%", gap: 2, - flexDirection: { xs: "column", sm: "row" }, // Stack on extra small, side-by-side on small and up + flexDirection: { xs: "column", sm: "row" }, }} > { @@ -372,12 +399,10 @@ export const InformationTab = observer( }} onSelectVideoClick={(file) => { if (file) { - // Если передан файл, открываем диалог загрузки медиа editSightStore.setFileToUpload(file); setActiveMenuType("video_preview"); setIsUploadMediaOpen(true); } else { - // Если файл не передан, открываем диалог выбора существующих медиа setActiveMenuType("video_preview"); setIsAddMediaOpen(true); } @@ -387,31 +412,25 @@ export const InformationTab = observer( - {/* LanguageSwitcher positioned at the top right */} - - {/* Save Button fixed at the bottom right */} @@ -419,7 +438,6 @@ export const InformationTab = observer( - {/* Media Menu */} - {/* Модальное окно предпросмотра видео */} {sight.common.video_preview && sight.common.video_preview !== "" && ( )} + + {/* ИНТЕГРИРОВАННОЕ ПРЕДУПРЕЖДАЮЩЕЕ ОКНО */} + {isSaveWarningOpen && ( + + )} ); } -); +); \ No newline at end of file diff --git a/src/widgets/index.ts b/src/widgets/index.ts index 80952c2..154ed28 100644 --- a/src/widgets/index.ts +++ b/src/widgets/index.ts @@ -17,4 +17,5 @@ export * from "./LeaveAgree"; export * from "./DeleteModal"; export * from "./SnapshotRestore"; export * from "./CreateButton"; +export * from "./SaveWithoutCityAgree" export * from "./modals"; diff --git a/yarn.lock b/yarn.lock index 855e6e6..8264a51 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24,7 +24,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.3.tgz" integrity sha512-V42wFfx1ymFte+ecf6iXghnnP8kWTO+ZLXIyZq+1LAXHHvTZdVxicn4yiVYdYMGaCO3tmqub11AorKkv+iodqw== -"@babel/core@^7.26.10": +"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.26.10": version "7.27.3" resolved "https://registry.npmjs.org/@babel/core/-/core-7.27.3.tgz" integrity sha512-hyrN8ivxfvJ4i0fIJuV4EOlV0WDMz5Ui4StRTgVaAvWeiRCilXgwVvxJKtFQ3TKtHgJscB2YiXKGNJuVwhQMtA== @@ -173,28 +173,6 @@ resolved "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz" integrity sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow== -"@emnapi/core@^1.4.3": - version "1.4.4" - resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.4.4.tgz#76620673f3033626c6d79b1420d69f06a6bb153c" - integrity sha512-A9CnAbC6ARNMKcIcrQwq6HeHCjpcBZ5wSx4U01WXCqEKlrzB9F9315WDNHkrs2xbx7YjjSxbUYxuN6EQzpcY2g== - dependencies: - "@emnapi/wasi-threads" "1.0.3" - tslib "^2.4.0" - -"@emnapi/runtime@^1.4.3": - version "1.4.4" - resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.4.4.tgz#19a8f00719c51124e2d0fbf4aaad3fa7b0c92524" - integrity sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg== - dependencies: - tslib "^2.4.0" - -"@emnapi/wasi-threads@1.0.3", "@emnapi/wasi-threads@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.0.3.tgz#83fa228bde0e71668aad6db1af4937473d1d3ab1" - integrity sha512-8K5IFFsQqF9wQNJptGbS6FNKgUTsSRYnTqNCG1vPP8jFdjSv18n2mQfJpkt2Oibo9iBEzcDnDxNwKTzC7svlJw== - dependencies: - tslib "^2.4.0" - "@emotion/babel-plugin@^11.13.5": version "11.13.5" resolved "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz" @@ -240,7 +218,7 @@ resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz" integrity sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ== -"@emotion/react@^11.14.0": +"@emotion/react@^11.0.0-rc.0", "@emotion/react@^11.14.0", "@emotion/react@^11.4.1", "@emotion/react@^11.5.0", "@emotion/react@^11.9.0": version "11.14.0" resolved "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz" integrity sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA== @@ -270,7 +248,7 @@ resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz" integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg== -"@emotion/styled@^11.14.0": +"@emotion/styled@^11.14.0", "@emotion/styled@^11.3.0", "@emotion/styled@^11.8.1": version "11.14.0" resolved "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz" integrity sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA== @@ -302,131 +280,11 @@ resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz" integrity sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg== -"@esbuild/aix-ppc64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz#4e0f91776c2b340e75558f60552195f6fad09f18" - integrity sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA== - -"@esbuild/android-arm64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz#bc766407f1718923f6b8079c8c61bf86ac3a6a4f" - integrity sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg== - -"@esbuild/android-arm@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.5.tgz#4290d6d3407bae3883ad2cded1081a234473ce26" - integrity sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA== - -"@esbuild/android-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.5.tgz#40c11d9cbca4f2406548c8a9895d321bc3b35eff" - integrity sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw== - "@esbuild/darwin-arm64@0.25.5": version "0.25.5" resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz" integrity sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ== -"@esbuild/darwin-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz#e27a5d92a14886ef1d492fd50fc61a2d4d87e418" - integrity sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ== - -"@esbuild/freebsd-arm64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz#97cede59d638840ca104e605cdb9f1b118ba0b1c" - integrity sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw== - -"@esbuild/freebsd-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz#71c77812042a1a8190c3d581e140d15b876b9c6f" - integrity sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw== - -"@esbuild/linux-arm64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz#f7b7c8f97eff8ffd2e47f6c67eb5c9765f2181b8" - integrity sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg== - -"@esbuild/linux-arm@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz#2a0be71b6cd8201fa559aea45598dffabc05d911" - integrity sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw== - -"@esbuild/linux-ia32@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz#763414463cd9ea6fa1f96555d2762f9f84c61783" - integrity sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA== - -"@esbuild/linux-loong64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz#428cf2213ff786a502a52c96cf29d1fcf1eb8506" - integrity sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg== - -"@esbuild/linux-mips64el@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz#5cbcc7fd841b4cd53358afd33527cd394e325d96" - integrity sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg== - -"@esbuild/linux-ppc64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz#0d954ab39ce4f5e50f00c4f8c4fd38f976c13ad9" - integrity sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ== - -"@esbuild/linux-riscv64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz#0e7dd30730505abd8088321e8497e94b547bfb1e" - integrity sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA== - -"@esbuild/linux-s390x@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz#5669af81327a398a336d7e40e320b5bbd6e6e72d" - integrity sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ== - -"@esbuild/linux-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz#b2357dd153aa49038967ddc1ffd90c68a9d2a0d4" - integrity sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw== - -"@esbuild/netbsd-arm64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz#53b4dfb8fe1cee93777c9e366893bd3daa6ba63d" - integrity sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw== - -"@esbuild/netbsd-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz#a0206f6314ce7dc8713b7732703d0f58de1d1e79" - integrity sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ== - -"@esbuild/openbsd-arm64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz#2a796c87c44e8de78001d808c77d948a21ec22fd" - integrity sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw== - -"@esbuild/openbsd-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz#28d0cd8909b7fa3953af998f2b2ed34f576728f0" - integrity sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg== - -"@esbuild/sunos-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz#a28164f5b997e8247d407e36c90d3fd5ddbe0dc5" - integrity sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA== - -"@esbuild/win32-arm64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz#6eadbead38e8bd12f633a5190e45eff80e24007e" - integrity sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw== - -"@esbuild/win32-ia32@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz#bab6288005482f9ed2adb9ded7e88eba9a62cc0d" - integrity sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ== - -"@esbuild/win32-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz#7fc114af5f6563f19f73324b5d5ff36ece0803d1" - integrity sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g== - "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.7.0": version "4.7.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz" @@ -475,7 +333,7 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@9.27.0", "@eslint/js@^9.25.0": +"@eslint/js@^9.25.0", "@eslint/js@9.27.0": version "9.27.0" resolved "https://registry.npmjs.org/@eslint/js/-/js-9.27.0.tgz" integrity sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA== @@ -595,7 +453,7 @@ dependencies: "@babel/runtime" "^7.27.1" -"@mui/material@^7.1.0": +"@mui/material@^5.15.14 || ^6.0.0 || ^7.0.0", "@mui/material@^7.1.0", "@mui/material@^7.1.1": version "7.1.1" resolved "https://registry.npmjs.org/@mui/material/-/material-7.1.1.tgz" integrity sha512-mTpdmdZCaHCGOH3SrYM41+XKvNL0iQfM9KlYgpSjgadXx/fEKhhvOktxm8++Xw6FFeOHoOiV+lzOI8X1rsv71A== @@ -634,7 +492,7 @@ csstype "^3.1.3" prop-types "^15.8.1" -"@mui/system@^7.1.1": +"@mui/system@^5.15.14 || ^6.0.0 || ^7.0.0", "@mui/system@^7.1.1": version "7.1.1" resolved "https://registry.npmjs.org/@mui/system/-/system-7.1.1.tgz" integrity sha512-Kj1uhiqnj4Zo7PDjAOghtXJtNABunWvhcRU0O7RQJ7WOxeynoH6wXPcilphV8QTFtkKaip8EiNJRiCD+B3eROA== @@ -688,15 +546,6 @@ "@babel/runtime" "^7.27.4" "@mui/utils" "^7.1.1" -"@napi-rs/wasm-runtime@^0.2.10": - version "0.2.12" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz#3e78a8b96e6c33a6c517e1894efbd5385a7cb6f2" - integrity sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ== - dependencies: - "@emnapi/core" "^1.4.3" - "@emnapi/runtime" "^1.4.3" - "@tybys/wasm-util" "^0.10.0" - "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -705,7 +554,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -723,7 +572,7 @@ resolved "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.9.2.tgz" integrity sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog== -"@photo-sphere-viewer/core@^5.13.2": +"@photo-sphere-viewer/core@^5.13.2", "@photo-sphere-viewer/core@>=5.13.1": version "5.13.2" resolved "https://registry.npmjs.org/@photo-sphere-viewer/core/-/core-5.13.2.tgz" integrity sha512-rL4Ey39Prx4Iyxt1f2tAqlXvqu4/ovXfUvIpLt540OpZJiFjWccs6qLywof9vuhBJ7PXHudHWCjRPce0W8kx8w== @@ -775,7 +624,7 @@ utility-types "^3.11.0" zustand "^5.0.1" -"@react-three/fiber@^9.1.2": +"@react-three/fiber@^9.0.0", "@react-three/fiber@^9.1.2": version "9.1.2" resolved "https://registry.npmjs.org/@react-three/fiber/-/fiber-9.1.2.tgz" integrity sha512-k8FR9yVHV9kIF3iuOD0ds5hVymXYXfgdKklqziBVod9ZEJ8uk05Zjw29J/omU3IKeUfLNAIHfxneN3TUYM4I2w== @@ -798,106 +647,11 @@ resolved "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.9.tgz" integrity sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w== -"@rollup/rollup-android-arm-eabi@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.41.1.tgz#f39f09f60d4a562de727c960d7b202a2cf797424" - integrity sha512-NELNvyEWZ6R9QMkiytB4/L4zSEaBC03KIXEghptLGLZWJ6VPrL63ooZQCOnlx36aQPGhzuOMwDerC1Eb2VmrLw== - -"@rollup/rollup-android-arm64@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.41.1.tgz#d19af7e23760717f1d879d4ca3d2cd247742dff2" - integrity sha512-DXdQe1BJ6TK47ukAoZLehRHhfKnKg9BjnQYUu9gzhI8Mwa1d2fzxA1aw2JixHVl403bwp1+/o/NhhHtxWJBgEA== - "@rollup/rollup-darwin-arm64@4.41.1": version "4.41.1" resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.1.tgz" integrity sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w== -"@rollup/rollup-darwin-x64@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.1.tgz#aa66d2ba1a25e609500e13bef06dc0e71cc0c0d4" - integrity sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg== - -"@rollup/rollup-freebsd-arm64@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.41.1.tgz#df10a7b6316a0ef1028c6ca71a081124c537e30d" - integrity sha512-DBVMZH5vbjgRk3r0OzgjS38z+atlupJ7xfKIDJdZZL6sM6wjfDNo64aowcLPKIx7LMQi8vybB56uh1Ftck/Atg== - -"@rollup/rollup-freebsd-x64@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.41.1.tgz#a3fdce8a05e95b068cbcb46e4df5185e407d0c35" - integrity sha512-3FkydeohozEskBxNWEIbPfOE0aqQgB6ttTkJ159uWOFn42VLyfAiyD9UK5mhu+ItWzft60DycIN1Xdgiy8o/SA== - -"@rollup/rollup-linux-arm-gnueabihf@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.41.1.tgz#49f766c55383bd0498014a9d76924348c2f3890c" - integrity sha512-wC53ZNDgt0pqx5xCAgNunkTzFE8GTgdZ9EwYGVcg+jEjJdZGtq9xPjDnFgfFozQI/Xm1mh+D9YlYtl+ueswNEg== - -"@rollup/rollup-linux-arm-musleabihf@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.41.1.tgz#1d4d7d32fc557e17d52e1857817381ea365e2959" - integrity sha512-jwKCca1gbZkZLhLRtsrka5N8sFAaxrGz/7wRJ8Wwvq3jug7toO21vWlViihG85ei7uJTpzbXZRcORotE+xyrLA== - -"@rollup/rollup-linux-arm64-gnu@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.1.tgz#f4fc317268441e9589edad3be8f62b6c03009bc1" - integrity sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA== - -"@rollup/rollup-linux-arm64-musl@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.1.tgz#63a1f1b0671cb17822dabae827fef0e443aebeb7" - integrity sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg== - -"@rollup/rollup-linux-loongarch64-gnu@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.41.1.tgz#c659b01cc6c0730b547571fc3973e1e955369f98" - integrity sha512-bkCfDJ4qzWfFRCNt5RVV4DOw6KEgFTUZi2r2RuYhGWC8WhCA8lCAJhDeAmrM/fdiAH54m0mA0Vk2FGRPyzI+tw== - -"@rollup/rollup-linux-powerpc64le-gnu@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.41.1.tgz#612e746f9ad7e58480f964d65e0d6c3f4aae69a8" - integrity sha512-3mr3Xm+gvMX+/8EKogIZSIEF0WUu0HL9di+YWlJpO8CQBnoLAEL/roTCxuLncEdgcfJcvA4UMOf+2dnjl4Ut1A== - -"@rollup/rollup-linux-riscv64-gnu@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.41.1.tgz#4610dbd1dcfbbae32fbc10c20ae7387acb31110c" - integrity sha512-3rwCIh6MQ1LGrvKJitQjZFuQnT2wxfU+ivhNBzmxXTXPllewOF7JR1s2vMX/tWtUYFgphygxjqMl76q4aMotGw== - -"@rollup/rollup-linux-riscv64-musl@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.41.1.tgz#054911fab40dc83fafc21e470193c058108f19d8" - integrity sha512-LdIUOb3gvfmpkgFZuccNa2uYiqtgZAz3PTzjuM5bH3nvuy9ty6RGc/Q0+HDFrHrizJGVpjnTZ1yS5TNNjFlklw== - -"@rollup/rollup-linux-s390x-gnu@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.41.1.tgz#98896eca8012547c7f04bd07eaa6896825f9e1a5" - integrity sha512-oIE6M8WC9ma6xYqjvPhzZYk6NbobIURvP/lEbh7FWplcMO6gn7MM2yHKA1eC/GvYwzNKK/1LYgqzdkZ8YFxR8g== - -"@rollup/rollup-linux-x64-gnu@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.1.tgz#01cf56844a1e636ee80dfb364e72c2b7142ad896" - integrity sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A== - -"@rollup/rollup-linux-x64-musl@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.41.1.tgz#e67c7531df6dff0b4c241101d4096617fbca87c3" - integrity sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ== - -"@rollup/rollup-win32-arm64-msvc@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.1.tgz#7eeada98444e580674de6989284e4baacd48ea65" - integrity sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ== - -"@rollup/rollup-win32-ia32-msvc@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.41.1.tgz#516c4b54f80587b4a390aaf4940b40870271d35d" - integrity sha512-+psFT9+pIh2iuGsxFYYa/LhS5MFKmuivRsx9iPJWNSGbh2XVEjk90fmpUEjCnILPEPJnikAU6SFDiEUyOv90Pg== - -"@rollup/rollup-win32-x64-msvc@4.41.1": - version "4.41.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.1.tgz#848f99b0d9936d92221bb6070baeff4db6947a30" - integrity sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw== - "@tailwindcss/node@4.1.8": version "4.1.8" resolved "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.8.tgz" @@ -911,73 +665,11 @@ source-map-js "^1.2.1" tailwindcss "4.1.8" -"@tailwindcss/oxide-android-arm64@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.8.tgz#4cb4b464636fc7e3154a1bb7df38a828291b3e9a" - integrity sha512-Fbz7qni62uKYceWYvUjRqhGfZKwhZDQhlrJKGtnZfuNtHFqa8wmr+Wn74CTWERiW2hn3mN5gTpOoxWKk0jRxjg== - "@tailwindcss/oxide-darwin-arm64@4.1.8": version "4.1.8" resolved "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.8.tgz" integrity sha512-RdRvedGsT0vwVVDztvyXhKpsU2ark/BjgG0huo4+2BluxdXo8NDgzl77qh0T1nUxmM11eXwR8jA39ibvSTbi7A== -"@tailwindcss/oxide-darwin-x64@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.8.tgz#d0f3fa4c3bde21a772e29e31c9739d91db79de12" - integrity sha512-t6PgxjEMLp5Ovf7uMb2OFmb3kqzVTPPakWpBIFzppk4JE4ix0yEtbtSjPbU8+PZETpaYMtXvss2Sdkx8Vs4XRw== - -"@tailwindcss/oxide-freebsd-x64@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.8.tgz#545c94c941007ed1aa2e449465501b70d59cb3da" - integrity sha512-g8C8eGEyhHTqwPStSwZNSrOlyx0bhK/V/+zX0Y+n7DoRUzyS8eMbVshVOLJTDDC+Qn9IJnilYbIKzpB9n4aBsg== - -"@tailwindcss/oxide-linux-arm-gnueabihf@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.8.tgz#e1bdbf63a179081669b8cd1c9523889774760eb9" - integrity sha512-Jmzr3FA4S2tHhaC6yCjac3rGf7hG9R6Gf2z9i9JFcuyy0u79HfQsh/thifbYTF2ic82KJovKKkIB6Z9TdNhCXQ== - -"@tailwindcss/oxide-linux-arm64-gnu@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.8.tgz#8d28093bbd43bdae771a2dcca720e926baa57093" - integrity sha512-qq7jXtO1+UEtCmCeBBIRDrPFIVI4ilEQ97qgBGdwXAARrUqSn/L9fUrkb1XP/mvVtoVeR2bt/0L77xx53bPZ/Q== - -"@tailwindcss/oxide-linux-arm64-musl@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.8.tgz#cc6cece814d813885ead9cd8b9d55aeb3db56c97" - integrity sha512-O6b8QesPbJCRshsNApsOIpzKt3ztG35gfX9tEf4arD7mwNinsoCKxkj8TgEE0YRjmjtO3r9FlJnT/ENd9EVefQ== - -"@tailwindcss/oxide-linux-x64-gnu@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.8.tgz#4cac14fa71382574773fb7986d9f0681ad89e3de" - integrity sha512-32iEXX/pXwikshNOGnERAFwFSfiltmijMIAbUhnNyjFr3tmWmMJWQKU2vNcFX0DACSXJ3ZWcSkzNbaKTdngH6g== - -"@tailwindcss/oxide-linux-x64-musl@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.8.tgz#e085f1ccbc8f97625773a6a3afc2a6f88edf59da" - integrity sha512-s+VSSD+TfZeMEsCaFaHTaY5YNj3Dri8rST09gMvYQKwPphacRG7wbuQ5ZJMIJXN/puxPcg/nU+ucvWguPpvBDg== - -"@tailwindcss/oxide-wasm32-wasi@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.8.tgz#c5e19fffe67f25cabf12a357bba4e87128151ea0" - integrity sha512-CXBPVFkpDjM67sS1psWohZ6g/2/cd+cq56vPxK4JeawelxwK4YECgl9Y9TjkE2qfF+9/s1tHHJqrC4SS6cVvSg== - dependencies: - "@emnapi/core" "^1.4.3" - "@emnapi/runtime" "^1.4.3" - "@emnapi/wasi-threads" "^1.0.2" - "@napi-rs/wasm-runtime" "^0.2.10" - "@tybys/wasm-util" "^0.9.0" - tslib "^2.8.0" - -"@tailwindcss/oxide-win32-arm64-msvc@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.8.tgz#77521f23f91604c587736927fd2cb526667b7344" - integrity sha512-7GmYk1n28teDHUjPlIx4Z6Z4hHEgvP5ZW2QS9ygnDAdI/myh3HTHjDqtSqgu1BpRoI4OiLx+fThAyA1JePoENA== - -"@tailwindcss/oxide-win32-x64-msvc@4.1.8": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.8.tgz#55c876ab35f8779d1dceec61483cd9834d7365ac" - integrity sha512-fou+U20j+Jl0EHwK92spoWISON2OBnCazIc038Xj2TdweYV33ZRkS9nwqiUi2d/Wba5xg5UoHfvynnb/UB49cQ== - "@tailwindcss/oxide@4.1.8": version "4.1.8" resolved "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.8.tgz" @@ -1023,20 +715,6 @@ resolved "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz" integrity sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA== -"@tybys/wasm-util@^0.10.0": - version "0.10.0" - resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.10.0.tgz#2fd3cd754b94b378734ce17058d0507c45c88369" - integrity sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ== - dependencies: - tslib "^2.4.0" - -"@tybys/wasm-util@^0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.9.0.tgz#3e75eb00604c8d6db470bf18c37b7d984a0e3355" - integrity sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw== - dependencies: - tslib "^2.4.0" - "@types/babel__core@^7.20.5": version "7.20.5" resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz" @@ -1106,7 +784,7 @@ dependencies: "@types/estree" "*" -"@types/estree@*", "@types/estree@1.0.7", "@types/estree@^1.0.0", "@types/estree@^1.0.6": +"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.6", "@types/estree@1.0.7": version "1.0.7" resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz" integrity sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ== @@ -1140,7 +818,7 @@ resolved "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz" integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== -"@types/node@^22.15.24": +"@types/node@^18.0.0 || ^20.0.0 || >=22.0.0", "@types/node@^22.15.24": version "22.15.24" resolved "https://registry.npmjs.org/@types/node/-/node-22.15.24.tgz" integrity sha512-w9CZGm9RDjzTh/D+hFwlBJ3ziUaVw7oufKA3vOFSOZlzmW9AkZnfjPb+DLnrV6qtgL/LNmP0/2zBNCFHL3F0ng== @@ -1182,7 +860,7 @@ resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz" integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w== -"@types/react@^19.1.2": +"@types/react@*", "@types/react@^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react@^18.2.25 || ^19", "@types/react@^19.0.0", "@types/react@^19.1.2", "@types/react@>=16.8", "@types/react@>=18", "@types/react@>=18.0.0": version "19.1.6" resolved "https://registry.npmjs.org/@types/react/-/react-19.1.6.tgz" integrity sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q== @@ -1201,7 +879,7 @@ dependencies: "@types/estree" "*" -"@types/three@*": +"@types/three@*", "@types/three@>=0.134.0": version "0.177.0" resolved "https://registry.npmjs.org/@types/three/-/three-0.177.0.tgz" integrity sha512-/ZAkn4OLUijKQySNci47lFO+4JLE1TihEjsGWPUT+4jWqxtwOPPEwJV1C3k5MEx0mcBPCdkFjzRzDOnHEI1R+A== @@ -1249,7 +927,7 @@ natural-compare "^1.4.0" ts-api-utils "^2.1.0" -"@typescript-eslint/parser@8.33.0": +"@typescript-eslint/parser@^8.33.0", "@typescript-eslint/parser@8.33.0": version "8.33.0" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.0.tgz" integrity sha512-JaehZvf6m0yqYp34+RVnihBAChkqeH+tqqhS0GuX1qgPpwLvmTPheKEs6OeCK6hVJgXZHJ2vbjnC9j119auStQ== @@ -1277,7 +955,7 @@ "@typescript-eslint/types" "8.33.0" "@typescript-eslint/visitor-keys" "8.33.0" -"@typescript-eslint/tsconfig-utils@8.33.0", "@typescript-eslint/tsconfig-utils@^8.33.0": +"@typescript-eslint/tsconfig-utils@^8.33.0", "@typescript-eslint/tsconfig-utils@8.33.0": version "8.33.0" resolved "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.0.tgz" integrity sha512-sTkETlbqhEoiFmGr1gsdq5HyVbSOF0145SYDJ/EQmXHtKViCaGvnyLqWFFHtEXoS0J1yU8Wyou2UGmgW88fEug== @@ -1292,7 +970,7 @@ debug "^4.3.4" ts-api-utils "^2.1.0" -"@typescript-eslint/types@8.33.0", "@typescript-eslint/types@^8.33.0": +"@typescript-eslint/types@^8.33.0", "@typescript-eslint/types@8.33.0": version "8.33.0" resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.0.tgz" integrity sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg== @@ -1375,7 +1053,7 @@ acorn-jsx@^5.3.2: resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.14.0: +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.14.0: version "8.14.1" resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz" integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== @@ -1474,7 +1152,7 @@ braces@^3.0.3: dependencies: fill-range "^7.1.1" -browserslist@^4.24.0: +browserslist@^4.24.0, "browserslist@>= 4.21.0": version "4.24.5" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz" integrity sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw== @@ -1733,7 +1411,7 @@ earcut@^3.0.0, earcut@^3.0.1: resolved "https://registry.npmjs.org/earcut/-/earcut-3.0.1.tgz" integrity sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw== -easymde@^2.20.0: +easymde@^2.20.0, "easymde@>= 2.0.0 < 3.0.0": version "2.20.0" resolved "https://registry.npmjs.org/easymde/-/easymde-2.20.0.tgz" integrity sha512-V1Z5f92TfR42Na852OWnIZMbM7zotWQYTddNaLYZFVKj7APBbyZ3FYJ27gBw2grMW3R6Qdv9J8n5Ij7XRSIgXQ== @@ -1865,7 +1543,7 @@ eslint-visitor-keys@^4.2.0: resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz" integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== -eslint@^9.25.0: +"eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^8.57.0 || ^9.0.0", eslint@^9.25.0, eslint@>=8.40: version "9.27.0" resolved "https://registry.npmjs.org/eslint/-/eslint-9.27.0.tgz" integrity sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q== @@ -2433,7 +2111,7 @@ its-fine@^2.0.0: dependencies: "@types/react-reconciler" "^0.28.9" -jiti@^2.4.2: +jiti@*, jiti@^2.4.2, jiti@>=1.21.0: version "2.4.2" resolved "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz" integrity sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A== @@ -2517,52 +2195,7 @@ lightningcss-darwin-arm64@1.30.1: resolved "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz" integrity sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ== -lightningcss-darwin-x64@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz#e81105d3fd6330860c15fe860f64d39cff5fbd22" - integrity sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA== - -lightningcss-freebsd-x64@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz#a0e732031083ff9d625c5db021d09eb085af8be4" - integrity sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig== - -lightningcss-linux-arm-gnueabihf@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz#1f5ecca6095528ddb649f9304ba2560c72474908" - integrity sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q== - -lightningcss-linux-arm64-gnu@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz#eee7799726103bffff1e88993df726f6911ec009" - integrity sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw== - -lightningcss-linux-arm64-musl@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz#f2e4b53f42892feeef8f620cbb889f7c064a7dfe" - integrity sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ== - -lightningcss-linux-x64-gnu@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz#2fc7096224bc000ebb97eea94aea248c5b0eb157" - integrity sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw== - -lightningcss-linux-x64-musl@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz#66dca2b159fd819ea832c44895d07e5b31d75f26" - integrity sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ== - -lightningcss-win32-arm64-msvc@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz#7d8110a19d7c2d22bfdf2f2bb8be68e7d1b69039" - integrity sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA== - -lightningcss-win32-x64-msvc@1.30.1: - version "1.30.1" - resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz#fd7dd008ea98494b85d24b4bea016793f2e0e352" - integrity sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg== - -lightningcss@1.30.1: +lightningcss@^1.21.0, lightningcss@1.30.1: version "1.30.1" resolved "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz" integrity sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg== @@ -3025,7 +2658,7 @@ mobx-react-lite@^4.1.0: dependencies: use-sync-external-store "^1.4.0" -mobx@^6.13.7: +mobx@^6.13.7, mobx@^6.9.0: version "6.13.7" resolved "https://registry.npmjs.org/mobx/-/mobx-6.13.7.tgz" integrity sha512-aChaVU/DO5aRPmk1GX8L+whocagUUpBQqoPtJk+cm7UOXUk87J4PeWCh6nNmTTIfEhiR9DI/+FnA8dln/hTK7g== @@ -3189,12 +2822,12 @@ picomatch@^2.3.1: resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -picomatch@^4.0.2: +"picomatch@^3 || ^4", picomatch@^4.0.2: version "4.0.2" resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz" integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== -pixi.js@^8.10.1: +pixi.js@^8.10.1, pixi.js@^8.2.6: version "8.11.0" resolved "https://registry.npmjs.org/pixi.js/-/pixi.js-8.11.0.tgz" integrity sha512-dyuThzncsgEgJZnvd/A/5x6IkUERbK+phXqUQrI+0C6WE+8xqGH5VChRTLecemhgZF0kQ+gZOM3tJTX9937xpg== @@ -3250,7 +2883,7 @@ promise-worker-transferable@^1.0.4: is-promise "^2.1.0" lie "^3.0.2" -prop-types@^15.6.2, prop-types@^15.8.1: +prop-types@^15.5.4, prop-types@^15.6.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -3316,7 +2949,7 @@ react-colorful@^5.6.1: resolved "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz" integrity sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw== -react-dom@^19.1.0: +"react-dom@^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom@^18 || ^19", "react-dom@^18.0.0 || ^19.0.0", react-dom@^19, react-dom@^19.0.0, react-dom@^19.1.0, react-dom@>=16.0.0, react-dom@>=16.13, react-dom@>=16.6.0, react-dom@>=16.8.0, react-dom@>=16.8.2, react-dom@>=18: 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== @@ -3366,7 +2999,7 @@ react-photo-sphere-viewer@^6.2.3: dependencies: eventemitter3 "^5.0.1" -react-reconciler@0.31.0, react-reconciler@^0.31.0: +react-reconciler@^0.31.0, react-reconciler@0.31.0: version "0.31.0" resolved "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.31.0.tgz" integrity sha512-7Ob7Z+URmesIsIVRjnLoDGwBEG/tVitidU0nMsqX/eeJaLY89RISO/10ERe0MqmzuKUUB1rmY+h1itMbUHg9BQ== @@ -3430,12 +3063,12 @@ react-use-measure@^2.1.7: resolved "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz" integrity sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg== -react@^19.1.0: +"react@^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8.0 || ^17 || ^18 || ^19", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^17.0.0 || ^18.0.0 || ^19.0.0", "react@^18 || ^19", "react@^18.0 || ^19", "react@^18.0.0 || ^19.0.0", react@^19, react@^19.0.0, react@^19.1.0, "react@>= 16.8 || 18.0.0", "react@>= 16.8.0", react@>=16.0.0, react@>=16.13, react@>=16.6.0, react@>=16.8, react@>=16.8.0, react@>=16.8.2, react@>=17.0, react@>=18, react@>=18.0.0, react@>=19.0.0: version "19.1.0" resolved "https://registry.npmjs.org/react/-/react-19.1.0.tgz" integrity sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg== -redux@^5.0.1: +redux@^5.0.0, redux@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz" integrity sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w== @@ -3656,7 +3289,7 @@ suspend-react@^0.1.3: resolved "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz" integrity sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ== -tailwindcss@4.1.8, tailwindcss@^4.1.8: +tailwindcss@^4.1.8, "tailwindcss@>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1", tailwindcss@4.1.8: version "4.1.8" resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.8.tgz" integrity sha512-kjeW8gjdxasbmFKpVGrGd5T4i40mV5J2Rasw48QARfYeQ8YS9x02ON9SFWax3Qf616rt4Cp3nVNIj6Hd1mP3og== @@ -3705,7 +3338,7 @@ three@^0.175.0: resolved "https://registry.npmjs.org/three/-/three-0.175.0.tgz" integrity sha512-nNE3pnTHxXN/Phw768u0Grr7W4+rumGg/H6PgeseNJojkJtmeHJfZWi41Gp2mpXl1pg1pf1zjwR4McM1jTqkpg== -three@^0.177.0: +three@^0.177.0, "three@>= 0.159.0", three@>=0.125.0, three@>=0.126.1, three@>=0.128.0, three@>=0.134.0, three@>=0.137, three@>=0.156, three@>=0.159: version "0.177.0" resolved "https://registry.npmjs.org/three/-/three-0.177.0.tgz" integrity sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg== @@ -3765,9 +3398,9 @@ ts-api-utils@^2.1.0: resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz" integrity sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ== -tslib@^2.4.0, tslib@^2.7.0, tslib@^2.8.0: +tslib@^2.7.0: version "2.8.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== tunnel-rat@^0.1.2: @@ -3793,7 +3426,7 @@ typescript-eslint@^8.30.1: "@typescript-eslint/parser" "8.33.0" "@typescript-eslint/utils" "8.33.0" -typescript@~5.8.3: +typescript@>=4.8.4, "typescript@>=4.8.4 <5.9.0", typescript@~5.8.3: version "5.8.3" resolved "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz" integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== @@ -3874,7 +3507,7 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -use-sync-external-store@^1.2.2, use-sync-external-store@^1.4.0, use-sync-external-store@^1.5.0: +use-sync-external-store@^1.2.2, use-sync-external-store@^1.4.0, use-sync-external-store@^1.5.0, use-sync-external-store@>=1.2.0: version "1.5.0" resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz" integrity sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A== @@ -3920,7 +3553,7 @@ vfile@^6.0.0: "@types/unist" "^3.0.0" vfile-message "^4.0.0" -vite@^6.3.5: +"vite@^4.2.0 || ^5.0.0 || ^6.0.0", "vite@^5.2.0 || ^6", vite@^6.3.5: version "6.3.5" resolved "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz" integrity sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==