From c4cee122ff8c2679c9f9a4a8629ea635441b067c Mon Sep 17 00:00:00 2001
From: Baptiste-Ferrand <baptiste.ferrand@ynov.com>
Date: Tue, 26 Mar 2024 23:24:50 +0100
Subject: [PATCH 01/34] features create-travel add point on map, add road on
 map.

---
 src/components/header/DefaultHeader.tsx       |   2 +-
 src/components/stepEditor/MapStepEditor.tsx   | 163 ++++++++++++++++++
 src/pages/map/MapPage.tsx                     |  71 +++++---
 .../showTravels/editTravel/editTravel.tsx     |   9 +
 src/router/Router.tsx                         |  11 ++
 src/services/BaseApi.ts                       |   2 +-
 6 files changed, 230 insertions(+), 28 deletions(-)
 create mode 100644 src/components/stepEditor/MapStepEditor.tsx
 create mode 100644 src/pages/showTravels/editTravel/editTravel.tsx

diff --git a/src/components/header/DefaultHeader.tsx b/src/components/header/DefaultHeader.tsx
index fd39047..7d4a881 100644
--- a/src/components/header/DefaultHeader.tsx
+++ b/src/components/header/DefaultHeader.tsx
@@ -66,7 +66,7 @@ const DefaultHeader = (props: DefaultHeaderProps) => {
         />
         <Group>
           <Group visibleFrom="sm">
-            {isLogged && (
+            {isLogged() && (
               <>
                 <Button
                   leftSection={<IconSquareRoundedPlus size={20} />}
diff --git a/src/components/stepEditor/MapStepEditor.tsx b/src/components/stepEditor/MapStepEditor.tsx
new file mode 100644
index 0000000..7bd2af2
--- /dev/null
+++ b/src/components/stepEditor/MapStepEditor.tsx
@@ -0,0 +1,163 @@
+import { useDocumentTitle } from '@mantine/hooks';
+import { IconPinnedFilled } from '@tabler/icons-react';
+import { FeatureCollection, Position } from 'geojson';
+import React, { useEffect, useMemo, useState } from 'react';
+import {
+  GeolocateControl,
+  Layer,
+  LayerProps,
+  Map,
+  Marker,
+  ScaleControl,
+  Source,
+} from 'react-map-gl';
+import { calculateRoad } from '../../services/api/MapboxController';
+
+
+export const MapStepEditor = () => {
+  useDocumentTitle('From A2B - Map');
+
+  //#region States
+  //Point de vu de l'utilisateur sur la carte, les valeurs renseignées seront l'endroit où la carte se positionnera au chargement de la page
+  const [viewState, setViewState] = React.useState({
+    longitude: 4.860200783597507,
+    latitude: 45.73050608112574,
+    zoom: 2,
+    pitch: 30,
+    bearing: 0,
+  });
+
+  //Ensemble des points de passage du voyage
+  const [steps, setSteps] = useState([
+  ]);
+  const [dto, setDto] = useState([
+    // {
+    //   start: [4.860200783597507, 45.73050608112574],
+    //   end: [5.079252160492843, 45.71892384847893],
+    // },
+    // Ajoutez d'autres coordonnées initiales ici si nécessaire
+  ]);
+
+  const [roads, setRoads] = useState<Position[]>([]);
+  //#endregion
+
+  //#region Effects
+  useEffect(() => {
+    (async () => {
+      //Calcul de l'itinéraire entre les points de passage
+      //Doit être utilisé que si nécessaire, car il y a un quota de requêtes
+      //l'ensemble des itinéraires sont stockés dans la base de données
+      console.log("les dto pour le road", dto[dto.length-1])
+      if (dto.length > 0) {
+        const lastDto = [dto[dto.length-1]]
+        const road: Position[] = await calculateRoad('driving', lastDto);
+        console.log("road", road)
+        setRoads(prevRoads => prevRoads.concat(road));
+        console.log("roads", roads)
+      }
+      // const road: Position[] = await calculateRoad('driving', dto);
+      // setRoads(road);
+      // console.log("roads", roads)
+
+    })();
+  }, [dto]);
+  //#endregion
+
+  //#region Memos
+
+  let removePoint = (index: number) => {
+    console.log("remove", index)
+  }
+
+  //Création des pins sur la carte pour chaque étape du voyage
+  const pins = useMemo(() => {
+    return steps.map((step, index) => {
+      return (
+        <Marker
+          key={`stepMarker-${index}`}
+
+          draggable={false}
+          latitude={step.latitude ?? 0}
+          longitude={step.longitude ?? 0}
+          pitchAlignment="viewport"
+          rotationAlignment="viewport">
+          <IconPinnedFilled color="teal" size={32} stroke={2} onClick={()=>removePoint(index)} />
+        </Marker>
+      );
+    });
+  }, [steps]);
+
+  //#endregion
+
+  //#region Variables
+
+  const geojson: FeatureCollection = {
+    type: 'FeatureCollection',
+    features: [
+      {
+        type: 'Feature',
+        geometry: {
+          type: 'LineString',
+          coordinates: roads,
+        },
+        properties: {},
+      },
+    ],
+  };
+
+  const routeLineStyle: LayerProps = {
+    id: 'roadLayer',
+    type: 'line',
+    layout: {
+      'line-join': 'round',
+      'line-cap': 'round',
+    },
+    paint: {
+      'line-color': '#3887be',
+      'line-width': 5,
+      'line-opacity': 0.75,
+    },
+  };
+
+  let addPoint = (evt: any) => {
+    console.log("hello", evt.lngLat)
+    // @ts-ignore
+    setSteps([...steps, { latitude: evt.lngLat.lat, longitude: evt.lngLat.lng }])
+    console.log("steps", steps)
+    // @ts-ignore
+    if (steps.length > 0){
+      // @ts-ignore
+      setDto([...dto, { start: [steps[steps.length-1].longitude, steps[steps.length-1].latitude], end: [evt.lngLat.lng, evt.lngLat.lat] }])
+      console.log("ddto", dto)
+    }
+  }
+
+
+
+  //#endregion
+  return (
+    <>
+      <Map
+        {...viewState}
+        onMove={evt => setViewState(evt.viewState)}
+        onClick={addPoint}
+        minZoom={2}
+        dragRotate={true}
+        mapStyle="mapbox://styles/mapbox/streets-v12"
+        mapboxAccessToken="pk.eyJ1IjoiZGVyY3Jha2VyIiwiYSI6ImNsdHVnczc4dTB6N2QyanFwZDR1N2c2eHoifQ.arP7tBErlINY3-uiwfb7Ww"
+        attributionControl={true}
+        style={{
+          height: '80vh',
+          width: '80vw',
+        }}>
+        {pins}
+        <Source id="routeSource" type="geojson" data={geojson}>
+          <Layer {...routeLineStyle} />
+        </Source>
+
+        <GeolocateControl />
+        <ScaleControl />
+      </Map>
+    </>
+  );
+};
diff --git a/src/pages/map/MapPage.tsx b/src/pages/map/MapPage.tsx
index 223f9f1..0186736 100644
--- a/src/pages/map/MapPage.tsx
+++ b/src/pages/map/MapPage.tsx
@@ -12,7 +12,7 @@ import {
   Source,
 } from 'react-map-gl';
 import { calculateRoad } from '../../services/api/MapboxController';
-import RoadPositionDto from '../../services/api/Models/MapBoxDirections/RoadPositionDto';
+
 
 const MapPage = () => {
   useDocumentTitle('From A2B - Map');
@@ -27,43 +27,47 @@ const MapPage = () => {
     bearing: 0,
   });
 
+  //Ensemble des points de passage du voyage
+  const [steps, setSteps] = useState([
+  ]);
+  const [dto, setDto] = useState([
+    // {
+    //   start: [4.860200783597507, 45.73050608112574],
+    //   end: [5.079252160492843, 45.71892384847893],
+    // },
+    // Ajoutez d'autres coordonnées initiales ici si nécessaire
+  ]);
+
   const [roads, setRoads] = useState<Position[]>([]);
   //#endregion
 
   //#region Effects
   useEffect(() => {
     (async () => {
-      const dto: RoadPositionDto[] = [
-        {
-          start: [4.860200783597507, 45.73050608112574],
-          end: [5.079252160492843, 45.71892384847893],
-        },
-      ];
       //Calcul de l'itinéraire entre les points de passage
       //Doit être utilisé que si nécessaire, car il y a un quota de requêtes
       //l'ensemble des itinéraires sont stockés dans la base de données
-      const roads: Position[] = await calculateRoad('driving', dto);
-      setRoads(roads);
+      console.log("les dto pour le road", dto[dto.length-1])
+      if (dto.length > 0) {
+      const lastDto = [dto[dto.length-1]]
+      const road: Position[] = await calculateRoad('driving', lastDto);
+        console.log("road", road)
+      setRoads(prevRoads => prevRoads.concat(road));
+      console.log("roads", roads)
+    }
+      // const road: Position[] = await calculateRoad('driving', dto);
+      // setRoads(road);
+      // console.log("roads", roads)
+
     })();
-  }, []);
+  }, [dto]);
   //#endregion
 
   //#region Memos
 
-  //Ensemble des points de passage du voyage
-  const steps = useMemo(
-    () => [
-      {
-        longitude: 4.860200783597507,
-        latitude: 45.73050608112574,
-      },
-      {
-        longitude: 5.079252160492843,
-        latitude: 45.71892384847893,
-      },
-    ],
-    [],
-  );
+  let removePoint = (index: number) => {
+    console.log("remove", index)
+  }
 
   //Création des pins sur la carte pour chaque étape du voyage
   const pins = useMemo(() => {
@@ -71,12 +75,13 @@ const MapPage = () => {
       return (
         <Marker
           key={`stepMarker-${index}`}
+
           draggable={false}
           latitude={step.latitude ?? 0}
           longitude={step.longitude ?? 0}
           pitchAlignment="viewport"
           rotationAlignment="viewport">
-          <IconPinnedFilled color="teal" size={32} stroke={2} />
+          <IconPinnedFilled color="teal" size={32} stroke={2} onClick={()=>removePoint(index)} />
         </Marker>
       );
     });
@@ -114,13 +119,27 @@ const MapPage = () => {
     },
   };
 
-  //#endregion
+  let addPoint = (evt: any) => {
+    console.log("hello", evt.lngLat)
+    // @ts-ignore
+    setSteps([...steps, { latitude: evt.lngLat.lat, longitude: evt.lngLat.lng }])
+    console.log("steps", steps)
+    // @ts-ignore
+      if (steps.length > 0){
+        setDto([...dto, { start: [steps[steps.length-1].longitude, steps[steps.length-1].latitude], end: [evt.lngLat.lng, evt.lngLat.lat] }])
+        console.log("ddto", dto)
+      }
+  }
+
 
+
+  //#endregion
   return (
     <>
       <Map
         {...viewState}
         onMove={evt => setViewState(evt.viewState)}
+        onClick={addPoint}
         minZoom={2}
         dragRotate={true}
         mapStyle="mapbox://styles/mapbox/streets-v12"
diff --git a/src/pages/showTravels/editTravel/editTravel.tsx b/src/pages/showTravels/editTravel/editTravel.tsx
new file mode 100644
index 0000000..f064472
--- /dev/null
+++ b/src/pages/showTravels/editTravel/editTravel.tsx
@@ -0,0 +1,9 @@
+import { MapStepEditor } from '../../../components/stepEditor/MapStepEditor.tsx'
+export function EditTravel() {
+
+  return (
+    <div>
+      <MapStepEditor></MapStepEditor>
+    </div>
+  );
+}
\ No newline at end of file
diff --git a/src/router/Router.tsx b/src/router/Router.tsx
index 5ff8571..2704854 100644
--- a/src/router/Router.tsx
+++ b/src/router/Router.tsx
@@ -11,6 +11,7 @@ import MapPage from '../pages/map/MapPage';
 import { RegisterPage } from '../pages/register/RegisterPage';
 import { AuthStore, useAuthStore } from '../store/useAuthStore';
 import { PrivateRoute } from './PrivateRoute';
+import { EditTravel } from '../pages/showTravels/editTravel/editTravel.tsx'
 
 const Router = () => {
   const loadUser: () => void = useAuthStore((s: AuthStore) => s.loadUser);
@@ -20,6 +21,16 @@ const Router = () => {
     <Routes>
       <Route element={<DefaultLayout />}>
         <Route path="/" element={<LandingPage />} />
+        <Route
+        path="/editTravel"
+        element={
+          <PrivateRoute
+            authRequired
+            redirectPath="/login"
+            element={<EditTravel/>}
+          />
+        }
+        />
         <Route path="/map" element={<MapPage />} />
         <Route path="/*" element={<Navigate to="/" />} />
       </Route>
diff --git a/src/services/BaseApi.ts b/src/services/BaseApi.ts
index 121831f..f099801 100644
--- a/src/services/BaseApi.ts
+++ b/src/services/BaseApi.ts
@@ -2,7 +2,7 @@ import * as client from '@FullStackMap/from-a2b';
 import axios from 'axios';
 import Cookies from 'js-cookie';
 
-const basePath: string = 'http://localhost:32769';
+const basePath: string = 'http://localhost:32771';
 const token: string | undefined = Cookies.get('Auth-Token');
 
 const configAno = new client.Configuration({

From 866c54aa4d74a4a9577fe328650c5b57cfa2f3b4 Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Wed, 27 Mar 2024 01:57:29 +0100
Subject: [PATCH 02/34] Feat (Map) : Add Query

---
 package.json                                |    2 +-
 pnpm-lock.yaml                              | 1231 ++++++++++++++++++-
 src/components/stepEditor/MapStepEditor.tsx |  132 +-
 src/pages/map/MapPage.tsx                   |  176 ++-
 4 files changed, 1472 insertions(+), 69 deletions(-)

diff --git a/package.json b/package.json
index 7258e8f..92a6725 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
     "updateClientApi": "pnpm update @FullStackMap/from-a2b"
   },
   "dependencies": {
-    "@FullStackMap/from-a2b": "0.5.6-Alpha",
+    "@FullStackMap/from-a2b": "0.16.0-Beta",
     "@mantine/carousel": "^7.6.2",
     "@mantine/core": "^7.6.2",
     "@mantine/form": "^7.6.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6b93aa3..2107688 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -6,8 +6,8 @@ settings:
 
 dependencies:
   '@FullStackMap/from-a2b':
-    specifier: 0.5.6-Alpha
-    version: 0.5.6-Alpha
+    specifier: 0.16.0-Beta
+    version: 0.16.0-Beta
   '@mantine/carousel':
     specifier: ^7.6.2
     version: 7.6.2(@mantine/core@7.6.2)(@mantine/hooks@7.6.2)(embla-carousel-react@7.1.0)(react-dom@18.2.0)(react@18.2.0)
@@ -124,7 +124,7 @@ dependencies:
     version: 6.22.3(react-dom@18.2.0)(react@18.2.0)
   react-scripts:
     specifier: 5.0.1
-    version: 5.0.1(@babel/plugin-syntax-flow@7.23.3)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(react@18.2.0)(sass@1.72.0)(typescript@5.4.2)
+    version: 5.0.1(@babel/plugin-syntax-flow@7.24.1)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(react@18.2.0)(sass@1.72.0)(typescript@5.4.2)
   sass:
     specifier: ^1.71.1
     version: 1.72.0
@@ -157,8 +157,8 @@ devDependencies:
 
 packages:
 
-  /@FullStackMap/from-a2b@0.5.6-Alpha:
-    resolution: {integrity: sha512-3RRox4b31Q7RXWEo/4jPZs/Mugl4KSbcsOUheBYIm6mRkn0UCSQAdBVzStDMqmzxaqaz/764/YqUN1Ij/kgewA==, tarball: https://npm.pkg.github.com/download/@FullStackMap/from-a2b/0.5.6-Alpha/fbbe94dec2c8e7abbc17619b3e5963b643d4a573}
+  /@FullStackMap/from-a2b@0.16.0-Beta:
+    resolution: {integrity: sha512-l1GhLNkqxUrIz8uzMA7vixcPMy2d1M/Byo78RKaTWDqBNoMO5Y0zRbvQUVEjtr4N0PHuQlyZiO6PveOuQyTcwg==, tarball: https://npm.pkg.github.com/download/@FullStackMap/from-a2b/0.16.0-Beta/9f2ffc27e865a37b617886e16788e0f1a073d0b1}
     dependencies:
       axios: 1.6.8
     transitivePeerDependencies:
@@ -204,10 +204,23 @@ packages:
       '@babel/highlight': 7.23.4
       chalk: 2.4.2
 
+  /@babel/code-frame@7.24.2:
+    resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/highlight': 7.24.2
+      picocolors: 1.0.0
+    dev: true
+
   /@babel/compat-data@7.23.5:
     resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==}
     engines: {node: '>=6.9.0'}
 
+  /@babel/compat-data@7.24.1:
+    resolution: {integrity: sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
   /@babel/core@7.24.0:
     resolution: {integrity: sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==}
     engines: {node: '>=6.9.0'}
@@ -229,6 +242,30 @@ packages:
       semver: 6.3.1
     transitivePeerDependencies:
       - supports-color
+    dev: false
+
+  /@babel/core@7.24.3:
+    resolution: {integrity: sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@ampproject/remapping': 2.3.0
+      '@babel/code-frame': 7.24.2
+      '@babel/generator': 7.24.1
+      '@babel/helper-compilation-targets': 7.23.6
+      '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3)
+      '@babel/helpers': 7.24.1
+      '@babel/parser': 7.24.1
+      '@babel/template': 7.24.0
+      '@babel/traverse': 7.24.1
+      '@babel/types': 7.24.0
+      convert-source-map: 2.0.0
+      debug: 4.3.4
+      gensync: 1.0.0-beta.2
+      json5: 2.2.3
+      semver: 6.3.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
 
   /@babel/eslint-parser@7.23.10(@babel/core@7.24.0)(eslint@8.57.0):
     resolution: {integrity: sha512-3wSYDPZVnhseRnxRJH6ZVTNknBz76AEnyC+AYYhasjP3Yy23qz0ERR7Fcd2SHmYuSFJ2kY9gaaDd3vyqU09eSw==}
@@ -252,6 +289,17 @@ packages:
       '@jridgewell/gen-mapping': 0.3.5
       '@jridgewell/trace-mapping': 0.3.25
       jsesc: 2.5.2
+    dev: false
+
+  /@babel/generator@7.24.1:
+    resolution: {integrity: sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.24.0
+      '@jridgewell/gen-mapping': 0.3.5
+      '@jridgewell/trace-mapping': 0.3.25
+      jsesc: 2.5.2
+    dev: true
 
   /@babel/helper-annotate-as-pure@7.22.5:
     resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==}
@@ -291,6 +339,25 @@ packages:
       '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
       '@babel/helper-split-export-declaration': 7.22.6
       semver: 6.3.1
+    dev: false
+
+  /@babel/helper-create-class-features-plugin@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-annotate-as-pure': 7.22.5
+      '@babel/helper-environment-visitor': 7.22.20
+      '@babel/helper-function-name': 7.23.0
+      '@babel/helper-member-expression-to-functions': 7.23.0
+      '@babel/helper-optimise-call-expression': 7.22.5
+      '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.3)
+      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+      '@babel/helper-split-export-declaration': 7.22.6
+      semver: 6.3.1
+    dev: true
 
   /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.24.0):
     resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==}
@@ -302,6 +369,19 @@ packages:
       '@babel/helper-annotate-as-pure': 7.22.5
       regexpu-core: 5.3.2
       semver: 6.3.1
+    dev: false
+
+  /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.24.3):
+    resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-annotate-as-pure': 7.22.5
+      regexpu-core: 5.3.2
+      semver: 6.3.1
+    dev: true
 
   /@babel/helper-define-polyfill-provider@0.5.0(@babel/core@7.24.0):
     resolution: {integrity: sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==}
@@ -316,6 +396,7 @@ packages:
       resolve: 1.22.8
     transitivePeerDependencies:
       - supports-color
+    dev: false
 
   /@babel/helper-define-polyfill-provider@0.6.1(@babel/core@7.24.0):
     resolution: {integrity: sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==}
@@ -330,6 +411,22 @@ packages:
       resolve: 1.22.8
     transitivePeerDependencies:
       - supports-color
+    dev: false
+
+  /@babel/helper-define-polyfill-provider@0.6.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==}
+    peerDependencies:
+      '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-compilation-targets': 7.23.6
+      '@babel/helper-plugin-utils': 7.24.0
+      debug: 4.3.4
+      lodash.debounce: 4.0.8
+      resolve: 1.22.8
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
 
   /@babel/helper-environment-visitor@7.22.20:
     resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==}
@@ -360,6 +457,13 @@ packages:
     dependencies:
       '@babel/types': 7.24.0
 
+  /@babel/helper-module-imports@7.24.3:
+    resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.24.0
+    dev: true
+
   /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==}
     engines: {node: '>=6.9.0'}
@@ -372,6 +476,21 @@ packages:
       '@babel/helper-simple-access': 7.22.5
       '@babel/helper-split-export-declaration': 7.22.6
       '@babel/helper-validator-identifier': 7.22.20
+    dev: false
+
+  /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.3):
+    resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-environment-visitor': 7.22.20
+      '@babel/helper-module-imports': 7.22.15
+      '@babel/helper-simple-access': 7.22.5
+      '@babel/helper-split-export-declaration': 7.22.6
+      '@babel/helper-validator-identifier': 7.22.20
+    dev: true
 
   /@babel/helper-optimise-call-expression@7.22.5:
     resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==}
@@ -393,6 +512,19 @@ packages:
       '@babel/helper-annotate-as-pure': 7.22.5
       '@babel/helper-environment-visitor': 7.22.20
       '@babel/helper-wrap-function': 7.22.20
+    dev: false
+
+  /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.24.3):
+    resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-annotate-as-pure': 7.22.5
+      '@babel/helper-environment-visitor': 7.22.20
+      '@babel/helper-wrap-function': 7.22.20
+    dev: true
 
   /@babel/helper-replace-supers@7.22.20(@babel/core@7.24.0):
     resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==}
@@ -404,6 +536,19 @@ packages:
       '@babel/helper-environment-visitor': 7.22.20
       '@babel/helper-member-expression-to-functions': 7.23.0
       '@babel/helper-optimise-call-expression': 7.22.5
+    dev: false
+
+  /@babel/helper-replace-supers@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-environment-visitor': 7.22.20
+      '@babel/helper-member-expression-to-functions': 7.23.0
+      '@babel/helper-optimise-call-expression': 7.22.5
+    dev: true
 
   /@babel/helper-simple-access@7.22.5:
     resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==}
@@ -452,6 +597,18 @@ packages:
       '@babel/types': 7.24.0
     transitivePeerDependencies:
       - supports-color
+    dev: false
+
+  /@babel/helpers@7.24.1:
+    resolution: {integrity: sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/template': 7.24.0
+      '@babel/traverse': 7.24.1
+      '@babel/types': 7.24.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
 
   /@babel/highlight@7.23.4:
     resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==}
@@ -461,6 +618,16 @@ packages:
       chalk: 2.4.2
       js-tokens: 4.0.0
 
+  /@babel/highlight@7.24.2:
+    resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/helper-validator-identifier': 7.22.20
+      chalk: 2.4.2
+      js-tokens: 4.0.0
+      picocolors: 1.0.0
+    dev: true
+
   /@babel/parser@7.24.0:
     resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==}
     engines: {node: '>=6.0.0'}
@@ -468,6 +635,14 @@ packages:
     dependencies:
       '@babel/types': 7.24.0
 
+  /@babel/parser@7.24.1:
+    resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==}
+    engines: {node: '>=6.0.0'}
+    hasBin: true
+    dependencies:
+      '@babel/types': 7.24.0
+    dev: true
+
   /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==}
     engines: {node: '>=6.9.0'}
@@ -476,6 +651,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==}
@@ -487,6 +673,19 @@ packages:
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
       '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.24.0)
+    dev: false
+
+  /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.13.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+      '@babel/plugin-transform-optional-chaining': 7.24.1(@babel/core@7.24.3)
+    dev: true
 
   /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.23.7(@babel/core@7.24.0):
     resolution: {integrity: sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==}
@@ -497,6 +696,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-environment-visitor': 7.22.20
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-environment-visitor': 7.22.20
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.24.0):
     resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==}
@@ -578,6 +789,16 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.24.0
+    dev: false
+
+  /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.3):
+    resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+    dev: true
 
   /@babel/plugin-proposal-private-property-in-object@7.21.11(@babel/core@7.24.0):
     resolution: {integrity: sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==}
@@ -600,6 +821,16 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.3):
+    resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
@@ -617,6 +848,16 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.3):
+    resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.0):
     resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==}
@@ -626,6 +867,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.3):
+    resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-decorators@7.24.0(@babel/core@7.24.0):
     resolution: {integrity: sha512-MXW3pQCu9gUiVGzqkGqsgiINDVYXoAnrY8FYF/rmb+OfufNF0zHMpHPN4ulRrinxYT8Vk/aZJxYqOKsDECjKAw==}
@@ -644,6 +896,16 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.3):
+    resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
@@ -652,6 +914,16 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.3):
+    resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-flow@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==}
@@ -663,6 +935,16 @@ packages:
       '@babel/helper-plugin-utils': 7.24.0
     dev: false
 
+  /@babel/plugin-syntax-flow@7.24.1(@babel/core@7.24.0):
+    resolution: {integrity: sha512-sxi2kLTI5DeW5vDtMUsk4mTPwvlUDbjOnoWayhynCwrw4QXRld4QEYwqzY8JmQXaJUtgUuCIurtSRH5sn4c7mA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.0
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
   /@babel/plugin-syntax-import-assertions@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==}
     engines: {node: '>=6.9.0'}
@@ -671,6 +953,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-import-assertions@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-import-attributes@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==}
@@ -680,6 +973,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-import-attributes@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.0):
     resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
@@ -688,6 +992,16 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.3):
+    resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
@@ -696,6 +1010,16 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.3):
+    resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==}
@@ -714,14 +1038,34 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
 
-  /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
+  /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.3):
+    resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
+    dev: true
+
+  /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.0):
+    resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.0
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.3):
+    resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.0):
     resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
@@ -730,6 +1074,16 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.3):
+    resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
@@ -738,6 +1092,16 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.3):
+    resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
@@ -746,6 +1110,16 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.3):
+    resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
@@ -754,6 +1128,16 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.3):
+    resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.0):
     resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==}
@@ -763,6 +1147,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.3):
+    resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.0):
     resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
@@ -772,6 +1167,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.3):
+    resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==}
@@ -792,6 +1198,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.3):
+    resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3)
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-arrow-functions@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==}
@@ -801,6 +1219,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-arrow-functions@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-async-generator-functions@7.23.9(@babel/core@7.24.0):
     resolution: {integrity: sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==}
@@ -813,6 +1242,20 @@ packages:
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.0)
       '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.0)
+    dev: false
+
+  /@babel/plugin-transform-async-generator-functions@7.24.3(@babel/core@7.24.3):
+    resolution: {integrity: sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-environment-visitor': 7.22.20
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.3)
+      '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.3)
+    dev: true
 
   /@babel/plugin-transform-async-to-generator@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==}
@@ -824,6 +1267,19 @@ packages:
       '@babel/helper-module-imports': 7.22.15
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.0)
+    dev: false
+
+  /@babel/plugin-transform-async-to-generator@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-module-imports': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.3)
+    dev: true
 
   /@babel/plugin-transform-block-scoped-functions@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==}
@@ -833,6 +1289,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-block-scoped-functions@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-block-scoping@7.23.4(@babel/core@7.24.0):
     resolution: {integrity: sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==}
@@ -842,6 +1309,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-block-scoping@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-h71T2QQvDgM2SmT29UYU6ozjMlAt7s7CSs5Hvy8f8cf/GM/Z4a2zMfN+fjVGaieeCrXR3EdQl6C4gQG+OgmbKw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-class-properties@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==}
@@ -852,6 +1330,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0)
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-class-properties@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3)
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-class-static-block@7.23.4(@babel/core@7.24.0):
     resolution: {integrity: sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==}
@@ -863,6 +1353,19 @@ packages:
       '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0)
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.0)
+    dev: false
+
+  /@babel/plugin-transform-class-static-block@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-FUHlKCn6J3ERiu8Dv+4eoz7w8+kFLSyeVG4vDAikwADGjUCoHw/JHokyGtr8OR4UjpwPVivyF+h8Q5iv/JmrtA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.12.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3)
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.3)
+    dev: true
 
   /@babel/plugin-transform-classes@7.23.8(@babel/core@7.24.0):
     resolution: {integrity: sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==}
@@ -879,6 +1382,24 @@ packages:
       '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.0)
       '@babel/helper-split-export-declaration': 7.22.6
       globals: 11.12.0
+    dev: false
+
+  /@babel/plugin-transform-classes@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-annotate-as-pure': 7.22.5
+      '@babel/helper-compilation-targets': 7.23.6
+      '@babel/helper-environment-visitor': 7.22.20
+      '@babel/helper-function-name': 7.23.0
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.3)
+      '@babel/helper-split-export-declaration': 7.22.6
+      globals: 11.12.0
+    dev: true
 
   /@babel/plugin-transform-computed-properties@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==}
@@ -889,6 +1410,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/template': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-computed-properties@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/template': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-destructuring@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==}
@@ -898,6 +1431,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-destructuring@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-dotall-regex@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==}
@@ -908,6 +1452,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-dotall-regex@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3)
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-duplicate-keys@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==}
@@ -917,6 +1473,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-duplicate-keys@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-dynamic-import@7.23.4(@babel/core@7.24.0):
     resolution: {integrity: sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==}
@@ -927,6 +1494,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.0)
+    dev: false
+
+  /@babel/plugin-transform-dynamic-import@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.3)
+    dev: true
 
   /@babel/plugin-transform-exponentiation-operator@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==}
@@ -937,6 +1516,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-exponentiation-operator@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-export-namespace-from@7.23.4(@babel/core@7.24.0):
     resolution: {integrity: sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==}
@@ -947,6 +1538,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.0)
+    dev: false
+
+  /@babel/plugin-transform-export-namespace-from@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.3)
+    dev: true
 
   /@babel/plugin-transform-flow-strip-types@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==}
@@ -968,6 +1571,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+    dev: false
+
+  /@babel/plugin-transform-for-of@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+    dev: true
 
   /@babel/plugin-transform-function-name@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==}
@@ -979,6 +1594,19 @@ packages:
       '@babel/helper-compilation-targets': 7.23.6
       '@babel/helper-function-name': 7.23.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-function-name@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-compilation-targets': 7.23.6
+      '@babel/helper-function-name': 7.23.0
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-json-strings@7.23.4(@babel/core@7.24.0):
     resolution: {integrity: sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==}
@@ -989,6 +1617,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.0)
+    dev: false
+
+  /@babel/plugin-transform-json-strings@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.3)
+    dev: true
 
   /@babel/plugin-transform-literals@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==}
@@ -998,6 +1638,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-literals@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-logical-assignment-operators@7.23.4(@babel/core@7.24.0):
     resolution: {integrity: sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==}
@@ -1008,6 +1659,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.0)
+    dev: false
+
+  /@babel/plugin-transform-logical-assignment-operators@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.3)
+    dev: true
 
   /@babel/plugin-transform-member-expression-literals@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==}
@@ -1017,6 +1680,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-member-expression-literals@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-modules-amd@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==}
@@ -1027,6 +1701,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-modules-amd@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3)
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==}
@@ -1038,6 +1724,19 @@ packages:
       '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-simple-access': 7.22.5
+    dev: false
+
+  /@babel/plugin-transform-modules-commonjs@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3)
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/helper-simple-access': 7.22.5
+    dev: true
 
   /@babel/plugin-transform-modules-systemjs@7.23.9(@babel/core@7.24.0):
     resolution: {integrity: sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==}
@@ -1050,6 +1749,20 @@ packages:
       '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-validator-identifier': 7.22.20
+    dev: false
+
+  /@babel/plugin-transform-modules-systemjs@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-hoist-variables': 7.22.5
+      '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3)
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/helper-validator-identifier': 7.22.20
+    dev: true
 
   /@babel/plugin-transform-modules-umd@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==}
@@ -1060,6 +1773,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-modules-umd@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3)
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.24.0):
     resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==}
@@ -1070,6 +1795,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.24.3):
+    resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3)
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-new-target@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==}
@@ -1079,6 +1816,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-new-target@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-nullish-coalescing-operator@7.23.4(@babel/core@7.24.0):
     resolution: {integrity: sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==}
@@ -1089,6 +1837,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0)
+    dev: false
+
+  /@babel/plugin-transform-nullish-coalescing-operator@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.3)
+    dev: true
 
   /@babel/plugin-transform-numeric-separator@7.23.4(@babel/core@7.24.0):
     resolution: {integrity: sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==}
@@ -1096,9 +1856,21 @@ packages:
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.0
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.0)
+    dev: false
+
+  /@babel/plugin-transform-numeric-separator@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.0)
+      '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.3)
+    dev: true
 
   /@babel/plugin-transform-object-rest-spread@7.24.0(@babel/core@7.24.0):
     resolution: {integrity: sha512-y/yKMm7buHpFFXfxVFS4Vk1ToRJDilIa6fKRioB9Vjichv58TDGXTvqV0dN7plobAmTW5eSEGXDngE+Mm+uO+w==}
@@ -1112,6 +1884,20 @@ packages:
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.0)
       '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.24.0)
+    dev: false
+
+  /@babel/plugin-transform-object-rest-spread@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-compilation-targets': 7.23.6
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.3)
+      '@babel/plugin-transform-parameters': 7.24.1(@babel/core@7.24.3)
+    dev: true
 
   /@babel/plugin-transform-object-super@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==}
@@ -1122,6 +1908,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.0)
+    dev: false
+
+  /@babel/plugin-transform-object-super@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.3)
+    dev: true
 
   /@babel/plugin-transform-optional-catch-binding@7.23.4(@babel/core@7.24.0):
     resolution: {integrity: sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==}
@@ -1132,6 +1930,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.0)
+    dev: false
+
+  /@babel/plugin-transform-optional-catch-binding@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.3)
+    dev: true
 
   /@babel/plugin-transform-optional-chaining@7.23.4(@babel/core@7.24.0):
     resolution: {integrity: sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==}
@@ -1143,6 +1953,19 @@ packages:
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
       '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0)
+    dev: false
+
+  /@babel/plugin-transform-optional-chaining@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+      '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.3)
+    dev: true
 
   /@babel/plugin-transform-parameters@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==}
@@ -1152,6 +1975,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-parameters@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-private-methods@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==}
@@ -1162,6 +1996,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0)
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-private-methods@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3)
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-private-property-in-object@7.23.4(@babel/core@7.24.0):
     resolution: {integrity: sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==}
@@ -1174,6 +2020,20 @@ packages:
       '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0)
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.0)
+    dev: false
+
+  /@babel/plugin-transform-private-property-in-object@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-annotate-as-pure': 7.22.5
+      '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3)
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.3)
+    dev: true
 
   /@babel/plugin-transform-property-literals@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==}
@@ -1183,6 +2043,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-property-literals@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-react-constant-elements@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-zP0QKq/p6O42OL94udMgSfKXyse4RyJ0JqbQ34zDAONWjyrEsghYEyTSK5FIpmXmCpB55SHokL1cRRKHv8L2Qw==}
@@ -1268,6 +2139,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
       regenerator-transform: 0.15.2
+    dev: false
+
+  /@babel/plugin-transform-regenerator@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+      regenerator-transform: 0.15.2
+    dev: true
 
   /@babel/plugin-transform-reserved-words@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==}
@@ -1277,6 +2160,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-reserved-words@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-runtime@7.24.0(@babel/core@7.24.0):
     resolution: {integrity: sha512-zc0GA5IitLKJrSfXlXmp8KDqLrnGECK7YRfQBmEKg1NmBOQ7e+KuclBEKJgzifQeUYLdNiAw4B4bjyvzWVLiSA==}
@@ -1303,6 +2197,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-shorthand-properties@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-spread@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==}
@@ -1313,6 +2218,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+    dev: false
+
+  /@babel/plugin-transform-spread@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
+    dev: true
 
   /@babel/plugin-transform-sticky-regex@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==}
@@ -1322,6 +2239,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-sticky-regex@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-template-literals@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==}
@@ -1331,6 +2259,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-template-literals@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-typeof-symbol@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==}
@@ -1340,6 +2279,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-typeof-symbol@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-typescript@7.23.6(@babel/core@7.24.0):
     resolution: {integrity: sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==}
@@ -1362,6 +2312,17 @@ packages:
     dependencies:
       '@babel/core': 7.24.0
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-unicode-escapes@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-unicode-property-regex@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==}
@@ -1372,6 +2333,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-unicode-property-regex@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3)
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-unicode-regex@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==}
@@ -1382,6 +2355,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-unicode-regex@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3)
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/plugin-transform-unicode-sets-regex@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==}
@@ -1392,6 +2377,18 @@ packages:
       '@babel/core': 7.24.0
       '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
       '@babel/helper-plugin-utils': 7.24.0
+    dev: false
+
+  /@babel/plugin-transform-unicode-sets-regex@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3)
+      '@babel/helper-plugin-utils': 7.24.0
+    dev: true
 
   /@babel/preset-env@7.24.0(@babel/core@7.24.0):
     resolution: {integrity: sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA==}
@@ -1482,6 +2479,98 @@ packages:
       semver: 6.3.1
     transitivePeerDependencies:
       - supports-color
+    dev: false
+
+  /@babel/preset-env@7.24.3(@babel/core@7.24.3):
+    resolution: {integrity: sha512-fSk430k5c2ff8536JcPvPWK4tZDwehWLGlBp0wrsBUjZVdeQV6lePbwKWZaZfK2vnh/1kQX1PzAJWsnBmVgGJA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/compat-data': 7.24.1
+      '@babel/core': 7.24.3
+      '@babel/helper-compilation-targets': 7.23.6
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/helper-validator-option': 7.23.5
+      '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.3)
+      '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.3)
+      '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.3)
+      '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.3)
+      '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.3)
+      '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.3)
+      '@babel/plugin-syntax-import-assertions': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-syntax-import-attributes': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.3)
+      '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.3)
+      '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.3)
+      '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.3)
+      '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.3)
+      '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.3)
+      '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.3)
+      '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.3)
+      '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.3)
+      '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.3)
+      '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.3)
+      '@babel/plugin-transform-arrow-functions': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-async-generator-functions': 7.24.3(@babel/core@7.24.3)
+      '@babel/plugin-transform-async-to-generator': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-block-scoped-functions': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-block-scoping': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-class-properties': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-class-static-block': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-classes': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-computed-properties': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-destructuring': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-dotall-regex': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-duplicate-keys': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-dynamic-import': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-exponentiation-operator': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-export-namespace-from': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-for-of': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-function-name': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-json-strings': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-literals': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-logical-assignment-operators': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-member-expression-literals': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-modules-amd': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-modules-systemjs': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-modules-umd': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.24.3)
+      '@babel/plugin-transform-new-target': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-nullish-coalescing-operator': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-numeric-separator': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-object-rest-spread': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-object-super': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-optional-catch-binding': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-optional-chaining': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-parameters': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-private-methods': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-private-property-in-object': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-property-literals': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-regenerator': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-reserved-words': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-shorthand-properties': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-spread': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-sticky-regex': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-template-literals': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-typeof-symbol': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-unicode-escapes': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-unicode-property-regex': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-unicode-regex': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-unicode-sets-regex': 7.24.1(@babel/core@7.24.3)
+      '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.3)
+      babel-plugin-polyfill-corejs2: 0.4.10(@babel/core@7.24.3)
+      babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.3)
+      babel-plugin-polyfill-regenerator: 0.6.1(@babel/core@7.24.3)
+      core-js-compat: 3.36.1
+      semver: 6.3.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
 
   /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.0):
     resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==}
@@ -1492,6 +2581,18 @@ packages:
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/types': 7.24.0
       esutils: 2.0.3
+    dev: false
+
+  /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.3):
+    resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-plugin-utils': 7.24.0
+      '@babel/types': 7.24.0
+      esutils: 2.0.3
+    dev: true
 
   /@babel/preset-react@7.23.3(@babel/core@7.24.0):
     resolution: {integrity: sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==}
@@ -1531,6 +2632,13 @@ packages:
     dependencies:
       regenerator-runtime: 0.14.1
 
+  /@babel/runtime@7.24.1:
+    resolution: {integrity: sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      regenerator-runtime: 0.14.1
+    dev: true
+
   /@babel/template@7.24.0:
     resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==}
     engines: {node: '>=6.9.0'}
@@ -1555,6 +2663,25 @@ packages:
       globals: 11.12.0
     transitivePeerDependencies:
       - supports-color
+    dev: false
+
+  /@babel/traverse@7.24.1:
+    resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/code-frame': 7.24.2
+      '@babel/generator': 7.24.1
+      '@babel/helper-environment-visitor': 7.22.20
+      '@babel/helper-function-name': 7.23.0
+      '@babel/helper-hoist-variables': 7.22.5
+      '@babel/helper-split-export-declaration': 7.22.6
+      '@babel/parser': 7.24.1
+      '@babel/types': 7.24.0
+      debug: 4.3.4
+      globals: 11.12.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
 
   /@babel/types@7.24.0:
     resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==}
@@ -2541,6 +3668,24 @@ packages:
       '@babel/helper-module-imports': 7.22.15
       '@rollup/pluginutils': 3.1.0(rollup@2.79.1)
       rollup: 2.79.1
+    dev: false
+
+  /@rollup/plugin-babel@5.3.1(@babel/core@7.24.3)(rollup@2.79.1):
+    resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
+    engines: {node: '>= 10.0.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+      '@types/babel__core': ^7.1.9
+      rollup: ^1.20.0||^2.0.0
+    peerDependenciesMeta:
+      '@types/babel__core':
+        optional: true
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-module-imports': 7.22.15
+      '@rollup/pluginutils': 3.1.0(rollup@2.79.1)
+      rollup: 2.79.1
+    dev: true
 
   /@rollup/plugin-node-resolve@11.2.1(rollup@2.79.1):
     resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==}
@@ -4050,6 +5195,32 @@ packages:
       semver: 6.3.1
     transitivePeerDependencies:
       - supports-color
+    dev: false
+
+  /babel-plugin-polyfill-corejs2@0.4.10(@babel/core@7.24.3):
+    resolution: {integrity: sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==}
+    peerDependencies:
+      '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
+    dependencies:
+      '@babel/compat-data': 7.23.5
+      '@babel/core': 7.24.3
+      '@babel/helper-define-polyfill-provider': 0.6.1(@babel/core@7.24.3)
+      semver: 6.3.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.24.3):
+    resolution: {integrity: sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==}
+    peerDependencies:
+      '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-define-polyfill-provider': 0.6.1(@babel/core@7.24.3)
+      core-js-compat: 3.36.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
 
   /babel-plugin-polyfill-corejs3@0.9.0(@babel/core@7.24.0):
     resolution: {integrity: sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==}
@@ -4061,6 +5232,7 @@ packages:
       core-js-compat: 3.36.0
     transitivePeerDependencies:
       - supports-color
+    dev: false
 
   /babel-plugin-polyfill-regenerator@0.5.5(@babel/core@7.24.0):
     resolution: {integrity: sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==}
@@ -4071,6 +5243,18 @@ packages:
       '@babel/helper-define-polyfill-provider': 0.5.0(@babel/core@7.24.0)
     transitivePeerDependencies:
       - supports-color
+    dev: false
+
+  /babel-plugin-polyfill-regenerator@0.6.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==}
+    peerDependencies:
+      '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
+    dependencies:
+      '@babel/core': 7.24.3
+      '@babel/helper-define-polyfill-provider': 0.6.1(@babel/core@7.24.3)
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
 
   /babel-plugin-transform-react-remove-prop-types@0.4.24:
     resolution: {integrity: sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==}
@@ -4622,6 +5806,13 @@ packages:
     resolution: {integrity: sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==}
     dependencies:
       browserslist: 4.23.0
+    dev: false
+
+  /core-js-compat@3.36.1:
+    resolution: {integrity: sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==}
+    dependencies:
+      browserslist: 4.23.0
+    dev: true
 
   /core-js-pure@3.36.0:
     resolution: {integrity: sha512-cN28qmhRNgbMZZMc/RFu5w8pK9VJzpb2rJVR/lHuZJKwmXnoWOpXmMkxqBB514igkp1Hu8WGROsiOAzUcKdHOQ==}
@@ -5595,7 +6786,7 @@ packages:
       source-map: 0.6.1
     dev: false
 
-  /eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.23.3)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(jest@27.5.1)(typescript@5.4.2):
+  /eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.24.1)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(jest@27.5.1)(typescript@5.4.2):
     resolution: {integrity: sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
@@ -5613,7 +6804,7 @@ packages:
       babel-preset-react-app: 10.0.1
       confusing-browser-globals: 1.0.11
       eslint: 8.57.0
-      eslint-plugin-flowtype: 8.0.3(@babel/plugin-syntax-flow@7.23.3)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)
+      eslint-plugin-flowtype: 8.0.3(@babel/plugin-syntax-flow@7.24.1)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)
       eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)
       eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.62.0)(eslint@8.57.0)(jest@27.5.1)(typescript@5.4.2)
       eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0)
@@ -5669,7 +6860,7 @@ packages:
       - supports-color
     dev: false
 
-  /eslint-plugin-flowtype@8.0.3(@babel/plugin-syntax-flow@7.23.3)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0):
+  /eslint-plugin-flowtype@8.0.3(@babel/plugin-syntax-flow@7.24.1)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0):
     resolution: {integrity: sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==}
     engines: {node: '>=12.0.0'}
     peerDependencies:
@@ -5677,7 +6868,7 @@ packages:
       '@babel/plugin-transform-react-jsx': ^7.14.9
       eslint: ^8.1.0
     dependencies:
-      '@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.24.0)
+      '@babel/plugin-syntax-flow': 7.24.1(@babel/core@7.24.0)
       '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.24.0)
       eslint: 8.57.0
       lodash: 4.17.21
@@ -9895,7 +11086,7 @@ packages:
       react: 18.2.0
     dev: false
 
-  /react-scripts@5.0.1(@babel/plugin-syntax-flow@7.23.3)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(react@18.2.0)(sass@1.72.0)(typescript@5.4.2):
+  /react-scripts@5.0.1(@babel/plugin-syntax-flow@7.24.1)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(react@18.2.0)(sass@1.72.0)(typescript@5.4.2):
     resolution: {integrity: sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==}
     engines: {node: '>=14.0.0'}
     hasBin: true
@@ -9923,7 +11114,7 @@ packages:
       dotenv: 10.0.0
       dotenv-expand: 5.1.0
       eslint: 8.57.0
-      eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.23.3)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(jest@27.5.1)(typescript@5.4.2)
+      eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.24.1)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(jest@27.5.1)(typescript@5.4.2)
       eslint-webpack-plugin: 3.2.0(eslint@8.57.0)(webpack@5.90.3)
       file-loader: 6.2.0(webpack@5.90.3)
       fs-extra: 10.1.0
@@ -12124,10 +13315,10 @@ packages:
     engines: {node: '>=16.0.0'}
     dependencies:
       '@apideck/better-ajv-errors': 0.3.6(ajv@8.12.0)
-      '@babel/core': 7.24.0
-      '@babel/preset-env': 7.24.0(@babel/core@7.24.0)
-      '@babel/runtime': 7.24.0
-      '@rollup/plugin-babel': 5.3.1(@babel/core@7.24.0)(rollup@2.79.1)
+      '@babel/core': 7.24.3
+      '@babel/preset-env': 7.24.3(@babel/core@7.24.3)
+      '@babel/runtime': 7.24.1
+      '@rollup/plugin-babel': 5.3.1(@babel/core@7.24.3)(rollup@2.79.1)
       '@rollup/plugin-node-resolve': 11.2.1(rollup@2.79.1)
       '@rollup/plugin-replace': 2.4.2(rollup@2.79.1)
       '@surma/rollup-plugin-off-main-thread': 2.2.3
diff --git a/src/components/stepEditor/MapStepEditor.tsx b/src/components/stepEditor/MapStepEditor.tsx
index 7bd2af2..ac9f6bc 100644
--- a/src/components/stepEditor/MapStepEditor.tsx
+++ b/src/components/stepEditor/MapStepEditor.tsx
@@ -1,3 +1,4 @@
+import { StepDto } from '@FullStackMap/from-a2b';
 import { useDocumentTitle } from '@mantine/hooks';
 import { IconPinnedFilled } from '@tabler/icons-react';
 import { FeatureCollection, Position } from 'geojson';
@@ -13,7 +14,6 @@ import {
 } from 'react-map-gl';
 import { calculateRoad } from '../../services/api/MapboxController';
 
-
 export const MapStepEditor = () => {
   useDocumentTitle('From A2B - Map');
 
@@ -28,8 +28,87 @@ export const MapStepEditor = () => {
   });
 
   //Ensemble des points de passage du voyage
-  const [steps, setSteps] = useState([
+  const [steps, setSteps] = useState<StepDto[]>([
+    {
+      stepId: '1',
+      tripId: '1',
+      latitude: 45.73050608112574,
+      longitude: 4.860200783597507,
+    },
+    {
+      stepId: '2',
+      tripId: '1',
+      latitude: 46.123456,
+      longitude: 4.56789,
+    },
+    {
+      stepId: '3',
+      tripId: '1',
+      latitude: 47.234567,
+      longitude: 3.456789,
+    },
+    {
+      stepId: '4',
+      tripId: '1',
+      latitude: 48.345678,
+      longitude: 2.345678,
+    },
+    {
+      stepId: '5',
+      tripId: '1',
+      latitude: 49.456789,
+      longitude: 1.234567,
+    },
+    {
+      stepId: '6',
+      tripId: '1',
+      latitude: 50.56789,
+      longitude: 0.123456,
+    },
+    {
+      stepId: '7',
+      tripId: '1',
+      latitude: 51.678901,
+      longitude: -0.987654,
+    },
+    {
+      stepId: '8',
+      tripId: '1',
+      latitude: 52.789012,
+      longitude: -1.876543,
+    },
+    {
+      stepId: '9',
+      tripId: '1',
+      latitude: 53.890123,
+      longitude: -2.765432,
+    },
+    {
+      stepId: '10',
+      tripId: '1',
+      latitude: 54.901234,
+      longitude: -3.654321,
+    },
+    {
+      stepId: '11',
+      tripId: '1',
+      latitude: 55.912345,
+      longitude: -4.54321,
+    },
+    {
+      stepId: '12',
+      tripId: '1',
+      latitude: 56.923456,
+      longitude: -5.432109,
+    },
+    {
+      stepId: '13',
+      tripId: '1',
+      latitude: 57.934567,
+      longitude: -6.321098,
+    },
   ]);
+
   const [dto, setDto] = useState([
     // {
     //   start: [4.860200783597507, 45.73050608112574],
@@ -47,18 +126,17 @@ export const MapStepEditor = () => {
       //Calcul de l'itinéraire entre les points de passage
       //Doit être utilisé que si nécessaire, car il y a un quota de requêtes
       //l'ensemble des itinéraires sont stockés dans la base de données
-      console.log("les dto pour le road", dto[dto.length-1])
+      console.log('les dto pour le road', dto[dto.length - 1]);
       if (dto.length > 0) {
-        const lastDto = [dto[dto.length-1]]
+        const lastDto = [dto[dto.length - 1]];
         const road: Position[] = await calculateRoad('driving', lastDto);
-        console.log("road", road)
+        console.log('road', road);
         setRoads(prevRoads => prevRoads.concat(road));
-        console.log("roads", roads)
+        console.log('roads', roads);
       }
       // const road: Position[] = await calculateRoad('driving', dto);
       // setRoads(road);
       // console.log("roads", roads)
-
     })();
   }, [dto]);
   //#endregion
@@ -66,8 +144,8 @@ export const MapStepEditor = () => {
   //#region Memos
 
   let removePoint = (index: number) => {
-    console.log("remove", index)
-  }
+    console.log('remove', index);
+  };
 
   //Création des pins sur la carte pour chaque étape du voyage
   const pins = useMemo(() => {
@@ -75,13 +153,17 @@ export const MapStepEditor = () => {
       return (
         <Marker
           key={`stepMarker-${index}`}
-
           draggable={false}
           latitude={step.latitude ?? 0}
           longitude={step.longitude ?? 0}
           pitchAlignment="viewport"
           rotationAlignment="viewport">
-          <IconPinnedFilled color="teal" size={32} stroke={2} onClick={()=>removePoint(index)} />
+          <IconPinnedFilled
+            color="teal"
+            size={32}
+            stroke={2}
+            onClick={() => removePoint(index)}
+          />
         </Marker>
       );
     });
@@ -120,19 +202,29 @@ export const MapStepEditor = () => {
   };
 
   let addPoint = (evt: any) => {
-    console.log("hello", evt.lngLat)
+    console.log('hello', evt.lngLat);
     // @ts-ignore
-    setSteps([...steps, { latitude: evt.lngLat.lat, longitude: evt.lngLat.lng }])
-    console.log("steps", steps)
+    setSteps([
+      ...steps,
+      { latitude: evt.lngLat.lat, longitude: evt.lngLat.lng },
+    ]);
+    console.log('steps', steps);
     // @ts-ignore
-    if (steps.length > 0){
+    if (steps.length > 0) {
       // @ts-ignore
-      setDto([...dto, { start: [steps[steps.length-1].longitude, steps[steps.length-1].latitude], end: [evt.lngLat.lng, evt.lngLat.lat] }])
-      console.log("ddto", dto)
+      setDto([
+        ...dto,
+        {
+          start: [
+            steps[steps.length - 1].longitude,
+            steps[steps.length - 1].latitude,
+          ],
+          end: [evt.lngLat.lng, evt.lngLat.lat],
+        },
+      ]);
+      console.log('ddto', dto);
     }
-  }
-
-
+  };
 
   //#endregion
   return (
diff --git a/src/pages/map/MapPage.tsx b/src/pages/map/MapPage.tsx
index 0186736..18859a6 100644
--- a/src/pages/map/MapPage.tsx
+++ b/src/pages/map/MapPage.tsx
@@ -1,5 +1,8 @@
+import { StepDto, TravelDtoList, TripDto } from '@FullStackMap/from-a2b';
 import { useDocumentTitle } from '@mantine/hooks';
 import { IconPinnedFilled } from '@tabler/icons-react';
+import { useQuery } from '@tanstack/react-query';
+import { AxiosResponse } from 'axios';
 import { FeatureCollection, Position } from 'geojson';
 import React, { useEffect, useMemo, useState } from 'react';
 import {
@@ -11,11 +14,19 @@ import {
   ScaleControl,
   Source,
 } from 'react-map-gl';
+import { TripController } from '../../services/BaseApi';
 import { calculateRoad } from '../../services/api/MapboxController';
 
-
 const MapPage = () => {
   useDocumentTitle('From A2B - Map');
+  const tripId = '279ec620-7f7c-4f79-f276-08dc4df18256';
+  const { data: trips } = useQuery({
+    queryKey: ['Trip', tripId],
+    queryFn: async () =>
+      await TripController.getTripByIdGET(tripId).then(
+        (res: AxiosResponse<TripDto, any>) => res.data,
+      ),
+  });
 
   //#region States
   //Point de vu de l'utilisateur sur la carte, les valeurs renseignées seront l'endroit où la carte se positionnera au chargement de la page
@@ -28,8 +39,88 @@ const MapPage = () => {
   });
 
   //Ensemble des points de passage du voyage
-  const [steps, setSteps] = useState([
+  const [steps, setSteps] = useState<StepDto[]>([
+    {
+      stepId: 1,
+      tripId: '1',
+      latitude: 45.73050608112574,
+      longitude: 4.860200783597507,
+    },
+    {
+      stepId: 2,
+      tripId: '1',
+      latitude: 46.123456,
+      longitude: 4.56789,
+    },
+    {
+      stepId: 3,
+      tripId: '1',
+      latitude: 47.234567,
+      longitude: 3.456789,
+    },
+    {
+      stepId: 4,
+      tripId: '1',
+      latitude: 48.345678,
+      longitude: 2.345678,
+    },
+    {
+      stepId: 5,
+      tripId: '1',
+      latitude: 49.456789,
+      longitude: 1.234567,
+    },
+    {
+      stepId: 6,
+      tripId: '1',
+      latitude: 50.56789,
+      longitude: 0.123456,
+    },
+    {
+      stepId: 7,
+      tripId: '1',
+      latitude: 51.678901,
+      longitude: -0.987654,
+    },
+    {
+      stepId: 8,
+      tripId: '1',
+      latitude: 52.789012,
+      longitude: -1.876543,
+    },
+    {
+      stepId: 9,
+      tripId: '1',
+      latitude: 53.890123,
+      longitude: -2.765432,
+    },
+    {
+      stepId: 10,
+      tripId: '1',
+      latitude: 54.901234,
+      longitude: -3.654321,
+    },
+    {
+      stepId: 11,
+      tripId: '1',
+      latitude: 55.912345,
+      longitude: -4.54321,
+    },
+    {
+      stepId: 12,
+      tripId: '1',
+      latitude: 56.923456,
+      longitude: -5.432109,
+    },
+    {
+      stepId: 13,
+      tripId: '1',
+      latitude: 57.934567,
+      longitude: -6.321098,
+    },
   ]);
+  const [roads, setRoads] = useState<TravelDtoList[]>([]);
+
   const [dto, setDto] = useState([
     // {
     //   start: [4.860200783597507, 45.73050608112574],
@@ -38,36 +129,47 @@ const MapPage = () => {
     // Ajoutez d'autres coordonnées initiales ici si nécessaire
   ]);
 
-  const [roads, setRoads] = useState<Position[]>([]);
   //#endregion
 
   //#region Effects
+  useEffect(() => {
+    if (!trips) return;
+    setSteps(trips.steps as StepDto[]);
+    setRoads(trips.travels as TravelDtoList[]);
+    console.log('🚀 ~ useEffect ~ trips.steps:', trips.steps);
+    console.log('🚀 ~ useEffect ~ trips.travels:', trips.travels);
+    console.log(
+      trips.travels
+        ?.map(road => road.travelRoad?.roadCoordinates as unknown as Position[])
+        .join(',') as unknown as Position[],
+    );
+  }, [trips]);
+
   useEffect(() => {
     (async () => {
       //Calcul de l'itinéraire entre les points de passage
       //Doit être utilisé que si nécessaire, car il y a un quota de requêtes
       //l'ensemble des itinéraires sont stockés dans la base de données
-      console.log("les dto pour le road", dto[dto.length-1])
+      console.log('les dto pour le road', dto[dto.length - 1]);
       if (dto.length > 0) {
-      const lastDto = [dto[dto.length-1]]
-      const road: Position[] = await calculateRoad('driving', lastDto);
-        console.log("road", road)
-      setRoads(prevRoads => prevRoads.concat(road));
-      console.log("roads", roads)
-    }
+        const lastDto = [dto[dto.length - 1]];
+        const road: Position[] = await calculateRoad('driving', lastDto);
+        console.log('road', road);
+        setRoads(prevRoads => prevRoads.concat(road));
+        console.log('roads', roads);
+      }
       // const road: Position[] = await calculateRoad('driving', dto);
       // setRoads(road);
       // console.log("roads", roads)
-
     })();
   }, [dto]);
   //#endregion
 
   //#region Memos
 
-  let removePoint = (index: number) => {
-    console.log("remove", index)
-  }
+  const removePoint = (index: number) => {
+    console.log('remove', index);
+  };
 
   //Création des pins sur la carte pour chaque étape du voyage
   const pins = useMemo(() => {
@@ -75,13 +177,17 @@ const MapPage = () => {
       return (
         <Marker
           key={`stepMarker-${index}`}
-
           draggable={false}
           latitude={step.latitude ?? 0}
           longitude={step.longitude ?? 0}
           pitchAlignment="viewport"
           rotationAlignment="viewport">
-          <IconPinnedFilled color="teal" size={32} stroke={2} onClick={()=>removePoint(index)} />
+          <IconPinnedFilled
+            color="teal"
+            size={32}
+            stroke={2}
+            onClick={() => removePoint(index)}
+          />
         </Marker>
       );
     });
@@ -98,7 +204,11 @@ const MapPage = () => {
         type: 'Feature',
         geometry: {
           type: 'LineString',
-          coordinates: roads,
+          coordinates: roads
+            .map(
+              road => road.travelRoad?.roadCoordinates as unknown as Position[],
+            )
+            .join(',') as unknown as Position[],
         },
         properties: {},
       },
@@ -119,19 +229,29 @@ const MapPage = () => {
     },
   };
 
-  let addPoint = (evt: any) => {
-    console.log("hello", evt.lngLat)
+  const addPoint = (evt: any) => {
+    console.log('hello', evt.lngLat);
     // @ts-ignore
-    setSteps([...steps, { latitude: evt.lngLat.lat, longitude: evt.lngLat.lng }])
-    console.log("steps", steps)
+    setSteps([
+      ...steps,
+      { latitude: evt.lngLat.lat, longitude: evt.lngLat.lng },
+    ]);
+    console.log('steps', steps);
     // @ts-ignore
-      if (steps.length > 0){
-        setDto([...dto, { start: [steps[steps.length-1].longitude, steps[steps.length-1].latitude], end: [evt.lngLat.lng, evt.lngLat.lat] }])
-        console.log("ddto", dto)
-      }
-  }
-
-
+    if (steps.length > 0) {
+      setDto([
+        ...dto,
+        {
+          start: [
+            steps[steps.length - 1].longitude,
+            steps[steps.length - 1].latitude,
+          ],
+          end: [evt.lngLat.lng, evt.lngLat.lat],
+        },
+      ]);
+      console.log('ddto', dto);
+    }
+  };
 
   //#endregion
   return (

From 59c7e6e4a1c5b3a28a9d248d1d92e0290c7b6a5b Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Wed, 27 Mar 2024 23:10:54 +0100
Subject: [PATCH 03/34] Feat M'ap : UpdateLocation

---
 package.json              |   2 +-
 pnpm-lock.yaml            |   8 +-
 src/pages/map/MapPage.tsx | 223 +++++++++++++++++---------------------
 src/services/BaseApi.ts   |  29 ++---
 4 files changed, 120 insertions(+), 142 deletions(-)

diff --git a/package.json b/package.json
index 92a6725..070e173 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
     "updateClientApi": "pnpm update @FullStackMap/from-a2b"
   },
   "dependencies": {
-    "@FullStackMap/from-a2b": "0.16.0-Beta",
+    "@FullStackMap/from-a2b": "0.16.1-Alpha",
     "@mantine/carousel": "^7.6.2",
     "@mantine/core": "^7.6.2",
     "@mantine/form": "^7.6.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 2107688..bdc0afc 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -6,8 +6,8 @@ settings:
 
 dependencies:
   '@FullStackMap/from-a2b':
-    specifier: 0.16.0-Beta
-    version: 0.16.0-Beta
+    specifier: 0.16.1-Alpha
+    version: 0.16.1-Alpha
   '@mantine/carousel':
     specifier: ^7.6.2
     version: 7.6.2(@mantine/core@7.6.2)(@mantine/hooks@7.6.2)(embla-carousel-react@7.1.0)(react-dom@18.2.0)(react@18.2.0)
@@ -157,8 +157,8 @@ devDependencies:
 
 packages:
 
-  /@FullStackMap/from-a2b@0.16.0-Beta:
-    resolution: {integrity: sha512-l1GhLNkqxUrIz8uzMA7vixcPMy2d1M/Byo78RKaTWDqBNoMO5Y0zRbvQUVEjtr4N0PHuQlyZiO6PveOuQyTcwg==, tarball: https://npm.pkg.github.com/download/@FullStackMap/from-a2b/0.16.0-Beta/9f2ffc27e865a37b617886e16788e0f1a073d0b1}
+  /@FullStackMap/from-a2b@0.16.1-Alpha:
+    resolution: {integrity: sha512-lOeMF90UWX6USS1MlDB8VOLQg3U3OXMHOSTxKjHItCC3z3d4QBzgpbv05wd1e40CPYsA1sVsAM5u1GmKDlcx7A==, tarball: https://npm.pkg.github.com/download/@FullStackMap/from-a2b/0.16.1-Alpha/ed55b0586dea2d8c677cafd1310c1562b3c164a6}
     dependencies:
       axios: 1.6.8
     transitivePeerDependencies:
diff --git a/src/pages/map/MapPage.tsx b/src/pages/map/MapPage.tsx
index 18859a6..f4f6831 100644
--- a/src/pages/map/MapPage.tsx
+++ b/src/pages/map/MapPage.tsx
@@ -1,7 +1,13 @@
-import { StepDto, TravelDtoList, TripDto } from '@FullStackMap/from-a2b';
+import {
+  StepDto,
+  StepDtoList,
+  TravelDtoList,
+  TripDto,
+  UpdateStepLocationDto,
+} from '@FullStackMap/from-a2b';
 import { useDocumentTitle } from '@mantine/hooks';
 import { IconPinnedFilled } from '@tabler/icons-react';
-import { useQuery } from '@tanstack/react-query';
+import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
 import { AxiosResponse } from 'axios';
 import { FeatureCollection, Position } from 'geojson';
 import React, { useEffect, useMemo, useState } from 'react';
@@ -11,15 +17,26 @@ import {
   LayerProps,
   Map,
   Marker,
+  MarkerDragEvent,
   ScaleControl,
   Source,
 } from 'react-map-gl';
-import { TripController } from '../../services/BaseApi';
+import { StepController, TripController } from '../../services/BaseApi';
 import { calculateRoad } from '../../services/api/MapboxController';
 
+interface updateStepLocationMutationProps {
+  stepId: number;
+  updateStateLocationDto: UpdateStepLocationDto;
+}
+
 const MapPage = () => {
   useDocumentTitle('From A2B - Map');
-  const tripId = '279ec620-7f7c-4f79-f276-08dc4df18256';
+
+  //#region UseQuery
+
+  const queryClient = useQueryClient();
+
+  const tripId = 'E92913FE-5115-46BB-7A9C-08DC4E850E01';
   const { data: trips } = useQuery({
     queryKey: ['Trip', tripId],
     queryFn: async () =>
@@ -28,6 +45,27 @@ const MapPage = () => {
       ),
   });
 
+  // const deleteStepMutation = useMutation({
+  //   mutationFn: async (stepId: number) =>
+  //     await StepController.deleteStepByIdAsyncDELETE(stepId),
+  //   onSuccess: () => {
+  //     queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
+  //   },
+  // });
+
+  const updateStepLocationMutation = useMutation({
+    mutationFn: async (args: updateStepLocationMutationProps) =>
+      await StepController.updateStepLocationAsyncPATCH(
+        args.stepId,
+        args.updateStateLocationDto,
+      ).catch(err => console.error(err)),
+    onSuccess: () => {
+      queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
+    },
+  });
+
+  //#endregion
+
   //#region States
   //Point de vu de l'utilisateur sur la carte, les valeurs renseignées seront l'endroit où la carte se positionnera au chargement de la page
   const [viewState, setViewState] = React.useState({
@@ -39,86 +77,7 @@ const MapPage = () => {
   });
 
   //Ensemble des points de passage du voyage
-  const [steps, setSteps] = useState<StepDto[]>([
-    {
-      stepId: 1,
-      tripId: '1',
-      latitude: 45.73050608112574,
-      longitude: 4.860200783597507,
-    },
-    {
-      stepId: 2,
-      tripId: '1',
-      latitude: 46.123456,
-      longitude: 4.56789,
-    },
-    {
-      stepId: 3,
-      tripId: '1',
-      latitude: 47.234567,
-      longitude: 3.456789,
-    },
-    {
-      stepId: 4,
-      tripId: '1',
-      latitude: 48.345678,
-      longitude: 2.345678,
-    },
-    {
-      stepId: 5,
-      tripId: '1',
-      latitude: 49.456789,
-      longitude: 1.234567,
-    },
-    {
-      stepId: 6,
-      tripId: '1',
-      latitude: 50.56789,
-      longitude: 0.123456,
-    },
-    {
-      stepId: 7,
-      tripId: '1',
-      latitude: 51.678901,
-      longitude: -0.987654,
-    },
-    {
-      stepId: 8,
-      tripId: '1',
-      latitude: 52.789012,
-      longitude: -1.876543,
-    },
-    {
-      stepId: 9,
-      tripId: '1',
-      latitude: 53.890123,
-      longitude: -2.765432,
-    },
-    {
-      stepId: 10,
-      tripId: '1',
-      latitude: 54.901234,
-      longitude: -3.654321,
-    },
-    {
-      stepId: 11,
-      tripId: '1',
-      latitude: 55.912345,
-      longitude: -4.54321,
-    },
-    {
-      stepId: 12,
-      tripId: '1',
-      latitude: 56.923456,
-      longitude: -5.432109,
-    },
-    {
-      stepId: 13,
-      tripId: '1',
-      latitude: 57.934567,
-      longitude: -6.321098,
-    },
-  ]);
+  const [steps, setSteps] = useState<StepDto[]>([]);
   const [roads, setRoads] = useState<TravelDtoList[]>([]);
 
   const [dto, setDto] = useState([
@@ -134,15 +93,12 @@ const MapPage = () => {
   //#region Effects
   useEffect(() => {
     if (!trips) return;
-    setSteps(trips.steps as StepDto[]);
-    setRoads(trips.travels as TravelDtoList[]);
-    console.log('🚀 ~ useEffect ~ trips.steps:', trips.steps);
-    console.log('🚀 ~ useEffect ~ trips.travels:', trips.travels);
-    console.log(
-      trips.travels
-        ?.map(road => road.travelRoad?.roadCoordinates as unknown as Position[])
-        .join(',') as unknown as Position[],
+    setSteps(
+      trips.steps?.sort(
+        (a: StepDtoList, b: StepDtoList) => a.order! - b.order!,
+      ) as StepDto[],
     );
+    setRoads(trips.travels as TravelDtoList[]);
   }, [trips]);
 
   useEffect(() => {
@@ -171,13 +127,28 @@ const MapPage = () => {
     console.log('remove', index);
   };
 
+  const handleMoveMarker = (evt: MarkerDragEvent, stepId: number) => {
+    const updateStateLocationDto: UpdateStepLocationDto = {
+      latitude: evt.lngLat.lat,
+      longitude: evt.lngLat.lng,
+    };
+
+    updateStepLocationMutation.mutate({
+      stepId: stepId,
+      updateStateLocationDto,
+    });
+  };
+
   //Création des pins sur la carte pour chaque étape du voyage
   const pins = useMemo(() => {
     return steps.map((step, index) => {
       return (
         <Marker
-          key={`stepMarker-${index}`}
-          draggable={false}
+          key={step.stepId}
+          draggable
+          onDragEnd={(evn: MarkerDragEvent) =>
+            handleMoveMarker(evn, step.stepId as number)
+          }
           latitude={step.latitude ?? 0}
           longitude={step.longitude ?? 0}
           pitchAlignment="viewport"
@@ -204,11 +175,9 @@ const MapPage = () => {
         type: 'Feature',
         geometry: {
           type: 'LineString',
-          coordinates: roads
-            .map(
-              road => road.travelRoad?.roadCoordinates as unknown as Position[],
-            )
-            .join(',') as unknown as Position[],
+          coordinates: roads.flatMap(road =>
+            JSON.parse(road.travelRoad?.roadCoordinates as string),
+          ),
         },
         properties: {},
       },
@@ -229,37 +198,45 @@ const MapPage = () => {
     },
   };
 
-  const addPoint = (evt: any) => {
-    console.log('hello', evt.lngLat);
-    // @ts-ignore
-    setSteps([
-      ...steps,
-      { latitude: evt.lngLat.lat, longitude: evt.lngLat.lng },
-    ]);
-    console.log('steps', steps);
-    // @ts-ignore
-    if (steps.length > 0) {
-      setDto([
-        ...dto,
-        {
-          start: [
-            steps[steps.length - 1].longitude,
-            steps[steps.length - 1].latitude,
-          ],
-          end: [evt.lngLat.lng, evt.lngLat.lat],
-        },
-      ]);
-      console.log('ddto', dto);
-    }
-  };
+  // const addPoint = (evt: any) => {
+  //   console.log('hello', evt.lngLat);
+  //   // @ts-ignore
+  //   setSteps([
+  //     ...steps,
+  //     { latitude: evt.lngLat.lat, longitude: evt.lngLat.lng },
+  //   ]);
+  //   console.log('steps', steps);
+  //   // @ts-ignore
+  //   if (steps.length > 0) {
+  //     setDto([
+  //       ...dto,
+  //       {
+  //         start: [
+  //           steps[steps.length - 1].longitude,
+  //           steps[steps.length - 1].latitude,
+  //         ],
+  //         end: [evt.lngLat.lng, evt.lngLat.lat],
+  //       },
+  //     ]);
+  //     console.log('ddto', dto);
+  //   }
+  // };
 
   //#endregion
   return (
     <>
+      <ul>
+        {steps.map(step => (
+          <li key={step.stepId}>
+            {step.stepId} - {step.name} - {step.latitude} - {step.longitude}
+          </li>
+        ))}
+      </ul>
+
       <Map
         {...viewState}
         onMove={evt => setViewState(evt.viewState)}
-        onClick={addPoint}
+        // onClick={addPoint}
         minZoom={2}
         dragRotate={true}
         mapStyle="mapbox://styles/mapbox/streets-v12"
diff --git a/src/services/BaseApi.ts b/src/services/BaseApi.ts
index a95e627..52d4f80 100644
--- a/src/services/BaseApi.ts
+++ b/src/services/BaseApi.ts
@@ -9,6 +9,8 @@ const configAno = new client.Configuration({
   basePath: basePath,
 });
 
+export const AnoAuthController = client.AuthApiFactory(configAno);
+
 const TripControllerFunc = () => {
   const configLogged = new client.Configuration({
     basePath: basePath,
@@ -20,22 +22,21 @@ const TripControllerFunc = () => {
   });
   return client.TripApiFactory(configLogged);
 };
+export const TripController = TripControllerFunc();
 
-export const AnoAxiosClient = axios.create({
-  baseURL: basePath,
-});
-
-export const AxiosClient = axios.create({
-  baseURL: basePath,
-  headers: {
-    Authorization: `Bearer ${token}`,
-  },
-});
+const StepControllerFunc = () => {
+  const configLogged = new client.Configuration({
+    basePath: basePath,
+    baseOptions: {
+      headers: {
+        Authorization: `Bearer ${token}`,
+      },
+    },
+  });
+  return client.StepApiFactory(configLogged);
+};
+export const StepController = StepControllerFunc();
 
 export const MapboxClient = axios.create({
   baseURL: 'https://api.mapbox.com',
 });
-
-export const TripController = TripControllerFunc();
-
-export const AnoAuthController = client.AuthApiFactory(configAno);

From b3211a6856edf4bc4939144f6ea40f2504b37f45 Mon Sep 17 00:00:00 2001
From: Baptiste-Ferrand <baptiste.ferrand@ynov.com>
Date: Thu, 28 Mar 2024 00:19:33 +0100
Subject: [PATCH 04/34] add steps add useTripDetailsStore.ts and EditTravel.tsx
 as page add modal for adding and steps to travel

---
 .../createStepModal/CreateStepModal.tsx       | 93 +++++++++++++++++++
 src/pages/editTravel/EditTravel.tsx           | 12 +++
 src/store/useTripDetailsStore.ts              | 12 +++
 3 files changed, 117 insertions(+)
 create mode 100644 src/components/createStepModal/CreateStepModal.tsx
 create mode 100644 src/pages/editTravel/EditTravel.tsx
 create mode 100644 src/store/useTripDetailsStore.ts

diff --git a/src/components/createStepModal/CreateStepModal.tsx b/src/components/createStepModal/CreateStepModal.tsx
new file mode 100644
index 0000000..74f14ee
--- /dev/null
+++ b/src/components/createStepModal/CreateStepModal.tsx
@@ -0,0 +1,93 @@
+import { useDebouncedState } from '@mantine/hooks';
+import { Group, TextInput, Textarea, Modal, Button } from '@mantine/core'
+import { IconX } from '@tabler/icons-react'
+
+import { useForm } from '@mantine/form';
+import { zodResolver } from 'mantine-form-zod-resolver';
+import { z } from 'zod';
+
+import { useCreateStepModalStore } from '../../store/useTripDetailsStore.ts'
+
+export const CreateStepModal=()=> {
+
+  const [value, setValue] = useDebouncedState('', 200, { leading: true });
+
+  const isOpen = useCreateStepModalStore((state) => state.status);
+  const close = useCreateStepModalStore((state) => state.setStatus);
+
+  const stepSchema = z.object({
+    title: z.string().min(3, 'Le titre doit contenir au moins 3 caractères').max(50, 'Le titre doit contenir au maximum 50 caractères'),
+    description: z.string(),
+    destination: z.object({ place: z.string(), coordinates: z.array(z.number()) }),
+  });
+
+  const stepForm = useForm({
+    validateInputOnChange: true,
+    validate: zodResolver(stepSchema),
+    initialValues: {
+      title: '',
+      description: '',
+    },
+  });
+
+
+  return (
+      <Modal
+        opened={isOpen}
+        onClose={() => close(false)}
+        centered
+        title="Créer un voyage"
+        className="mantine-Modal-header"
+        closeOnClickOutside={false}
+        closeButtonProps={{
+          icon: <IconX size={24} stroke={2} />,
+        }}
+        overlayProps={{
+          backgroundOpacity: 0.55,
+          blur: 3,
+        }}>
+        <div className="img-modal"></div>
+        <form onReset={() => stepForm.reset()} className="form">
+          <TextInput
+            label="Titre de votre voyage"
+            placeholder="Titre"
+            required
+            data-autofocus
+            {...stepForm.getInputProps('title')}
+          />
+          <Textarea
+            mt="sm"
+            label="Description"
+            placeholder="Description"
+            {...stepForm.getInputProps('description')}
+          />
+
+          <TextInput
+            label="Destination"
+            defaultValue={value}
+            onChange={(event) => setValue(event.currentTarget.value)}
+          />
+
+
+          <Group justify="flex-end" mt="md">
+            <Button
+              type="submit"
+              mt="sm"
+              disabled={!stepForm.isValid()}
+              onClick={(event) => {
+                event.preventDefault();
+                createTravel.mutate({
+                  name: travelForm.values.title,
+                  description: travelForm.values.description,
+                  userId: userId,
+                  startDate: travelForm.values.dates[0] as unknown as string,
+                  endDate: travelForm.values.dates[1] as unknown as string,
+                });
+              }}>
+              Sauvegarder
+            </Button>
+          </Group>
+        </form>
+      </Modal>
+  );
+}
\ No newline at end of file
diff --git a/src/pages/editTravel/EditTravel.tsx b/src/pages/editTravel/EditTravel.tsx
new file mode 100644
index 0000000..0d5d9d3
--- /dev/null
+++ b/src/pages/editTravel/EditTravel.tsx
@@ -0,0 +1,12 @@
+import { Button } from '@mantine/core';
+
+export const EditTravel = () => {
+
+  return (
+      <div>
+
+        <Button variant="outline" color="yellow" size="lg" radius="xl">ADD</Button>
+      </div>
+    );
+
+}
\ No newline at end of file
diff --git a/src/store/useTripDetailsStore.ts b/src/store/useTripDetailsStore.ts
new file mode 100644
index 0000000..1ddee3e
--- /dev/null
+++ b/src/store/useTripDetailsStore.ts
@@ -0,0 +1,12 @@
+import {create} from 'zustand'
+
+export type CallCreateStepModal = {
+  status: boolean;
+  setStatus: (status: boolean) => void;
+}
+
+export const useCreateStepModalStore = create<CallCreateStepModal>((set) => ({
+  status: false,
+  setStatus: (status: boolean) => set({status}),
+}))
+

From d3e4e1dc4fc5d7f03b988c3a7d41aaa602a0a599 Mon Sep 17 00:00:00 2001
From: Baptiste-Ferrand <baptiste.ferrand@ynov.com>
Date: Thu, 28 Mar 2024 00:58:10 +0100
Subject: [PATCH 05/34] remove editTravel.tsx page

---
 src/pages/showTravels/editTravel/editTravel.tsx | 9 ---------
 1 file changed, 9 deletions(-)
 delete mode 100644 src/pages/showTravels/editTravel/editTravel.tsx

diff --git a/src/pages/showTravels/editTravel/editTravel.tsx b/src/pages/showTravels/editTravel/editTravel.tsx
deleted file mode 100644
index f064472..0000000
--- a/src/pages/showTravels/editTravel/editTravel.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { MapStepEditor } from '../../../components/stepEditor/MapStepEditor.tsx'
-export function EditTravel() {
-
-  return (
-    <div>
-      <MapStepEditor></MapStepEditor>
-    </div>
-  );
-}
\ No newline at end of file

From 4827cb4096a869a6560acadf978c17ed00d72ef2 Mon Sep 17 00:00:00 2001
From: Baptiste-Ferrand <baptiste.ferrand@ynov.com>
Date: Thu, 28 Mar 2024 00:59:12 +0100
Subject: [PATCH 06/34] add modal to MapStepEditor.tsx for create step

---
 .../createStepModal/CreateStepModal.tsx       |  23 +-
 .../MapStepEditor.tsx                         | 238 +++++++++---------
 src/pages/editTravel/EditTravel.tsx           |   7 +-
 3 files changed, 139 insertions(+), 129 deletions(-)
 rename src/components/{stepEditor => mapStepEditor}/MapStepEditor.tsx (50%)

diff --git a/src/components/createStepModal/CreateStepModal.tsx b/src/components/createStepModal/CreateStepModal.tsx
index 74f14ee..d093509 100644
--- a/src/components/createStepModal/CreateStepModal.tsx
+++ b/src/components/createStepModal/CreateStepModal.tsx
@@ -18,7 +18,7 @@ export const CreateStepModal=()=> {
   const stepSchema = z.object({
     title: z.string().min(3, 'Le titre doit contenir au moins 3 caractères').max(50, 'Le titre doit contenir au maximum 50 caractères'),
     description: z.string(),
-    destination: z.object({ place: z.string(), coordinates: z.array(z.number()) }),
+    // destination: z.object({ place: z.string(), coordinates: z.array(z.number()) }),
   });
 
   const stepForm = useForm({
@@ -36,7 +36,7 @@ export const CreateStepModal=()=> {
         opened={isOpen}
         onClose={() => close(false)}
         centered
-        title="Créer un voyage"
+        title="Créer une étape de vôtre voyage"
         className="mantine-Modal-header"
         closeOnClickOutside={false}
         closeButtonProps={{
@@ -49,7 +49,7 @@ export const CreateStepModal=()=> {
         <div className="img-modal"></div>
         <form onReset={() => stepForm.reset()} className="form">
           <TextInput
-            label="Titre de votre voyage"
+            label="Titre de votre étape"
             placeholder="Titre"
             required
             data-autofocus
@@ -65,25 +65,20 @@ export const CreateStepModal=()=> {
           <TextInput
             label="Destination"
             defaultValue={value}
-            onChange={(event) => setValue(event.currentTarget.value)}
+            onChange={(event) => {
+              setValue(event.currentTarget.value);
+              console.log(value);
+            }}
           />
 
 
           <Group justify="flex-end" mt="md">
+            <Button mt="sm" onClick={()=>close(false)}>Annuler</Button>
             <Button
               type="submit"
               mt="sm"
               disabled={!stepForm.isValid()}
-              onClick={(event) => {
-                event.preventDefault();
-                createTravel.mutate({
-                  name: travelForm.values.title,
-                  description: travelForm.values.description,
-                  userId: userId,
-                  startDate: travelForm.values.dates[0] as unknown as string,
-                  endDate: travelForm.values.dates[1] as unknown as string,
-                });
-              }}>
+              onClick={()=>console.log("sending")}>
               Sauvegarder
             </Button>
           </Group>
diff --git a/src/components/stepEditor/MapStepEditor.tsx b/src/components/mapStepEditor/MapStepEditor.tsx
similarity index 50%
rename from src/components/stepEditor/MapStepEditor.tsx
rename to src/components/mapStepEditor/MapStepEditor.tsx
index ac9f6bc..7aa24a5 100644
--- a/src/components/stepEditor/MapStepEditor.tsx
+++ b/src/components/mapStepEditor/MapStepEditor.tsx
@@ -1,6 +1,14 @@
-import { StepDto } from '@FullStackMap/from-a2b';
+import {
+  StepDto,
+  StepDtoList,
+  TravelDtoList,
+  TripDto,
+  UpdateStepLocationDto,
+} from '@FullStackMap/from-a2b';
 import { useDocumentTitle } from '@mantine/hooks';
 import { IconPinnedFilled } from '@tabler/icons-react';
+import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
+import { AxiosResponse } from 'axios';
 import { FeatureCollection, Position } from 'geojson';
 import React, { useEffect, useMemo, useState } from 'react';
 import {
@@ -9,14 +17,64 @@ import {
   LayerProps,
   Map,
   Marker,
+  MarkerDragEvent,
   ScaleControl,
   Source,
 } from 'react-map-gl';
+import { StepController, TripController } from '../../services/BaseApi';
 import { calculateRoad } from '../../services/api/MapboxController';
+import { Button } from '@mantine/core'
+
+import { useCreateStepModalStore } from '../../store/useTripDetailsStore.ts'
+
+interface updateStepLocationMutationProps {
+  stepId: number;
+  updateStateLocationDto: UpdateStepLocationDto;
+}
 
 export const MapStepEditor = () => {
   useDocumentTitle('From A2B - Map');
 
+  const setIsStepModalOpen = useCreateStepModalStore((state) => state.setStatus);
+
+  const handleCreateStep = ()=>{
+    setIsStepModalOpen(true);
+  }
+
+  //#region UseQuery
+
+  const queryClient = useQueryClient();
+
+  const tripId = 'E92913FE-5115-46BB-7A9C-08DC4E850E01';
+  const { data: trips } = useQuery({
+    queryKey: ['Trip', tripId],
+    queryFn: async () =>
+      await TripController.getTripByIdGET(tripId).then(
+        (res: AxiosResponse<TripDto, any>) => res.data,
+      ),
+  });
+
+  // const deleteStepMutation = useMutation({
+  //   mutationFn: async (stepId: number) =>
+  //     await StepController.deleteStepByIdAsyncDELETE(stepId),
+  //   onSuccess: () => {
+  //     queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
+  //   },
+  // });
+
+  const updateStepLocationMutation = useMutation({
+    mutationFn: async (args: updateStepLocationMutationProps) =>
+      await StepController.updateStepLocationAsyncPATCH(
+        args.stepId,
+        args.updateStateLocationDto,
+      ).catch(err => console.error(err)),
+    onSuccess: () => {
+      queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
+    },
+  });
+
+  //#endregion
+
   //#region States
   //Point de vu de l'utilisateur sur la carte, les valeurs renseignées seront l'endroit où la carte se positionnera au chargement de la page
   const [viewState, setViewState] = React.useState({
@@ -28,86 +86,8 @@ export const MapStepEditor = () => {
   });
 
   //Ensemble des points de passage du voyage
-  const [steps, setSteps] = useState<StepDto[]>([
-    {
-      stepId: '1',
-      tripId: '1',
-      latitude: 45.73050608112574,
-      longitude: 4.860200783597507,
-    },
-    {
-      stepId: '2',
-      tripId: '1',
-      latitude: 46.123456,
-      longitude: 4.56789,
-    },
-    {
-      stepId: '3',
-      tripId: '1',
-      latitude: 47.234567,
-      longitude: 3.456789,
-    },
-    {
-      stepId: '4',
-      tripId: '1',
-      latitude: 48.345678,
-      longitude: 2.345678,
-    },
-    {
-      stepId: '5',
-      tripId: '1',
-      latitude: 49.456789,
-      longitude: 1.234567,
-    },
-    {
-      stepId: '6',
-      tripId: '1',
-      latitude: 50.56789,
-      longitude: 0.123456,
-    },
-    {
-      stepId: '7',
-      tripId: '1',
-      latitude: 51.678901,
-      longitude: -0.987654,
-    },
-    {
-      stepId: '8',
-      tripId: '1',
-      latitude: 52.789012,
-      longitude: -1.876543,
-    },
-    {
-      stepId: '9',
-      tripId: '1',
-      latitude: 53.890123,
-      longitude: -2.765432,
-    },
-    {
-      stepId: '10',
-      tripId: '1',
-      latitude: 54.901234,
-      longitude: -3.654321,
-    },
-    {
-      stepId: '11',
-      tripId: '1',
-      latitude: 55.912345,
-      longitude: -4.54321,
-    },
-    {
-      stepId: '12',
-      tripId: '1',
-      latitude: 56.923456,
-      longitude: -5.432109,
-    },
-    {
-      stepId: '13',
-      tripId: '1',
-      latitude: 57.934567,
-      longitude: -6.321098,
-    },
-  ]);
+  const [steps, setSteps] = useState<StepDto[]>([]);
+  const [roads, setRoads] = useState<TravelDtoList[]>([]);
 
   const [dto, setDto] = useState([
     // {
@@ -117,10 +97,19 @@ export const MapStepEditor = () => {
     // Ajoutez d'autres coordonnées initiales ici si nécessaire
   ]);
 
-  const [roads, setRoads] = useState<Position[]>([]);
   //#endregion
 
   //#region Effects
+  useEffect(() => {
+    if (!trips) return;
+    setSteps(
+      trips.steps?.sort(
+        (a: StepDtoList, b: StepDtoList) => a.order! - b.order!,
+      ) as StepDto[],
+    );
+    setRoads(trips.travels as TravelDtoList[]);
+  }, [trips]);
+
   useEffect(() => {
     (async () => {
       //Calcul de l'itinéraire entre les points de passage
@@ -143,17 +132,32 @@ export const MapStepEditor = () => {
 
   //#region Memos
 
-  let removePoint = (index: number) => {
+  const removePoint = (index: number) => {
     console.log('remove', index);
   };
 
+  const handleMoveMarker = (evt: MarkerDragEvent, stepId: number) => {
+    const updateStateLocationDto: UpdateStepLocationDto = {
+      latitude: evt.lngLat.lat,
+      longitude: evt.lngLat.lng,
+    };
+
+    updateStepLocationMutation.mutate({
+      stepId: stepId,
+      updateStateLocationDto,
+    });
+  };
+
   //Création des pins sur la carte pour chaque étape du voyage
   const pins = useMemo(() => {
     return steps.map((step, index) => {
       return (
         <Marker
-          key={`stepMarker-${index}`}
-          draggable={false}
+          key={step.stepId}
+          draggable
+          onDragEnd={(evn: MarkerDragEvent) =>
+            handleMoveMarker(evn, step.stepId as number)
+          }
           latitude={step.latitude ?? 0}
           longitude={step.longitude ?? 0}
           pitchAlignment="viewport"
@@ -180,7 +184,9 @@ export const MapStepEditor = () => {
         type: 'Feature',
         geometry: {
           type: 'LineString',
-          coordinates: roads,
+          coordinates: roads.flatMap(road =>
+            JSON.parse(road.travelRoad?.roadCoordinates as string),
+          ),
         },
         properties: {},
       },
@@ -201,38 +207,45 @@ export const MapStepEditor = () => {
     },
   };
 
-  let addPoint = (evt: any) => {
-    console.log('hello', evt.lngLat);
-    // @ts-ignore
-    setSteps([
-      ...steps,
-      { latitude: evt.lngLat.lat, longitude: evt.lngLat.lng },
-    ]);
-    console.log('steps', steps);
-    // @ts-ignore
-    if (steps.length > 0) {
-      // @ts-ignore
-      setDto([
-        ...dto,
-        {
-          start: [
-            steps[steps.length - 1].longitude,
-            steps[steps.length - 1].latitude,
-          ],
-          end: [evt.lngLat.lng, evt.lngLat.lat],
-        },
-      ]);
-      console.log('ddto', dto);
-    }
-  };
+  // const addPoint = (evt: any) => {
+  //   console.log('hello', evt.lngLat);
+  //   // @ts-ignore
+  //   setSteps([
+  //     ...steps,
+  //     { latitude: evt.lngLat.lat, longitude: evt.lngLat.lng },
+  //   ]);
+  //   console.log('steps', steps);
+  //   // @ts-ignore
+  //   if (steps.length > 0) {
+  //     setDto([
+  //       ...dto,
+  //       {
+  //         start: [
+  //           steps[steps.length - 1].longitude,
+  //           steps[steps.length - 1].latitude,
+  //         ],
+  //         end: [evt.lngLat.lng, evt.lngLat.lat],
+  //       },
+  //     ]);
+  //     console.log('ddto', dto);
+  //   }
+  // };
 
   //#endregion
   return (
     <>
+      <ul>
+        {steps.map(step => (
+          <li key={step.stepId}>
+            {step.stepId} - {step.name} - {step.latitude} - {step.longitude}
+          </li>
+        ))}
+      </ul>
+
       <Map
         {...viewState}
         onMove={evt => setViewState(evt.viewState)}
-        onClick={addPoint}
+        // onClick={addPoint}
         minZoom={2}
         dragRotate={true}
         mapStyle="mapbox://styles/mapbox/streets-v12"
@@ -250,6 +263,7 @@ export const MapStepEditor = () => {
         <GeolocateControl />
         <ScaleControl />
       </Map>
+      <Button variant="outline" color="yellow" size="lg" radius="xl" onClick={handleCreateStep}>ADD</Button>
     </>
   );
-};
+};
\ No newline at end of file
diff --git a/src/pages/editTravel/EditTravel.tsx b/src/pages/editTravel/EditTravel.tsx
index 0d5d9d3..b9add13 100644
--- a/src/pages/editTravel/EditTravel.tsx
+++ b/src/pages/editTravel/EditTravel.tsx
@@ -1,11 +1,12 @@
-import { Button } from '@mantine/core';
+import { MapStepEditor } from '../../components/mapStepEditor/MapStepEditor';
+import { CreateStepModal} from '../../components/createStepModal/CreateStepModal.tsx'
 
 export const EditTravel = () => {
 
   return (
       <div>
-
-        <Button variant="outline" color="yellow" size="lg" radius="xl">ADD</Button>
+        <MapStepEditor />
+        <CreateStepModal/>
       </div>
     );
 

From 8f83d88515dd5e414a778f370466ff3229758ab0 Mon Sep 17 00:00:00 2001
From: Baptiste-Ferrand <baptiste.ferrand@ynov.com>
Date: Thu, 28 Mar 2024 00:59:24 +0100
Subject: [PATCH 07/34] update router

---
 src/router/Router.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/router/Router.tsx b/src/router/Router.tsx
index 9cb39a3..854e4d4 100644
--- a/src/router/Router.tsx
+++ b/src/router/Router.tsx
@@ -15,7 +15,7 @@ import FaqPage from '../pages/faq/FaqPage';
 import ContactPage from '../pages/contact/ContactPage';
 import { AuthStore, useAuthStore } from '../store/useAuthStore';
 import { PrivateRoute } from './PrivateRoute';
-import { EditTravel } from '../pages/showTravels/editTravel/editTravel.tsx'
+import { EditTravel } from '../pages/editTravel/EditTravel.tsx'
 
 const Router = () => {
   const loadUser: () => void = useAuthStore((s: AuthStore) => s.loadUser);

From 130167447415435867d021a10b0c37994f2b882c Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Thu, 28 Mar 2024 13:56:23 +0100
Subject: [PATCH 08/34] Feat (Map) : [WIP] Add Card List

---
 src/components/stepCard/Menu/StepCardMenu.tsx | 43 ++++++++++
 src/components/stepCard/StepCard.scss         |  7 ++
 src/components/stepCard/StepCard.tsx          | 41 +++++++++
 .../transportModeIcon/TransportModeIcon.tsx   | 24 ++++++
 src/hooks/useDistance.ts                      | 40 +++++++++
 src/hooks/useTime.ts                          | 24 ++++++
 src/pages/map/MapPage.tsx                     | 83 ++++++++++---------
 .../Models/MapBoxDirections/DirectionMode.ts  |  7 +-
 8 files changed, 230 insertions(+), 39 deletions(-)
 create mode 100644 src/components/stepCard/Menu/StepCardMenu.tsx
 create mode 100644 src/components/stepCard/StepCard.scss
 create mode 100644 src/components/stepCard/StepCard.tsx
 create mode 100644 src/components/transportModeIcon/TransportModeIcon.tsx
 create mode 100644 src/hooks/useDistance.ts
 create mode 100644 src/hooks/useTime.ts

diff --git a/src/components/stepCard/Menu/StepCardMenu.tsx b/src/components/stepCard/Menu/StepCardMenu.tsx
new file mode 100644
index 0000000..95a2bc6
--- /dev/null
+++ b/src/components/stepCard/Menu/StepCardMenu.tsx
@@ -0,0 +1,43 @@
+import { ActionIcon, Menu } from '@mantine/core';
+import {
+  IconArrowBarToDown,
+  IconArrowBarToUp,
+  IconArrowDownBar,
+  IconArrowMoveUp,
+  IconCopy,
+  IconDotsVertical,
+  IconEdit,
+  IconTrash,
+} from '@tabler/icons-react';
+
+export const StepCardMenu = () => {
+  return (
+    <Menu shadow="md" width={200}>
+      <Menu.Target>
+        <ActionIcon>
+          <IconDotsVertical />
+        </ActionIcon>
+      </Menu.Target>
+
+      <Menu.Dropdown>
+        <Menu.Item leftSection={<IconEdit />}>Modifier l'étape</Menu.Item>
+        <Menu.Item color="red" leftSection={<IconTrash />}>
+          Supprimer l'étape
+        </Menu.Item>
+
+        <Menu.Divider />
+        <Menu.Label>Déplacement de l'étape</Menu.Label>
+        <Menu.Item leftSection={<IconArrowMoveUp />}>Déplacer avant</Menu.Item>
+        <Menu.Item leftSection={<IconArrowDownBar />}>Déplacer après</Menu.Item>
+
+        <Menu.Divider />
+        <Menu.Label>Nouvelle étape</Menu.Label>
+        <Menu.Item leftSection={<IconCopy />}>Dupliquer mon étape</Menu.Item>
+        <Menu.Item leftSection={<IconArrowBarToDown />}>
+          Ajouter Avant
+        </Menu.Item>
+        <Menu.Item leftSection={<IconArrowBarToUp />}>Ajouter Après</Menu.Item>
+      </Menu.Dropdown>
+    </Menu>
+  );
+};
diff --git a/src/components/stepCard/StepCard.scss b/src/components/stepCard/StepCard.scss
new file mode 100644
index 0000000..0ce1f90
--- /dev/null
+++ b/src/components/stepCard/StepCard.scss
@@ -0,0 +1,7 @@
+.card {
+  padding: 10px;
+  border: 1px solid #ccc;
+  border-radius: 5px;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+  transition: box-shadow 0.3s;
+}
diff --git a/src/components/stepCard/StepCard.tsx b/src/components/stepCard/StepCard.tsx
new file mode 100644
index 0000000..5987502
--- /dev/null
+++ b/src/components/stepCard/StepCard.tsx
@@ -0,0 +1,41 @@
+import { StepDto, TravelDtoList } from '@FullStackMap/from-a2b';
+import { Paper, Text } from '@mantine/core';
+import useDistance from '../../hooks/useDistance';
+import useTime from '../../hooks/useTime';
+import DirectionMode from '../../services/api/Models/MapBoxDirections/DirectionMode';
+import { TransportModeIcon } from '../transportModeIcon/TransportModeIcon';
+import { StepCardMenu } from './Menu/StepCardMenu';
+import './StepCard.scss';
+
+interface StepCardProps {
+  step: StepDto;
+  travel: TravelDtoList;
+}
+
+export const StepCard = (props: StepCardProps) => {
+  const { MetreToDistance } = useDistance();
+  const { SecondeToTime } = useTime();
+
+  return (
+    <Paper className="card">
+      <Text>StepName : {props.step.name}</Text>
+      <Text>StepOrder : {props.step.order}</Text>
+      {props.step.order !== 1 && (
+        <>
+          <Text>
+            TravelDistance :{' '}
+            {MetreToDistance(Number((props.travel.distance || 0).toFixed(0)))}
+          </Text>
+          <Text>
+            TravelDuration : {SecondeToTime(props.travel.duration ?? 0)}
+          </Text>
+          <Text>TravelTransportMode : {props.travel.transportMode}</Text>
+          <TransportModeIcon
+            transportMode={props.travel.transportMode as DirectionMode}
+          />
+        </>
+      )}
+      <StepCardMenu />
+    </Paper>
+  );
+};
diff --git a/src/components/transportModeIcon/TransportModeIcon.tsx b/src/components/transportModeIcon/TransportModeIcon.tsx
new file mode 100644
index 0000000..a286183
--- /dev/null
+++ b/src/components/transportModeIcon/TransportModeIcon.tsx
@@ -0,0 +1,24 @@
+import { IconBike, IconCar, IconPlane, IconWalk } from '@tabler/icons-react';
+import DirectionMode from '../../services/api/Models/MapBoxDirections/DirectionMode';
+
+export type TransportModeIconProps = {
+  transportMode: DirectionMode;
+};
+
+export const TransportModeIcon = (props: TransportModeIconProps) => {
+  if (!props.transportMode) return;
+
+  switch (props.transportMode) {
+    case DirectionMode.DRIVING:
+      return <IconCar />;
+
+    case DirectionMode.CYCLING:
+      return <IconBike />;
+
+    case DirectionMode.WALKING:
+      return <IconWalk />;
+
+    case DirectionMode.PLANE:
+      return <IconPlane />;
+  }
+};
diff --git a/src/hooks/useDistance.ts b/src/hooks/useDistance.ts
new file mode 100644
index 0000000..e6107ec
--- /dev/null
+++ b/src/hooks/useDistance.ts
@@ -0,0 +1,40 @@
+const useDistance = () => {
+  const MetersToKilometers = (meters: number) => meters / 1000;
+  const KilometersToMeters = (kilometers: number) => kilometers * 1000;
+
+  const YardToMiles = (yard: number) => yard / 1760;
+  const MilesToYard = (miles: number) => miles * 1760;
+
+  const YardToMeters = (yard: number) => yard / 1.094;
+  const MetersToYard = (meters: number) => meters * 1.094;
+
+  const KilometersToMiles = (kilometers: number) => kilometers / 1.60934;
+  const MilesToKilometers = (miles: number) => miles * 1.60934;
+
+  const MetreToDistance = (metres: number) => {
+    const kilometres = Math.floor(metres / 1000);
+    const metresRestants = metres % 1000;
+
+    const kilometreStr = kilometres > 0 ? `${kilometres} km, ` : '';
+    const metreStr = metresRestants > 0 ? `${metresRestants} m` : '';
+
+    let distanceString = kilometreStr + metreStr;
+    if (distanceString === '') distanceString = '0 m';
+
+    return distanceString;
+  };
+
+  return {
+    MetreToDistance,
+    MetersToKilometers,
+    KilometersToMeters,
+    YardToMiles,
+    MilesToYard,
+    YardToMeters,
+    MetersToYard,
+    KilometersToMiles,
+    MilesToKilometers,
+  };
+};
+
+export default useDistance;
diff --git a/src/hooks/useTime.ts b/src/hooks/useTime.ts
new file mode 100644
index 0000000..24096c6
--- /dev/null
+++ b/src/hooks/useTime.ts
@@ -0,0 +1,24 @@
+const useTime = () => {
+  const SecondeToTime = (seconde: number) => {
+    const jours = Math.floor(seconde / (3600 * 24));
+    const heures = Math.floor((seconde % (3600 * 24)) / 3600);
+    const minutes = Math.floor((seconde % 3600) / 60);
+    const secondes = seconde % 60;
+
+    const joursStr = jours > 0 ? `${jours} jour${jours > 1 ? 's' : ''}, ` : '';
+    const heuresStr =
+      heures > 0 ? `${heures} heure${heures > 1 ? 's' : ''}, ` : '';
+    const minutesStr =
+      minutes > 0 ? `${minutes} minute${minutes > 1 ? 's' : ''}` : '';
+
+    let timeString = joursStr + heuresStr + minutesStr;
+    if (timeString === '')
+      timeString = `${secondes.toFixed(0)} seconde${secondes > 1 ? 's' : ''}`;
+
+    return timeString;
+  };
+
+  return { SecondeToTime };
+};
+
+export default useTime;
diff --git a/src/pages/map/MapPage.tsx b/src/pages/map/MapPage.tsx
index f4f6831..7b534be 100644
--- a/src/pages/map/MapPage.tsx
+++ b/src/pages/map/MapPage.tsx
@@ -5,11 +5,12 @@ import {
   TripDto,
   UpdateStepLocationDto,
 } from '@FullStackMap/from-a2b';
+import { Group, Stack } from '@mantine/core';
 import { useDocumentTitle } from '@mantine/hooks';
 import { IconPinnedFilled } from '@tabler/icons-react';
 import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
 import { AxiosResponse } from 'axios';
-import { FeatureCollection, Position } from 'geojson';
+import { FeatureCollection } from 'geojson';
 import React, { useEffect, useMemo, useState } from 'react';
 import {
   GeolocateControl,
@@ -21,8 +22,8 @@ import {
   ScaleControl,
   Source,
 } from 'react-map-gl';
+import { StepCard } from '../../components/stepCard/StepCard';
 import { StepController, TripController } from '../../services/BaseApi';
-import { calculateRoad } from '../../services/api/MapboxController';
 
 interface updateStepLocationMutationProps {
   stepId: number;
@@ -36,7 +37,7 @@ const MapPage = () => {
 
   const queryClient = useQueryClient();
 
-  const tripId = 'E92913FE-5115-46BB-7A9C-08DC4E850E01';
+  const tripId = '075855B5-C93F-4574-7AC8-08DC4E850E01';
   const { data: trips } = useQuery({
     queryKey: ['Trip', tripId],
     queryFn: async () =>
@@ -80,13 +81,13 @@ const MapPage = () => {
   const [steps, setSteps] = useState<StepDto[]>([]);
   const [roads, setRoads] = useState<TravelDtoList[]>([]);
 
-  const [dto, setDto] = useState([
-    // {
-    //   start: [4.860200783597507, 45.73050608112574],
-    //   end: [5.079252160492843, 45.71892384847893],
-    // },
-    // Ajoutez d'autres coordonnées initiales ici si nécessaire
-  ]);
+  // const [dto, setDto] = useState([
+  //   // {
+  //   //   start: [4.860200783597507, 45.73050608112574],
+  //   //   end: [5.079252160492843, 45.71892384847893],
+  //   // },
+  //   // Ajoutez d'autres coordonnées initiales ici si nécessaire
+  // ]);
 
   //#endregion
 
@@ -101,24 +102,24 @@ const MapPage = () => {
     setRoads(trips.travels as TravelDtoList[]);
   }, [trips]);
 
-  useEffect(() => {
-    (async () => {
-      //Calcul de l'itinéraire entre les points de passage
-      //Doit être utilisé que si nécessaire, car il y a un quota de requêtes
-      //l'ensemble des itinéraires sont stockés dans la base de données
-      console.log('les dto pour le road', dto[dto.length - 1]);
-      if (dto.length > 0) {
-        const lastDto = [dto[dto.length - 1]];
-        const road: Position[] = await calculateRoad('driving', lastDto);
-        console.log('road', road);
-        setRoads(prevRoads => prevRoads.concat(road));
-        console.log('roads', roads);
-      }
-      // const road: Position[] = await calculateRoad('driving', dto);
-      // setRoads(road);
-      // console.log("roads", roads)
-    })();
-  }, [dto]);
+  // useEffect(() => {
+  //   (async () => {
+  //     //Calcul de l'itinéraire entre les points de passage
+  //     //Doit être utilisé que si nécessaire, car il y a un quota de requêtes
+  //     //l'ensemble des itinéraires sont stockés dans la base de données
+  //     console.log('les dto pour le road', dto[dto.length - 1]);
+  //     if (dto.length > 0) {
+  //       const lastDto = [dto[dto.length - 1]];
+  //       const road: Position[] = await calculateRoad('driving', lastDto);
+  //       console.log('road', road);
+  //       setRoads(prevRoads => prevRoads.concat(road));
+  //       console.log('roads', roads);
+  //     }
+  //     // const road: Position[] = await calculateRoad('driving', dto);
+  //     // setRoads(road);
+  //     // console.log("roads", roads)
+  //   })();
+  // }, [dto]);
   //#endregion
 
   //#region Memos
@@ -224,14 +225,20 @@ const MapPage = () => {
 
   //#endregion
   return (
-    <>
-      <ul>
-        {steps.map(step => (
-          <li key={step.stepId}>
-            {step.stepId} - {step.name} - {step.latitude} - {step.longitude}
-          </li>
+    <Group justify="space-between">
+      <Stack>
+        {steps.map((step: StepDto) => (
+          <StepCard
+            key={step.stepId}
+            step={step}
+            travel={
+              roads.filter(t => t.destinationStepId == step.stepId)[0]
+            }></StepCard>
+          // <li key={step.stepId}>
+          //   {step.stepId} - {step.name} - {step.latitude} - {step.longitude}
+          // </li>
         ))}
-      </ul>
+      </Stack>
 
       <Map
         {...viewState}
@@ -243,8 +250,8 @@ const MapPage = () => {
         mapboxAccessToken="pk.eyJ1IjoiZGVyY3Jha2VyIiwiYSI6ImNsdHVnczc4dTB6N2QyanFwZDR1N2c2eHoifQ.arP7tBErlINY3-uiwfb7Ww"
         attributionControl={true}
         style={{
-          height: '80vh',
-          width: '80vw',
+          height: '93vh',
+          width: '60vw',
         }}>
         {pins}
         <Source id="routeSource" type="geojson" data={geojson}>
@@ -254,7 +261,7 @@ const MapPage = () => {
         <GeolocateControl />
         <ScaleControl />
       </Map>
-    </>
+    </Group>
   );
 };
 
diff --git a/src/services/api/Models/MapBoxDirections/DirectionMode.ts b/src/services/api/Models/MapBoxDirections/DirectionMode.ts
index 6eefe58..dbea86c 100644
--- a/src/services/api/Models/MapBoxDirections/DirectionMode.ts
+++ b/src/services/api/Models/MapBoxDirections/DirectionMode.ts
@@ -1,2 +1,7 @@
-type DirectionMode = 'driving' | 'walking' | 'cycling';
+enum DirectionMode {
+  PLANE = 'plane',
+  DRIVING = 'driving',
+  WALKING = 'walking',
+  CYCLING = 'cycling',
+}
 export default DirectionMode;

From ff95147be6de8c64e5613ab1e798d3083c5126c2 Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Thu, 28 Mar 2024 17:31:27 +0100
Subject: [PATCH 09/34] Feat (Map) : [WIP] DeleteStep

---
 .../createStepModal/CreateStepModal.tsx       | 122 ++++++++--------
 .../mapStepEditor/MapStepEditor.tsx           |  21 ++-
 src/components/stepCard/Menu/StepCardMenu.tsx |  94 ++++++++----
 src/components/stepCard/StepCard.tsx          |   4 +-
 .../confirmDeleteModal/ConfirmDeleteModal.tsx | 134 ++++++++++++++++++
 src/pages/map/MapPage.tsx                     |  50 +++----
 src/store/useTripDetailsStore.ts              |  75 +++++++++-
 7 files changed, 370 insertions(+), 130 deletions(-)
 create mode 100644 src/components/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx

diff --git a/src/components/createStepModal/CreateStepModal.tsx b/src/components/createStepModal/CreateStepModal.tsx
index d093509..393d289 100644
--- a/src/components/createStepModal/CreateStepModal.tsx
+++ b/src/components/createStepModal/CreateStepModal.tsx
@@ -1,22 +1,24 @@
+import { Button, Group, Modal, TextInput, Textarea } from '@mantine/core';
 import { useDebouncedState } from '@mantine/hooks';
-import { Group, TextInput, Textarea, Modal, Button } from '@mantine/core'
-import { IconX } from '@tabler/icons-react'
+import { IconX } from '@tabler/icons-react';
 
 import { useForm } from '@mantine/form';
 import { zodResolver } from 'mantine-form-zod-resolver';
 import { z } from 'zod';
 
-import { useCreateStepModalStore } from '../../store/useTripDetailsStore.ts'
-
-export const CreateStepModal=()=> {
+import { useTripDetailsStore } from '../../store/useTripDetailsStore.ts';
 
+export const CreateStepModal = () => {
   const [value, setValue] = useDebouncedState('', 200, { leading: true });
 
-  const isOpen = useCreateStepModalStore((state) => state.status);
-  const close = useCreateStepModalStore((state) => state.setStatus);
+  const isOpen = useTripDetailsStore(state => state.status);
+  const close = useTripDetailsStore(state => state.setStatus);
 
   const stepSchema = z.object({
-    title: z.string().min(3, 'Le titre doit contenir au moins 3 caractères').max(50, 'Le titre doit contenir au maximum 50 caractères'),
+    title: z
+      .string()
+      .min(3, 'Le titre doit contenir au moins 3 caractères')
+      .max(50, 'Le titre doit contenir au maximum 50 caractères'),
     description: z.string(),
     // destination: z.object({ place: z.string(), coordinates: z.array(z.number()) }),
   });
@@ -30,59 +32,59 @@ export const CreateStepModal=()=> {
     },
   });
 
-
   return (
-      <Modal
-        opened={isOpen}
-        onClose={() => close(false)}
-        centered
-        title="Créer une étape de vôtre voyage"
-        className="mantine-Modal-header"
-        closeOnClickOutside={false}
-        closeButtonProps={{
-          icon: <IconX size={24} stroke={2} />,
-        }}
-        overlayProps={{
-          backgroundOpacity: 0.55,
-          blur: 3,
-        }}>
-        <div className="img-modal"></div>
-        <form onReset={() => stepForm.reset()} className="form">
-          <TextInput
-            label="Titre de votre étape"
-            placeholder="Titre"
-            required
-            data-autofocus
-            {...stepForm.getInputProps('title')}
-          />
-          <Textarea
-            mt="sm"
-            label="Description"
-            placeholder="Description"
-            {...stepForm.getInputProps('description')}
-          />
+    <Modal
+      opened={isOpen}
+      onClose={() => close(false)}
+      centered
+      title="Créer une étape de vôtre voyage"
+      className="mantine-Modal-header"
+      closeOnClickOutside={false}
+      closeButtonProps={{
+        icon: <IconX size={24} stroke={2} />,
+      }}
+      overlayProps={{
+        backgroundOpacity: 0.55,
+        blur: 3,
+      }}>
+      <div className="img-modal"></div>
+      <form onReset={() => stepForm.reset()} className="form">
+        <TextInput
+          label="Titre de votre étape"
+          placeholder="Titre"
+          required
+          data-autofocus
+          {...stepForm.getInputProps('title')}
+        />
+        <Textarea
+          mt="sm"
+          label="Description"
+          placeholder="Description"
+          {...stepForm.getInputProps('description')}
+        />
 
-          <TextInput
-            label="Destination"
-            defaultValue={value}
-            onChange={(event) => {
-              setValue(event.currentTarget.value);
-              console.log(value);
-            }}
-          />
+        <TextInput
+          label="Destination"
+          defaultValue={value}
+          onChange={event => {
+            setValue(event.currentTarget.value);
+            console.log(value);
+          }}
+        />
 
-
-          <Group justify="flex-end" mt="md">
-            <Button mt="sm" onClick={()=>close(false)}>Annuler</Button>
-            <Button
-              type="submit"
-              mt="sm"
-              disabled={!stepForm.isValid()}
-              onClick={()=>console.log("sending")}>
-              Sauvegarder
-            </Button>
-          </Group>
-        </form>
-      </Modal>
+        <Group justify="flex-end" mt="md">
+          <Button mt="sm" onClick={() => close(false)}>
+            Annuler
+          </Button>
+          <Button
+            type="submit"
+            mt="sm"
+            disabled={!stepForm.isValid()}
+            onClick={() => console.log('sending')}>
+            Sauvegarder
+          </Button>
+        </Group>
+      </form>
+    </Modal>
   );
-}
\ No newline at end of file
+};
diff --git a/src/components/mapStepEditor/MapStepEditor.tsx b/src/components/mapStepEditor/MapStepEditor.tsx
index 7aa24a5..3f0109a 100644
--- a/src/components/mapStepEditor/MapStepEditor.tsx
+++ b/src/components/mapStepEditor/MapStepEditor.tsx
@@ -5,6 +5,7 @@ import {
   TripDto,
   UpdateStepLocationDto,
 } from '@FullStackMap/from-a2b';
+import { Button } from '@mantine/core';
 import { useDocumentTitle } from '@mantine/hooks';
 import { IconPinnedFilled } from '@tabler/icons-react';
 import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
@@ -23,9 +24,8 @@ import {
 } from 'react-map-gl';
 import { StepController, TripController } from '../../services/BaseApi';
 import { calculateRoad } from '../../services/api/MapboxController';
-import { Button } from '@mantine/core'
 
-import { useCreateStepModalStore } from '../../store/useTripDetailsStore.ts'
+import { useTripDetailsStore } from '../../store/useTripDetailsStore.ts';
 
 interface updateStepLocationMutationProps {
   stepId: number;
@@ -35,11 +35,11 @@ interface updateStepLocationMutationProps {
 export const MapStepEditor = () => {
   useDocumentTitle('From A2B - Map');
 
-  const setIsStepModalOpen = useCreateStepModalStore((state) => state.setStatus);
+  const setIsStepModalOpen = useTripDetailsStore(state => state.setStatus);
 
-  const handleCreateStep = ()=>{
+  const handleCreateStep = () => {
     setIsStepModalOpen(true);
-  }
+  };
 
   //#region UseQuery
 
@@ -263,7 +263,14 @@ export const MapStepEditor = () => {
         <GeolocateControl />
         <ScaleControl />
       </Map>
-      <Button variant="outline" color="yellow" size="lg" radius="xl" onClick={handleCreateStep}>ADD</Button>
+      <Button
+        variant="outline"
+        color="yellow"
+        size="lg"
+        radius="xl"
+        onClick={handleCreateStep}>
+        ADD
+      </Button>
     </>
   );
-};
\ No newline at end of file
+};
diff --git a/src/components/stepCard/Menu/StepCardMenu.tsx b/src/components/stepCard/Menu/StepCardMenu.tsx
index 95a2bc6..eb43b7f 100644
--- a/src/components/stepCard/Menu/StepCardMenu.tsx
+++ b/src/components/stepCard/Menu/StepCardMenu.tsx
@@ -1,4 +1,5 @@
 import { ActionIcon, Menu } from '@mantine/core';
+import { useDisclosure } from '@mantine/hooks';
 import {
   IconArrowBarToDown,
   IconArrowBarToUp,
@@ -9,35 +10,72 @@ import {
   IconEdit,
   IconTrash,
 } from '@tabler/icons-react';
+import {
+  TripDetailsStore,
+  useTripDetailsStore,
+} from '../../../store/useTripDetailsStore';
+import { ConfirmDeleteModal } from '../confirmDeleteModal/ConfirmDeleteModal';
+
+interface StepCardMenuProps {
+  stepId: number;
+}
+
+export const StepCardMenu = (props: StepCardMenuProps) => {
+  const [deleteStepModalOpened, deleteStepModalController] =
+    useDisclosure(false);
+
+  const SelectStep = useTripDetailsStore(
+    (state: TripDetailsStore) => state.SelectStep,
+  );
+
+  const handleDeleteStep = () => {
+    SelectStep(props.stepId);
+    deleteStepModalController.open();
+  };
 
-export const StepCardMenu = () => {
   return (
-    <Menu shadow="md" width={200}>
-      <Menu.Target>
-        <ActionIcon>
-          <IconDotsVertical />
-        </ActionIcon>
-      </Menu.Target>
-
-      <Menu.Dropdown>
-        <Menu.Item leftSection={<IconEdit />}>Modifier l'étape</Menu.Item>
-        <Menu.Item color="red" leftSection={<IconTrash />}>
-          Supprimer l'étape
-        </Menu.Item>
-
-        <Menu.Divider />
-        <Menu.Label>Déplacement de l'étape</Menu.Label>
-        <Menu.Item leftSection={<IconArrowMoveUp />}>Déplacer avant</Menu.Item>
-        <Menu.Item leftSection={<IconArrowDownBar />}>Déplacer après</Menu.Item>
-
-        <Menu.Divider />
-        <Menu.Label>Nouvelle étape</Menu.Label>
-        <Menu.Item leftSection={<IconCopy />}>Dupliquer mon étape</Menu.Item>
-        <Menu.Item leftSection={<IconArrowBarToDown />}>
-          Ajouter Avant
-        </Menu.Item>
-        <Menu.Item leftSection={<IconArrowBarToUp />}>Ajouter Après</Menu.Item>
-      </Menu.Dropdown>
-    </Menu>
+    <>
+      <Menu shadow="md" width={200}>
+        <Menu.Target>
+          <ActionIcon>
+            <IconDotsVertical />
+          </ActionIcon>
+        </Menu.Target>
+
+        <Menu.Dropdown>
+          <Menu.Item leftSection={<IconEdit />}>Modifier l'étape</Menu.Item>
+          <Menu.Item
+            color="red"
+            leftSection={<IconTrash />}
+            onClick={handleDeleteStep}>
+            Supprimer l'étape
+          </Menu.Item>
+
+          <Menu.Divider />
+          <Menu.Label>Déplacement de l'étape</Menu.Label>
+          <Menu.Item leftSection={<IconArrowMoveUp />}>
+            Déplacer avant
+          </Menu.Item>
+          <Menu.Item leftSection={<IconArrowDownBar />}>
+            Déplacer après
+          </Menu.Item>
+
+          <Menu.Divider />
+          <Menu.Label>Nouvelle étape</Menu.Label>
+          <Menu.Item leftSection={<IconCopy />}>Dupliquer mon étape</Menu.Item>
+          <Menu.Item leftSection={<IconArrowBarToDown />}>
+            Ajouter Avant
+          </Menu.Item>
+          <Menu.Item leftSection={<IconArrowBarToUp />}>
+            Ajouter Après
+          </Menu.Item>
+        </Menu.Dropdown>
+      </Menu>
+
+      <ConfirmDeleteModal
+        opened={deleteStepModalOpened}
+        close={deleteStepModalController.close}
+      />
+    </>
   );
 };
diff --git a/src/components/stepCard/StepCard.tsx b/src/components/stepCard/StepCard.tsx
index 5987502..448bb1e 100644
--- a/src/components/stepCard/StepCard.tsx
+++ b/src/components/stepCard/StepCard.tsx
@@ -20,7 +20,7 @@ export const StepCard = (props: StepCardProps) => {
     <Paper className="card">
       <Text>StepName : {props.step.name}</Text>
       <Text>StepOrder : {props.step.order}</Text>
-      {props.step.order !== 1 && (
+      {props.step.order !== 1 && props.travel && (
         <>
           <Text>
             TravelDistance :{' '}
@@ -35,7 +35,7 @@ export const StepCard = (props: StepCardProps) => {
           />
         </>
       )}
-      <StepCardMenu />
+      <StepCardMenu stepId={props.step.stepId!} />
     </Paper>
   );
 };
diff --git a/src/components/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx b/src/components/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx
new file mode 100644
index 0000000..bbd9a49
--- /dev/null
+++ b/src/components/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx
@@ -0,0 +1,134 @@
+import { Button, Group, Modal, Stack, Text } from '@mantine/core';
+import { IconTrash } from '@tabler/icons-react';
+import { useMutation, useQueryClient } from '@tanstack/react-query';
+import { Position } from 'geojson';
+import useNotify from '../../../hooks/useNotify';
+import { StepController } from '../../../services/BaseApi';
+import { calculateRoad } from '../../../services/api/MapboxController';
+import DirectionMode from '../../../services/api/Models/MapBoxDirections/DirectionMode';
+import RoadPositionDto from '../../../services/api/Models/MapBoxDirections/RoadPositionDto';
+import {
+  TripDetailsStore,
+  useTripDetailsStore,
+} from '../../../store/useTripDetailsStore';
+
+export type ConfirmDeleteModalProps = {
+  opened: boolean;
+  close: () => void;
+};
+
+interface getTravelBetweenPositionsArgs {
+  drivingMode: DirectionMode;
+  data: Position[];
+}
+
+export const ConfirmDeleteModal = (props: ConfirmDeleteModalProps) => {
+  const queryClient = useQueryClient();
+  const { ErrorNotify } = useNotify();
+
+  const selectedStep = useTripDetailsStore(
+    (state: TripDetailsStore) => state.selectedStep,
+  );
+  const selectedStepBefore = useTripDetailsStore(
+    (state: TripDetailsStore) => state.selectedStepBefore,
+  );
+  const selectedStepAfter = useTripDetailsStore(
+    (state: TripDetailsStore) => state.selectedStepAfter,
+  );
+
+  const deleteStepMutation = useMutation({
+    mutationFn: async () =>
+      await StepController.deleteStepByIdAsyncDELETE(
+        selectedStep?.stepId as number,
+      ),
+    onSuccess: () => {
+      console.log(
+        '🚀 ~ ConfirmDeleteModal ~ selectedStep?.tripId:',
+        selectedStep?.tripId,
+      );
+      queryClient.invalidateQueries({
+        queryKey: ['Trip', selectedStep?.tripId?.toUpperCase() as string],
+      });
+    },
+  });
+
+  const handleDeleteStep = async () => {
+    await deleteStepMutation.mutateAsync();
+    if (deleteStepMutation.isError) props.close();
+
+    if (selectedStepBefore && selectedStepAfter) {
+      const startEndPosition: RoadPositionDto[] = [
+        {
+          start: [
+            selectedStepBefore.longitude as number,
+            selectedStepBefore.latitude as number,
+          ],
+          end: [
+            selectedStepAfter?.longitude as number,
+            selectedStepAfter?.latitude as number,
+          ],
+        },
+      ];
+
+      await calculateRoad(DirectionMode.DRIVING, startEndPosition)
+        .then(res =>
+          console.log(
+            '🚀 ~ file: ConfirmDeleteModal.tsx ~ line 77 ~ handleDeleteStep ~ res',
+            res,
+          ),
+        )
+        .catch(err => {
+          switch (err.response?.data?.code) {
+            case 'InvalidInput':
+              ErrorNotify({
+                title: 'Échec du calcul du nouvel itinéraire',
+                message:
+                  'La distance entre les deux points est trop grande pour ce mode de transport',
+                autoClose: undefined,
+              });
+              break;
+
+            default:
+              ErrorNotify({
+                title: 'Échec du calcul du nouvel itinéraire',
+                message:
+                  "Une erreur est survenue lors du calcul de l'itinéraire entre les deux points de passage. Veuillez réessayer plus tard.",
+                autoClose: undefined,
+              });
+              break;
+          }
+          console.error(err);
+        });
+    }
+  };
+
+  return (
+    <Modal.Root opened={props.opened} onClose={props.close} centered>
+      <Modal.Overlay backgroundOpacity={0.55} blur={3} />
+      <Modal.Content>
+        <Modal.Header>
+          <Modal.Title>Confirmation de suppression</Modal.Title>
+          <Modal.CloseButton />
+        </Modal.Header>
+        <Modal.Body>
+          <Stack>
+            <Text>Êtes-vous sûr de vouloir supprimer l'étape :</Text>
+            <Text>{selectedStep?.name}</Text>
+            <Group justify="flex-end">
+              <Button variant="outline" onClick={() => props.close()}>
+                Annuler
+              </Button>
+              <Button
+                leftSection={<IconTrash color="red" />}
+                variant="light"
+                color="red"
+                onClick={handleDeleteStep}>
+                Supprimer
+              </Button>
+            </Group>
+          </Stack>
+        </Modal.Body>
+      </Modal.Content>
+    </Modal.Root>
+  );
+};
diff --git a/src/pages/map/MapPage.tsx b/src/pages/map/MapPage.tsx
index 7b534be..88d4bfe 100644
--- a/src/pages/map/MapPage.tsx
+++ b/src/pages/map/MapPage.tsx
@@ -11,7 +11,7 @@ import { IconPinnedFilled } from '@tabler/icons-react';
 import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
 import { AxiosResponse } from 'axios';
 import { FeatureCollection } from 'geojson';
-import React, { useEffect, useMemo, useState } from 'react';
+import React, { useEffect, useMemo } from 'react';
 import {
   GeolocateControl,
   Layer,
@@ -24,6 +24,10 @@ import {
 } from 'react-map-gl';
 import { StepCard } from '../../components/stepCard/StepCard';
 import { StepController, TripController } from '../../services/BaseApi';
+import {
+  TripDetailsStore,
+  useTripDetailsStore,
+} from '../../store/useTripDetailsStore';
 
 interface updateStepLocationMutationProps {
   stepId: number;
@@ -32,13 +36,20 @@ interface updateStepLocationMutationProps {
 
 const MapPage = () => {
   useDocumentTitle('From A2B - Map');
+  const { SetSteps, SetTravels } = useTripDetailsStore();
+  const steps: StepDto[] = useTripDetailsStore(
+    (state: TripDetailsStore) => state.steps,
+  );
+  const travels: TravelDtoList[] = useTripDetailsStore(
+    (state: TripDetailsStore) => state.travels,
+  );
 
   //#region UseQuery
 
   const queryClient = useQueryClient();
 
-  const tripId = '075855B5-C93F-4574-7AC8-08DC4E850E01';
-  const { data: trips } = useQuery({
+  const tripId = '6D10DFEE-DF2C-47D7-C03D-08DC4F3894F7';
+  const { data: trip } = useQuery({
     queryKey: ['Trip', tripId],
     queryFn: async () =>
       await TripController.getTripByIdGET(tripId).then(
@@ -46,14 +57,6 @@ const MapPage = () => {
       ),
   });
 
-  // const deleteStepMutation = useMutation({
-  //   mutationFn: async (stepId: number) =>
-  //     await StepController.deleteStepByIdAsyncDELETE(stepId),
-  //   onSuccess: () => {
-  //     queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
-  //   },
-  // });
-
   const updateStepLocationMutation = useMutation({
     mutationFn: async (args: updateStepLocationMutationProps) =>
       await StepController.updateStepLocationAsyncPATCH(
@@ -68,7 +71,6 @@ const MapPage = () => {
   //#endregion
 
   //#region States
-  //Point de vu de l'utilisateur sur la carte, les valeurs renseignées seront l'endroit où la carte se positionnera au chargement de la page
   const [viewState, setViewState] = React.useState({
     longitude: 4.860200783597507,
     latitude: 45.73050608112574,
@@ -77,10 +79,6 @@ const MapPage = () => {
     bearing: 0,
   });
 
-  //Ensemble des points de passage du voyage
-  const [steps, setSteps] = useState<StepDto[]>([]);
-  const [roads, setRoads] = useState<TravelDtoList[]>([]);
-
   // const [dto, setDto] = useState([
   //   // {
   //   //   start: [4.860200783597507, 45.73050608112574],
@@ -93,14 +91,15 @@ const MapPage = () => {
 
   //#region Effects
   useEffect(() => {
-    if (!trips) return;
-    setSteps(
-      trips.steps?.sort(
+    if (!trip) return;
+    SetSteps(
+      trip.steps?.sort(
         (a: StepDtoList, b: StepDtoList) => a.order! - b.order!,
       ) as StepDto[],
     );
-    setRoads(trips.travels as TravelDtoList[]);
-  }, [trips]);
+
+    SetTravels(trip.travels as TravelDtoList[]);
+  }, [trip]);
 
   // useEffect(() => {
   //   (async () => {
@@ -176,7 +175,7 @@ const MapPage = () => {
         type: 'Feature',
         geometry: {
           type: 'LineString',
-          coordinates: roads.flatMap(road =>
+          coordinates: travels.flatMap(road =>
             JSON.parse(road.travelRoad?.roadCoordinates as string),
           ),
         },
@@ -219,7 +218,7 @@ const MapPage = () => {
   //         end: [evt.lngLat.lng, evt.lngLat.lat],
   //       },
   //     ]);
-  //     console.log('ddto', dto);
+  //     console.log('dto', dto);
   //   }
   // };
 
@@ -232,11 +231,8 @@ const MapPage = () => {
             key={step.stepId}
             step={step}
             travel={
-              roads.filter(t => t.destinationStepId == step.stepId)[0]
+              travels.filter(t => t.destinationStepId == step.stepId)[0]
             }></StepCard>
-          // <li key={step.stepId}>
-          //   {step.stepId} - {step.name} - {step.latitude} - {step.longitude}
-          // </li>
         ))}
       </Stack>
 
diff --git a/src/store/useTripDetailsStore.ts b/src/store/useTripDetailsStore.ts
index 1ddee3e..bb76dd5 100644
--- a/src/store/useTripDetailsStore.ts
+++ b/src/store/useTripDetailsStore.ts
@@ -1,12 +1,75 @@
-import {create} from 'zustand'
+import { StepDto, TravelDtoList } from '@FullStackMap/from-a2b';
+import { create } from 'zustand';
 
-export type CallCreateStepModal = {
+export type TripDetailsStore = {
   status: boolean;
   setStatus: (status: boolean) => void;
-}
 
-export const useCreateStepModalStore = create<CallCreateStepModal>((set) => ({
+  steps: StepDto[];
+  SetSteps: (steps: StepDto[]) => void;
+
+  selectedStepBefore: StepDto | null;
+  selectedStep: StepDto | null;
+  selectedStepAfter: StepDto | null;
+  SetSelectedStep: (step: StepDto) => void;
+  SelectStep: (stepId: number) => void;
+  UnSelectStep: () => void;
+
+  travels: TravelDtoList[];
+  SetTravels: (travels: TravelDtoList[]) => void;
+};
+
+export const useTripDetailsStore = create<TripDetailsStore>(set => ({
   status: false,
-  setStatus: (status: boolean) => set({status}),
-}))
+  setStatus: (status: boolean) => set({ status }),
+
+  steps: [],
+  SetSteps: (steps: StepDto[]) => set({ steps }),
+
+  selectedStepBefore: null,
+  selectedStep: null,
+  selectedStepAfter: null,
+  SetSelectedStep: (step: StepDto) =>
+    set((state: TripDetailsStore) => {
+      const stepBefore: StepDto | undefined = state.steps.find(
+        step => step.order === (step.order as number) - 1,
+      );
+      const stepAfter: StepDto | undefined = state.steps.find(
+        step => step.order === (step.order as number) + 1,
+      );
+
+      return {
+        selectedStepBefore: stepBefore,
+        selectedStep: step,
+        selectedStepAfter: stepAfter,
+      };
+    }),
+  SelectStep: (stepId: number) => {
+    set((state: TripDetailsStore) => {
+      const currentStep: StepDto | undefined = state.steps.find(
+        step => step.stepId === stepId,
+      );
+      const stepBefore: StepDto | undefined = state.steps.find(
+        step => step.order === (currentStep?.order as number) - 1,
+      );
+      const stepAfter: StepDto | undefined = state.steps.find(
+        step => step.order === (currentStep?.order as number) + 1,
+      );
+
+      return {
+        selectedStepBefore: stepBefore,
+        selectedStep: currentStep,
+        selectedStepAfter: stepAfter,
+      };
+    });
+  },
+  UnSelectStep: () =>
+    set({
+      selectedStep: null,
+      selectedStepBefore: null,
+      selectedStepAfter: null,
+    }),
 
+  travels: [],
+  SetTravels: (travels: TravelDtoList[]) => set({ travels }),
+}));

From 1f843c3b99bbbf667b93ff91482085c3b89a26a6 Mon Sep 17 00:00:00 2001
From: Baptiste-Ferrand <baptiste.ferrand@ynov.com>
Date: Thu, 28 Mar 2024 17:48:17 +0100
Subject: [PATCH 10/34] update CreateStepModal.tsx MapboxController.ts

---
 .../createStepModal/CreateStepModal.tsx       | 61 +++++++++++++++----
 src/services/api/MapboxController.ts          | 19 ++++++
 2 files changed, 67 insertions(+), 13 deletions(-)

diff --git a/src/components/createStepModal/CreateStepModal.tsx b/src/components/createStepModal/CreateStepModal.tsx
index d093509..4ee9be9 100644
--- a/src/components/createStepModal/CreateStepModal.tsx
+++ b/src/components/createStepModal/CreateStepModal.tsx
@@ -1,24 +1,55 @@
 import { useDebouncedState } from '@mantine/hooks';
-import { Group, TextInput, Textarea, Modal, Button } from '@mantine/core'
+import { Group, TextInput, Textarea, Modal, Button, Autocomplete } from '@mantine/core'
 import { IconX } from '@tabler/icons-react'
-
+import { useEffect, useState } from 'react';
 import { useForm } from '@mantine/form';
 import { zodResolver } from 'mantine-form-zod-resolver';
 import { z } from 'zod';
 
 import { useCreateStepModalStore } from '../../store/useTripDetailsStore.ts'
+import { getPlace } from '../../services/api/MapboxController.ts'
+
+import {useMutation, QueryClient} from '@tanstack/react-query'
+
+import { AddStepDto } from '@FullStackMap/from-a2b';
+import { StepController } from '../../services/BaseApi.ts'
+
+const queryClient = new QueryClient();
 
 export const CreateStepModal=()=> {
 
+  const tripId = 'E92913FE-5115-46BB-7A9C-08DC4E850E01';
+
   const [value, setValue] = useDebouncedState('', 200, { leading: true });
+  const [places, setPlaces] = useState([]);
+
+  useEffect(() => {
+    const fetchPlaces = async () => {
+
+      setPlaces(await getPlace(value));
+    };
+
+    if (value) {
+      fetchPlaces();
+    }
+  }, [value]);
 
   const isOpen = useCreateStepModalStore((state) => state.status);
   const close = useCreateStepModalStore((state) => state.setStatus);
 
+  const createStep = useMutation({
+    mutationFn: (data: AddStepDto )=> StepController.addStepAsyncPOST(tripId, data).catch((error)=>{
+      throw new Error(error);
+  }),
+    onSuccess: () => {
+      queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
+    },
+  });
+
+
   const stepSchema = z.object({
     title: z.string().min(3, 'Le titre doit contenir au moins 3 caractères').max(50, 'Le titre doit contenir au maximum 50 caractères'),
     description: z.string(),
-    // destination: z.object({ place: z.string(), coordinates: z.array(z.number()) }),
   });
 
   const stepForm = useForm({
@@ -31,6 +62,11 @@ export const CreateStepModal=()=> {
   });
 
 
+
+  const getCoordinate = (place:string)=>{
+    return  places.find((item)=> item.place === place)
+  }
+
   return (
       <Modal
         opened={isOpen}
@@ -61,28 +97,27 @@ export const CreateStepModal=()=> {
             placeholder="Description"
             {...stepForm.getInputProps('description')}
           />
-
-          <TextInput
+          <Autocomplete
             label="Destination"
-            defaultValue={value}
-            onChange={(event) => {
-              setValue(event.currentTarget.value);
-              console.log(value);
-            }}
+            placeholder="Entrez une adresse"
+            data={places.map(item=> ({ label: item.place, value: item.place }))}
+            onChange={(event)=> setValue(event)}
           />
 
 
           <Group justify="flex-end" mt="md">
             <Button mt="sm" onClick={()=>close(false)}>Annuler</Button>
             <Button
-              type="submit"
+
               mt="sm"
-              disabled={!stepForm.isValid()}
-              onClick={()=>console.log("sending")}>
+              disabled={!stepForm.isValid() }
+              onClick={()=>console.log(stepForm.values, getCoordinate(value))}>
               Sauvegarder
             </Button>
           </Group>
         </form>
       </Modal>
   );
+
+
 }
\ No newline at end of file
diff --git a/src/services/api/MapboxController.ts b/src/services/api/MapboxController.ts
index d29a4d3..377b23c 100644
--- a/src/services/api/MapboxController.ts
+++ b/src/services/api/MapboxController.ts
@@ -6,6 +6,7 @@ import RoadPositionDto from './Models/MapBoxDirections/RoadPositionDto';
 const mapBoxToken =
   'pk.eyJ1IjoiZGVyY3Jha2VyIiwiYSI6ImNsdHVnczc4dTB6N2QyanFwZDR1N2c2eHoifQ.arP7tBErlINY3-uiwfb7Ww';
 
+
 export const calculateRoad = async (
   directionMode: DirectionMode,
   positions: RoadPositionDto[],
@@ -22,3 +23,21 @@ export const calculateRoad = async (
 
   return coords;
 };
+
+export const getPlace = async(place: string)=>{
+
+  let response = await MapboxClient.get(
+    `/geocoding/v5/mapbox.places/${place}.json?proximity=ip&language=fr&access_token=${mapBoxToken}`,
+  );
+
+  response = response.data.features.map((item: { place_name_fr: any; center: any; })=>{
+    return {
+      place: item.place_name_fr,
+      coordinate: item.center
+    }
+  })
+  console.log(response, 'places dans le store')
+  return response;
+}
+
+

From 51e04da050fe924eedd3de41094cb8bd49b987cf Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Thu, 28 Mar 2024 20:25:04 +0100
Subject: [PATCH 11/34] Feat (map) : [WIP] Add Travels between steps

---
 .../mapStepEditor/MapStepEditor.tsx           |   6 +-
 src/pages/map/MapPage.tsx                     | 196 +++++++++++++++---
 src/services/BaseApi.ts                       |  13 ++
 src/services/api/MapboxController.ts          |  10 +-
 .../CalculateTravelRoadDto.ts                 |   8 +
 src/store/useTripDetailsStore.ts              |  51 -----
 6 files changed, 203 insertions(+), 81 deletions(-)
 create mode 100644 src/services/api/Models/MapBoxDirections/CalculateTravelRoadDto.ts

diff --git a/src/components/mapStepEditor/MapStepEditor.tsx b/src/components/mapStepEditor/MapStepEditor.tsx
index 3f0109a..751f2b1 100644
--- a/src/components/mapStepEditor/MapStepEditor.tsx
+++ b/src/components/mapStepEditor/MapStepEditor.tsx
@@ -26,6 +26,7 @@ import { StepController, TripController } from '../../services/BaseApi';
 import { calculateRoad } from '../../services/api/MapboxController';
 
 import { useTripDetailsStore } from '../../store/useTripDetailsStore.ts';
+import DirectionMode from '../../services/api/Models/MapBoxDirections/DirectionMode.ts';
 
 interface updateStepLocationMutationProps {
   stepId: number;
@@ -118,7 +119,10 @@ export const MapStepEditor = () => {
       console.log('les dto pour le road', dto[dto.length - 1]);
       if (dto.length > 0) {
         const lastDto = [dto[dto.length - 1]];
-        const road: Position[] = await calculateRoad('driving', lastDto);
+        const road: Position[] = await calculateRoad(
+          DirectionMode.DRIVING,
+          lastDto,
+        );
         console.log('road', road);
         setRoads(prevRoads => prevRoads.concat(road));
         console.log('roads', roads);
diff --git a/src/pages/map/MapPage.tsx b/src/pages/map/MapPage.tsx
index 88d4bfe..17eecf9 100644
--- a/src/pages/map/MapPage.tsx
+++ b/src/pages/map/MapPage.tsx
@@ -1,4 +1,5 @@
 import {
+  AddTravelDto,
   StepDto,
   StepDtoList,
   TravelDtoList,
@@ -23,11 +24,17 @@ import {
   Source,
 } from 'react-map-gl';
 import { StepCard } from '../../components/stepCard/StepCard';
-import { StepController, TripController } from '../../services/BaseApi';
+import useNotify from '../../hooks/useNotify';
 import {
-  TripDetailsStore,
-  useTripDetailsStore,
-} from '../../store/useTripDetailsStore';
+  StepController,
+  TravelController,
+  TripController,
+} from '../../services/BaseApi';
+import { calculateRoad } from '../../services/api/MapboxController';
+import CalculateTravelRoadDto from '../../services/api/Models/MapBoxDirections/CalculateTravelRoadDto';
+import DirectionMode from '../../services/api/Models/MapBoxDirections/DirectionMode';
+import RoadPositionDto from '../../services/api/Models/MapBoxDirections/RoadPositionDto';
+import { useTripDetailsStore } from '../../store/useTripDetailsStore';
 
 interface updateStepLocationMutationProps {
   stepId: number;
@@ -36,19 +43,16 @@ interface updateStepLocationMutationProps {
 
 const MapPage = () => {
   useDocumentTitle('From A2B - Map');
-  const { SetSteps, SetTravels } = useTripDetailsStore();
-  const steps: StepDto[] = useTripDetailsStore(
-    (state: TripDetailsStore) => state.steps,
-  );
-  const travels: TravelDtoList[] = useTripDetailsStore(
-    (state: TripDetailsStore) => state.travels,
-  );
+  const { steps, travels, SetSteps, SetTravels } = useTripDetailsStore();
+
+  const { ErrorNotify } = useNotify();
 
   //#region UseQuery
 
   const queryClient = useQueryClient();
 
-  const tripId = '6D10DFEE-DF2C-47D7-C03D-08DC4F3894F7';
+  // const tripId = 'AA16BE27-5E15-489D-C043-08DC4F3894F7';
+  const tripId = '969059C1-EBD1-44E8-C047-08DC4F3894F7';
   const { data: trip } = useQuery({
     queryKey: ['Trip', tripId],
     queryFn: async () =>
@@ -63,9 +67,13 @@ const MapPage = () => {
         args.stepId,
         args.updateStateLocationDto,
       ).catch(err => console.error(err)),
-    onSuccess: () => {
-      queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
-    },
+  });
+
+  const addTravelBetweenStepsMutation = useMutation({
+    mutationFn: async (addTravelDto: AddTravelDto) =>
+      await TravelController.addTravelBetweenStepsPOST(addTravelDto).catch(
+        err => console.error(err),
+      ),
   });
 
   //#endregion
@@ -123,29 +131,166 @@ const MapPage = () => {
 
   //#region Memos
 
-  const removePoint = (index: number) => {
-    console.log('remove', index);
-  };
-
-  const handleMoveMarker = (evt: MarkerDragEvent, stepId: number) => {
+  const handleMoveMarker = async (evt: MarkerDragEvent, stepId: number) => {
     const updateStateLocationDto: UpdateStepLocationDto = {
       latitude: evt.lngLat.lat,
       longitude: evt.lngLat.lng,
     };
 
-    updateStepLocationMutation.mutate({
+    const currentStep: StepDto | undefined = steps.find(
+      (s: StepDto) => s.stepId === stepId,
+    );
+    console.log('🚀 ~ handleMoveMarker ~ currentStep:', currentStep);
+    const stepBefore: StepDto | undefined = steps.find(
+      (s: StepDto) => s.order === (currentStep?.order as number) - 1,
+    );
+    console.log('🚀 ~ handleMoveMarker ~ stepBefore:', stepBefore);
+    const stepAfter: StepDto | undefined = steps.find(
+      (s: StepDto) => s.order === (currentStep?.order as number) + 1,
+    );
+    console.log('🚀 ~ handleMoveMarker ~ stepAfter:', stepAfter);
+
+    await updateStepLocationMutation.mutateAsync({
       stepId: stepId,
       updateStateLocationDto,
     });
+
+    if (updateStepLocationMutation.error) return;
+
+    if (stepBefore && currentStep) {
+      const startEndPosition: RoadPositionDto[] = [
+        {
+          start: [
+            stepBefore.longitude as number,
+            stepBefore.latitude as number,
+          ],
+          end: [
+            updateStateLocationDto?.longitude as number,
+            updateStateLocationDto?.latitude as number,
+          ],
+        },
+      ];
+
+      const travelBeforeResponse: CalculateTravelRoadDto = await calculateRoad(
+        DirectionMode.DRIVING,
+        startEndPosition,
+      ).catch(err => {
+        switch (err.response?.data?.code) {
+          case 'InvalidInput':
+            ErrorNotify({
+              title: 'Échec du calcul du nouvel itinéraire',
+              message:
+                'La distance entre les deux points est trop grande pour ce mode de transport',
+              autoClose: undefined,
+            });
+            break;
+          case 'NoRoute':
+            ErrorNotify({
+              title: 'Échec du calcul du nouvel itinéraire',
+              message: "Aucune route n'a été trouvée entre les deux points",
+              autoClose: undefined,
+            });
+            break;
+
+          default:
+            ErrorNotify({
+              title: 'Échec du calcul du nouvel itinéraire',
+              message:
+                "Une erreur est survenue lors du calcul de l'itinéraire entre les deux points de passage. Veuillez réessayer plus tard.",
+              autoClose: undefined,
+            });
+            break;
+        }
+        console.error(err);
+      });
+
+      const addTravelDto: AddTravelDto = {
+        transportMode: travelBeforeResponse.transportMode,
+        distance: Number(travelBeforeResponse.distance.toFixed(0)),
+        duration: Number(travelBeforeResponse.duration.toFixed(0)),
+        originStepId: stepBefore.stepId as number,
+        destinationStepId: currentStep?.stepId as number,
+        travelRoad: travelBeforeResponse.travelRoad,
+      };
+      await addTravelBetweenStepsMutation.mutateAsync(addTravelDto);
+
+      console.log(
+        '🚀 ~ handleMoveMarker ~ travelBeforeResponse:',
+        travelBeforeResponse,
+      );
+    }
+
+    if (stepAfter && currentStep) {
+      const startEndPosition: RoadPositionDto[] = [
+        {
+          start: [
+            updateStateLocationDto.longitude as number,
+            updateStateLocationDto.latitude as number,
+          ],
+          end: [stepAfter?.longitude as number, stepAfter?.latitude as number],
+        },
+      ];
+
+      const travelAfterResponse: CalculateTravelRoadDto = await calculateRoad(
+        DirectionMode.DRIVING,
+        startEndPosition,
+      ).catch(err => {
+        switch (err.response?.data?.code) {
+          case 'InvalidInput':
+            ErrorNotify({
+              title: 'Échec du calcul du nouvel itinéraire',
+              message:
+                'La distance entre les deux points est trop grande pour ce mode de transport',
+              autoClose: undefined,
+            });
+            break;
+          case 'NoRoute':
+            ErrorNotify({
+              title: 'Échec du calcul du nouvel itinéraire',
+              message: "Aucune route n'a été trouvée entre les deux points",
+              autoClose: undefined,
+            });
+            break;
+
+          default:
+            ErrorNotify({
+              title: 'Échec du calcul du nouvel itinéraire',
+              message:
+                "Une erreur est survenue lors du calcul de l'itinéraire entre les deux points de passage. Veuillez réessayer plus tard.",
+              autoClose: undefined,
+            });
+            break;
+        }
+        console.error(err);
+      });
+
+      const addTravelDto: AddTravelDto = {
+        transportMode: travelAfterResponse.transportMode,
+        distance: Number(travelAfterResponse.distance.toFixed(0)),
+        duration: Number(travelAfterResponse.duration.toFixed(0)),
+        originStepId: currentStep.stepId as number,
+        destinationStepId: stepAfter?.stepId as number,
+        travelRoad: travelAfterResponse.travelRoad,
+      };
+      await addTravelBetweenStepsMutation.mutateAsync(addTravelDto);
+
+      console.log(
+        '🚀 ~ handleMoveMarker ~ travelAfterResponse:',
+        travelAfterResponse,
+      );
+    }
+
+    queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
   };
 
   //Création des pins sur la carte pour chaque étape du voyage
   const pins = useMemo(() => {
-    return steps.map((step, index) => {
+    return steps.map((step: StepDto) => {
       return (
         <Marker
           key={step.stepId}
           draggable
+          onClick={() => console.log('step', step.order)}
           onDragEnd={(evn: MarkerDragEvent) =>
             handleMoveMarker(evn, step.stepId as number)
           }
@@ -153,12 +298,7 @@ const MapPage = () => {
           longitude={step.longitude ?? 0}
           pitchAlignment="viewport"
           rotationAlignment="viewport">
-          <IconPinnedFilled
-            color="teal"
-            size={32}
-            stroke={2}
-            onClick={() => removePoint(index)}
-          />
+          <IconPinnedFilled color="teal" size={32} stroke={2} />
         </Marker>
       );
     });
diff --git a/src/services/BaseApi.ts b/src/services/BaseApi.ts
index 52d4f80..be6395d 100644
--- a/src/services/BaseApi.ts
+++ b/src/services/BaseApi.ts
@@ -37,6 +37,19 @@ const StepControllerFunc = () => {
 };
 export const StepController = StepControllerFunc();
 
+const TravelControllerFunc = () => {
+  const configLogged = new client.Configuration({
+    basePath: basePath,
+    baseOptions: {
+      headers: {
+        Authorization: `Bearer ${token}`,
+      },
+    },
+  });
+  return client.TravelApiFactory(configLogged);
+};
+export const TravelController = TravelControllerFunc();
+
 export const MapboxClient = axios.create({
   baseURL: 'https://api.mapbox.com',
 });
diff --git a/src/services/api/MapboxController.ts b/src/services/api/MapboxController.ts
index d29a4d3..b794d6b 100644
--- a/src/services/api/MapboxController.ts
+++ b/src/services/api/MapboxController.ts
@@ -1,5 +1,6 @@
 import { Position } from 'geojson';
 import { MapboxClient } from '../BaseApi';
+import CalculateTravelRoadDto from './Models/MapBoxDirections/CalculateTravelRoadDto';
 import DirectionMode from './Models/MapBoxDirections/DirectionMode';
 import RoadPositionDto from './Models/MapBoxDirections/RoadPositionDto';
 
@@ -20,5 +21,12 @@ export const calculateRoad = async (
   const data = response.data.routes[0];
   const coords: Position[] = data.geometry.coordinates;
 
-  return coords;
+  const travelRoadDto: CalculateTravelRoadDto = {
+    transportMode: DirectionMode.DRIVING,
+    distance: data.distance,
+    duration: data.duration,
+    travelRoad: JSON.stringify(coords),
+  };
+
+  return travelRoadDto;
 };
diff --git a/src/services/api/Models/MapBoxDirections/CalculateTravelRoadDto.ts b/src/services/api/Models/MapBoxDirections/CalculateTravelRoadDto.ts
new file mode 100644
index 0000000..3c238c0
--- /dev/null
+++ b/src/services/api/Models/MapBoxDirections/CalculateTravelRoadDto.ts
@@ -0,0 +1,8 @@
+type CalculateTravelRoadDto = {
+  transportMode: string;
+  distance: number;
+  duration: number;
+  travelRoad: string;
+};
+
+export default CalculateTravelRoadDto;
diff --git a/src/store/useTripDetailsStore.ts b/src/store/useTripDetailsStore.ts
index bb76dd5..ea2aa98 100644
--- a/src/store/useTripDetailsStore.ts
+++ b/src/store/useTripDetailsStore.ts
@@ -8,13 +8,6 @@ export type TripDetailsStore = {
   steps: StepDto[];
   SetSteps: (steps: StepDto[]) => void;
 
-  selectedStepBefore: StepDto | null;
-  selectedStep: StepDto | null;
-  selectedStepAfter: StepDto | null;
-  SetSelectedStep: (step: StepDto) => void;
-  SelectStep: (stepId: number) => void;
-  UnSelectStep: () => void;
-
   travels: TravelDtoList[];
   SetTravels: (travels: TravelDtoList[]) => void;
 };
@@ -26,50 +19,6 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
   steps: [],
   SetSteps: (steps: StepDto[]) => set({ steps }),
 
-  selectedStepBefore: null,
-  selectedStep: null,
-  selectedStepAfter: null,
-  SetSelectedStep: (step: StepDto) =>
-    set((state: TripDetailsStore) => {
-      const stepBefore: StepDto | undefined = state.steps.find(
-        step => step.order === (step.order as number) - 1,
-      );
-      const stepAfter: StepDto | undefined = state.steps.find(
-        step => step.order === (step.order as number) + 1,
-      );
-
-      return {
-        selectedStepBefore: stepBefore,
-        selectedStep: step,
-        selectedStepAfter: stepAfter,
-      };
-    }),
-  SelectStep: (stepId: number) => {
-    set((state: TripDetailsStore) => {
-      const currentStep: StepDto | undefined = state.steps.find(
-        step => step.stepId === stepId,
-      );
-      const stepBefore: StepDto | undefined = state.steps.find(
-        step => step.order === (currentStep?.order as number) - 1,
-      );
-      const stepAfter: StepDto | undefined = state.steps.find(
-        step => step.order === (currentStep?.order as number) + 1,
-      );
-
-      return {
-        selectedStepBefore: stepBefore,
-        selectedStep: currentStep,
-        selectedStepAfter: stepAfter,
-      };
-    });
-  },
-  UnSelectStep: () =>
-    set({
-      selectedStep: null,
-      selectedStepBefore: null,
-      selectedStepAfter: null,
-    }),
-
   travels: [],
   SetTravels: (travels: TravelDtoList[]) => set({ travels }),
 }));

From 73a778e8acad062a9218a4f18eaa9e1c5782341b Mon Sep 17 00:00:00 2001
From: Baptiste-Ferrand <baptiste.ferrand@ynov.com>
Date: Thu, 28 Mar 2024 23:37:04 +0100
Subject: [PATCH 12/34] edit docker-compose.yml

---
 docker-compose.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docker-compose.yml b/docker-compose.yml
index d04cade..fb0f188 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -11,4 +11,4 @@ services:
     ports:
       - '3000:3000'
     environment:
-      VITE_API_URL: http://localhost:32769
+      VITE_API_URL: ${VITE_API_URL}

From 32ea33dfdf3002ee228decc87c8e4d2d4edc683c Mon Sep 17 00:00:00 2001
From: Baptiste-Ferrand <baptiste.ferrand@ynov.com>
Date: Thu, 28 Mar 2024 23:38:55 +0100
Subject: [PATCH 13/34] update the CreateStepModal.tsx

---
 .../createStepModal/CreateStepModal.tsx       | 51 ++++++++-----------
 1 file changed, 21 insertions(+), 30 deletions(-)

diff --git a/src/components/createStepModal/CreateStepModal.tsx b/src/components/createStepModal/CreateStepModal.tsx
index 0922c57..8f8b725 100644
--- a/src/components/createStepModal/CreateStepModal.tsx
+++ b/src/components/createStepModal/CreateStepModal.tsx
@@ -1,13 +1,12 @@
-import { Button, Group, Modal, TextInput, Textarea } from '@mantine/core';
+import { Button, Group, Modal, TextInput, Textarea, Autocomplete } from '@mantine/core';
 import { useDebouncedState } from '@mantine/hooks';
-import { Group, TextInput, Textarea, Modal, Button, Autocomplete } from '@mantine/core'
 import { IconX } from '@tabler/icons-react'
 import { useEffect, useState } from 'react';
 import { useForm } from '@mantine/form';
 import { zodResolver } from 'mantine-form-zod-resolver';
 import { z } from 'zod';
 
-import { useCreateStepModalStore } from '../../store/useTripDetailsStore.ts'
+import { useTripDetailsStore } from '../../store/useTripDetailsStore.ts'
 import { getPlace } from '../../services/api/MapboxController.ts'
 
 import {useMutation, QueryClient} from '@tanstack/react-query'
@@ -19,7 +18,7 @@ const queryClient = new QueryClient();
 
 export const CreateStepModal=()=> {
 
-  const tripId = 'E92913FE-5115-46BB-7A9C-08DC4E850E01';
+  const tripId: string = useTripDetailsStore((state) => state.trip.tripId);
 
   const [value, setValue] = useDebouncedState('', 200, { leading: true });
   const [places, setPlaces] = useState([]);
@@ -35,8 +34,8 @@ export const CreateStepModal=()=> {
     }
   }, [value]);
 
-  const isOpen = useCreateStepModalStore((state) => state.status);
-  const close = useCreateStepModalStore((state) => state.setStatus);
+  const isOpen = useTripDetailsStore((state) => state.status);
+  const close = useTripDetailsStore((state) => state.setStatus);
 
   const createStep = useMutation({
     mutationFn: (data: AddStepDto )=> StepController.addStepAsyncPOST(tripId, data).catch((error)=>{
@@ -68,7 +67,8 @@ export const CreateStepModal=()=> {
 
 
   const getCoordinate = (place:string)=>{
-    return  places.find((item)=> item.place === place)
+    const coordinate  = places.find((item)=> item.place === place)
+    return coordinate?.coordinate
   }
 
   return (
@@ -106,38 +106,29 @@ export const CreateStepModal=()=> {
             placeholder="Entrez une adresse"
             data={places.map(item=> ({ label: item.place, value: item.place }))}
             onChange={(event)=> setValue(event)}
-          />
 
-        <Group justify="flex-end" mt="md">
-          <Button mt="sm" onClick={() => close(false)}>
-            Annuler
-          </Button>
-          <Button
-            type="submit"
-            mt="sm"
-            disabled={!stepForm.isValid()}
-            onClick={() => console.log('sending')}>
-            Sauvegarder
-          </Button>
-        </Group>
-      </form>
-    </Modal>
-  );
-};
+          />
 
           <Group justify="flex-end" mt="md">
             <Button mt="sm" onClick={()=>close(false)}>Annuler</Button>
             <Button
-
+              type="submit"
               mt="sm"
               disabled={!stepForm.isValid() }
-              onClick={()=>console.log(stepForm.values, getCoordinate(value))}>
+              onClick={(event)=>{
+                event.preventDefault();
+                createStep.mutate({
+                  name: stepForm.values.title,
+                  description: stepForm.values.description,
+                  latitude: getCoordinate(value)?.latitude,
+                  longitude: getCoordinate(value)?.longitude,
+                });
+              }}>
               Sauvegarder
             </Button>
           </Group>
-        </form>
-      </Modal>
+      </form>
+    </Modal>
   );
+};
 
-
-}
\ No newline at end of file

From 6a9630bc468a45dd40050d89149301081635d4f4 Mon Sep 17 00:00:00 2001
From: Baptiste-Ferrand <baptiste.ferrand@ynov.com>
Date: Thu, 28 Mar 2024 23:39:27 +0100
Subject: [PATCH 14/34] update useTripDetailsStore.ts

add trip as TripDto
for get and set it
---
 src/store/useTripDetailsStore.ts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/store/useTripDetailsStore.ts b/src/store/useTripDetailsStore.ts
index bb76dd5..1e6a385 100644
--- a/src/store/useTripDetailsStore.ts
+++ b/src/store/useTripDetailsStore.ts
@@ -1,10 +1,15 @@
 import { StepDto, TravelDtoList } from '@FullStackMap/from-a2b';
 import { create } from 'zustand';
+import { TripDto } from '@FullStackMap/from-a2b';
 
 export type TripDetailsStore = {
   status: boolean;
   setStatus: (status: boolean) => void;
 
+  trip: TripDto;
+  setTrip: (trip: TripDto) => void;
+
+
   steps: StepDto[];
   SetSteps: (steps: StepDto[]) => void;
 
@@ -26,6 +31,9 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
   steps: [],
   SetSteps: (steps: StepDto[]) => set({ steps }),
 
+  trip: {} as TripDto,
+  setTrip: (trip: TripDto) => set({ trip }),
+
   selectedStepBefore: null,
   selectedStep: null,
   selectedStepAfter: null,

From 9cbbf4079c222b721324d102bed2bf699a07c678 Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Fri, 29 Mar 2024 15:45:55 +0100
Subject: [PATCH 15/34] feat (map) : Delete step and calculate new travel

---
 package.json                                  |   2 +-
 pnpm-lock.yaml                                |   8 +-
 src/components/stepCard/Menu/StepCardMenu.tsx |  10 +-
 src/components/stepCard/StepCard.tsx          |   1 +
 .../confirmDeleteModal/ConfirmDeleteModal.tsx | 155 +++++++++++-------
 src/pages/map/MapPage.tsx                     | 146 +++++++++--------
 src/pages/test/TestPage.tsx                   |  23 +++
 src/pages/test/components/TestModal.tsx       |  26 +++
 src/router/Router.tsx                         |  31 ++--
 src/services/BaseApi.ts                       |  19 +--
 src/services/api/MapboxController.ts          |  50 ++++--
 src/store/useTripDetailsStore.ts              |  11 ++
 src/vite-env.d.ts                             |   1 +
 13 files changed, 300 insertions(+), 183 deletions(-)
 create mode 100644 src/pages/test/TestPage.tsx
 create mode 100644 src/pages/test/components/TestModal.tsx

diff --git a/package.json b/package.json
index e3434b1..c9f3fd2 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
     "updateClientApi": "pnpm update @FullStackMap/from-a2b"
   },
   "dependencies": {
-    "@FullStackMap/from-a2b": "0.20.3-Alpha",
+    "@FullStackMap/from-a2b": "0.20.4-Alpha",
     "@mantine/carousel": "^7.6.2",
     "@mantine/core": "^7.6.2",
     "@mantine/form": "^7.6.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 76f5c22..05bd454 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -6,8 +6,8 @@ settings:
 
 dependencies:
   '@FullStackMap/from-a2b':
-    specifier: 0.20.3-Alpha
-    version: 0.20.3-Alpha
+    specifier: 0.20.4-Alpha
+    version: 0.20.4-Alpha
   '@mantine/carousel':
     specifier: ^7.6.2
     version: 7.6.2(@mantine/core@7.6.2)(@mantine/hooks@7.6.2)(embla-carousel-react@7.1.0)(react-dom@18.2.0)(react@18.2.0)
@@ -157,8 +157,8 @@ devDependencies:
 
 packages:
 
-  /@FullStackMap/from-a2b@0.20.3-Alpha:
-    resolution: {integrity: sha512-bNj9D4f7zBur4hVZWB4cVWuJcmbfjQQeaFIlUV6MfnPZvIWqZtGvZ3u5VQy7lASS36eL4yeUhxJm9JCImG1UqQ==, tarball: https://npm.pkg.github.com/download/@FullStackMap/from-a2b/0.20.3-Alpha/0f37d16518eb3b8c888b5215e33f6eb671831537}
+  /@FullStackMap/from-a2b@0.20.4-Alpha:
+    resolution: {integrity: sha512-XrzxA1L5JCwD6ZwY0zbvFueUFVXKwp/6Jl49AQVedpmsacVCs0lcMlfzD1EQnVOz1RS8H9G6jOi1SS2ipcVhCw==, tarball: https://npm.pkg.github.com/download/@FullStackMap/from-a2b/0.20.4-Alpha/30b2a92c87f6b625a812a8512a04d43032ba8dcd}
     dependencies:
       axios: 1.6.8
     transitivePeerDependencies:
diff --git a/src/components/stepCard/Menu/StepCardMenu.tsx b/src/components/stepCard/Menu/StepCardMenu.tsx
index eb43b7f..6f772e3 100644
--- a/src/components/stepCard/Menu/StepCardMenu.tsx
+++ b/src/components/stepCard/Menu/StepCardMenu.tsx
@@ -10,10 +10,6 @@ import {
   IconEdit,
   IconTrash,
 } from '@tabler/icons-react';
-import {
-  TripDetailsStore,
-  useTripDetailsStore,
-} from '../../../store/useTripDetailsStore';
 import { ConfirmDeleteModal } from '../confirmDeleteModal/ConfirmDeleteModal';
 
 interface StepCardMenuProps {
@@ -24,12 +20,7 @@ export const StepCardMenu = (props: StepCardMenuProps) => {
   const [deleteStepModalOpened, deleteStepModalController] =
     useDisclosure(false);
 
-  const SelectStep = useTripDetailsStore(
-    (state: TripDetailsStore) => state.SelectStep,
-  );
-
   const handleDeleteStep = () => {
-    SelectStep(props.stepId);
     deleteStepModalController.open();
   };
 
@@ -73,6 +64,7 @@ export const StepCardMenu = (props: StepCardMenuProps) => {
       </Menu>
 
       <ConfirmDeleteModal
+        stepId={props.stepId}
         opened={deleteStepModalOpened}
         close={deleteStepModalController.close}
       />
diff --git a/src/components/stepCard/StepCard.tsx b/src/components/stepCard/StepCard.tsx
index 448bb1e..8753b40 100644
--- a/src/components/stepCard/StepCard.tsx
+++ b/src/components/stepCard/StepCard.tsx
@@ -19,6 +19,7 @@ export const StepCard = (props: StepCardProps) => {
   return (
     <Paper className="card">
       <Text>StepName : {props.step.name}</Text>
+      <Text>StepId : {props.step.stepId}</Text>
       <Text>StepOrder : {props.step.order}</Text>
       {props.step.order !== 1 && props.travel && (
         <>
diff --git a/src/components/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx b/src/components/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx
index bbd9a49..78a76c6 100644
--- a/src/components/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx
+++ b/src/components/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx
@@ -1,10 +1,12 @@
+import { AddTravelDto, StepDto } from '@FullStackMap/from-a2b';
 import { Button, Group, Modal, Stack, Text } from '@mantine/core';
 import { IconTrash } from '@tabler/icons-react';
 import { useMutation, useQueryClient } from '@tanstack/react-query';
-import { Position } from 'geojson';
+import { useEffect, useState } from 'react';
 import useNotify from '../../../hooks/useNotify';
-import { StepController } from '../../../services/BaseApi';
+import { StepController, TravelController } from '../../../services/BaseApi';
 import { calculateRoad } from '../../../services/api/MapboxController';
+import CalculateTravelRoadDto from '../../../services/api/Models/MapBoxDirections/CalculateTravelRoadDto';
 import DirectionMode from '../../../services/api/Models/MapBoxDirections/DirectionMode';
 import RoadPositionDto from '../../../services/api/Models/MapBoxDirections/RoadPositionDto';
 import {
@@ -13,93 +15,120 @@ import {
 } from '../../../store/useTripDetailsStore';
 
 export type ConfirmDeleteModalProps = {
+  stepId: number;
   opened: boolean;
   close: () => void;
 };
 
-interface getTravelBetweenPositionsArgs {
-  drivingMode: DirectionMode;
-  data: Position[];
-}
-
 export const ConfirmDeleteModal = (props: ConfirmDeleteModalProps) => {
   const queryClient = useQueryClient();
-  const { ErrorNotify } = useNotify();
-
-  const selectedStep = useTripDetailsStore(
-    (state: TripDetailsStore) => state.selectedStep,
-  );
-  const selectedStepBefore = useTripDetailsStore(
-    (state: TripDetailsStore) => state.selectedStepBefore,
-  );
-  const selectedStepAfter = useTripDetailsStore(
-    (state: TripDetailsStore) => state.selectedStepAfter,
+  const { SuccessNotify } = useNotify();
+  const steps: StepDto[] = useTripDetailsStore(
+    (state: TripDetailsStore) => state.steps,
   );
 
+  const [stepBefore, SetStepBefore] = useState<StepDto | undefined>();
+  const [currentStep, SetCurrentStep] = useState<StepDto | undefined>();
+  const [stepAfter, SetStepAfter] = useState<StepDto | undefined>();
+  const [newTravelRoad, SetNewTravelRoad] = useState<
+    CalculateTravelRoadDto | undefined
+  >();
+
+  useEffect(() => {
+    if (!props.stepId && steps.length == 0) return;
+
+    const currentStep: StepDto | undefined = steps.find(
+      step => step.stepId === props.stepId,
+    );
+    if (!currentStep) return;
+
+    const stepBefore: StepDto | undefined = steps.find(
+      (step: StepDto) => step.order === currentStep.order! - 1,
+    );
+    const stepAfter: StepDto | undefined = steps.find(
+      (step: StepDto) => step.order === currentStep.order! + 1,
+    );
+
+    SetStepBefore(stepBefore);
+    SetCurrentStep(currentStep);
+    SetStepAfter(stepAfter);
+  }, [props.stepId, steps]);
+
+  useEffect(() => {
+    if (!newTravelRoad) return;
+
+    const addTravelRoad: AddTravelDto = {
+      transportMode: DirectionMode.DRIVING,
+      distance: Number(newTravelRoad.distance.toFixed(2)),
+      duration: Number(newTravelRoad.duration.toFixed(2)),
+      originStepId: stepBefore?.stepId as number,
+      destinationStepId: stepAfter?.stepId as number,
+      travelRoad: newTravelRoad.travelRoad,
+    };
+
+    saveTravelRoadMutation.mutate(addTravelRoad);
+  }, [newTravelRoad]);
+
   const deleteStepMutation = useMutation({
     mutationFn: async () =>
       await StepController.deleteStepByIdAsyncDELETE(
-        selectedStep?.stepId as number,
-      ),
-    onSuccess: () => {
-      console.log(
-        '🚀 ~ ConfirmDeleteModal ~ selectedStep?.tripId:',
-        selectedStep?.tripId,
-      );
+        currentStep?.stepId as number,
+      ).then(() => {
+        SuccessNotify({
+          title: 'Suppression réussie',
+          message: "L'étape a été supprimée avec succès",
+          autoClose: 5000,
+        });
+      }),
+  });
+  const calculateTravelRoadMutation = useMutation({
+    mutationFn: async ([directionMode, positions]: [
+      directionMode: DirectionMode,
+      positions: RoadPositionDto[],
+    ]) =>
+      await calculateRoad(directionMode, positions)
+        .then(res => SetNewTravelRoad(res))
+        .catch(() => {
+          queryClient.invalidateQueries({
+            queryKey: ['Trip', currentStep?.tripId?.toUpperCase()],
+          });
+        }),
+  });
+  const saveTravelRoadMutation = useMutation({
+    mutationFn: async (addTravelRoad: AddTravelDto) =>
+      await TravelController.addTravelBetweenStepsPOST(addTravelRoad),
+
+    onSettled: () => {
+      SetNewTravelRoad(undefined);
       queryClient.invalidateQueries({
-        queryKey: ['Trip', selectedStep?.tripId?.toUpperCase() as string],
+        queryKey: ['Trip', currentStep?.tripId?.toUpperCase()],
       });
     },
   });
 
   const handleDeleteStep = async () => {
     await deleteStepMutation.mutateAsync();
-    if (deleteStepMutation.isError) props.close();
+    props.close();
 
-    if (selectedStepBefore && selectedStepAfter) {
+    if (stepBefore && stepAfter) {
       const startEndPosition: RoadPositionDto[] = [
         {
           start: [
-            selectedStepBefore.longitude as number,
-            selectedStepBefore.latitude as number,
-          ],
-          end: [
-            selectedStepAfter?.longitude as number,
-            selectedStepAfter?.latitude as number,
+            stepBefore.longitude as number,
+            stepBefore.latitude as number,
           ],
+          end: [stepAfter?.longitude as number, stepAfter?.latitude as number],
         },
       ];
 
-      await calculateRoad(DirectionMode.DRIVING, startEndPosition)
-        .then(res =>
-          console.log(
-            '🚀 ~ file: ConfirmDeleteModal.tsx ~ line 77 ~ handleDeleteStep ~ res',
-            res,
-          ),
-        )
-        .catch(err => {
-          switch (err.response?.data?.code) {
-            case 'InvalidInput':
-              ErrorNotify({
-                title: 'Échec du calcul du nouvel itinéraire',
-                message:
-                  'La distance entre les deux points est trop grande pour ce mode de transport',
-                autoClose: undefined,
-              });
-              break;
-
-            default:
-              ErrorNotify({
-                title: 'Échec du calcul du nouvel itinéraire',
-                message:
-                  "Une erreur est survenue lors du calcul de l'itinéraire entre les deux points de passage. Veuillez réessayer plus tard.",
-                autoClose: undefined,
-              });
-              break;
-          }
-          console.error(err);
-        });
+      await calculateTravelRoadMutation.mutateAsync([
+        DirectionMode.DRIVING,
+        startEndPosition,
+      ]);
     }
+    queryClient.invalidateQueries({
+      queryKey: ['Trip', currentStep?.tripId?.toUpperCase()],
+    });
   };
 
   return (
@@ -113,7 +142,7 @@ export const ConfirmDeleteModal = (props: ConfirmDeleteModalProps) => {
         <Modal.Body>
           <Stack>
             <Text>Êtes-vous sûr de vouloir supprimer l'étape :</Text>
-            <Text>{selectedStep?.name}</Text>
+            <Text>{currentStep?.name}</Text>
             <Group justify="flex-end">
               <Button variant="outline" onClick={() => props.close()}>
                 Annuler
diff --git a/src/pages/map/MapPage.tsx b/src/pages/map/MapPage.tsx
index 17eecf9..aa7cab5 100644
--- a/src/pages/map/MapPage.tsx
+++ b/src/pages/map/MapPage.tsx
@@ -1,4 +1,5 @@
 import {
+  AddStepDto,
   AddTravelDto,
   StepDto,
   StepDtoList,
@@ -34,7 +35,10 @@ import { calculateRoad } from '../../services/api/MapboxController';
 import CalculateTravelRoadDto from '../../services/api/Models/MapBoxDirections/CalculateTravelRoadDto';
 import DirectionMode from '../../services/api/Models/MapBoxDirections/DirectionMode';
 import RoadPositionDto from '../../services/api/Models/MapBoxDirections/RoadPositionDto';
-import { useTripDetailsStore } from '../../store/useTripDetailsStore';
+import {
+  TripDetailsStore,
+  useTripDetailsStore,
+} from '../../store/useTripDetailsStore';
 
 interface updateStepLocationMutationProps {
   stepId: number;
@@ -43,7 +47,13 @@ interface updateStepLocationMutationProps {
 
 const MapPage = () => {
   useDocumentTitle('From A2B - Map');
-  const { steps, travels, SetSteps, SetTravels } = useTripDetailsStore();
+  const { SetSteps, SetTravels } = useTripDetailsStore();
+  const steps: StepDto[] = useTripDetailsStore(
+    (state: TripDetailsStore) => state.steps,
+  );
+  const travels: TravelDtoList[] = useTripDetailsStore(
+    (state: TripDetailsStore) => state.travels,
+  );
 
   const { ErrorNotify } = useNotify();
 
@@ -51,8 +61,7 @@ const MapPage = () => {
 
   const queryClient = useQueryClient();
 
-  // const tripId = 'AA16BE27-5E15-489D-C043-08DC4F3894F7';
-  const tripId = '969059C1-EBD1-44E8-C047-08DC4F3894F7';
+  const tripId = 'A8EB1FCE-B9DE-4201-B1FC-08DC4FD48062';
   const { data: trip } = useQuery({
     queryKey: ['Trip', tripId],
     queryFn: async () =>
@@ -80,19 +89,26 @@ const MapPage = () => {
 
   //#region States
   const [viewState, setViewState] = React.useState({
-    longitude: 4.860200783597507,
-    latitude: 45.73050608112574,
-    zoom: 2,
-    pitch: 30,
-    bearing: 0,
+    longitude: 11.954124476295533,
+    latitude: 4.92847043661213,
+    zoom: 2.6680390382433834,
+    pitch: 0,
+    bearing: 90.25375000000258,
   });
+  // const [viewState, setViewState] = React.useState({
+  //   longitude: 4.860200783597507,
+  //   latitude: 45.73050608112574,
+  //   zoom: 2,
+  //   pitch: 30,
+  //   bearing: 0,
+  // });
 
   // const [dto, setDto] = useState([
-  //   // {
-  //   //   start: [4.860200783597507, 45.73050608112574],
-  //   //   end: [5.079252160492843, 45.71892384847893],
-  //   // },
-  //   // Ajoutez d'autres coordonnées initiales ici si nécessaire
+  // {
+  //   start: [4.860200783597507, 45.73050608112574],
+  //   end: [5.079252160492843, 45.71892384847893],
+  // },
+  // // Ajoutez d'autres coordonnées initiales ici si nécessaire
   // ]);
 
   //#endregion
@@ -171,38 +187,38 @@ const MapPage = () => {
         },
       ];
 
-      const travelBeforeResponse: CalculateTravelRoadDto = await calculateRoad(
-        DirectionMode.DRIVING,
-        startEndPosition,
-      ).catch(err => {
-        switch (err.response?.data?.code) {
-          case 'InvalidInput':
-            ErrorNotify({
-              title: 'Échec du calcul du nouvel itinéraire',
-              message:
-                'La distance entre les deux points est trop grande pour ce mode de transport',
-              autoClose: undefined,
-            });
-            break;
-          case 'NoRoute':
-            ErrorNotify({
-              title: 'Échec du calcul du nouvel itinéraire',
-              message: "Aucune route n'a été trouvée entre les deux points",
-              autoClose: undefined,
-            });
-            break;
-
-          default:
-            ErrorNotify({
-              title: 'Échec du calcul du nouvel itinéraire',
-              message:
-                "Une erreur est survenue lors du calcul de l'itinéraire entre les deux points de passage. Veuillez réessayer plus tard.",
-              autoClose: undefined,
-            });
-            break;
-        }
-        console.error(err);
-      });
+      const travelBeforeResponse: CalculateTravelRoadDto | undefined =
+        await calculateRoad(DirectionMode.DRIVING, startEndPosition).catch(
+          err => {
+            switch (err.response?.data?.code) {
+              case 'InvalidInput':
+                ErrorNotify({
+                  title: 'Échec du calcul du nouvel itinéraire',
+                  message:
+                    'La distance entre les deux points est trop grande pour ce mode de transport',
+                  autoClose: undefined,
+                });
+                break;
+              case 'NoRoute':
+                ErrorNotify({
+                  title: 'Échec du calcul du nouvel itinéraire',
+                  message: "Aucune route n'a été trouvée entre les deux points",
+                  autoClose: undefined,
+                });
+                break;
+
+              default:
+                ErrorNotify({
+                  title: 'Échec du calcul du nouvel itinéraire',
+                  message:
+                    "Une erreur est survenue lors du calcul de l'itinéraire entre les deux points de passage. Veuillez réessayer plus tard.",
+                  autoClose: undefined,
+                });
+                break;
+            }
+            console.error(err);
+          },
+        );
 
       const addTravelDto: AddTravelDto = {
         transportMode: travelBeforeResponse.transportMode,
@@ -338,29 +354,17 @@ const MapPage = () => {
     },
   };
 
-  // const addPoint = (evt: any) => {
-  //   console.log('hello', evt.lngLat);
-  //   // @ts-ignore
-  //   setSteps([
-  //     ...steps,
-  //     { latitude: evt.lngLat.lat, longitude: evt.lngLat.lng },
-  //   ]);
-  //   console.log('steps', steps);
-  //   // @ts-ignore
-  //   if (steps.length > 0) {
-  //     setDto([
-  //       ...dto,
-  //       {
-  //         start: [
-  //           steps[steps.length - 1].longitude,
-  //           steps[steps.length - 1].latitude,
-  //         ],
-  //         end: [evt.lngLat.lng, evt.lngLat.lat],
-  //       },
-  //     ]);
-  //     console.log('dto', dto);
-  //   }
-  // };
+  const addPoint = async (evt: any) => {
+    console.log('hello', evt.lngLat.lat, evt.lngLat.lng);
+    await StepController.addStepAsyncPOST(tripId, {
+      name: 'Nouvelle étape',
+      description: 'Description de la nouvelle étape',
+      latitude: evt.lngLat.lat,
+      longitude: evt.lngLat.lng,
+    } as AddStepDto).then(() =>
+      queryClient.invalidateQueries({ queryKey: ['Trip', tripId] }),
+    );
+  };
 
   //#endregion
   return (
@@ -379,11 +383,11 @@ const MapPage = () => {
       <Map
         {...viewState}
         onMove={evt => setViewState(evt.viewState)}
-        // onClick={addPoint}
+        onClick={addPoint}
         minZoom={2}
         dragRotate={true}
         mapStyle="mapbox://styles/mapbox/streets-v12"
-        mapboxAccessToken="pk.eyJ1IjoiZGVyY3Jha2VyIiwiYSI6ImNsdHVnczc4dTB6N2QyanFwZDR1N2c2eHoifQ.arP7tBErlINY3-uiwfb7Ww"
+        mapboxAccessToken={import.meta.env.VITE_MAPBOX_TOKEN}
         attributionControl={true}
         style={{
           height: '93vh',
diff --git a/src/pages/test/TestPage.tsx b/src/pages/test/TestPage.tsx
new file mode 100644
index 0000000..91a35c4
--- /dev/null
+++ b/src/pages/test/TestPage.tsx
@@ -0,0 +1,23 @@
+import { Button } from '@mantine/core';
+import { useDisclosure } from '@mantine/hooks';
+import { TestModal, testDto } from './components/TestModal';
+
+const TestPage = () => {
+  const [isModalOpenned, ModalController] = useDisclosure(false);
+
+  const handleModalClose = (dto: testDto) => {
+    console.log(dto);
+    ModalController.close();
+  };
+  return (
+    <>
+      <Button onClick={() => ModalController.open()}>Open Modal</Button>
+      <TestModal
+        isOpenned={isModalOpenned}
+        handleClose={dto => handleModalClose(dto)}
+      />
+    </>
+  );
+};
+
+export default TestPage;
diff --git a/src/pages/test/components/TestModal.tsx b/src/pages/test/components/TestModal.tsx
new file mode 100644
index 0000000..454cc29
--- /dev/null
+++ b/src/pages/test/components/TestModal.tsx
@@ -0,0 +1,26 @@
+import { Button, Modal } from '@mantine/core';
+import { useState } from 'react';
+
+export interface testDto {
+  id: number;
+  name: string;
+}
+
+export type TestModalProps = {
+  isOpenned: boolean;
+  handleClose: (dto: testDto) => void;
+};
+
+export const TestModal = (props: TestModalProps) => {
+  const [dto, setDto] = useState<testDto>({});
+
+  return (
+    <Modal opened={props.isOpenned} onClose={() => props.handleClose(dto)}>
+      <div>
+        <h1>Test Modal</h1>
+        <button onClick={() => setDto({ id: 1, name: 'test' })}>Set dto</button>
+      </div>
+      <Button onClick={() => props.handleClose(dto)}>Add Step</Button>
+    </Modal>
+  );
+};
diff --git a/src/router/Router.tsx b/src/router/Router.tsx
index d7d75b2..102193d 100644
--- a/src/router/Router.tsx
+++ b/src/router/Router.tsx
@@ -6,6 +6,7 @@ import LoginLayout from '../layout/login/LoginLayout';
 import CguPage from '../pages/cgu/CguPage';
 import { ConfirmMailPage } from '../pages/confirmMail/ConfirmMailPage';
 import ContactPage from '../pages/contact/ContactPage';
+import { EditTravel } from '../pages/editTravel/EditTravel.tsx';
 import FaqPage from '../pages/faq/FaqPage';
 import FeedbackPage from '../pages/feedback/FeedbackPage';
 import { ForgotPasswordPage } from '../pages/forgotPassword/ForgotPasswordPage';
@@ -14,9 +15,9 @@ import { LoginPage } from '../pages/login/LoginPage';
 import MapPage from '../pages/map/MapPage';
 import ProfilePage from '../pages/profile/ProfilePage.tsx';
 import { RegisterPage } from '../pages/register/RegisterPage';
+import TestPage from '../pages/test/TestPage.tsx';
 import { AuthStore, useAuthStore } from '../store/useAuthStore';
 import { PrivateRoute } from './PrivateRoute';
-import { EditTravel } from '../pages/editTravel/EditTravel.tsx'
 
 const Router = () => {
   const loadUser: () => void = useAuthStore((s: AuthStore) => s.loadUser);
@@ -30,17 +31,27 @@ const Router = () => {
         <Route path="/cgu" element={<CguPage />} />
         <Route path="/contact" element={<ContactPage />} />
         <Route path="/faq" element={<FaqPage />} />
+        <Route path="/t" element={<TestPage />} />
         <Route
-        path="/editTravel"
-        element={
-          <PrivateRoute
-            authRequired
-            redirectPath="/login"
-            element={<EditTravel/>}
-          />
-        }
+          path="/editTravel"
+          element={
+            <PrivateRoute
+              authRequired
+              redirectPath="/login"
+              element={<EditTravel />}
+            />
+          }
+        />
+        <Route
+          path="/map"
+          element={
+            <PrivateRoute
+              authRequired
+              redirectPath="/login"
+              element={<MapPage />}
+            />
+          }
         />
-        <Route path="/map" element={<MapPage />} />
         <Route path="/*" element={<Navigate to="/" />} />
         <Route
           path="/profile"
diff --git a/src/services/BaseApi.ts b/src/services/BaseApi.ts
index aa3c789..9ca4e65 100644
--- a/src/services/BaseApi.ts
+++ b/src/services/BaseApi.ts
@@ -8,8 +8,9 @@ const token: string | undefined = Cookies.get('Auth-Token');
 const configAno = new client.Configuration({
   basePath: basePath,
 });
-
-export const AnoAuthController = client.AuthApiFactory(configAno);
+export const AnoAxiosClient = axios.create({
+  baseURL: basePath,
+});
 
 const TripControllerFunc = () => {
   const configLogged = new client.Configuration({
@@ -22,8 +23,6 @@ const TripControllerFunc = () => {
   });
   return client.TripApiFactory(configLogged);
 };
-export const TripController = TripControllerFunc();
-
 const UserControllerFunc = () => {
   const configLogged = new client.Configuration({
     basePath: basePath,
@@ -36,10 +35,6 @@ const UserControllerFunc = () => {
 
   return client.UserApiFactory(configLogged);
 };
-
-export const AnoAxiosClient = axios.create({
-  baseURL: basePath,
-});
 const StepControllerFunc = () => {
   const configLogged = new client.Configuration({
     basePath: basePath,
@@ -51,8 +46,6 @@ const StepControllerFunc = () => {
   });
   return client.StepApiFactory(configLogged);
 };
-export const StepController = StepControllerFunc();
-
 const TravelControllerFunc = () => {
   const configLogged = new client.Configuration({
     basePath: basePath,
@@ -64,14 +57,14 @@ const TravelControllerFunc = () => {
   });
   return client.TravelApiFactory(configLogged);
 };
-export const TravelController = TravelControllerFunc();
 
 export const MapboxClient = axios.create({
   baseURL: 'https://api.mapbox.com',
 });
 
 export const TripController = TripControllerFunc();
+export const StepController = StepControllerFunc();
+export const TravelController = TravelControllerFunc();
+export const UserController = UserControllerFunc();
 
 export const AnoAuthController = client.AuthApiFactory(configAno);
-
-export const UserController = UserControllerFunc();
diff --git a/src/services/api/MapboxController.ts b/src/services/api/MapboxController.ts
index b794d6b..1a64a02 100644
--- a/src/services/api/MapboxController.ts
+++ b/src/services/api/MapboxController.ts
@@ -1,11 +1,12 @@
 import { Position } from 'geojson';
+import useNotify from '../../hooks/useNotify';
 import { MapboxClient } from '../BaseApi';
 import CalculateTravelRoadDto from './Models/MapBoxDirections/CalculateTravelRoadDto';
 import DirectionMode from './Models/MapBoxDirections/DirectionMode';
 import RoadPositionDto from './Models/MapBoxDirections/RoadPositionDto';
 
-const mapBoxToken =
-  'pk.eyJ1IjoiZGVyY3Jha2VyIiwiYSI6ImNsdHVnczc4dTB6N2QyanFwZDR1N2c2eHoifQ.arP7tBErlINY3-uiwfb7Ww';
+// eslint-disable-next-line react-hooks/rules-of-hooks
+const { ErrorNotify } = useNotify();
 
 export const calculateRoad = async (
   directionMode: DirectionMode,
@@ -16,17 +17,42 @@ export const calculateRoad = async (
     .join(';');
 
   const response = await MapboxClient.get(
-    `/directions/v5/mapbox/${directionMode}/${positionsString}/?geometries=geojson&overview=full&access_token=${mapBoxToken}`,
+    `/directions/v5/mapbox/${directionMode}/${positionsString}/?geometries=geojson&overview=full&access_token=${
+      import.meta.env.VITE_MAPBOX_TOKEN
+    }`,
   );
-  const data = response.data.routes[0];
-  const coords: Position[] = data.geometry.coordinates;
 
-  const travelRoadDto: CalculateTravelRoadDto = {
-    transportMode: DirectionMode.DRIVING,
-    distance: data.distance,
-    duration: data.duration,
-    travelRoad: JSON.stringify(coords),
-  };
+  switch (response?.data?.code) {
+    case 'InvalidInput':
+      ErrorNotify({
+        title: 'Échec du calcul du nouvel itinéraire',
+        message:
+          'La distance entre les deux points est trop grande pour ce mode de transport',
+        autoClose: undefined,
+      });
+      throw new Error('InvalidInput');
 
-  return travelRoadDto;
+    case 'NoSegment':
+      ErrorNotify({
+        title: 'Échec du calcul du nouvel itinéraire',
+        message:
+          'Le trajet entre les deux points de passage ne peut pas être calculé pour ce mode de transport.',
+        autoClose: undefined,
+      });
+      throw new Error('NoSegment');
+
+    case 'Ok': {
+      const data = response.data.routes[0];
+      const coords: Position[] = data.geometry.coordinates;
+
+      const travelRoadDto: CalculateTravelRoadDto = {
+        transportMode: DirectionMode.DRIVING,
+        distance: data.distance,
+        duration: data.duration,
+        travelRoad: JSON.stringify(coords),
+      };
+
+      return travelRoadDto;
+    }
+  }
 };
diff --git a/src/store/useTripDetailsStore.ts b/src/store/useTripDetailsStore.ts
index ea2aa98..5a35a68 100644
--- a/src/store/useTripDetailsStore.ts
+++ b/src/store/useTripDetailsStore.ts
@@ -6,8 +6,12 @@ export type TripDetailsStore = {
   setStatus: (status: boolean) => void;
 
   steps: StepDto[];
+  currentStep: StepDto;
+  SelectStep: (stepId: number) => void;
   SetSteps: (steps: StepDto[]) => void;
 
+  Unselect: () => void;
+
   travels: TravelDtoList[];
   SetTravels: (travels: TravelDtoList[]) => void;
 };
@@ -17,7 +21,14 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
   setStatus: (status: boolean) => set({ status }),
 
   steps: [],
+  currentStep: {} as StepDto,
   SetSteps: (steps: StepDto[]) => set({ steps }),
+  SelectStep: (stepId: number) =>
+    set((state: TripDetailsStore) => {
+      const currentStep = state.steps.find(step => step.stepId === stepId);
+      return { currentStep: currentStep };
+    }),
+  Unselect: () => set({ currentStep: {} as StepDto }),
 
   travels: [],
   SetTravels: (travels: TravelDtoList[]) => set({ travels }),
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
index 29c29a1..d3a698f 100644
--- a/src/vite-env.d.ts
+++ b/src/vite-env.d.ts
@@ -2,6 +2,7 @@
 
 interface ImportMetaEnv {
   readonly VITE_API_URL: string;
+  readonly VITE_MAPBOX_TOKEN: string;
 }
 
 interface ImportMeta {

From 303401bb37c7859e0407f05fd6fb91df3f4ab095 Mon Sep 17 00:00:00 2001
From: Baptiste-Ferrand <baptiste.ferrand@ynov.com>
Date: Fri, 29 Mar 2024 16:26:44 +0100
Subject: [PATCH 16/34] create setStore

---
 src/store/useStepStore.ts | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 src/store/useStepStore.ts

diff --git a/src/store/useStepStore.ts b/src/store/useStepStore.ts
new file mode 100644
index 0000000..1cecff2
--- /dev/null
+++ b/src/store/useStepStore.ts
@@ -0,0 +1,37 @@
+import { StepDto } from '@FullStackMap/from-a2b';
+import { create } from 'zustand';
+
+
+export type StepStore = {
+
+  status: boolean;
+  setStatus: (status: boolean) => void;
+
+  step: StepDto;
+  SetStep: (steps: StepDto) => void;
+
+  stepSelectedId: number;
+  SetStepSelectedId: (stepId: number) => void;
+
+};
+
+export const useStepStore = create<StepStore>(set => ({
+
+  status: false,
+  setStatus: (status: boolean) => set({ status }),
+
+  step: {
+    stepId: 0,
+    name: '',
+    description: '',
+    startDate: '',
+    endDate: '',
+    latitude: undefined,
+    longitude: undefined,
+  } as StepDto,
+  SetStep: (step: StepDto) => set({ step }),
+
+  stepSelectedId: 0,
+  SetStepSelectedId: (stepId: number) => set({ stepSelectedId: stepId }),
+}));
+

From c80ce7aab57faac009a30bdb195ddc3c61ef7e7b Mon Sep 17 00:00:00 2001
From: Baptiste-Ferrand <baptiste.ferrand@ynov.com>
Date: Fri, 29 Mar 2024 16:26:54 +0100
Subject: [PATCH 17/34] create PlaceLocationDto.ts

---
 src/services/api/Models/PlaceLocation/PlaceLocationDto.ts | 7 +++++++
 1 file changed, 7 insertions(+)
 create mode 100644 src/services/api/Models/PlaceLocation/PlaceLocationDto.ts

diff --git a/src/services/api/Models/PlaceLocation/PlaceLocationDto.ts b/src/services/api/Models/PlaceLocation/PlaceLocationDto.ts
new file mode 100644
index 0000000..464da48
--- /dev/null
+++ b/src/services/api/Models/PlaceLocation/PlaceLocationDto.ts
@@ -0,0 +1,7 @@
+
+export type PlaceDto = {
+  place: string
+  coordinate: [number, number]
+}
+
+

From 3b277952873df94c533c058ce6862fc397718277 Mon Sep 17 00:00:00 2001
From: Baptiste-Ferrand <baptiste.ferrand@ynov.com>
Date: Fri, 29 Mar 2024 16:27:33 +0100
Subject: [PATCH 18/34] update modal now modal use store for getting and update
 data, api call is not in the modal now

---
 .../createStepModal/CreateStepModal.tsx       | 83 ++++++++++---------
 .../mapStepEditor/MapStepEditor.tsx           |  4 +-
 src/services/api/MapboxController.ts          | 18 +++-
 3 files changed, 63 insertions(+), 42 deletions(-)

diff --git a/src/components/createStepModal/CreateStepModal.tsx b/src/components/createStepModal/CreateStepModal.tsx
index 8f8b725..7311fa1 100644
--- a/src/components/createStepModal/CreateStepModal.tsx
+++ b/src/components/createStepModal/CreateStepModal.tsx
@@ -6,27 +6,22 @@ import { useForm } from '@mantine/form';
 import { zodResolver } from 'mantine-form-zod-resolver';
 import { z } from 'zod';
 
-import { useTripDetailsStore } from '../../store/useTripDetailsStore.ts'
-import { getPlace } from '../../services/api/MapboxController.ts'
+import {useStepStore} from '../../store/useStepStore.ts'
+import { getPlaces, getPlaceWhitCoordinate } from '../../services/api/MapboxController.ts'
 
-import {useMutation, QueryClient} from '@tanstack/react-query'
-
-import { AddStepDto } from '@FullStackMap/from-a2b';
-import { StepController } from '../../services/BaseApi.ts'
-
-const queryClient = new QueryClient();
+import {PlaceDto} from '../../services/api/Models/PlaceLocation/PlaceLocationDto.ts'
 
 export const CreateStepModal=()=> {
 
-  const tripId: string = useTripDetailsStore((state) => state.trip.tripId);
-
   const [value, setValue] = useDebouncedState('', 200, { leading: true });
-  const [places, setPlaces] = useState([]);
+  const [places, setPlaces] = useState<PlaceDto[]>([]);
+
+
 
   useEffect(() => {
     const fetchPlaces = async () => {
 
-      setPlaces(await getPlace(value));
+      setPlaces(await getPlaces(value));
     };
 
     if (value) {
@@ -34,17 +29,38 @@ export const CreateStepModal=()=> {
     }
   }, [value]);
 
-  const isOpen = useTripDetailsStore((state) => state.status);
-  const close = useTripDetailsStore((state) => state.setStatus);
 
-  const createStep = useMutation({
-    mutationFn: (data: AddStepDto )=> StepController.addStepAsyncPOST(tripId, data).catch((error)=>{
-      throw new Error(error);
-  }),
-    onSuccess: () => {
-      queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
-    },
-  });
+
+  // get coordinate
+  const getCoordinate = (place:string)=>{
+    const coordinate  = places.find((item)=> item.place === place)
+    console.log(coordinate?.coordinate, 'les coordonée')
+    return coordinate?.coordinate
+  }
+
+  // call modal status
+  const isOpen = useStepStore((state) => state.status);
+
+  const close = useStepStore((state) => state.setStatus);
+  // get data steDto from store
+  const step = useStepStore((state) => state.step);
+
+  if (step.latitude !== undefined && step.longitude !== undefined) {
+    getPlaceWhitCoordinate(step.latitude, step.longitude).then((res) => {
+      console.log(res, 'place')
+    });
+  }
+
+  // console.log(step, 'step')
+
+  // const createStep = useMutation({
+  //   mutationFn: (data: AddStepDto )=> StepController.addStepAsyncPOST(tripId, data).catch((error)=>{
+  //     throw new Error(error);
+  // }),
+  //   onSuccess: () => {
+  //     queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
+  //   },
+  // });
 
 
   const stepSchema = z.object({
@@ -59,18 +75,16 @@ export const CreateStepModal=()=> {
     validateInputOnChange: true,
     validate: zodResolver(stepSchema),
     initialValues: {
-      title: '',
-      description: '',
+      title: step.name,
+      description: step.description,
     },
   });
 
+  // const updateStoreData = (data: any) => {
+  //
+  // }
 
 
-  const getCoordinate = (place:string)=>{
-    const coordinate  = places.find((item)=> item.place === place)
-    return coordinate?.coordinate
-  }
-
   return (
       <Modal
         opened={isOpen}
@@ -106,7 +120,6 @@ export const CreateStepModal=()=> {
             placeholder="Entrez une adresse"
             data={places.map(item=> ({ label: item.place, value: item.place }))}
             onChange={(event)=> setValue(event)}
-
           />
 
           <Group justify="flex-end" mt="md">
@@ -115,15 +128,7 @@ export const CreateStepModal=()=> {
               type="submit"
               mt="sm"
               disabled={!stepForm.isValid() }
-              onClick={(event)=>{
-                event.preventDefault();
-                createStep.mutate({
-                  name: stepForm.values.title,
-                  description: stepForm.values.description,
-                  latitude: getCoordinate(value)?.latitude,
-                  longitude: getCoordinate(value)?.longitude,
-                });
-              }}>
+              onClick={()=>console.log("cliquer bande de solope")}>
               Sauvegarder
             </Button>
           </Group>
diff --git a/src/components/mapStepEditor/MapStepEditor.tsx b/src/components/mapStepEditor/MapStepEditor.tsx
index 3f0109a..406459a 100644
--- a/src/components/mapStepEditor/MapStepEditor.tsx
+++ b/src/components/mapStepEditor/MapStepEditor.tsx
@@ -25,7 +25,7 @@ import {
 import { StepController, TripController } from '../../services/BaseApi';
 import { calculateRoad } from '../../services/api/MapboxController';
 
-import { useTripDetailsStore } from '../../store/useTripDetailsStore.ts';
+import { useStepStore } from '../../store/useStepStore.ts';
 
 interface updateStepLocationMutationProps {
   stepId: number;
@@ -35,7 +35,7 @@ interface updateStepLocationMutationProps {
 export const MapStepEditor = () => {
   useDocumentTitle('From A2B - Map');
 
-  const setIsStepModalOpen = useTripDetailsStore(state => state.setStatus);
+  const setIsStepModalOpen = useStepStore(state => state.setStatus);
 
   const handleCreateStep = () => {
     setIsStepModalOpen(true);
diff --git a/src/services/api/MapboxController.ts b/src/services/api/MapboxController.ts
index 377b23c..bfa6037 100644
--- a/src/services/api/MapboxController.ts
+++ b/src/services/api/MapboxController.ts
@@ -2,6 +2,7 @@ import { Position } from 'geojson';
 import { MapboxClient } from '../BaseApi';
 import DirectionMode from './Models/MapBoxDirections/DirectionMode';
 import RoadPositionDto from './Models/MapBoxDirections/RoadPositionDto';
+import { PlaceDto } from './Models/PlaceLocation/PlaceLocationDto.ts'
 
 const mapBoxToken =
   'pk.eyJ1IjoiZGVyY3Jha2VyIiwiYSI6ImNsdHVnczc4dTB6N2QyanFwZDR1N2c2eHoifQ.arP7tBErlINY3-uiwfb7Ww';
@@ -24,12 +25,27 @@ export const calculateRoad = async (
   return coords;
 };
 
-export const getPlace = async(place: string)=>{
+export const getPlaces = async(place: string)=>{
 
   let response = await MapboxClient.get(
     `/geocoding/v5/mapbox.places/${place}.json?proximity=ip&language=fr&access_token=${mapBoxToken}`,
   );
 
+  const places : PlaceDto[] = response.data.features.map((item: { place_name_fr: any; center: any; })=>{
+    return {
+      place: item.place_name_fr,
+      coordinate: item.center
+    }
+  })
+  return places;
+}
+
+export const getPlaceWhitCoordinate = async (latitude:number, longitude:number)=>{
+  let response = await MapboxClient.get(
+    `/geocoding/v5/mapbox.places/${longitude},${latitude}.json?proximity=ip&language=fr&access_token=${mapBoxToken}`,
+
+  );
+
   response = response.data.features.map((item: { place_name_fr: any; center: any; })=>{
     return {
       place: item.place_name_fr,

From eaf7d90e29588ec20153159b2bb5890667ecdc04 Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Fri, 29 Mar 2024 20:04:42 +0100
Subject: [PATCH 19/34] Feat (Map) : [WIP] Merge

---
 package.json                                  |   2 +-
 pnpm-lock.yaml                                |   8 +-
 .../createStepModal/CreateStepModal.tsx       | 234 +++++-----
 src/components/map/MapComponent.tsx           | 307 ++++++++++++++
 .../{ => map}/stepCard/Menu/StepCardMenu.tsx  |   0
 src/components/map/stepCard/StepList.scss     |   6 +
 src/components/map/stepCard/StepList.tsx      |  39 ++
 .../confirmDeleteModal/ConfirmDeleteModal.tsx |  14 +-
 .../{ => map/stepCard}/stepCard/StepCard.scss |   1 +
 .../{ => map/stepCard}/stepCard/StepCard.tsx  |  10 +-
 src/layout/halfMap/HalfMapLayout.scss         |   9 -
 src/layout/halfMap/HalfMapLayout.tsx          |  38 --
 src/pages/map/MapPage.tsx                     | 398 +-----------------
 src/pages/tripDetail/TripDetailPage.tsx       | 121 ++++++
 src/router/Router.tsx                         |  16 +-
 src/services/api/MapboxController.ts          |  58 +--
 .../Models/PlaceLocation/PlaceLocationDto.ts  |   9 +-
 src/store/useStepStore.ts                     |   7 +-
 src/store/useTripDetailsStore.ts              |  19 +-
 19 files changed, 704 insertions(+), 592 deletions(-)
 create mode 100644 src/components/map/MapComponent.tsx
 rename src/components/{ => map}/stepCard/Menu/StepCardMenu.tsx (100%)
 create mode 100644 src/components/map/stepCard/StepList.scss
 create mode 100644 src/components/map/stepCard/StepList.tsx
 rename src/components/{ => map}/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx (89%)
 rename src/components/{ => map/stepCard}/stepCard/StepCard.scss (90%)
 rename src/components/{ => map/stepCard}/stepCard/StepCard.tsx (77%)
 delete mode 100644 src/layout/halfMap/HalfMapLayout.scss
 delete mode 100644 src/layout/halfMap/HalfMapLayout.tsx
 create mode 100644 src/pages/tripDetail/TripDetailPage.tsx

diff --git a/package.json b/package.json
index c9f3fd2..dfaf5ee 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
     "updateClientApi": "pnpm update @FullStackMap/from-a2b"
   },
   "dependencies": {
-    "@FullStackMap/from-a2b": "0.20.4-Alpha",
+    "@FullStackMap/from-a2b": "0.20.5-Alpha",
     "@mantine/carousel": "^7.6.2",
     "@mantine/core": "^7.6.2",
     "@mantine/form": "^7.6.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 05bd454..584e034 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -6,8 +6,8 @@ settings:
 
 dependencies:
   '@FullStackMap/from-a2b':
-    specifier: 0.20.4-Alpha
-    version: 0.20.4-Alpha
+    specifier: 0.20.5-Alpha
+    version: 0.20.5-Alpha
   '@mantine/carousel':
     specifier: ^7.6.2
     version: 7.6.2(@mantine/core@7.6.2)(@mantine/hooks@7.6.2)(embla-carousel-react@7.1.0)(react-dom@18.2.0)(react@18.2.0)
@@ -157,8 +157,8 @@ devDependencies:
 
 packages:
 
-  /@FullStackMap/from-a2b@0.20.4-Alpha:
-    resolution: {integrity: sha512-XrzxA1L5JCwD6ZwY0zbvFueUFVXKwp/6Jl49AQVedpmsacVCs0lcMlfzD1EQnVOz1RS8H9G6jOi1SS2ipcVhCw==, tarball: https://npm.pkg.github.com/download/@FullStackMap/from-a2b/0.20.4-Alpha/30b2a92c87f6b625a812a8512a04d43032ba8dcd}
+  /@FullStackMap/from-a2b@0.20.5-Alpha:
+    resolution: {integrity: sha512-t4CpcjwMIyviXhcI6y7WhAd2gjEmLB/Am48wLsrT3McqK38WqENoF01M4SCUBEmpEP5cY+J+ganIOX7QXuASlg==, tarball: https://npm.pkg.github.com/download/@FullStackMap/from-a2b/0.20.5-Alpha/eee72e68d3cb2a5d0cc5f7b782f9537e464402db}
     dependencies:
       axios: 1.6.8
     transitivePeerDependencies:
diff --git a/src/components/createStepModal/CreateStepModal.tsx b/src/components/createStepModal/CreateStepModal.tsx
index 7311fa1..eb3ccf5 100644
--- a/src/components/createStepModal/CreateStepModal.tsx
+++ b/src/components/createStepModal/CreateStepModal.tsx
@@ -1,67 +1,46 @@
-import { Button, Group, Modal, TextInput, Textarea, Autocomplete } from '@mantine/core';
-import { useDebouncedState } from '@mantine/hooks';
-import { IconX } from '@tabler/icons-react'
-import { useEffect, useState } from 'react';
+import {
+  Autocomplete,
+  Button,
+  Group,
+  Modal,
+  Textarea,
+  TextInput,
+} from '@mantine/core';
 import { useForm } from '@mantine/form';
+import { useDebouncedState } from '@mantine/hooks';
+import { IconX } from '@tabler/icons-react';
 import { zodResolver } from 'mantine-form-zod-resolver';
+import { useEffect, useState } from 'react';
 import { z } from 'zod';
 
-import {useStepStore} from '../../store/useStepStore.ts'
-import { getPlaces, getPlaceWhitCoordinate } from '../../services/api/MapboxController.ts'
+import {
+  getPlaces,
+  getPlaceWhitCoordinate,
+} from '../../services/api/MapboxController.ts';
+import { useStepStore } from '../../store/useStepStore.ts';
 
-import {PlaceDto} from '../../services/api/Models/PlaceLocation/PlaceLocationDto.ts'
-
-export const CreateStepModal=()=> {
-
-  const [value, setValue] = useDebouncedState('', 200, { leading: true });
-  const [places, setPlaces] = useState<PlaceDto[]>([]);
+import { PlaceDto } from '../../services/api/Models/PlaceLocation/PlaceLocationDto.ts';
 
+interface CreateStepModalProps {
+  FormSend: () => void | undefined;
+}
 
+export const CreateStepModal = (props: CreateStepModalProps) => {
+  //#region Hooks
 
-  useEffect(() => {
-    const fetchPlaces = async () => {
-
-      setPlaces(await getPlaces(value));
-    };
-
-    if (value) {
-      fetchPlaces();
-    }
-  }, [value]);
-
-
-
-  // get coordinate
-  const getCoordinate = (place:string)=>{
-    const coordinate  = places.find((item)=> item.place === place)
-    console.log(coordinate?.coordinate, 'les coordonée')
-    return coordinate?.coordinate
-  }
+  const [value, setValue] = useDebouncedState('', 200, { leading: true });
 
-  // call modal status
-  const isOpen = useStepStore((state) => state.status);
+  const isOpen = useStepStore(state => state.status);
 
-  const close = useStepStore((state) => state.setStatus);
-  // get data steDto from store
-  const step = useStepStore((state) => state.step);
+  const close = useStepStore(state => state.setStatus);
 
-  if (step.latitude !== undefined && step.longitude !== undefined) {
-    getPlaceWhitCoordinate(step.latitude, step.longitude).then((res) => {
-      console.log(res, 'place')
-    });
-  }
+  const step = useStepStore(state => state.step);
 
-  // console.log(step, 'step')
+  const SetStep = useStepStore(state => state.SetStep);
 
-  // const createStep = useMutation({
-  //   mutationFn: (data: AddStepDto )=> StepController.addStepAsyncPOST(tripId, data).catch((error)=>{
-  //     throw new Error(error);
-  // }),
-  //   onSuccess: () => {
-  //     queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
-  //   },
-  // });
+  //#endregion
 
+  //#region Form
 
   const stepSchema = z.object({
     title: z
@@ -79,61 +58,118 @@ export const CreateStepModal=()=> {
       description: step.description,
     },
   });
+  //#endregion
+
+  //#region Queries
+
+  //#endregion
+
+  //#region Mutations
 
-  // const updateStoreData = (data: any) => {
-  //
-  // }
+  //#endregion
 
+  //#region Variables
+
+  //#endregion
+
+  //#region States
+
+  const [places, setPlaces] = useState<PlaceDto[]>([]);
+
+  //#endregion
+
+  //#region Effects
+
+  if (step.latitude !== undefined && step.longitude !== undefined) {
+    getPlaceWhitCoordinate(step.latitude, step.longitude).then(res => {
+      console.log(res, 'place');
+    });
+  }
+
+  useEffect(() => {
+    const fetchPlaces = async () => {
+      setPlaces(await getPlaces(value));
+    };
+
+    if (value) {
+      fetchPlaces();
+    }
+  }, [value]);
+
+  //#endregion
+
+  //#region Handlers
+
+  const getCoordinate = (placeName: string) => {
+    const coordinate = places.find(item => item.place === placeName);
+    console.log('🚀 ~ getCoordinate ~ coordinate:', coordinate);
+    return coordinate?.coordinate;
+  };
+
+  const handleSendForm = () => {
+    const coords: [number, number] | undefined = getCoordinate(value);
+
+    SetStep({
+      name: stepForm.values.title,
+      description: stepForm.values.description,
+      latitude: coords?.[0],
+      longitude: coords?.[1],
+    });
+
+    props.FormSend();
+  };
+
+  //#endregion
 
   return (
-      <Modal
-        opened={isOpen}
-        onClose={() => close(false)}
-        centered
-        title="Créer une étape de vôtre voyage"
-        className="mantine-Modal-header"
-        closeOnClickOutside={false}
-        closeButtonProps={{
-          icon: <IconX size={24} stroke={2} />,
-        }}
-        overlayProps={{
-          backgroundOpacity: 0.55,
-          blur: 3,
-        }}>
-        <div className="img-modal"></div>
-        <form onReset={() => stepForm.reset()} className="form">
-          <TextInput
-            label="Titre de votre étape"
-            placeholder="Titre"
-            required
-            data-autofocus
-            {...stepForm.getInputProps('title')}
-          />
-          <Textarea
+    <Modal
+      opened={isOpen}
+      onClose={() => close(false)}
+      centered
+      title="Créer une étape de vôtre voyage"
+      className="mantine-Modal-header"
+      closeOnClickOutside={false}
+      closeButtonProps={{
+        icon: <IconX size={24} stroke={2} />,
+      }}
+      overlayProps={{
+        backgroundOpacity: 0.55,
+        blur: 3,
+      }}>
+      <div className="img-modal"></div>
+      <form onReset={() => stepForm.reset()} className="form">
+        <TextInput
+          label="Titre de votre étape"
+          placeholder="Titre"
+          required
+          data-autofocus
+          {...stepForm.getInputProps('title')}
+        />
+        <Textarea
+          mt="sm"
+          label="Description"
+          placeholder="Description"
+          {...stepForm.getInputProps('description')}
+        />
+        <Autocomplete
+          label="Destination"
+          placeholder="Entrez une adresse"
+          data={places.map(item => ({ label: item.place, value: item.place }))}
+          onChange={event => setValue(event)}
+        />
+
+        <Group justify="flex-end" mt="md">
+          <Button mt="sm" onClick={() => close(false)}>
+            Annuler
+          </Button>
+          <Button
             mt="sm"
-            label="Description"
-            placeholder="Description"
-            {...stepForm.getInputProps('description')}
-          />
-          <Autocomplete
-            label="Destination"
-            placeholder="Entrez une adresse"
-            data={places.map(item=> ({ label: item.place, value: item.place }))}
-            onChange={(event)=> setValue(event)}
-          />
-
-          <Group justify="flex-end" mt="md">
-            <Button mt="sm" onClick={()=>close(false)}>Annuler</Button>
-            <Button
-              type="submit"
-              mt="sm"
-              disabled={!stepForm.isValid() }
-              onClick={()=>console.log("cliquer bande de solope")}>
-              Sauvegarder
-            </Button>
-          </Group>
+            disabled={!stepForm.isValid() && value != undefined}
+            onClick={handleSendForm}>
+            Sauvegarder
+          </Button>
+        </Group>
       </form>
     </Modal>
   );
 };
-
diff --git a/src/components/map/MapComponent.tsx b/src/components/map/MapComponent.tsx
new file mode 100644
index 0000000..313a6ad
--- /dev/null
+++ b/src/components/map/MapComponent.tsx
@@ -0,0 +1,307 @@
+import { StepDto, TravelDtoList } from '@FullStackMap/from-a2b';
+import { ActionIcon } from '@mantine/core';
+import { FeatureCollection } from 'geojson';
+import {
+  GeolocateControl,
+  Layer,
+  LayerProps,
+  Map,
+  Marker,
+  MarkerDragEvent,
+  ScaleControl,
+  Source,
+} from 'react-map-gl';
+
+import { useStepStore } from '../../store/useStepStore.ts';
+
+import { IconCirclePlus, IconPinnedFilled } from '@tabler/icons-react';
+import React, { useMemo } from 'react';
+import {
+  TripDetailsStore,
+  useTripDetailsStore,
+} from '../../store/useTripDetailsStore';
+
+export const MapComponent = () => {
+  //#region Hooks
+  const steps: StepDto[] = useTripDetailsStore(
+    (state: TripDetailsStore) => state.steps,
+  );
+  const travels: TravelDtoList[] = useTripDetailsStore(
+    (state: TripDetailsStore) => state.travels,
+  );
+
+  const setIsStepModalOpen = useStepStore(state => state.setStatus);
+  //#endregion
+
+  //#region Queries
+
+  //#endregion
+
+  //#region Mutations
+
+  //#endregion
+
+  //#region Variables
+
+  const geojson: FeatureCollection = {
+    type: 'FeatureCollection',
+    features: [
+      {
+        type: 'Feature',
+        geometry: {
+          type: 'LineString',
+          coordinates: travels.flatMap(road =>
+            JSON.parse(road.travelRoad?.roadCoordinates as string),
+          ),
+        },
+        properties: {},
+      },
+    ],
+  };
+
+  const routeLineStyle: LayerProps = {
+    id: 'roadLayer',
+    type: 'line',
+    layout: {
+      'line-join': 'round',
+      'line-cap': 'round',
+    },
+    paint: {
+      'line-color': '#3887be',
+      'line-width': 5,
+      'line-opacity': 0.75,
+    },
+  };
+
+  //#endregion
+
+  //#region States
+
+  const [viewState, setViewState] = React.useState({
+    longitude: 11.954124476295533,
+    latitude: 4.92847043661213,
+    zoom: 2.6680390382433834,
+    pitch: 0,
+    bearing: 90.25375000000258,
+  });
+
+  //#endregion
+
+  //#region Effects
+
+  //#endregion
+
+  //#region Memos
+
+  const pins = useMemo(() => {
+    return steps.map((step: StepDto) => {
+      return (
+        <Marker
+          key={step.stepId}
+          draggable
+          onClick={() => console.log('step', step.order)}
+          onDragEnd={(evn: MarkerDragEvent) =>
+            handleMoveMarker(evn, step.stepId as number)
+          }
+          latitude={step.latitude ?? 0}
+          longitude={step.longitude ?? 0}
+          pitchAlignment="viewport"
+          rotationAlignment="viewport">
+          <IconPinnedFilled color="teal" size={32} stroke={2} />
+        </Marker>
+      );
+    });
+  }, [steps]);
+
+  //#endregion
+
+  //#region Handlers
+
+  const handleCreateStep = () => {
+    setIsStepModalOpen(true);
+  };
+
+  //TODO: Update this
+  // const handleMoveMarker = async (evt: MarkerDragEvent, stepId: number) => {
+  //   const updateStateLocationDto: UpdateStepLocationDto = {
+  //     latitude: evt.lngLat.lat,
+  //     longitude: evt.lngLat.lng,
+  //   };
+
+  //   const currentStep: StepDto | undefined = steps.find(
+  //     (s: StepDto) => s.stepId === stepId,
+  //   );
+  //   console.log('🚀 ~ handleMoveMarker ~ currentStep:', currentStep);
+  //   const stepBefore: StepDto | undefined = steps.find(
+  //     (s: StepDto) => s.order === (currentStep?.order as number) - 1,
+  //   );
+  //   console.log('🚀 ~ handleMoveMarker ~ stepBefore:', stepBefore);
+  //   const stepAfter: StepDto | undefined = steps.find(
+  //     (s: StepDto) => s.order === (currentStep?.order as number) + 1,
+  //   );
+  //   console.log('🚀 ~ handleMoveMarker ~ stepAfter:', stepAfter);
+
+  //   await updateStepLocationMutation.mutateAsync({
+  //     stepId: stepId,
+  //     updateStateLocationDto,
+  //   });
+
+  //   if (updateStepLocationMutation.error) return;
+
+  //   if (stepBefore && currentStep) {
+  //     const startEndPosition: RoadPositionDto[] = [
+  //       {
+  //         start: [
+  //           stepBefore.longitude as number,
+  //           stepBefore.latitude as number,
+  //         ],
+  //         end: [
+  //           updateStateLocationDto?.longitude as number,
+  //           updateStateLocationDto?.latitude as number,
+  //         ],
+  //       },
+  //     ];
+
+  //     const travelBeforeResponse: CalculateTravelRoadDto | undefined =
+  //       await calculateRoad(DirectionMode.DRIVING, startEndPosition).catch(
+  //         err => {
+  //           switch (err.response?.data?.code) {
+  //             case 'InvalidInput':
+  //               ErrorNotify({
+  //                 title: 'Échec du calcul du nouvel itinéraire',
+  //                 message:
+  //                   'La distance entre les deux points est trop grande pour ce mode de transport',
+  //                 autoClose: undefined,
+  //               });
+  //               break;
+  //             case 'NoRoute':
+  //               ErrorNotify({
+  //                 title: 'Échec du calcul du nouvel itinéraire',
+  //                 message: "Aucune route n'a été trouvée entre les deux points",
+  //                 autoClose: undefined,
+  //               });
+  //               break;
+
+  //             default:
+  //               ErrorNotify({
+  //                 title: 'Échec du calcul du nouvel itinéraire',
+  //                 message:
+  //                   "Une erreur est survenue lors du calcul de l'itinéraire entre les deux points de passage. Veuillez réessayer plus tard.",
+  //                 autoClose: undefined,
+  //               });
+  //               break;
+  //           }
+  //           console.error(err);
+  //         },
+  //       );
+
+  //     const addTravelDto: AddTravelDto = {
+  //       transportMode: travelBeforeResponse.transportMode,
+  //       distance: Number(travelBeforeResponse.distance.toFixed(0)),
+  //       duration: Number(travelBeforeResponse.duration.toFixed(0)),
+  //       originStepId: stepBefore.stepId as number,
+  //       destinationStepId: currentStep?.stepId as number,
+  //       travelRoad: travelBeforeResponse.travelRoad,
+  //     };
+  //     await addTravelBetweenStepsMutation.mutateAsync(addTravelDto);
+
+  //     console.log(
+  //       '🚀 ~ handleMoveMarker ~ travelBeforeResponse:',
+  //       travelBeforeResponse,
+  //     );
+  //   }
+
+  //   if (stepAfter && currentStep) {
+  //     const startEndPosition: RoadPositionDto[] = [
+  //       {
+  //         start: [
+  //           updateStateLocationDto.longitude as number,
+  //           updateStateLocationDto.latitude as number,
+  //         ],
+  //         end: [stepAfter?.longitude as number, stepAfter?.latitude as number],
+  //       },
+  //     ];
+
+  //     const travelAfterResponse: CalculateTravelRoadDto = await calculateRoad(
+  //       DirectionMode.DRIVING,
+  //       startEndPosition,
+  //     ).catch(err => {
+  //       switch (err.response?.data?.code) {
+  //         case 'InvalidInput':
+  //           ErrorNotify({
+  //             title: 'Échec du calcul du nouvel itinéraire',
+  //             message:
+  //               'La distance entre les deux points est trop grande pour ce mode de transport',
+  //             autoClose: undefined,
+  //           });
+  //           break;
+  //         case 'NoRoute':
+  //           ErrorNotify({
+  //             title: 'Échec du calcul du nouvel itinéraire',
+  //             message: "Aucune route n'a été trouvée entre les deux points",
+  //             autoClose: undefined,
+  //           });
+  //           break;
+
+  //         default:
+  //           ErrorNotify({
+  //             title: 'Échec du calcul du nouvel itinéraire',
+  //             message:
+  //               "Une erreur est survenue lors du calcul de l'itinéraire entre les deux points de passage. Veuillez réessayer plus tard.",
+  //             autoClose: undefined,
+  //           });
+  //           break;
+  //       }
+  //       console.error(err);
+  //     });
+
+  //     const addTravelDto: AddTravelDto = {
+  //       transportMode: travelAfterResponse.transportMode,
+  //       distance: Number(travelAfterResponse.distance.toFixed(0)),
+  //       duration: Number(travelAfterResponse.duration.toFixed(0)),
+  //       originStepId: currentStep.stepId as number,
+  //       destinationStepId: stepAfter?.stepId as number,
+  //       travelRoad: travelAfterResponse.travelRoad,
+  //     };
+  //     await addTravelBetweenStepsMutation.mutateAsync(addTravelDto);
+
+  //     console.log(
+  //       '🚀 ~ handleMoveMarker ~ travelAfterResponse:',
+  //       travelAfterResponse,
+  //     );
+  //   }
+
+  //   queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
+  // };
+
+  //#endregion
+
+  return (
+    <>
+      <Map
+        {...viewState}
+        onMove={evt => setViewState(evt.viewState)}
+        // onClick={addPoint}
+        minZoom={2}
+        dragRotate={true}
+        mapStyle="mapbox://styles/mapbox/streets-v12"
+        mapboxAccessToken={import.meta.env.VITE_MAPBOX_TOKEN}
+        attributionControl={true}
+        style={{
+          height: '93vh',
+          width: '60vw',
+        }}>
+        {pins}
+        <Source id="routeSource" type="geojson" data={geojson}>
+          <Layer {...routeLineStyle} />
+        </Source>
+
+        <GeolocateControl />
+        <ScaleControl />
+        <ActionIcon radius={'xl'}>
+          <IconCirclePlus size={48} onClick={handleCreateStep} />
+        </ActionIcon>
+      </Map>
+    </>
+  );
+};
diff --git a/src/components/stepCard/Menu/StepCardMenu.tsx b/src/components/map/stepCard/Menu/StepCardMenu.tsx
similarity index 100%
rename from src/components/stepCard/Menu/StepCardMenu.tsx
rename to src/components/map/stepCard/Menu/StepCardMenu.tsx
diff --git a/src/components/map/stepCard/StepList.scss b/src/components/map/stepCard/StepList.scss
new file mode 100644
index 0000000..134a505
--- /dev/null
+++ b/src/components/map/stepCard/StepList.scss
@@ -0,0 +1,6 @@
+#map_step_list {
+  align-items: center;
+  height: 93vh;
+  overflow-y: scroll;
+  padding: 0 1rem;
+}
diff --git a/src/components/map/stepCard/StepList.tsx b/src/components/map/stepCard/StepList.tsx
new file mode 100644
index 0000000..2b01478
--- /dev/null
+++ b/src/components/map/stepCard/StepList.tsx
@@ -0,0 +1,39 @@
+import { StepDto, TravelDtoList } from '@FullStackMap/from-a2b';
+import { Stack } from '@mantine/core';
+import {
+  TripDetailsStore,
+  useTripDetailsStore,
+} from '../../../store/useTripDetailsStore';
+import './StepList.scss';
+import { StepCard } from './stepCard/StepCard';
+
+export const StepList = () => {
+  //#region Hooks
+
+  const steps: StepDto[] = useTripDetailsStore(
+    (state: TripDetailsStore) => state.steps,
+  );
+  const travels: TravelDtoList[] = useTripDetailsStore(
+    (state: TripDetailsStore) => state.travels,
+  );
+
+  //#endregion
+
+  return (
+    <>
+      <Stack id="map_step_list">
+        {steps.map((step: StepDto) => (
+          <StepCard
+            key={step.stepId}
+            step={step}
+            travel={
+              travels.filter(
+                (t: TravelDtoList) => t.destinationStepId == step.stepId,
+              )[0]
+            }
+          />
+        ))}
+      </Stack>
+    </>
+  );
+};
diff --git a/src/components/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx b/src/components/map/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx
similarity index 89%
rename from src/components/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx
rename to src/components/map/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx
index 78a76c6..d6761f2 100644
--- a/src/components/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx
+++ b/src/components/map/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx
@@ -3,16 +3,16 @@ import { Button, Group, Modal, Stack, Text } from '@mantine/core';
 import { IconTrash } from '@tabler/icons-react';
 import { useMutation, useQueryClient } from '@tanstack/react-query';
 import { useEffect, useState } from 'react';
-import useNotify from '../../../hooks/useNotify';
-import { StepController, TravelController } from '../../../services/BaseApi';
-import { calculateRoad } from '../../../services/api/MapboxController';
-import CalculateTravelRoadDto from '../../../services/api/Models/MapBoxDirections/CalculateTravelRoadDto';
-import DirectionMode from '../../../services/api/Models/MapBoxDirections/DirectionMode';
-import RoadPositionDto from '../../../services/api/Models/MapBoxDirections/RoadPositionDto';
+import useNotify from '../../../../hooks/useNotify';
+import { StepController, TravelController } from '../../../../services/BaseApi';
+import { calculateRoad } from '../../../../services/api/MapboxController';
+import CalculateTravelRoadDto from '../../../../services/api/Models/MapBoxDirections/CalculateTravelRoadDto';
+import DirectionMode from '../../../../services/api/Models/MapBoxDirections/DirectionMode';
+import RoadPositionDto from '../../../../services/api/Models/MapBoxDirections/RoadPositionDto';
 import {
   TripDetailsStore,
   useTripDetailsStore,
-} from '../../../store/useTripDetailsStore';
+} from '../../../../store/useTripDetailsStore';
 
 export type ConfirmDeleteModalProps = {
   stepId: number;
diff --git a/src/components/stepCard/StepCard.scss b/src/components/map/stepCard/stepCard/StepCard.scss
similarity index 90%
rename from src/components/stepCard/StepCard.scss
rename to src/components/map/stepCard/stepCard/StepCard.scss
index 0ce1f90..a7dc03d 100644
--- a/src/components/stepCard/StepCard.scss
+++ b/src/components/map/stepCard/stepCard/StepCard.scss
@@ -4,4 +4,5 @@
   border-radius: 5px;
   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
   transition: box-shadow 0.3s;
+  width: 30vw;
 }
diff --git a/src/components/stepCard/StepCard.tsx b/src/components/map/stepCard/stepCard/StepCard.tsx
similarity index 77%
rename from src/components/stepCard/StepCard.tsx
rename to src/components/map/stepCard/stepCard/StepCard.tsx
index 8753b40..00bda2e 100644
--- a/src/components/stepCard/StepCard.tsx
+++ b/src/components/map/stepCard/stepCard/StepCard.tsx
@@ -1,10 +1,10 @@
 import { StepDto, TravelDtoList } from '@FullStackMap/from-a2b';
 import { Paper, Text } from '@mantine/core';
-import useDistance from '../../hooks/useDistance';
-import useTime from '../../hooks/useTime';
-import DirectionMode from '../../services/api/Models/MapBoxDirections/DirectionMode';
-import { TransportModeIcon } from '../transportModeIcon/TransportModeIcon';
-import { StepCardMenu } from './Menu/StepCardMenu';
+import useDistance from '../../../../hooks/useDistance';
+import useTime from '../../../../hooks/useTime';
+import DirectionMode from '../../../../services/api/Models/MapBoxDirections/DirectionMode';
+import { TransportModeIcon } from '../../../transportModeIcon/TransportModeIcon';
+import { StepCardMenu } from '../Menu/StepCardMenu';
 import './StepCard.scss';
 
 interface StepCardProps {
diff --git a/src/layout/halfMap/HalfMapLayout.scss b/src/layout/halfMap/HalfMapLayout.scss
deleted file mode 100644
index 9713678..0000000
--- a/src/layout/halfMap/HalfMapLayout.scss
+++ /dev/null
@@ -1,9 +0,0 @@
-.content {
-  flex: 1;
-  border: 1px solid red;
-}
-
-.map-container {
-  flex: 1;
-  border: 1px solid blue;
-}
diff --git a/src/layout/halfMap/HalfMapLayout.tsx b/src/layout/halfMap/HalfMapLayout.tsx
deleted file mode 100644
index 163fdbb..0000000
--- a/src/layout/halfMap/HalfMapLayout.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { AppShell } from '@mantine/core';
-import { useDisclosure } from '@mantine/hooks';
-import { Outlet } from 'react-router-dom';
-import DefaultFooter from '../../components/footer/DefaultFooter';
-import DefaultHeader from '../../components/header/DefaultHeader';
-import './HalfMapLayout.scss';
-
-export const HalfMapLayout = () => {
-  const [opened, { toggle }] = useDisclosure();
-
-  return (
-    <AppShell
-      header={{ height: 60 }}
-      navbar={{
-        width: 300,
-        breakpoint: 'sm',
-        collapsed: { desktop: true, mobile: !opened },
-      }}
-      footer={{ height: 120 }}
-      padding="md">
-      <AppShell.Header>
-        <DefaultHeader burgerOpened={opened} toggleBurgerState={toggle} />
-      </AppShell.Header>
-
-      <AppShell.Main style={{ display: 'flex', flex: 1 }}>
-        <div className="content">
-          <Outlet />
-        </div>
-        <div className="map-container">
-          <h1>MapComponent</h1>
-        </div>
-      </AppShell.Main>
-      <AppShell.Footer>
-        <DefaultFooter />
-      </AppShell.Footer>
-    </AppShell>
-  );
-};
diff --git a/src/pages/map/MapPage.tsx b/src/pages/map/MapPage.tsx
index aa7cab5..d469fb9 100644
--- a/src/pages/map/MapPage.tsx
+++ b/src/pages/map/MapPage.tsx
@@ -1,44 +1,8 @@
-import {
-  AddStepDto,
-  AddTravelDto,
-  StepDto,
-  StepDtoList,
-  TravelDtoList,
-  TripDto,
-  UpdateStepLocationDto,
-} from '@FullStackMap/from-a2b';
-import { Group, Stack } from '@mantine/core';
-import { useDocumentTitle } from '@mantine/hooks';
-import { IconPinnedFilled } from '@tabler/icons-react';
-import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
-import { AxiosResponse } from 'axios';
-import { FeatureCollection } from 'geojson';
-import React, { useEffect, useMemo } from 'react';
-import {
-  GeolocateControl,
-  Layer,
-  LayerProps,
-  Map,
-  Marker,
-  MarkerDragEvent,
-  ScaleControl,
-  Source,
-} from 'react-map-gl';
-import { StepCard } from '../../components/stepCard/StepCard';
-import useNotify from '../../hooks/useNotify';
-import {
-  StepController,
-  TravelController,
-  TripController,
-} from '../../services/BaseApi';
-import { calculateRoad } from '../../services/api/MapboxController';
-import CalculateTravelRoadDto from '../../services/api/Models/MapBoxDirections/CalculateTravelRoadDto';
-import DirectionMode from '../../services/api/Models/MapBoxDirections/DirectionMode';
-import RoadPositionDto from '../../services/api/Models/MapBoxDirections/RoadPositionDto';
-import {
-  TripDetailsStore,
-  useTripDetailsStore,
-} from '../../store/useTripDetailsStore';
+import { AddTravelDto, UpdateStepLocationDto } from '@FullStackMap/from-a2b';
+import { Group } from '@mantine/core';
+import { useMutation } from '@tanstack/react-query';
+import { StepController, TravelController } from '../../services/BaseApi';
+1;
 
 interface updateStepLocationMutationProps {
   stepId: number;
@@ -46,30 +10,6 @@ interface updateStepLocationMutationProps {
 }
 
 const MapPage = () => {
-  useDocumentTitle('From A2B - Map');
-  const { SetSteps, SetTravels } = useTripDetailsStore();
-  const steps: StepDto[] = useTripDetailsStore(
-    (state: TripDetailsStore) => state.steps,
-  );
-  const travels: TravelDtoList[] = useTripDetailsStore(
-    (state: TripDetailsStore) => state.travels,
-  );
-
-  const { ErrorNotify } = useNotify();
-
-  //#region UseQuery
-
-  const queryClient = useQueryClient();
-
-  const tripId = 'A8EB1FCE-B9DE-4201-B1FC-08DC4FD48062';
-  const { data: trip } = useQuery({
-    queryKey: ['Trip', tripId],
-    queryFn: async () =>
-      await TripController.getTripByIdGET(tripId).then(
-        (res: AxiosResponse<TripDto, any>) => res.data,
-      ),
-  });
-
   const updateStepLocationMutation = useMutation({
     mutationFn: async (args: updateStepLocationMutationProps) =>
       await StepController.updateStepLocationAsyncPATCH(
@@ -85,324 +25,20 @@ const MapPage = () => {
       ),
   });
 
-  //#endregion
-
-  //#region States
-  const [viewState, setViewState] = React.useState({
-    longitude: 11.954124476295533,
-    latitude: 4.92847043661213,
-    zoom: 2.6680390382433834,
-    pitch: 0,
-    bearing: 90.25375000000258,
-  });
-  // const [viewState, setViewState] = React.useState({
-  //   longitude: 4.860200783597507,
-  //   latitude: 45.73050608112574,
-  //   zoom: 2,
-  //   pitch: 30,
-  //   bearing: 0,
-  // });
-
-  // const [dto, setDto] = useState([
-  // {
-  //   start: [4.860200783597507, 45.73050608112574],
-  //   end: [5.079252160492843, 45.71892384847893],
-  // },
-  // // Ajoutez d'autres coordonnées initiales ici si nécessaire
-  // ]);
-
-  //#endregion
-
-  //#region Effects
-  useEffect(() => {
-    if (!trip) return;
-    SetSteps(
-      trip.steps?.sort(
-        (a: StepDtoList, b: StepDtoList) => a.order! - b.order!,
-      ) as StepDto[],
-    );
-
-    SetTravels(trip.travels as TravelDtoList[]);
-  }, [trip]);
-
-  // useEffect(() => {
-  //   (async () => {
-  //     //Calcul de l'itinéraire entre les points de passage
-  //     //Doit être utilisé que si nécessaire, car il y a un quota de requêtes
-  //     //l'ensemble des itinéraires sont stockés dans la base de données
-  //     console.log('les dto pour le road', dto[dto.length - 1]);
-  //     if (dto.length > 0) {
-  //       const lastDto = [dto[dto.length - 1]];
-  //       const road: Position[] = await calculateRoad('driving', lastDto);
-  //       console.log('road', road);
-  //       setRoads(prevRoads => prevRoads.concat(road));
-  //       console.log('roads', roads);
-  //     }
-  //     // const road: Position[] = await calculateRoad('driving', dto);
-  //     // setRoads(road);
-  //     // console.log("roads", roads)
-  //   })();
-  // }, [dto]);
-  //#endregion
-
-  //#region Memos
-
-  const handleMoveMarker = async (evt: MarkerDragEvent, stepId: number) => {
-    const updateStateLocationDto: UpdateStepLocationDto = {
-      latitude: evt.lngLat.lat,
-      longitude: evt.lngLat.lng,
-    };
-
-    const currentStep: StepDto | undefined = steps.find(
-      (s: StepDto) => s.stepId === stepId,
-    );
-    console.log('🚀 ~ handleMoveMarker ~ currentStep:', currentStep);
-    const stepBefore: StepDto | undefined = steps.find(
-      (s: StepDto) => s.order === (currentStep?.order as number) - 1,
-    );
-    console.log('🚀 ~ handleMoveMarker ~ stepBefore:', stepBefore);
-    const stepAfter: StepDto | undefined = steps.find(
-      (s: StepDto) => s.order === (currentStep?.order as number) + 1,
-    );
-    console.log('🚀 ~ handleMoveMarker ~ stepAfter:', stepAfter);
-
-    await updateStepLocationMutation.mutateAsync({
-      stepId: stepId,
-      updateStateLocationDto,
-    });
-
-    if (updateStepLocationMutation.error) return;
-
-    if (stepBefore && currentStep) {
-      const startEndPosition: RoadPositionDto[] = [
-        {
-          start: [
-            stepBefore.longitude as number,
-            stepBefore.latitude as number,
-          ],
-          end: [
-            updateStateLocationDto?.longitude as number,
-            updateStateLocationDto?.latitude as number,
-          ],
-        },
-      ];
-
-      const travelBeforeResponse: CalculateTravelRoadDto | undefined =
-        await calculateRoad(DirectionMode.DRIVING, startEndPosition).catch(
-          err => {
-            switch (err.response?.data?.code) {
-              case 'InvalidInput':
-                ErrorNotify({
-                  title: 'Échec du calcul du nouvel itinéraire',
-                  message:
-                    'La distance entre les deux points est trop grande pour ce mode de transport',
-                  autoClose: undefined,
-                });
-                break;
-              case 'NoRoute':
-                ErrorNotify({
-                  title: 'Échec du calcul du nouvel itinéraire',
-                  message: "Aucune route n'a été trouvée entre les deux points",
-                  autoClose: undefined,
-                });
-                break;
-
-              default:
-                ErrorNotify({
-                  title: 'Échec du calcul du nouvel itinéraire',
-                  message:
-                    "Une erreur est survenue lors du calcul de l'itinéraire entre les deux points de passage. Veuillez réessayer plus tard.",
-                  autoClose: undefined,
-                });
-                break;
-            }
-            console.error(err);
-          },
-        );
-
-      const addTravelDto: AddTravelDto = {
-        transportMode: travelBeforeResponse.transportMode,
-        distance: Number(travelBeforeResponse.distance.toFixed(0)),
-        duration: Number(travelBeforeResponse.duration.toFixed(0)),
-        originStepId: stepBefore.stepId as number,
-        destinationStepId: currentStep?.stepId as number,
-        travelRoad: travelBeforeResponse.travelRoad,
-      };
-      await addTravelBetweenStepsMutation.mutateAsync(addTravelDto);
-
-      console.log(
-        '🚀 ~ handleMoveMarker ~ travelBeforeResponse:',
-        travelBeforeResponse,
-      );
-    }
-
-    if (stepAfter && currentStep) {
-      const startEndPosition: RoadPositionDto[] = [
-        {
-          start: [
-            updateStateLocationDto.longitude as number,
-            updateStateLocationDto.latitude as number,
-          ],
-          end: [stepAfter?.longitude as number, stepAfter?.latitude as number],
-        },
-      ];
-
-      const travelAfterResponse: CalculateTravelRoadDto = await calculateRoad(
-        DirectionMode.DRIVING,
-        startEndPosition,
-      ).catch(err => {
-        switch (err.response?.data?.code) {
-          case 'InvalidInput':
-            ErrorNotify({
-              title: 'Échec du calcul du nouvel itinéraire',
-              message:
-                'La distance entre les deux points est trop grande pour ce mode de transport',
-              autoClose: undefined,
-            });
-            break;
-          case 'NoRoute':
-            ErrorNotify({
-              title: 'Échec du calcul du nouvel itinéraire',
-              message: "Aucune route n'a été trouvée entre les deux points",
-              autoClose: undefined,
-            });
-            break;
-
-          default:
-            ErrorNotify({
-              title: 'Échec du calcul du nouvel itinéraire',
-              message:
-                "Une erreur est survenue lors du calcul de l'itinéraire entre les deux points de passage. Veuillez réessayer plus tard.",
-              autoClose: undefined,
-            });
-            break;
-        }
-        console.error(err);
-      });
-
-      const addTravelDto: AddTravelDto = {
-        transportMode: travelAfterResponse.transportMode,
-        distance: Number(travelAfterResponse.distance.toFixed(0)),
-        duration: Number(travelAfterResponse.duration.toFixed(0)),
-        originStepId: currentStep.stepId as number,
-        destinationStepId: stepAfter?.stepId as number,
-        travelRoad: travelAfterResponse.travelRoad,
-      };
-      await addTravelBetweenStepsMutation.mutateAsync(addTravelDto);
-
-      console.log(
-        '🚀 ~ handleMoveMarker ~ travelAfterResponse:',
-        travelAfterResponse,
-      );
-    }
-
-    queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
-  };
-
-  //Création des pins sur la carte pour chaque étape du voyage
-  const pins = useMemo(() => {
-    return steps.map((step: StepDto) => {
-      return (
-        <Marker
-          key={step.stepId}
-          draggable
-          onClick={() => console.log('step', step.order)}
-          onDragEnd={(evn: MarkerDragEvent) =>
-            handleMoveMarker(evn, step.stepId as number)
-          }
-          latitude={step.latitude ?? 0}
-          longitude={step.longitude ?? 0}
-          pitchAlignment="viewport"
-          rotationAlignment="viewport">
-          <IconPinnedFilled color="teal" size={32} stroke={2} />
-        </Marker>
-      );
-    });
-  }, [steps]);
-
-  //#endregion
-
-  //#region Variables
-
-  const geojson: FeatureCollection = {
-    type: 'FeatureCollection',
-    features: [
-      {
-        type: 'Feature',
-        geometry: {
-          type: 'LineString',
-          coordinates: travels.flatMap(road =>
-            JSON.parse(road.travelRoad?.roadCoordinates as string),
-          ),
-        },
-        properties: {},
-      },
-    ],
-  };
-
-  const routeLineStyle: LayerProps = {
-    id: 'roadLayer',
-    type: 'line',
-    layout: {
-      'line-join': 'round',
-      'line-cap': 'round',
-    },
-    paint: {
-      'line-color': '#3887be',
-      'line-width': 5,
-      'line-opacity': 0.75,
-    },
-  };
-
-  const addPoint = async (evt: any) => {
-    console.log('hello', evt.lngLat.lat, evt.lngLat.lng);
-    await StepController.addStepAsyncPOST(tripId, {
-      name: 'Nouvelle étape',
-      description: 'Description de la nouvelle étape',
-      latitude: evt.lngLat.lat,
-      longitude: evt.lngLat.lng,
-    } as AddStepDto).then(() =>
-      queryClient.invalidateQueries({ queryKey: ['Trip', tripId] }),
-    );
-  };
+  // const addPoint = async (evt: any) => {
+  //   console.log('hello', evt.lngLat.lat, evt.lngLat.lng);
+  //   await StepController.addStepAsyncPOST(tripId, {
+  //     name: 'Nouvelle étape',
+  //     description: 'Description de la nouvelle étape',
+  //     latitude: evt.lngLat.lat,
+  //     longitude: evt.lngLat.lng,
+  //   } as AddStepDto).then(() =>
+  //     queryClient.invalidateQueries({ queryKey: ['Trip', tripId] }),
+  //   );
+  // };
 
   //#endregion
-  return (
-    <Group justify="space-between">
-      <Stack>
-        {steps.map((step: StepDto) => (
-          <StepCard
-            key={step.stepId}
-            step={step}
-            travel={
-              travels.filter(t => t.destinationStepId == step.stepId)[0]
-            }></StepCard>
-        ))}
-      </Stack>
-
-      <Map
-        {...viewState}
-        onMove={evt => setViewState(evt.viewState)}
-        onClick={addPoint}
-        minZoom={2}
-        dragRotate={true}
-        mapStyle="mapbox://styles/mapbox/streets-v12"
-        mapboxAccessToken={import.meta.env.VITE_MAPBOX_TOKEN}
-        attributionControl={true}
-        style={{
-          height: '93vh',
-          width: '60vw',
-        }}>
-        {pins}
-        <Source id="routeSource" type="geojson" data={geojson}>
-          <Layer {...routeLineStyle} />
-        </Source>
-
-        <GeolocateControl />
-        <ScaleControl />
-      </Map>
-    </Group>
-  );
+  return <Group justify="space-between"></Group>;
 };
 
 export default MapPage;
diff --git a/src/pages/tripDetail/TripDetailPage.tsx b/src/pages/tripDetail/TripDetailPage.tsx
new file mode 100644
index 0000000..db288e9
--- /dev/null
+++ b/src/pages/tripDetail/TripDetailPage.tsx
@@ -0,0 +1,121 @@
+import { AddStepDto, TripDto } from '@FullStackMap/from-a2b';
+import { Group, Stack } from '@mantine/core';
+import { useQuery, useQueryClient } from '@tanstack/react-query';
+import { AxiosResponse } from 'axios';
+import { StepController, TripController } from '../../services/BaseApi';
+
+import { useEffect } from 'react';
+import { CreateStepModal } from '../../components/createStepModal/CreateStepModal.tsx';
+import { MapComponent } from '../../components/map/MapComponent';
+
+import { useMutation } from '@tanstack/react-query';
+
+import { StepList } from '../../components/map/stepCard/StepList.tsx';
+import { useStepStore } from '../../store/useStepStore.ts';
+import {
+  TripDetailsStore,
+  useTripDetailsStore,
+} from '../../store/useTripDetailsStore';
+
+const TripDetailPage = () => {
+  //#region Hooks
+
+  const tripId: string | undefined = useTripDetailsStore(
+    (state: TripDetailsStore) => state.tripId,
+  );
+  const { setTrip } = useTripDetailsStore();
+
+  const queryClient = useQueryClient();
+
+  const step = useStepStore(state => state.step);
+
+  const SetStep = useStepStore(state => state.SetStep);
+
+  const close = useStepStore(state => state.setStatus);
+
+  //#endregion
+
+  //#region Queries
+  const { data: tripDto } = useQuery({
+    queryKey: ['Trip', tripId],
+    queryFn: async () =>
+      await TripController.getTripByIdGET(tripId as string).then(
+        (res: AxiosResponse<TripDto, any>) => res.data,
+      ),
+    enabled: !!tripId,
+  });
+
+  //#endregion
+
+  //#region Mutations
+
+  const createStepMutation = useMutation({
+    mutationFn: (data: AddStepDto) =>
+      StepController.addStepAsyncPOST(tripId, data).catch(error => {
+        throw new Error(error);
+      }),
+    onSuccess: () => {
+      console.log('sucefull');
+      queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
+      SetStep({
+        name: '',
+        description: '',
+        startDate: '',
+        endDate: '',
+        latitude: undefined,
+        longitude: undefined,
+      });
+      close(true);
+    },
+    onError: () => {
+      console.log('error rekekeke');
+    },
+  });
+
+  //#endregion
+
+  //#region Variables
+
+  //#endregion
+
+  //#region States
+
+  //#endregion
+
+  //#region Effects
+
+  useEffect(() => {
+    if (!tripDto) return;
+    setTrip(tripDto);
+  }, [tripDto]);
+
+  //#endregion
+
+  //#region Handlers
+  const handleCreateStepFromModal = () => {
+    console.log('je vais créer la rekeke', step, tripId);
+
+    // createStepMutation.mutate({
+    //   name: step.name,
+    //   description: step.description,
+    //   longitude: step.longitude,
+    //   latitude: step.latitude,
+    // });
+  };
+
+  //#endregion
+
+  return (
+    <>
+      <Group justify="space-between">
+        <StepList />
+        <Stack>
+          <MapComponent />
+        </Stack>
+      </Group>
+      <CreateStepModal FormSend={() => handleCreateStepFromModal()} />
+    </>
+  );
+};
+
+export default TripDetailPage;
diff --git a/src/router/Router.tsx b/src/router/Router.tsx
index 102193d..f0d5077 100644
--- a/src/router/Router.tsx
+++ b/src/router/Router.tsx
@@ -1,7 +1,6 @@
 import { useEffect } from 'react';
 import { Navigate, Route, Routes } from 'react-router-dom';
 import DefaultLayout from '../layout/default/DefaultLayout';
-import { HalfMapLayout } from '../layout/halfMap/HalfMapLayout';
 import LoginLayout from '../layout/login/LoginLayout';
 import CguPage from '../pages/cgu/CguPage';
 import { ConfirmMailPage } from '../pages/confirmMail/ConfirmMailPage';
@@ -16,6 +15,7 @@ import MapPage from '../pages/map/MapPage';
 import ProfilePage from '../pages/profile/ProfilePage.tsx';
 import { RegisterPage } from '../pages/register/RegisterPage';
 import TestPage from '../pages/test/TestPage.tsx';
+import TripDetailPage from '../pages/tripDetail/TripDetailPage.tsx';
 import { AuthStore, useAuthStore } from '../store/useAuthStore';
 import { PrivateRoute } from './PrivateRoute';
 
@@ -32,6 +32,16 @@ const Router = () => {
         <Route path="/contact" element={<ContactPage />} />
         <Route path="/faq" element={<FaqPage />} />
         <Route path="/t" element={<TestPage />} />
+        <Route
+          path="/tripDetail"
+          element={
+            <PrivateRoute
+              authRequired
+              redirectPath="/login"
+              element={<TripDetailPage />}
+            />
+          }
+        />
         <Route
           path="/editTravel"
           element={
@@ -52,7 +62,6 @@ const Router = () => {
             />
           }
         />
-        <Route path="/*" element={<Navigate to="/" />} />
         <Route
           path="/profile"
           element={
@@ -63,10 +72,9 @@ const Router = () => {
             />
           }
         />
+        <Route path="/*" element={<Navigate to="/" />} />
       </Route>
 
-      <Route element={<HalfMapLayout />}></Route>
-
       <Route element={<LoginLayout />}>
         <Route
           path="/login"
diff --git a/src/services/api/MapboxController.ts b/src/services/api/MapboxController.ts
index 2825d90..921695e 100644
--- a/src/services/api/MapboxController.ts
+++ b/src/services/api/MapboxController.ts
@@ -4,12 +4,11 @@ import { MapboxClient } from '../BaseApi';
 import CalculateTravelRoadDto from './Models/MapBoxDirections/CalculateTravelRoadDto';
 import DirectionMode from './Models/MapBoxDirections/DirectionMode';
 import RoadPositionDto from './Models/MapBoxDirections/RoadPositionDto';
-import { PlaceDto } from './Models/PlaceLocation/PlaceLocationDto.ts'
+import { PlaceDto } from './Models/PlaceLocation/PlaceLocationDto.ts';
 
 // eslint-disable-next-line react-hooks/rules-of-hooks
 const { ErrorNotify } = useNotify();
 
-
 export const calculateRoad = async (
   directionMode: DirectionMode,
   positions: RoadPositionDto[],
@@ -59,35 +58,40 @@ export const calculateRoad = async (
   }
 };
 
-export const getPlaces = async(place: string)=>{
-
-  let response = await MapboxClient.get(
-    `/geocoding/v5/mapbox.places/${place}.json?proximity=ip&language=fr&access_token=${mapBoxToken}`,
+export const getPlaces = async (place: string) => {
+  const response = await MapboxClient.get(
+    `/geocoding/v5/mapbox.places/${place}.json?proximity=ip&language=fr&access_token=${
+      import.meta.env.VITE_MAPBOX_TOKEN
+    }`,
   );
 
-  const places : PlaceDto[] = response.data.features.map((item: { place_name_fr: any; center: any; })=>{
-    return {
-      place: item.place_name_fr,
-      coordinate: item.center
-    }
-  })
+  const places: PlaceDto[] = response.data.features.map(
+    (item: { place_name_fr: any; center: any }) => {
+      return {
+        place: item.place_name_fr,
+        coordinate: item.center,
+      };
+    },
+  );
   return places;
-}
+};
 
-export const getPlaceWhitCoordinate = async (latitude:number, longitude:number)=>{
+export const getPlaceWhitCoordinate = async (
+  latitude: number,
+  longitude: number,
+) => {
   let response = await MapboxClient.get(
-    `/geocoding/v5/mapbox.places/${longitude},${latitude}.json?proximity=ip&language=fr&access_token=${mapBoxToken}`,
-
+    `/geocoding/v5/mapbox.places/${longitude},${latitude}.json?proximity=ip&language=fr&access_token=${
+      import.meta.env.VITE_MAPBOX_TOKEN
+    }`,
+  );
+  response = response.data.features.map(
+    (item: { place_name_fr: any; center: any }) => {
+      return {
+        place: item.place_name_fr,
+        coordinate: item.center,
+      };
+    },
   );
-
-  response = response.data.features.map((item: { place_name_fr: any; center: any; })=>{
-    return {
-      place: item.place_name_fr,
-      coordinate: item.center
-    }
-  })
-  console.log(response, 'places dans le store')
   return response;
-}
-
-
+};
diff --git a/src/services/api/Models/PlaceLocation/PlaceLocationDto.ts b/src/services/api/Models/PlaceLocation/PlaceLocationDto.ts
index 464da48..52f647f 100644
--- a/src/services/api/Models/PlaceLocation/PlaceLocationDto.ts
+++ b/src/services/api/Models/PlaceLocation/PlaceLocationDto.ts
@@ -1,7 +1,4 @@
-
 export type PlaceDto = {
-  place: string
-  coordinate: [number, number]
-}
-
-
+  place: string;
+  coordinate: [number, number];
+};
diff --git a/src/store/useStepStore.ts b/src/store/useStepStore.ts
index 1cecff2..c5c7112 100644
--- a/src/store/useStepStore.ts
+++ b/src/store/useStepStore.ts
@@ -1,9 +1,7 @@
 import { StepDto } from '@FullStackMap/from-a2b';
 import { create } from 'zustand';
 
-
 export type StepStore = {
-
   status: boolean;
   setStatus: (status: boolean) => void;
 
@@ -12,16 +10,13 @@ export type StepStore = {
 
   stepSelectedId: number;
   SetStepSelectedId: (stepId: number) => void;
-
 };
 
 export const useStepStore = create<StepStore>(set => ({
-
   status: false,
   setStatus: (status: boolean) => set({ status }),
 
   step: {
-    stepId: 0,
     name: '',
     description: '',
     startDate: '',
@@ -29,9 +24,9 @@ export const useStepStore = create<StepStore>(set => ({
     latitude: undefined,
     longitude: undefined,
   } as StepDto,
+
   SetStep: (step: StepDto) => set({ step }),
 
   stepSelectedId: 0,
   SetStepSelectedId: (stepId: number) => set({ stepSelectedId: stepId }),
 }));
-
diff --git a/src/store/useTripDetailsStore.ts b/src/store/useTripDetailsStore.ts
index 2f338d6..aa750e0 100644
--- a/src/store/useTripDetailsStore.ts
+++ b/src/store/useTripDetailsStore.ts
@@ -1,15 +1,15 @@
-import { StepDto, TravelDtoList } from '@FullStackMap/from-a2b';
+import { StepDto, TravelDtoList, TripDto } from '@FullStackMap/from-a2b';
 import { create } from 'zustand';
-import { TripDto } from '@FullStackMap/from-a2b';
 
 export type TripDetailsStore = {
   status: boolean;
   setStatus: (status: boolean) => void;
 
+  tripId: string;
+  setTripId: (tripId: string) => void;
   trip: TripDto;
   setTrip: (trip: TripDto) => void;
 
-
   steps: StepDto[];
   currentStep: StepDto;
   SelectStep: (stepId: number) => void;
@@ -25,12 +25,21 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
   status: false,
   setStatus: (status: boolean) => set({ status }),
 
+  // tripId: undefined,
+  tripId: 'A8EB1FCE-B9DE-4201-B1FC-08DC4FD48062',
+  setTripId: (tripId: string) => set({ tripId }),
+
   trip: {} as TripDto,
-  setTrip: (trip: TripDto) => set({ trip }),
+  setTrip: (tripDto: TripDto) =>
+    set({
+      trip: tripDto,
+      steps: tripDto.steps || [],
+      travels: tripDto.travels || [],
+    }),
 
   steps: [],
-  currentStep: {} as StepDto,
   SetSteps: (steps: StepDto[]) => set({ steps }),
+  currentStep: {} as StepDto,
   SelectStep: (stepId: number) =>
     set((state: TripDetailsStore) => {
       const currentStep = state.steps.find(step => step.stepId === stepId);

From 8d7ad7b6473943ce8a0799b7451e4a1bfe3b4e84 Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Sat, 30 Mar 2024 01:48:28 +0100
Subject: [PATCH 20/34] Feat (TripDetail) : [WIP] Delete & Add Travel

---
 package.json                                  |   2 +-
 pnpm-lock.yaml                                |   8 +-
 .../createStepModal/CreateStepModal.tsx       | 175 ------------
 src/components/map/MapComponent.tsx           |  49 ++--
 .../map/addStep/CreateStepModal.tsx           | 205 ++++++++++++++
 .../map/stepCard/{stepCard => }/StepCard.scss |   0
 .../map/stepCard/{stepCard => }/StepCard.tsx  |  17 +-
 .../confirmDeleteModal/ConfirmDeleteModal.tsx |   9 +-
 .../map/{stepCard => stepList}/StepList.scss  |   0
 .../map/{stepCard => stepList}/StepList.tsx   |   2 +-
 .../TransportModeSelector.tsx                 | 107 +++++++
 src/layout/map/MapLayout.tsx                  |  30 ++
 src/pages/editTravel/EditTravel.tsx           |  13 -
 src/pages/map/MapPage.tsx                     |   7 -
 src/pages/tripDetail/TripDetailPage.tsx       | 154 +++++++---
 src/router/Router.tsx                         |  26 +-
 src/services/ErrorHandler.ts                  |  10 +-
 src/services/api/MapboxController.ts          | 265 ++++++++++++------
 src/store/useTripDetailsStore.ts              |  50 +++-
 19 files changed, 739 insertions(+), 390 deletions(-)
 delete mode 100644 src/components/createStepModal/CreateStepModal.tsx
 create mode 100644 src/components/map/addStep/CreateStepModal.tsx
 rename src/components/map/stepCard/{stepCard => }/StepCard.scss (100%)
 rename src/components/map/stepCard/{stepCard => }/StepCard.tsx (64%)
 rename src/components/map/{stepCard => stepList}/StepList.scss (100%)
 rename src/components/map/{stepCard => stepList}/StepList.tsx (94%)
 create mode 100644 src/components/map/transportModeSelector/TransportModeSelector.tsx
 create mode 100644 src/layout/map/MapLayout.tsx
 delete mode 100644 src/pages/editTravel/EditTravel.tsx

diff --git a/package.json b/package.json
index dfaf5ee..66144f3 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
     "updateClientApi": "pnpm update @FullStackMap/from-a2b"
   },
   "dependencies": {
-    "@FullStackMap/from-a2b": "0.20.5-Alpha",
+    "@FullStackMap/from-a2b": "0.21.1-Alpha",
     "@mantine/carousel": "^7.6.2",
     "@mantine/core": "^7.6.2",
     "@mantine/form": "^7.6.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 584e034..c40b20e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -6,8 +6,8 @@ settings:
 
 dependencies:
   '@FullStackMap/from-a2b':
-    specifier: 0.20.5-Alpha
-    version: 0.20.5-Alpha
+    specifier: 0.21.1-Alpha
+    version: 0.21.1-Alpha
   '@mantine/carousel':
     specifier: ^7.6.2
     version: 7.6.2(@mantine/core@7.6.2)(@mantine/hooks@7.6.2)(embla-carousel-react@7.1.0)(react-dom@18.2.0)(react@18.2.0)
@@ -157,8 +157,8 @@ devDependencies:
 
 packages:
 
-  /@FullStackMap/from-a2b@0.20.5-Alpha:
-    resolution: {integrity: sha512-t4CpcjwMIyviXhcI6y7WhAd2gjEmLB/Am48wLsrT3McqK38WqENoF01M4SCUBEmpEP5cY+J+ganIOX7QXuASlg==, tarball: https://npm.pkg.github.com/download/@FullStackMap/from-a2b/0.20.5-Alpha/eee72e68d3cb2a5d0cc5f7b782f9537e464402db}
+  /@FullStackMap/from-a2b@0.21.1-Alpha:
+    resolution: {integrity: sha512-Wrybc+kBUJsRLSDT/8rD0gYvddubTYoyJnr9NLj4ZN9WueOlcazXeOUZz4hpxIWIhxMgeRfKpH8kt5VUZAlTVQ==, tarball: https://npm.pkg.github.com/download/@FullStackMap/from-a2b/0.21.1-Alpha/41d182cff1111a4b0f3b91067875207a9c31a2e9}
     dependencies:
       axios: 1.6.8
     transitivePeerDependencies:
diff --git a/src/components/createStepModal/CreateStepModal.tsx b/src/components/createStepModal/CreateStepModal.tsx
deleted file mode 100644
index eb3ccf5..0000000
--- a/src/components/createStepModal/CreateStepModal.tsx
+++ /dev/null
@@ -1,175 +0,0 @@
-import {
-  Autocomplete,
-  Button,
-  Group,
-  Modal,
-  Textarea,
-  TextInput,
-} from '@mantine/core';
-import { useForm } from '@mantine/form';
-import { useDebouncedState } from '@mantine/hooks';
-import { IconX } from '@tabler/icons-react';
-import { zodResolver } from 'mantine-form-zod-resolver';
-import { useEffect, useState } from 'react';
-import { z } from 'zod';
-
-import {
-  getPlaces,
-  getPlaceWhitCoordinate,
-} from '../../services/api/MapboxController.ts';
-import { useStepStore } from '../../store/useStepStore.ts';
-
-import { PlaceDto } from '../../services/api/Models/PlaceLocation/PlaceLocationDto.ts';
-
-interface CreateStepModalProps {
-  FormSend: () => void | undefined;
-}
-
-export const CreateStepModal = (props: CreateStepModalProps) => {
-  //#region Hooks
-
-  const [value, setValue] = useDebouncedState('', 200, { leading: true });
-
-  const isOpen = useStepStore(state => state.status);
-
-  const close = useStepStore(state => state.setStatus);
-
-  const step = useStepStore(state => state.step);
-
-  const SetStep = useStepStore(state => state.SetStep);
-
-  //#endregion
-
-  //#region Form
-
-  const stepSchema = z.object({
-    title: z
-      .string()
-      .min(3, 'Le titre doit contenir au moins 3 caractères')
-      .max(50, 'Le titre doit contenir au maximum 50 caractères'),
-    description: z.string(),
-  });
-
-  const stepForm = useForm({
-    validateInputOnChange: true,
-    validate: zodResolver(stepSchema),
-    initialValues: {
-      title: step.name,
-      description: step.description,
-    },
-  });
-  //#endregion
-
-  //#region Queries
-
-  //#endregion
-
-  //#region Mutations
-
-  //#endregion
-
-  //#region Variables
-
-  //#endregion
-
-  //#region States
-
-  const [places, setPlaces] = useState<PlaceDto[]>([]);
-
-  //#endregion
-
-  //#region Effects
-
-  if (step.latitude !== undefined && step.longitude !== undefined) {
-    getPlaceWhitCoordinate(step.latitude, step.longitude).then(res => {
-      console.log(res, 'place');
-    });
-  }
-
-  useEffect(() => {
-    const fetchPlaces = async () => {
-      setPlaces(await getPlaces(value));
-    };
-
-    if (value) {
-      fetchPlaces();
-    }
-  }, [value]);
-
-  //#endregion
-
-  //#region Handlers
-
-  const getCoordinate = (placeName: string) => {
-    const coordinate = places.find(item => item.place === placeName);
-    console.log('🚀 ~ getCoordinate ~ coordinate:', coordinate);
-    return coordinate?.coordinate;
-  };
-
-  const handleSendForm = () => {
-    const coords: [number, number] | undefined = getCoordinate(value);
-
-    SetStep({
-      name: stepForm.values.title,
-      description: stepForm.values.description,
-      latitude: coords?.[0],
-      longitude: coords?.[1],
-    });
-
-    props.FormSend();
-  };
-
-  //#endregion
-
-  return (
-    <Modal
-      opened={isOpen}
-      onClose={() => close(false)}
-      centered
-      title="Créer une étape de vôtre voyage"
-      className="mantine-Modal-header"
-      closeOnClickOutside={false}
-      closeButtonProps={{
-        icon: <IconX size={24} stroke={2} />,
-      }}
-      overlayProps={{
-        backgroundOpacity: 0.55,
-        blur: 3,
-      }}>
-      <div className="img-modal"></div>
-      <form onReset={() => stepForm.reset()} className="form">
-        <TextInput
-          label="Titre de votre étape"
-          placeholder="Titre"
-          required
-          data-autofocus
-          {...stepForm.getInputProps('title')}
-        />
-        <Textarea
-          mt="sm"
-          label="Description"
-          placeholder="Description"
-          {...stepForm.getInputProps('description')}
-        />
-        <Autocomplete
-          label="Destination"
-          placeholder="Entrez une adresse"
-          data={places.map(item => ({ label: item.place, value: item.place }))}
-          onChange={event => setValue(event)}
-        />
-
-        <Group justify="flex-end" mt="md">
-          <Button mt="sm" onClick={() => close(false)}>
-            Annuler
-          </Button>
-          <Button
-            mt="sm"
-            disabled={!stepForm.isValid() && value != undefined}
-            onClick={handleSendForm}>
-            Sauvegarder
-          </Button>
-        </Group>
-      </form>
-    </Modal>
-  );
-};
diff --git a/src/components/map/MapComponent.tsx b/src/components/map/MapComponent.tsx
index 313a6ad..73b5eeb 100644
--- a/src/components/map/MapComponent.tsx
+++ b/src/components/map/MapComponent.tsx
@@ -1,5 +1,5 @@
 import { StepDto, TravelDtoList } from '@FullStackMap/from-a2b';
-import { ActionIcon } from '@mantine/core';
+import { ActionIcon, Box, LoadingOverlay } from '@mantine/core';
 import { FeatureCollection } from 'geojson';
 import {
   GeolocateControl,
@@ -12,8 +12,7 @@ import {
   Source,
 } from 'react-map-gl';
 
-import { useStepStore } from '../../store/useStepStore.ts';
-
+import { useDisclosure } from '@mantine/hooks';
 import { IconCirclePlus, IconPinnedFilled } from '@tabler/icons-react';
 import React, { useMemo } from 'react';
 import {
@@ -23,6 +22,8 @@ import {
 
 export const MapComponent = () => {
   //#region Hooks
+  const { SetAddModalIsOpened } = useTripDetailsStore();
+
   const steps: StepDto[] = useTripDetailsStore(
     (state: TripDetailsStore) => state.steps,
   );
@@ -30,7 +31,8 @@ export const MapComponent = () => {
     (state: TripDetailsStore) => state.travels,
   );
 
-  const setIsStepModalOpen = useStepStore(state => state.setStatus);
+  const [isMapLoading, { toggle: toggleIsMapLoading }] = useDisclosure(true);
+
   //#endregion
 
   //#region Queries
@@ -77,12 +79,20 @@ export const MapComponent = () => {
 
   //#region States
 
+  // const [viewState, setViewState] = React.useState({
+  //   longitude: 11.954124476295533,
+  //   latitude: 4.92847043661213,
+  //   zoom: 2.6680390382433834,
+  //   pitch: 0,
+  //   bearing: 90.25375000000258,
+  // });
+
   const [viewState, setViewState] = React.useState({
-    longitude: 11.954124476295533,
-    latitude: 4.92847043661213,
-    zoom: 2.6680390382433834,
-    pitch: 0,
-    bearing: 90.25375000000258,
+    longitude: 4.860200783597507,
+    latitude: 45.73050608112574,
+    zoom: 2,
+    pitch: 30,
+    bearing: 0,
   });
 
   //#endregion
@@ -117,10 +127,6 @@ export const MapComponent = () => {
 
   //#region Handlers
 
-  const handleCreateStep = () => {
-    setIsStepModalOpen(true);
-  };
-
   //TODO: Update this
   // const handleMoveMarker = async (evt: MarkerDragEvent, stepId: number) => {
   //   const updateStateLocationDto: UpdateStepLocationDto = {
@@ -277,18 +283,23 @@ export const MapComponent = () => {
   //#endregion
 
   return (
-    <>
+    <Box pos={'relative'}>
+      <LoadingOverlay
+        visible={isMapLoading}
+        zIndex={1000}
+        overlayProps={{ radius: 'sm', blur: 2 }}
+      />
       <Map
         {...viewState}
+        onLoad={() => toggleIsMapLoading()}
         onMove={evt => setViewState(evt.viewState)}
-        // onClick={addPoint}
         minZoom={2}
         dragRotate={true}
         mapStyle="mapbox://styles/mapbox/streets-v12"
         mapboxAccessToken={import.meta.env.VITE_MAPBOX_TOKEN}
         attributionControl={true}
         style={{
-          height: '93vh',
+          height: '94vh',
           width: '60vw',
         }}>
         {pins}
@@ -298,10 +309,10 @@ export const MapComponent = () => {
 
         <GeolocateControl />
         <ScaleControl />
-        <ActionIcon radius={'xl'}>
-          <IconCirclePlus size={48} onClick={handleCreateStep} />
+        <ActionIcon radius={'xl'} onClick={() => SetAddModalIsOpened(true)}>
+          <IconCirclePlus size={48} />
         </ActionIcon>
       </Map>
-    </>
+    </Box>
   );
 };
diff --git a/src/components/map/addStep/CreateStepModal.tsx b/src/components/map/addStep/CreateStepModal.tsx
new file mode 100644
index 0000000..b3d796e
--- /dev/null
+++ b/src/components/map/addStep/CreateStepModal.tsx
@@ -0,0 +1,205 @@
+import { AddStepDto } from '@FullStackMap/from-a2b';
+import {
+  Autocomplete,
+  Button,
+  Group,
+  Modal,
+  TextInput,
+  Textarea,
+} from '@mantine/core';
+import { useForm } from '@mantine/form';
+import { useDebouncedState } from '@mantine/hooks';
+import { IconX } from '@tabler/icons-react';
+import { zodResolver } from 'mantine-form-zod-resolver';
+import { useEffect, useState } from 'react';
+import { z } from 'zod';
+import { MapBoxController } from '../../../services/api/MapboxController';
+import DirectionMode from '../../../services/api/Models/MapBoxDirections/DirectionMode';
+import { PlaceDto } from '../../../services/api/Models/PlaceLocation/PlaceLocationDto';
+import {
+  TripDetailsStore,
+  useTripDetailsStore,
+} from '../../../store/useTripDetailsStore';
+import {
+  TransportMode,
+  TransportModeSelector,
+} from '../transportModeSelector/TransportModeSelector';
+
+export type CreateStepModalProps = {
+  FormSend: (addStepDto: AddStepDto) => void;
+};
+
+export const CreateStepModal = (props: CreateStepModalProps) => {
+  //#region Hooks
+  const { SetAddModalIsOpened } = useTripDetailsStore();
+  const isOpened: boolean = useTripDetailsStore(
+    (state: TripDetailsStore) => state.isAddModalOpened,
+  );
+
+  const [addressValue, setAddressValue] = useDebouncedState('', 200);
+  //#endregion
+
+  //#region Forms
+
+  const addStepSchema = z.object({
+    name: z
+      .string()
+      .min(3, 'Le titre doit contenir au moins 3 caractères')
+      .max(50, 'Le titre doit contenir au maximum 50 caractères'),
+    description: z.string(),
+    latitude: z.number().min(-180).max(180),
+    longitude: z.number().min(-180).max(180),
+    transportMode: z.string().min(1),
+  });
+
+  const addStepForm = useForm({
+    validateInputOnChange: true,
+    validate: zodResolver(addStepSchema),
+    initialValues: {
+      name: '',
+      description: '',
+      latitude: undefined as number | undefined,
+      longitude: undefined as number | undefined,
+      transportMode: '',
+    },
+  });
+
+  //#endregion
+
+  //#region Queries
+
+  //#endregion
+
+  //#region Mutations
+
+  //#endregion
+
+  //#region Variables
+
+  //#endregion
+
+  //#region States
+
+  const [places, setPlaces] = useState<PlaceDto[]>([]);
+
+  //#endregion
+
+  //#region Effects
+
+  useEffect(() => {
+    (async () => {
+      const places: PlaceDto[] = await MapBoxController.getPlaces(addressValue);
+
+      if (places.length === 0) return;
+      setPlaces(places);
+
+      const currentPlace: PlaceDto | undefined = places.find(
+        (place: PlaceDto) => place.place === addressValue,
+      );
+      if (currentPlace) {
+        addStepForm.setFieldValue('latitude', currentPlace.coordinate[1]);
+        addStepForm.setFieldValue('longitude', currentPlace.coordinate[0]);
+      } else {
+        addStepForm.setFieldValue('latitude', undefined);
+        addStepForm.setFieldValue('longitude', undefined);
+      }
+    })();
+  }, [addressValue]);
+
+  //#endregion
+  //#region Memo
+
+  //#endregion
+
+  //#region Handlers
+  const handleCloseModal = () => {
+    addStepForm.reset();
+    setPlaces([]);
+    setAddressValue('');
+    SetAddModalIsOpened(false);
+  };
+
+  const handleTransportModeSelected = (transportMode: string) => {
+    switch (transportMode) {
+      case TransportMode.Voiture:
+        transportMode = DirectionMode.DRIVING;
+        break;
+      case TransportMode.Vélo:
+        transportMode = DirectionMode.CYCLING;
+        break;
+      case TransportMode.Marche:
+        transportMode = DirectionMode.WALKING;
+        break;
+      case TransportMode.Avion:
+        transportMode = DirectionMode.PLANE;
+        break;
+      case TransportMode.Fusée:
+        transportMode = DirectionMode.PLANE;
+        break;
+    }
+    addStepForm.setFieldValue('transportMode', transportMode);
+  };
+
+  const handleSendForm = () => {
+    props.FormSend(addStepForm.values);
+    handleCloseModal();
+  };
+  //#endregion
+
+  return (
+    <Modal.Root
+      opened={isOpened}
+      onClose={handleCloseModal}
+      centered
+      closeOnClickOutside={false}>
+      <Modal.Overlay backgroundOpacity={0.55} blur={3} />
+      <Modal.Content>
+        <Modal.Header>
+          <Modal.Title>Créer une étape de vôtre voyage</Modal.Title>
+          <Modal.CloseButton icon={<IconX />} />
+        </Modal.Header>
+        <Modal.Body>
+          <form onReset={() => addStepForm.reset()} className="form">
+            <TextInput
+              label="Titre de votre étape"
+              placeholder="Titre"
+              required
+              data-autofocus
+              {...addStepForm.getInputProps('name')}
+            />
+            <Textarea
+              mt="sm"
+              label="Description"
+              placeholder="Description"
+              {...addStepForm.getInputProps('description')}
+            />
+            <Autocomplete
+              label="Destination"
+              placeholder="Entrez une adresse"
+              withAsterisk
+              data={places.map(place => place.place)}
+              onChange={(event: string) => setAddressValue(event)}
+            />
+            <TransportModeSelector
+              selectedValue={(transportMode: string) =>
+                handleTransportModeSelected(transportMode)
+              }
+            />
+
+            <Group justify="flex-end" mt="md">
+              <Button mt="sm" onClick={handleCloseModal}>
+                Annuler
+              </Button>
+              <Button
+                mt="sm"
+                disabled={!addStepForm.isValid()}
+                onClick={handleSendForm}>
+                Sauvegarder
+              </Button>
+            </Group>
+          </form>
+        </Modal.Body>
+      </Modal.Content>
+    </Modal.Root>
+  );
+};
diff --git a/src/components/map/stepCard/stepCard/StepCard.scss b/src/components/map/stepCard/StepCard.scss
similarity index 100%
rename from src/components/map/stepCard/stepCard/StepCard.scss
rename to src/components/map/stepCard/StepCard.scss
diff --git a/src/components/map/stepCard/stepCard/StepCard.tsx b/src/components/map/stepCard/StepCard.tsx
similarity index 64%
rename from src/components/map/stepCard/stepCard/StepCard.tsx
rename to src/components/map/stepCard/StepCard.tsx
index 00bda2e..8cac3b5 100644
--- a/src/components/map/stepCard/stepCard/StepCard.tsx
+++ b/src/components/map/stepCard/StepCard.tsx
@@ -1,10 +1,10 @@
 import { StepDto, TravelDtoList } from '@FullStackMap/from-a2b';
 import { Paper, Text } from '@mantine/core';
-import useDistance from '../../../../hooks/useDistance';
-import useTime from '../../../../hooks/useTime';
-import DirectionMode from '../../../../services/api/Models/MapBoxDirections/DirectionMode';
-import { TransportModeIcon } from '../../../transportModeIcon/TransportModeIcon';
-import { StepCardMenu } from '../Menu/StepCardMenu';
+import useDistance from '../../../hooks/useDistance';
+import useTime from '../../../hooks/useTime';
+import DirectionMode from '../../../services/api/Models/MapBoxDirections/DirectionMode';
+import { TransportModeIcon } from '../../transportModeIcon/TransportModeIcon';
+import { StepCardMenu } from './Menu/StepCardMenu';
 import './StepCard.scss';
 
 interface StepCardProps {
@@ -21,6 +21,9 @@ export const StepCard = (props: StepCardProps) => {
       <Text>StepName : {props.step.name}</Text>
       <Text>StepId : {props.step.stepId}</Text>
       <Text>StepOrder : {props.step.order}</Text>
+      <TransportModeIcon
+        transportMode={props.step.transportMode as DirectionMode}
+      />
       {props.step.order !== 1 && props.travel && (
         <>
           <Text>
@@ -30,10 +33,6 @@ export const StepCard = (props: StepCardProps) => {
           <Text>
             TravelDuration : {SecondeToTime(props.travel.duration ?? 0)}
           </Text>
-          <Text>TravelTransportMode : {props.travel.transportMode}</Text>
-          <TransportModeIcon
-            transportMode={props.travel.transportMode as DirectionMode}
-          />
         </>
       )}
       <StepCardMenu stepId={props.step.stepId!} />
diff --git a/src/components/map/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx b/src/components/map/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx
index d6761f2..932c218 100644
--- a/src/components/map/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx
+++ b/src/components/map/stepCard/confirmDeleteModal/ConfirmDeleteModal.tsx
@@ -5,7 +5,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
 import { useEffect, useState } from 'react';
 import useNotify from '../../../../hooks/useNotify';
 import { StepController, TravelController } from '../../../../services/BaseApi';
-import { calculateRoad } from '../../../../services/api/MapboxController';
+import { MapBoxController } from '../../../../services/api/MapboxController';
 import CalculateTravelRoadDto from '../../../../services/api/Models/MapBoxDirections/CalculateTravelRoadDto';
 import DirectionMode from '../../../../services/api/Models/MapBoxDirections/DirectionMode';
 import RoadPositionDto from '../../../../services/api/Models/MapBoxDirections/RoadPositionDto';
@@ -58,7 +58,7 @@ export const ConfirmDeleteModal = (props: ConfirmDeleteModalProps) => {
     if (!newTravelRoad) return;
 
     const addTravelRoad: AddTravelDto = {
-      transportMode: DirectionMode.DRIVING,
+      transportMode: newTravelRoad.transportMode,
       distance: Number(newTravelRoad.distance.toFixed(2)),
       duration: Number(newTravelRoad.duration.toFixed(2)),
       originStepId: stepBefore?.stepId as number,
@@ -86,7 +86,7 @@ export const ConfirmDeleteModal = (props: ConfirmDeleteModalProps) => {
       directionMode: DirectionMode,
       positions: RoadPositionDto[],
     ]) =>
-      await calculateRoad(directionMode, positions)
+      await MapBoxController.calculateRoad(directionMode, positions)
         .then(res => SetNewTravelRoad(res))
         .catch(() => {
           queryClient.invalidateQueries({
@@ -105,7 +105,6 @@ export const ConfirmDeleteModal = (props: ConfirmDeleteModalProps) => {
       });
     },
   });
-
   const handleDeleteStep = async () => {
     await deleteStepMutation.mutateAsync();
     props.close();
@@ -122,7 +121,7 @@ export const ConfirmDeleteModal = (props: ConfirmDeleteModalProps) => {
       ];
 
       await calculateTravelRoadMutation.mutateAsync([
-        DirectionMode.DRIVING,
+        stepAfter.transportMode as DirectionMode,
         startEndPosition,
       ]);
     }
diff --git a/src/components/map/stepCard/StepList.scss b/src/components/map/stepList/StepList.scss
similarity index 100%
rename from src/components/map/stepCard/StepList.scss
rename to src/components/map/stepList/StepList.scss
diff --git a/src/components/map/stepCard/StepList.tsx b/src/components/map/stepList/StepList.tsx
similarity index 94%
rename from src/components/map/stepCard/StepList.tsx
rename to src/components/map/stepList/StepList.tsx
index 2b01478..2bcccf1 100644
--- a/src/components/map/stepCard/StepList.tsx
+++ b/src/components/map/stepList/StepList.tsx
@@ -4,8 +4,8 @@ import {
   TripDetailsStore,
   useTripDetailsStore,
 } from '../../../store/useTripDetailsStore';
+import { StepCard } from '../stepCard/StepCard';
 import './StepList.scss';
-import { StepCard } from './stepCard/StepCard';
 
 export const StepList = () => {
   //#region Hooks
diff --git a/src/components/map/transportModeSelector/TransportModeSelector.tsx b/src/components/map/transportModeSelector/TransportModeSelector.tsx
new file mode 100644
index 0000000..abf8c19
--- /dev/null
+++ b/src/components/map/transportModeSelector/TransportModeSelector.tsx
@@ -0,0 +1,107 @@
+import { Combobox, Group, InputBase, useCombobox } from '@mantine/core';
+import {
+  IconBike,
+  IconCar,
+  IconPlane,
+  IconRocket,
+  IconWalk,
+} from '@tabler/icons-react';
+import { useEffect, useState } from 'react';
+
+export enum TransportMode {
+  Voiture = 'Voiture',
+  Vélo = 'Vélo',
+  Marche = 'Marche',
+  Avion = 'Avion',
+  Fusée = 'Fusée',
+}
+
+export type TransportModeSelectorProps = {
+  selectedValue: (value: string) => void;
+};
+
+const transportModes: { name: string; icon: JSX.Element }[] = [
+  { name: TransportMode.Voiture, icon: <IconCar /> },
+  { name: TransportMode.Vélo, icon: <IconBike /> },
+  { name: TransportMode.Marche, icon: <IconWalk /> },
+  { name: TransportMode.Avion, icon: <IconPlane /> },
+  { name: TransportMode.Fusée, icon: <IconRocket /> },
+];
+
+export const TransportModeSelector = (props: TransportModeSelectorProps) => {
+  //#region Hooks
+  const combobox = useCombobox({
+    onDropdownClose: () => combobox.resetSelectedOption(),
+  });
+  //#endregion
+
+  //#region Queries
+
+  //#endregion
+
+  //#region Mutations
+
+  //#endregion
+
+  //#region States
+  const [value, setValue] = useState<string | null>(null);
+  //#endregion
+
+  //#region Effects
+
+  useEffect(() => {
+    if (!value) return;
+
+    props.selectedValue(value);
+  }, [value]);
+
+  //#endregion
+
+  //#region Variables
+
+  const options = transportModes.map(item => (
+    <Combobox.Option value={item.name} key={item.name}>
+      <Group gap="xs">
+        {item.icon}
+        <span>{item.name}</span>
+      </Group>
+    </Combobox.Option>
+  ));
+  //#endregion
+
+  //#region Memo
+
+  //#endregion
+
+  //#region Handlers
+
+  //#endregion
+  return (
+    <>
+      <Combobox
+        store={combobox}
+        onOptionSubmit={val => {
+          setValue(val);
+          combobox.closeDropdown();
+        }}>
+        <Combobox.Target>
+          <InputBase
+            label="Mode de Transport"
+            component="button"
+            type="button"
+            withAsterisk
+            pointer
+            rightSection={<Combobox.Chevron />}
+            rightSectionPointerEvents="none"
+            onClick={() => combobox.toggleDropdown()}>
+            {value}
+          </InputBase>
+        </Combobox.Target>
+
+        <Combobox.Dropdown>
+          <Combobox.Options>{options}</Combobox.Options>
+        </Combobox.Dropdown>
+      </Combobox>
+    </>
+  );
+};
diff --git a/src/layout/map/MapLayout.tsx b/src/layout/map/MapLayout.tsx
new file mode 100644
index 0000000..4d18b5a
--- /dev/null
+++ b/src/layout/map/MapLayout.tsx
@@ -0,0 +1,30 @@
+import { AppShell } from '@mantine/core';
+import { useDisclosure } from '@mantine/hooks';
+import { Outlet } from 'react-router-dom';
+import DefaultHeader from '../../components/header/DefaultHeader';
+
+const MapLayout = () => {
+  const [opened, { toggle }] = useDisclosure();
+
+  return (
+    <AppShell
+      header={{ height: 60 }}
+      navbar={{
+        width: 300,
+        breakpoint: 'sm',
+        collapsed: { desktop: true, mobile: !opened },
+      }}>
+      <AppShell.Header>
+        <DefaultHeader burgerOpened={opened} toggleBurgerState={toggle} />
+      </AppShell.Header>
+
+      <AppShell.Main>
+        <div>
+          <Outlet />
+        </div>
+      </AppShell.Main>
+    </AppShell>
+  );
+};
+
+export default MapLayout;
diff --git a/src/pages/editTravel/EditTravel.tsx b/src/pages/editTravel/EditTravel.tsx
deleted file mode 100644
index b9add13..0000000
--- a/src/pages/editTravel/EditTravel.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import { MapStepEditor } from '../../components/mapStepEditor/MapStepEditor';
-import { CreateStepModal} from '../../components/createStepModal/CreateStepModal.tsx'
-
-export const EditTravel = () => {
-
-  return (
-      <div>
-        <MapStepEditor />
-        <CreateStepModal/>
-      </div>
-    );
-
-}
\ No newline at end of file
diff --git a/src/pages/map/MapPage.tsx b/src/pages/map/MapPage.tsx
index d469fb9..79f756b 100644
--- a/src/pages/map/MapPage.tsx
+++ b/src/pages/map/MapPage.tsx
@@ -18,13 +18,6 @@ const MapPage = () => {
       ).catch(err => console.error(err)),
   });
 
-  const addTravelBetweenStepsMutation = useMutation({
-    mutationFn: async (addTravelDto: AddTravelDto) =>
-      await TravelController.addTravelBetweenStepsPOST(addTravelDto).catch(
-        err => console.error(err),
-      ),
-  });
-
   // const addPoint = async (evt: any) => {
   //   console.log('hello', evt.lngLat.lat, evt.lngLat.lng);
   //   await StepController.addStepAsyncPOST(tripId, {
diff --git a/src/pages/tripDetail/TripDetailPage.tsx b/src/pages/tripDetail/TripDetailPage.tsx
index db288e9..6ef060a 100644
--- a/src/pages/tripDetail/TripDetailPage.tsx
+++ b/src/pages/tripDetail/TripDetailPage.tsx
@@ -1,17 +1,30 @@
-import { AddStepDto, TripDto } from '@FullStackMap/from-a2b';
+import {
+  AddStepDto,
+  AddTravelDto,
+  StepDto,
+  TripDto,
+} from '@FullStackMap/from-a2b';
 import { Group, Stack } from '@mantine/core';
 import { useQuery, useQueryClient } from '@tanstack/react-query';
 import { AxiosResponse } from 'axios';
-import { StepController, TripController } from '../../services/BaseApi';
+import {
+  StepController,
+  TravelController,
+  TripController,
+} from '../../services/BaseApi';
 
 import { useEffect } from 'react';
-import { CreateStepModal } from '../../components/createStepModal/CreateStepModal.tsx';
 import { MapComponent } from '../../components/map/MapComponent';
 
 import { useMutation } from '@tanstack/react-query';
 
-import { StepList } from '../../components/map/stepCard/StepList.tsx';
-import { useStepStore } from '../../store/useStepStore.ts';
+import { CreateStepModal } from '../../components/map/addStep/CreateStepModal.tsx';
+import { StepList } from '../../components/map/stepList/StepList.tsx';
+import useNotify from '../../hooks/useNotify.tsx';
+import { MapBoxController } from '../../services/api/MapboxController.ts';
+import CalculateTravelRoadDto from '../../services/api/Models/MapBoxDirections/CalculateTravelRoadDto.ts';
+import DirectionMode from '../../services/api/Models/MapBoxDirections/DirectionMode.ts';
+import RoadPositionDto from '../../services/api/Models/MapBoxDirections/RoadPositionDto.ts';
 import {
   TripDetailsStore,
   useTripDetailsStore,
@@ -20,19 +33,19 @@ import {
 const TripDetailPage = () => {
   //#region Hooks
 
+  const { ErrorNotify } = useNotify();
+
   const tripId: string | undefined = useTripDetailsStore(
     (state: TripDetailsStore) => state.tripId,
   );
-  const { setTrip } = useTripDetailsStore();
+  const steps: StepDto[] = useTripDetailsStore(
+    (state: TripDetailsStore) => state.steps,
+  );
+  const { SetTrip, SetSelectedStep, UnselectCurrentStep } =
+    useTripDetailsStore();
 
   const queryClient = useQueryClient();
 
-  const step = useStepStore(state => state.step);
-
-  const SetStep = useStepStore(state => state.SetStep);
-
-  const close = useStepStore(state => state.setStatus);
-
   //#endregion
 
   //#region Queries
@@ -50,25 +63,21 @@ const TripDetailPage = () => {
   //#region Mutations
 
   const createStepMutation = useMutation({
-    mutationFn: (data: AddStepDto) =>
-      StepController.addStepAsyncPOST(tripId, data).catch(error => {
-        throw new Error(error);
-      }),
-    onSuccess: () => {
-      console.log('sucefull');
+    mutationFn: async (dto: AddStepDto) =>
+      StepController.addStepAsyncPOST(tripId, dto),
+    onSuccess: res => {
+      SetSelectedStep(res.data);
       queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
-      SetStep({
-        name: '',
-        description: '',
-        startDate: '',
-        endDate: '',
-        latitude: undefined,
-        longitude: undefined,
-      });
-      close(true);
+      handleCalculateNewTravel(res.data);
     },
-    onError: () => {
-      console.log('error rekekeke');
+  });
+
+  const addTravelBetweenStepsMutation = useMutation({
+    mutationFn: async (addTravelDto: AddTravelDto) =>
+      await TravelController.addTravelBetweenStepsPOST(addTravelDto),
+    onSuccess: () => {
+      UnselectCurrentStep();
+      queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
     },
   });
 
@@ -86,21 +95,82 @@ const TripDetailPage = () => {
 
   useEffect(() => {
     if (!tripDto) return;
-    setTrip(tripDto);
+    SetTrip(tripDto);
   }, [tripDto]);
 
   //#endregion
 
   //#region Handlers
-  const handleCreateStepFromModal = () => {
-    console.log('je vais créer la rekeke', step, tripId);
-
-    // createStepMutation.mutate({
-    //   name: step.name,
-    //   description: step.description,
-    //   longitude: step.longitude,
-    //   latitude: step.latitude,
-    // });
+
+  const handleCalculateNewTravel = async (destinationStep: StepDto) => {
+    const originStep: StepDto | undefined = steps.find(
+      step => step.order === destinationStep.order! - 1,
+    );
+
+    if (!originStep) return;
+
+    let travelRoad: CalculateTravelRoadDto | undefined;
+
+    if (destinationStep.transportMode !== DirectionMode.PLANE) {
+      const startEndPosition: RoadPositionDto[] = [
+        {
+          start: [
+            originStep!.longitude as number,
+            originStep!.latitude as number,
+          ],
+          end: [
+            destinationStep.longitude as number,
+            destinationStep.latitude as number,
+          ],
+        },
+      ];
+
+      try {
+        const res: CalculateTravelRoadDto | undefined =
+          await MapBoxController.calculateRoad(
+            destinationStep.transportMode as DirectionMode,
+            startEndPosition,
+          );
+
+        travelRoad = res;
+      } catch (err) {
+        return ErrorNotify({
+          title: 'Erreur de calcul de route',
+          message:
+            'Une erreur est survenue lors du calcul de la route. Veuillez réessayer plus tard.',
+          autoClose: undefined,
+        });
+      }
+    } else {
+      travelRoad = {
+        transportMode: DirectionMode.PLANE,
+        distance: -1,
+        duration: -1,
+        travelRoad: JSON.stringify([
+          [originStep?.longitude, originStep?.latitude],
+          [destinationStep.longitude, destinationStep.latitude],
+        ]),
+      };
+    }
+
+    if (!travelRoad)
+      return ErrorNotify({
+        title: 'Erreur de calcul de route',
+        message:
+          'Une erreur est survenue lors du calcul de la route. Veuillez réessayer.',
+        autoClose: undefined,
+      });
+
+    const addTravelDto: AddTravelDto = {
+      transportMode: travelRoad.transportMode,
+      distance: travelRoad?.distance,
+      duration: travelRoad?.duration,
+      originStepId: originStep?.stepId,
+      destinationStepId: destinationStep.stepId,
+      travelRoad: travelRoad?.travelRoad,
+    };
+
+    addTravelBetweenStepsMutation.mutate(addTravelDto);
   };
 
   //#endregion
@@ -113,7 +183,11 @@ const TripDetailPage = () => {
           <MapComponent />
         </Stack>
       </Group>
-      <CreateStepModal FormSend={() => handleCreateStepFromModal()} />
+      <CreateStepModal
+        FormSend={(addStepDto: AddStepDto) =>
+          createStepMutation.mutate(addStepDto)
+        }
+      />
     </>
   );
 };
diff --git a/src/router/Router.tsx b/src/router/Router.tsx
index f0d5077..80781dd 100644
--- a/src/router/Router.tsx
+++ b/src/router/Router.tsx
@@ -2,10 +2,10 @@ import { useEffect } from 'react';
 import { Navigate, Route, Routes } from 'react-router-dom';
 import DefaultLayout from '../layout/default/DefaultLayout';
 import LoginLayout from '../layout/login/LoginLayout';
+import MapLayout from '../layout/map/MapLayout.tsx';
 import CguPage from '../pages/cgu/CguPage';
 import { ConfirmMailPage } from '../pages/confirmMail/ConfirmMailPage';
 import ContactPage from '../pages/contact/ContactPage';
-import { EditTravel } from '../pages/editTravel/EditTravel.tsx';
 import FaqPage from '../pages/faq/FaqPage';
 import FeedbackPage from '../pages/feedback/FeedbackPage';
 import { ForgotPasswordPage } from '../pages/forgotPassword/ForgotPasswordPage';
@@ -32,23 +32,28 @@ const Router = () => {
         <Route path="/contact" element={<ContactPage />} />
         <Route path="/faq" element={<FaqPage />} />
         <Route path="/t" element={<TestPage />} />
+
         <Route
-          path="/tripDetail"
+          path="/profile"
           element={
             <PrivateRoute
               authRequired
               redirectPath="/login"
-              element={<TripDetailPage />}
+              element={<ProfilePage />}
             />
           }
         />
+        <Route path="/*" element={<Navigate to="/" />} />
+      </Route>
+
+      <Route element={<MapLayout />}>
         <Route
-          path="/editTravel"
+          path="/tripDetail"
           element={
             <PrivateRoute
               authRequired
               redirectPath="/login"
-              element={<EditTravel />}
+              element={<TripDetailPage />}
             />
           }
         />
@@ -62,17 +67,6 @@ const Router = () => {
             />
           }
         />
-        <Route
-          path="/profile"
-          element={
-            <PrivateRoute
-              authRequired
-              redirectPath="/login"
-              element={<ProfilePage />}
-            />
-          }
-        />
-        <Route path="/*" element={<Navigate to="/" />} />
       </Route>
 
       <Route element={<LoginLayout />}>
diff --git a/src/services/ErrorHandler.ts b/src/services/ErrorHandler.ts
index 0b3dab6..c15a699 100644
--- a/src/services/ErrorHandler.ts
+++ b/src/services/ErrorHandler.ts
@@ -3,11 +3,16 @@ import useNotify, { NotifyDto } from '../hooks/useNotify';
 const ErrorHandler = (error: any) => {
   const { ErrorNotify, NotifyMultipleErrors } = useNotify();
   const { response } = error;
+  const autoCloseTime = 6500;
 
   switch (response.status) {
     case 400: {
       const errors: NotifyDto[] = response.data?.map((error: any) => {
-        return { title: undefined, message: error.message } as NotifyDto;
+        return {
+          title: undefined,
+          message: error.message,
+          autoClose: autoCloseTime,
+        } as NotifyDto;
       });
       NotifyMultipleErrors(errors);
       break;
@@ -16,16 +21,19 @@ const ErrorHandler = (error: any) => {
       ErrorNotify({
         message:
           "Vous n'êtes pas autorisé à accéder à cette ressource. Veuillez vous connecter.",
+        autoClose: autoCloseTime,
       } as NotifyDto);
       break;
     case 403:
       ErrorNotify({
         message: "Vous n'êtes pas autorisé à accéder à cette ressource.",
+        autoClose: autoCloseTime,
       } as NotifyDto);
       break;
     case 404:
       ErrorNotify({
         message: "La ressource demandée n'a pas été trouvée.",
+        autoClose: autoCloseTime,
       } as NotifyDto);
       break;
     default:
diff --git a/src/services/api/MapboxController.ts b/src/services/api/MapboxController.ts
index 921695e..eaf6465 100644
--- a/src/services/api/MapboxController.ts
+++ b/src/services/api/MapboxController.ts
@@ -9,89 +9,186 @@ import { PlaceDto } from './Models/PlaceLocation/PlaceLocationDto.ts';
 // eslint-disable-next-line react-hooks/rules-of-hooks
 const { ErrorNotify } = useNotify();
 
-export const calculateRoad = async (
-  directionMode: DirectionMode,
-  positions: RoadPositionDto[],
-) => {
-  const positionsString = positions
-    .map(({ start, end }) => `${start};${end}`)
-    .join(';');
-
-  const response = await MapboxClient.get(
-    `/directions/v5/mapbox/${directionMode}/${positionsString}/?geometries=geojson&overview=full&access_token=${
-      import.meta.env.VITE_MAPBOX_TOKEN
-    }`,
-  );
-
-  switch (response?.data?.code) {
-    case 'InvalidInput':
-      ErrorNotify({
-        title: 'Échec du calcul du nouvel itinéraire',
-        message:
-          'La distance entre les deux points est trop grande pour ce mode de transport',
-        autoClose: undefined,
-      });
-      throw new Error('InvalidInput');
-
-    case 'NoSegment':
-      ErrorNotify({
-        title: 'Échec du calcul du nouvel itinéraire',
-        message:
-          'Le trajet entre les deux points de passage ne peut pas être calculé pour ce mode de transport.',
-        autoClose: undefined,
-      });
-      throw new Error('NoSegment');
-
-    case 'Ok': {
-      const data = response.data.routes[0];
-      const coords: Position[] = data.geometry.coordinates;
-
-      const travelRoadDto: CalculateTravelRoadDto = {
-        transportMode: DirectionMode.DRIVING,
-        distance: data.distance,
-        duration: data.duration,
-        travelRoad: JSON.stringify(coords),
-      };
-
-      return travelRoadDto;
+export class MapBoxController {
+  public static async calculateRoad(
+    directionMode: DirectionMode,
+    positions: RoadPositionDto[],
+  ) {
+    const positionsString = positions
+      .map(({ start, end }) => `${start};${end}`)
+      .join(';');
+
+    const response = await MapboxClient.get(
+      `/directions/v5/mapbox/${directionMode}/${positionsString}/?geometries=geojson&overview=full&access_token=${
+        import.meta.env.VITE_MAPBOX_TOKEN
+      }`,
+    );
+
+    switch (response?.data?.code) {
+      case 'InvalidInput':
+        ErrorNotify({
+          title: 'Échec du calcul du nouvel itinéraire',
+          message:
+            'La distance entre les deux points est trop grande pour ce mode de transport',
+          autoClose: undefined,
+        });
+        throw new Error('InvalidInput');
+
+      case 'NoSegment':
+        ErrorNotify({
+          title: 'Échec du calcul du nouvel itinéraire',
+          message:
+            'Le trajet entre les deux points de passage ne peut pas être calculé pour ce mode de transport.',
+          autoClose: undefined,
+        });
+        throw new Error('NoSegment');
+      case 'NoRoute':
+        ErrorNotify({
+          title: 'Échec du calcul du nouvel itinéraire',
+          message:
+            'Aucune route permettant de relier les deux points de passage n’a été trouvée.',
+          autoClose: undefined,
+        });
+        throw new Error('NoSegment');
+
+      case 'Ok': {
+        const data = response.data.routes[0];
+        const coords: Position[] = data.geometry.coordinates;
+
+        const travelRoadDto: CalculateTravelRoadDto = {
+          transportMode: directionMode,
+          distance: data.distance,
+          duration: data.duration,
+          travelRoad: JSON.stringify(coords),
+        };
+
+        return travelRoadDto;
+      }
     }
   }
-};
-
-export const getPlaces = async (place: string) => {
-  const response = await MapboxClient.get(
-    `/geocoding/v5/mapbox.places/${place}.json?proximity=ip&language=fr&access_token=${
-      import.meta.env.VITE_MAPBOX_TOKEN
-    }`,
-  );
-
-  const places: PlaceDto[] = response.data.features.map(
-    (item: { place_name_fr: any; center: any }) => {
-      return {
-        place: item.place_name_fr,
-        coordinate: item.center,
-      };
-    },
-  );
-  return places;
-};
-
-export const getPlaceWhitCoordinate = async (
-  latitude: number,
-  longitude: number,
-) => {
-  let response = await MapboxClient.get(
-    `/geocoding/v5/mapbox.places/${longitude},${latitude}.json?proximity=ip&language=fr&access_token=${
-      import.meta.env.VITE_MAPBOX_TOKEN
-    }`,
-  );
-  response = response.data.features.map(
-    (item: { place_name_fr: any; center: any }) => {
-      return {
-        place: item.place_name_fr,
-        coordinate: item.center,
-      };
-    },
-  );
-  return response;
-};
+
+  public static async getPlaces(placeName: string) {
+    const response = await MapboxClient.get(
+      `/geocoding/v5/mapbox.places/${placeName}.json?proximity=ip&language=fr&access_token=${
+        import.meta.env.VITE_MAPBOX_TOKEN
+      }`,
+    );
+
+    const places: PlaceDto[] = response.data.features.map(
+      (item: { place_name_fr: any; center: any }) => {
+        return {
+          place: item.place_name_fr,
+          coordinate: item.center,
+        };
+      },
+    );
+    return places;
+  }
+
+  public static async getPlaceWhitCoordinate(
+    latitude: number,
+    longitude: number,
+  ) {
+    let response = await MapboxClient.get(
+      `/geocoding/v5/mapbox.places/${longitude},${latitude}.json?proximity=ip&language=fr&access_token=${
+        import.meta.env.VITE_MAPBOX_TOKEN
+      }`,
+    );
+    response = response.data.features.map(
+      (item: { place_name_fr: any; center: any }) => {
+        return {
+          place: item.place_name_fr,
+          coordinate: item.center,
+        };
+      },
+    );
+    return response;
+  }
+}
+
+// export const calculateRoad = async (
+//   directionMode: DirectionMode,
+//   positions: RoadPositionDto[],
+// ) => {
+//   const positionsString = positions
+//     .map(({ start, end }) => `${start};${end}`)
+//     .join(';');
+
+//   const response = await MapboxClient.get(
+//     `/directions/v5/mapbox/${directionMode}/${positionsString}/?geometries=geojson&overview=full&access_token=${
+//       import.meta.env.VITE_MAPBOX_TOKEN
+//     }`,
+//   );
+
+//   switch (response?.data?.code) {
+//     case 'InvalidInput':
+//       ErrorNotify({
+//         title: 'Échec du calcul du nouvel itinéraire',
+//         message:
+//           'La distance entre les deux points est trop grande pour ce mode de transport',
+//         autoClose: undefined,
+//       });
+//       throw new Error('InvalidInput');
+
+//     case 'NoSegment':
+//       ErrorNotify({
+//         title: 'Échec du calcul du nouvel itinéraire',
+//         message:
+//           'Le trajet entre les deux points de passage ne peut pas être calculé pour ce mode de transport.',
+//         autoClose: undefined,
+//       });
+//       throw new Error('NoSegment');
+
+//     case 'Ok': {
+//       const data = response.data.routes[0];
+//       const coords: Position[] = data.geometry.coordinates;
+
+//       const travelRoadDto: CalculateTravelRoadDto = {
+//         transportMode: DirectionMode.DRIVING,
+//         distance: data.distance,
+//         duration: data.duration,
+//         travelRoad: JSON.stringify(coords),
+//       };
+
+//       return travelRoadDto;
+//     }
+//   }
+// };
+
+// export const getPlaces = async (placeName: string) => {
+//   const response = await MapboxClient.get(
+//     `/geocoding/v5/mapbox.places/${placeName}.json?proximity=ip&language=fr&access_token=${
+//       import.meta.env.VITE_MAPBOX_TOKEN
+//     }`,
+//   );
+
+//   const places: PlaceDto[] = response.data.features.map(
+//     (item: { place_name_fr: any; center: any }) => {
+//       return {
+//         place: item.place_name_fr,
+//         coordinate: item.center,
+//       };
+//     },
+//   );
+//   return places;
+// };
+
+// export const getPlaceWhitCoordinate = async (
+//   latitude: number,
+//   longitude: number,
+// ) => {
+//   let response = await MapboxClient.get(
+//     `/geocoding/v5/mapbox.places/${longitude},${latitude}.json?proximity=ip&language=fr&access_token=${
+//       import.meta.env.VITE_MAPBOX_TOKEN
+//     }`,
+//   );
+//   response = response.data.features.map(
+//     (item: { place_name_fr: any; center: any }) => {
+//       return {
+//         place: item.place_name_fr,
+//         coordinate: item.center,
+//       };
+//     },
+//   );
+//   return response;
+// };
diff --git a/src/store/useTripDetailsStore.ts b/src/store/useTripDetailsStore.ts
index aa750e0..7f2f26c 100644
--- a/src/store/useTripDetailsStore.ts
+++ b/src/store/useTripDetailsStore.ts
@@ -2,35 +2,39 @@ import { StepDto, TravelDtoList, TripDto } from '@FullStackMap/from-a2b';
 import { create } from 'zustand';
 
 export type TripDetailsStore = {
-  status: boolean;
-  setStatus: (status: boolean) => void;
+  isAddModalOpened: boolean;
+  SetAddModalIsOpened: (status: boolean) => void;
 
   tripId: string;
-  setTripId: (tripId: string) => void;
+  SetTripId: (tripId: string) => void;
+
   trip: TripDto;
-  setTrip: (trip: TripDto) => void;
+  SetTrip: (trip: TripDto) => void;
 
   steps: StepDto[];
-  currentStep: StepDto;
-  SelectStep: (stepId: number) => void;
   SetSteps: (steps: StepDto[]) => void;
 
-  Unselect: () => void;
+  currentStepId: number | undefined;
+  SetCurrentStepId: (stepId: number) => void;
+
+  currentStep: StepDto | undefined;
+  SelectStep: (stepId: number) => void;
+  SetSelectedStep: (step: StepDto) => void;
+  UnselectCurrentStep: () => void;
 
   travels: TravelDtoList[];
   SetTravels: (travels: TravelDtoList[]) => void;
 };
 
 export const useTripDetailsStore = create<TripDetailsStore>(set => ({
-  status: false,
-  setStatus: (status: boolean) => set({ status }),
+  isAddModalOpened: false,
+  SetAddModalIsOpened: (status: boolean) => set({ isAddModalOpened: status }),
 
-  // tripId: undefined,
   tripId: 'A8EB1FCE-B9DE-4201-B1FC-08DC4FD48062',
-  setTripId: (tripId: string) => set({ tripId }),
+  SetTripId: (tripId: string) => set({ tripId }),
 
   trip: {} as TripDto,
-  setTrip: (tripDto: TripDto) =>
+  SetTrip: (tripDto: TripDto) =>
     set({
       trip: tripDto,
       steps: tripDto.steps || [],
@@ -39,13 +43,29 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
 
   steps: [],
   SetSteps: (steps: StepDto[]) => set({ steps }),
-  currentStep: {} as StepDto,
+
+  currentStepId: undefined,
+  SetCurrentStepId: (stepId: number) => set({ currentStepId: stepId }),
+
+  currentStep: undefined,
+  SetSelectedStep: (step: StepDto) =>
+    set({
+      currentStepId: step.stepId,
+      currentStep: step,
+    }),
   SelectStep: (stepId: number) =>
     set((state: TripDetailsStore) => {
       const currentStep = state.steps.find(step => step.stepId === stepId);
-      return { currentStep: currentStep };
+      return {
+        currentStepId: stepId,
+        currentStep: currentStep,
+      };
+    }),
+  UnselectCurrentStep: () =>
+    set({
+      currentStep: {} as StepDto,
+      currentStepId: undefined,
     }),
-  Unselect: () => set({ currentStep: {} as StepDto }),
 
   travels: [],
   SetTravels: (travels: TravelDtoList[]) => set({ travels }),

From 787420e6dcc5f7444615af3ccb44e1d9a32a8a33 Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Sat, 30 Mar 2024 04:13:28 +0100
Subject: [PATCH 21/34] feat (TripDetails) : [WIP] AddBefore And After

---
 src/components/map/MapComponent.tsx           |  10 +-
 .../map/addStep/CreateStepModal.tsx           |  12 +-
 .../map/stepCard/Menu/StepCardMenu.tsx        |  71 ++++++++++--
 src/components/map/stepList/StepList.tsx      |  24 ++--
 src/pages/tripDetail/TripDetailPage.tsx       | 107 +++++++++++++++---
 src/store/useTripDetailsStore.ts              |  45 +++++++-
 6 files changed, 227 insertions(+), 42 deletions(-)

diff --git a/src/components/map/MapComponent.tsx b/src/components/map/MapComponent.tsx
index 73b5eeb..008d58a 100644
--- a/src/components/map/MapComponent.tsx
+++ b/src/components/map/MapComponent.tsx
@@ -16,13 +16,14 @@ import { useDisclosure } from '@mantine/hooks';
 import { IconCirclePlus, IconPinnedFilled } from '@tabler/icons-react';
 import React, { useMemo } from 'react';
 import {
+  AddStepMode,
   TripDetailsStore,
   useTripDetailsStore,
 } from '../../store/useTripDetailsStore';
 
 export const MapComponent = () => {
   //#region Hooks
-  const { SetAddModalIsOpened } = useTripDetailsStore();
+  const { SetAddStepMode, SetAddModalIsOpened } = useTripDetailsStore();
 
   const steps: StepDto[] = useTripDetailsStore(
     (state: TripDetailsStore) => state.steps,
@@ -280,6 +281,11 @@ export const MapComponent = () => {
   //   queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
   // };
 
+  const handleAddStepToEnd = () => {
+    SetAddStepMode(AddStepMode.END);
+    SetAddModalIsOpened(true);
+  };
+
   //#endregion
 
   return (
@@ -309,7 +315,7 @@ export const MapComponent = () => {
 
         <GeolocateControl />
         <ScaleControl />
-        <ActionIcon radius={'xl'} onClick={() => SetAddModalIsOpened(true)}>
+        <ActionIcon radius={'xl'} onClick={handleAddStepToEnd}>
           <IconCirclePlus size={48} />
         </ActionIcon>
       </Map>
diff --git a/src/components/map/addStep/CreateStepModal.tsx b/src/components/map/addStep/CreateStepModal.tsx
index b3d796e..fd0af6c 100644
--- a/src/components/map/addStep/CreateStepModal.tsx
+++ b/src/components/map/addStep/CreateStepModal.tsx
@@ -17,6 +17,7 @@ import { MapBoxController } from '../../../services/api/MapboxController';
 import DirectionMode from '../../../services/api/Models/MapBoxDirections/DirectionMode';
 import { PlaceDto } from '../../../services/api/Models/PlaceLocation/PlaceLocationDto';
 import {
+  AddStepMode,
   TripDetailsStore,
   useTripDetailsStore,
 } from '../../../store/useTripDetailsStore';
@@ -31,6 +32,9 @@ export type CreateStepModalProps = {
 
 export const CreateStepModal = (props: CreateStepModalProps) => {
   //#region Hooks
+  const addStepMode: AddStepMode = useTripDetailsStore(
+    (state: TripDetailsStore) => state.addStepMode,
+  );
   const { SetAddModalIsOpened } = useTripDetailsStore();
   const isOpened: boolean = useTripDetailsStore(
     (state: TripDetailsStore) => state.isAddModalOpened,
@@ -155,7 +159,13 @@ export const CreateStepModal = (props: CreateStepModalProps) => {
       <Modal.Overlay backgroundOpacity={0.55} blur={3} />
       <Modal.Content>
         <Modal.Header>
-          <Modal.Title>Créer une étape de vôtre voyage</Modal.Title>
+          <Modal.Title>
+            {addStepMode === AddStepMode.END
+              ? 'Créer une nouvelle étape pour vôtre voyage'
+              : addStepMode === AddStepMode.BEFORE
+              ? "Ajouter une étape avant l'étape actuelle"
+              : "Ajouter une étape après l'étape actuelle"}
+          </Modal.Title>
           <Modal.CloseButton icon={<IconX />} />
         </Modal.Header>
         <Modal.Body>
diff --git a/src/components/map/stepCard/Menu/StepCardMenu.tsx b/src/components/map/stepCard/Menu/StepCardMenu.tsx
index 6f772e3..17c488d 100644
--- a/src/components/map/stepCard/Menu/StepCardMenu.tsx
+++ b/src/components/map/stepCard/Menu/StepCardMenu.tsx
@@ -10,6 +10,10 @@ import {
   IconEdit,
   IconTrash,
 } from '@tabler/icons-react';
+import {
+  AddStepMode,
+  useTripDetailsStore,
+} from '../../../../store/useTripDetailsStore';
 import { ConfirmDeleteModal } from '../confirmDeleteModal/ConfirmDeleteModal';
 
 interface StepCardMenuProps {
@@ -17,13 +21,54 @@ interface StepCardMenuProps {
 }
 
 export const StepCardMenu = (props: StepCardMenuProps) => {
+  //#region Hooks
+
+  const { SetAddStepMode, SetAddModalIsOpened, SelectOtherStep } =
+    useTripDetailsStore();
+
   const [deleteStepModalOpened, deleteStepModalController] =
     useDisclosure(false);
 
-  const handleDeleteStep = () => {
-    deleteStepModalController.open();
+  //#endregion
+
+  //#region Queries
+
+  //#endregion
+
+  //#region Mutations
+
+  //#endregion
+
+  //#region Variables
+
+  //#endregion
+
+  //#region States
+
+  //#endregion
+
+  //#region Effects
+
+  //#endregion
+  //#region Memo
+
+  //#endregion
+
+  //#region Handlers
+
+  const handleCreateStepBefore = () => {
+    SetAddStepMode(AddStepMode.BEFORE);
+    SelectOtherStep(props.stepId);
+    SetAddModalIsOpened(true);
+  };
+  const handleCreateStepAfter = () => {
+    SetAddStepMode(AddStepMode.AFTER);
+    SelectOtherStep(props.stepId);
+    SetAddModalIsOpened(true);
   };
 
+  //#endregion
+
   return (
     <>
       <Menu shadow="md" width={200}>
@@ -34,30 +79,38 @@ export const StepCardMenu = (props: StepCardMenuProps) => {
         </Menu.Target>
 
         <Menu.Dropdown>
-          <Menu.Item leftSection={<IconEdit />}>Modifier l'étape</Menu.Item>
+          <Menu.Item leftSection={<IconEdit />} disabled>
+            Modifier l'étape
+          </Menu.Item>
           <Menu.Item
             color="red"
             leftSection={<IconTrash />}
-            onClick={handleDeleteStep}>
+            onClick={() => deleteStepModalController.open()}>
             Supprimer l'étape
           </Menu.Item>
 
           <Menu.Divider />
           <Menu.Label>Déplacement de l'étape</Menu.Label>
-          <Menu.Item leftSection={<IconArrowMoveUp />}>
+          <Menu.Item leftSection={<IconArrowMoveUp />} disabled>
             Déplacer avant
           </Menu.Item>
-          <Menu.Item leftSection={<IconArrowDownBar />}>
+          <Menu.Item leftSection={<IconArrowDownBar />} disabled>
             Déplacer après
           </Menu.Item>
 
           <Menu.Divider />
           <Menu.Label>Nouvelle étape</Menu.Label>
-          <Menu.Item leftSection={<IconCopy />}>Dupliquer mon étape</Menu.Item>
-          <Menu.Item leftSection={<IconArrowBarToDown />}>
+          <Menu.Item leftSection={<IconCopy />} disabled>
+            Dupliquer mon étape
+          </Menu.Item>
+          <Menu.Item
+            leftSection={<IconArrowBarToDown />}
+            onClick={handleCreateStepBefore}>
             Ajouter Avant
           </Menu.Item>
-          <Menu.Item leftSection={<IconArrowBarToUp />}>
+          <Menu.Item
+            leftSection={<IconArrowBarToUp />}
+            onClick={handleCreateStepAfter}>
             Ajouter Après
           </Menu.Item>
         </Menu.Dropdown>
diff --git a/src/components/map/stepList/StepList.tsx b/src/components/map/stepList/StepList.tsx
index 2bcccf1..7188123 100644
--- a/src/components/map/stepList/StepList.tsx
+++ b/src/components/map/stepList/StepList.tsx
@@ -22,17 +22,19 @@ export const StepList = () => {
   return (
     <>
       <Stack id="map_step_list">
-        {steps.map((step: StepDto) => (
-          <StepCard
-            key={step.stepId}
-            step={step}
-            travel={
-              travels.filter(
-                (t: TravelDtoList) => t.destinationStepId == step.stepId,
-              )[0]
-            }
-          />
-        ))}
+        {steps
+          .sort((a: StepDto, b: StepDto) => a.order! - b.order!)
+          .map((step: StepDto) => (
+            <StepCard
+              key={step.stepId}
+              step={step}
+              travel={
+                travels.filter(
+                  (t: TravelDtoList) => t.destinationStepId == step.stepId,
+                )[0]
+              }
+            />
+          ))}
       </Stack>
     </>
   );
diff --git a/src/pages/tripDetail/TripDetailPage.tsx b/src/pages/tripDetail/TripDetailPage.tsx
index 6ef060a..4ee6574 100644
--- a/src/pages/tripDetail/TripDetailPage.tsx
+++ b/src/pages/tripDetail/TripDetailPage.tsx
@@ -26,6 +26,7 @@ import CalculateTravelRoadDto from '../../services/api/Models/MapBoxDirections/C
 import DirectionMode from '../../services/api/Models/MapBoxDirections/DirectionMode.ts';
 import RoadPositionDto from '../../services/api/Models/MapBoxDirections/RoadPositionDto.ts';
 import {
+  AddStepMode,
   TripDetailsStore,
   useTripDetailsStore,
 } from '../../store/useTripDetailsStore';
@@ -41,6 +42,18 @@ const TripDetailPage = () => {
   const steps: StepDto[] = useTripDetailsStore(
     (state: TripDetailsStore) => state.steps,
   );
+
+  const addStepMode: AddStepMode = useTripDetailsStore(
+    (state: TripDetailsStore) => state.addStepMode,
+  );
+
+  const otherStepId: number | undefined = useTripDetailsStore(
+    (state: TripDetailsStore) => state.otherStepId,
+  );
+  const otherStep: StepDto | undefined = useTripDetailsStore(
+    (state: TripDetailsStore) => state.otherStep,
+  );
+
   const { SetTrip, SetSelectedStep, UnselectCurrentStep } =
     useTripDetailsStore();
 
@@ -68,7 +81,33 @@ const TripDetailPage = () => {
     onSuccess: res => {
       SetSelectedStep(res.data);
       queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
-      handleCalculateNewTravel(res.data);
+      handleCalculateNewTravel(undefined, res.data);
+    },
+  });
+
+  const createStepBeforeMutation = useMutation({
+    mutationFn: async ([previousStepId, dto]: [number, AddStepDto]) =>
+      StepController.addStepBeforAsyncPOST(tripId, previousStepId, dto),
+    onSuccess: async res => {
+      SetSelectedStep(res.data);
+      queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
+      await handleCalculateNewTravel(undefined, res.data);
+      await handleCalculateNewTravel(res.data, otherStep);
+    },
+  });
+
+  const createStepAfterMutation = useMutation({
+    mutationFn: async ([nextStepId, dto]: [number, AddStepDto]) =>
+      StepController.addStepAfterAsyncPOST(tripId, nextStepId, dto),
+    onSuccess: res => {
+      SetSelectedStep(res.data);
+      queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
+      handleCalculateNewTravel(otherStep, res.data);
+      console.log(
+        '==================================================================================================',
+      );
+
+      handleCalculateNewTravel(res.data, undefined);
     },
   });
 
@@ -102,16 +141,36 @@ const TripDetailPage = () => {
 
   //#region Handlers
 
-  const handleCalculateNewTravel = async (destinationStep: StepDto) => {
-    const originStep: StepDto | undefined = steps.find(
-      step => step.order === destinationStep.order! - 1,
-    );
+  const handleCalculateNewTravel = async (
+    originStep: StepDto | undefined,
+    destinationStep: StepDto | undefined,
+  ) => {
+    if (!originStep && !destinationStep) return;
+
+    if (!originStep && destinationStep) {
+      originStep = steps.find(
+        step => step.order === destinationStep!.order! - 1,
+      );
+
+      if (!originStep) return;
+    }
+    console.log('🚀 ~ TripDetailPage ~ originStep:', originStep);
 
-    if (!originStep) return;
+    if (!destinationStep && originStep) {
+      if (!destinationStep && addStepMode === AddStepMode.AFTER)
+        destinationStep = steps.find(step => step.order === originStep!.order!);
+
+      destinationStep = steps.find(
+        step => step.order === originStep!.order! + 1,
+      );
+
+      if (!destinationStep) return;
+    }
+    console.log('🚀 ~ TripDetailPage ~ destinationStep:', destinationStep);
 
     let travelRoad: CalculateTravelRoadDto | undefined;
 
-    if (destinationStep.transportMode !== DirectionMode.PLANE) {
+    if (destinationStep!.transportMode !== DirectionMode.PLANE) {
       const startEndPosition: RoadPositionDto[] = [
         {
           start: [
@@ -119,8 +178,8 @@ const TripDetailPage = () => {
             originStep!.latitude as number,
           ],
           end: [
-            destinationStep.longitude as number,
-            destinationStep.latitude as number,
+            destinationStep!.longitude as number,
+            destinationStep!.latitude as number,
           ],
         },
       ];
@@ -128,7 +187,7 @@ const TripDetailPage = () => {
       try {
         const res: CalculateTravelRoadDto | undefined =
           await MapBoxController.calculateRoad(
-            destinationStep.transportMode as DirectionMode,
+            destinationStep!.transportMode as DirectionMode,
             startEndPosition,
           );
 
@@ -147,8 +206,8 @@ const TripDetailPage = () => {
         distance: -1,
         duration: -1,
         travelRoad: JSON.stringify([
-          [originStep?.longitude, originStep?.latitude],
-          [destinationStep.longitude, destinationStep.latitude],
+          [originStep!.longitude, originStep!.latitude],
+          [destinationStep!.longitude, destinationStep!.latitude],
         ]),
       };
     }
@@ -157,7 +216,7 @@ const TripDetailPage = () => {
       return ErrorNotify({
         title: 'Erreur de calcul de route',
         message:
-          'Une erreur est survenue lors du calcul de la route. Veuillez réessayer.',
+          'Une erreur est survenue lors du calcul de la route. Veuillez réessayer plus tard.',
         autoClose: undefined,
       });
 
@@ -166,11 +225,25 @@ const TripDetailPage = () => {
       distance: travelRoad?.distance,
       duration: travelRoad?.duration,
       originStepId: originStep?.stepId,
-      destinationStepId: destinationStep.stepId,
+      destinationStepId: destinationStep?.stepId,
       travelRoad: travelRoad?.travelRoad,
     };
 
-    addTravelBetweenStepsMutation.mutate(addTravelDto);
+    await addTravelBetweenStepsMutation.mutateAsync(addTravelDto);
+  };
+
+  const handleAddStep = async (dto: AddStepDto) => {
+    switch (addStepMode) {
+      case AddStepMode.END:
+        createStepMutation.mutate(dto);
+        break;
+      case AddStepMode.BEFORE:
+        createStepBeforeMutation.mutate([otherStepId!, dto]);
+        break;
+      case AddStepMode.AFTER:
+        createStepAfterMutation.mutate([otherStepId!, dto]);
+        break;
+    }
   };
 
   //#endregion
@@ -184,9 +257,7 @@ const TripDetailPage = () => {
         </Stack>
       </Group>
       <CreateStepModal
-        FormSend={(addStepDto: AddStepDto) =>
-          createStepMutation.mutate(addStepDto)
-        }
+        FormSend={(addStepDto: AddStepDto) => handleAddStep(addStepDto)}
       />
     </>
   );
diff --git a/src/store/useTripDetailsStore.ts b/src/store/useTripDetailsStore.ts
index 7f2f26c..20c5794 100644
--- a/src/store/useTripDetailsStore.ts
+++ b/src/store/useTripDetailsStore.ts
@@ -1,10 +1,19 @@
 import { StepDto, TravelDtoList, TripDto } from '@FullStackMap/from-a2b';
 import { create } from 'zustand';
 
+export enum AddStepMode {
+  END = 'End',
+  BEFORE = 'Before',
+  AFTER = 'After',
+}
+
 export type TripDetailsStore = {
   isAddModalOpened: boolean;
   SetAddModalIsOpened: (status: boolean) => void;
 
+  addStepMode: AddStepMode;
+  SetAddStepMode: (mode: AddStepMode) => void;
+
   tripId: string;
   SetTripId: (tripId: string) => void;
 
@@ -22,6 +31,14 @@ export type TripDetailsStore = {
   SetSelectedStep: (step: StepDto) => void;
   UnselectCurrentStep: () => void;
 
+  otherStepId: number | undefined;
+  SetOtherStepId: (stepId: number) => void;
+
+  otherStep: StepDto | undefined;
+  SetOtherStep: (step: StepDto) => void;
+  SelectOtherStep: (stepId: number) => void;
+  UnSelectOtherStep: () => void;
+
   travels: TravelDtoList[];
   SetTravels: (travels: TravelDtoList[]) => void;
 };
@@ -30,6 +47,9 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
   isAddModalOpened: false,
   SetAddModalIsOpened: (status: boolean) => set({ isAddModalOpened: status }),
 
+  addStepMode: AddStepMode.END,
+  SetAddStepMode: (mode: AddStepMode) => set({ addStepMode: mode }),
+
   tripId: 'A8EB1FCE-B9DE-4201-B1FC-08DC4FD48062',
   SetTripId: (tripId: string) => set({ tripId }),
 
@@ -63,10 +83,33 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
     }),
   UnselectCurrentStep: () =>
     set({
-      currentStep: {} as StepDto,
+      currentStep: undefined,
       currentStepId: undefined,
     }),
 
+  otherStepId: undefined,
+  SetOtherStepId: (stepId: number) => set({ otherStepId: stepId }),
+
+  otherStep: undefined,
+  SetOtherStep: (step: StepDto) =>
+    set({
+      otherStepId: step.stepId,
+      otherStep: step,
+    }),
+  SelectOtherStep: (stepId: number) =>
+    set((state: TripDetailsStore) => {
+      const otherStep = state.steps.find(step => step.stepId === stepId);
+      return {
+        otherStepId: stepId,
+        otherStep: otherStep,
+      };
+    }),
+  UnSelectOtherStep: () =>
+    set({
+      otherStep: undefined,
+      otherStepId: undefined,
+    }),
+
   travels: [],
   SetTravels: (travels: TravelDtoList[]) => set({ travels }),
 }));

From 4ad9f23e54425bb1e3993f9d246138603471be27 Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Sat, 30 Mar 2024 14:57:49 +0100
Subject: [PATCH 22/34] Feat (TripDetail) : Move Point

---
 src/components/map/MapComponent.tsx           | 311 +++++++++---------
 .../map/stepCard/Menu/StepCardMenu.tsx        |   5 +-
 src/components/map/stepList/StepList.tsx      |   1 +
 src/pages/map/MapPage.tsx                     |   8 -
 src/pages/tripDetail/TripDetailPage.tsx       |  14 +-
 src/store/useTripDetailsStore.ts              |  14 +-
 6 files changed, 173 insertions(+), 180 deletions(-)

diff --git a/src/components/map/MapComponent.tsx b/src/components/map/MapComponent.tsx
index 008d58a..2a0c633 100644
--- a/src/components/map/MapComponent.tsx
+++ b/src/components/map/MapComponent.tsx
@@ -1,6 +1,11 @@
-import { StepDto, TravelDtoList } from '@FullStackMap/from-a2b';
+import {
+  AddTravelDto,
+  StepDto,
+  TravelDtoList,
+  UpdateStepLocationDto,
+} from '@FullStackMap/from-a2b';
 import { ActionIcon, Box, LoadingOverlay } from '@mantine/core';
-import { FeatureCollection } from 'geojson';
+import { FeatureCollection, Position } from 'geojson';
 import {
   GeolocateControl,
   Layer,
@@ -14,7 +19,13 @@ import {
 
 import { useDisclosure } from '@mantine/hooks';
 import { IconCirclePlus, IconPinnedFilled } from '@tabler/icons-react';
+import { useMutation, useQueryClient } from '@tanstack/react-query';
 import React, { useMemo } from 'react';
+import { StepController, TravelController } from '../../services/BaseApi';
+import { MapBoxController } from '../../services/api/MapboxController';
+import CalculateTravelRoadDto from '../../services/api/Models/MapBoxDirections/CalculateTravelRoadDto';
+import DirectionMode from '../../services/api/Models/MapBoxDirections/DirectionMode';
+import RoadPositionDto from '../../services/api/Models/MapBoxDirections/RoadPositionDto';
 import {
   AddStepMode,
   TripDetailsStore,
@@ -23,8 +34,13 @@ import {
 
 export const MapComponent = () => {
   //#region Hooks
-  const { SetAddStepMode, SetAddModalIsOpened } = useTripDetailsStore();
+  const queryClient = useQueryClient();
+  const { SetAddStepMode, SetAddModalIsOpened, UnSelectCurrentStep } =
+    useTripDetailsStore();
 
+  const tripId: string = useTripDetailsStore(
+    (state: TripDetailsStore) => state.tripId,
+  );
   const steps: StepDto[] = useTripDetailsStore(
     (state: TripDetailsStore) => state.steps,
   );
@@ -42,6 +58,22 @@ export const MapComponent = () => {
 
   //#region Mutations
 
+  const updateStepLocationMutation = useMutation({
+    mutationFn: async ([stepId, dto]: [number, UpdateStepLocationDto]) =>
+      await StepController.updateStepLocationAsyncPATCH(stepId, dto),
+    onSuccess: () =>
+      queryClient.invalidateQueries({ queryKey: ['Trip', tripId] }),
+  });
+
+  const addTravelBetweenStepsMutation = useMutation({
+    mutationFn: async (addTravelDto: AddTravelDto) =>
+      await TravelController.addTravelBetweenStepsPOST(addTravelDto),
+    onSuccess: () => {
+      UnSelectCurrentStep();
+      queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
+    },
+  });
+
   //#endregion
 
   //#region Variables
@@ -128,158 +160,127 @@ export const MapComponent = () => {
 
   //#region Handlers
 
-  //TODO: Update this
-  // const handleMoveMarker = async (evt: MarkerDragEvent, stepId: number) => {
-  //   const updateStateLocationDto: UpdateStepLocationDto = {
-  //     latitude: evt.lngLat.lat,
-  //     longitude: evt.lngLat.lng,
-  //   };
-
-  //   const currentStep: StepDto | undefined = steps.find(
-  //     (s: StepDto) => s.stepId === stepId,
-  //   );
-  //   console.log('🚀 ~ handleMoveMarker ~ currentStep:', currentStep);
-  //   const stepBefore: StepDto | undefined = steps.find(
-  //     (s: StepDto) => s.order === (currentStep?.order as number) - 1,
-  //   );
-  //   console.log('🚀 ~ handleMoveMarker ~ stepBefore:', stepBefore);
-  //   const stepAfter: StepDto | undefined = steps.find(
-  //     (s: StepDto) => s.order === (currentStep?.order as number) + 1,
-  //   );
-  //   console.log('🚀 ~ handleMoveMarker ~ stepAfter:', stepAfter);
-
-  //   await updateStepLocationMutation.mutateAsync({
-  //     stepId: stepId,
-  //     updateStateLocationDto,
-  //   });
-
-  //   if (updateStepLocationMutation.error) return;
-
-  //   if (stepBefore && currentStep) {
-  //     const startEndPosition: RoadPositionDto[] = [
-  //       {
-  //         start: [
-  //           stepBefore.longitude as number,
-  //           stepBefore.latitude as number,
-  //         ],
-  //         end: [
-  //           updateStateLocationDto?.longitude as number,
-  //           updateStateLocationDto?.latitude as number,
-  //         ],
-  //       },
-  //     ];
-
-  //     const travelBeforeResponse: CalculateTravelRoadDto | undefined =
-  //       await calculateRoad(DirectionMode.DRIVING, startEndPosition).catch(
-  //         err => {
-  //           switch (err.response?.data?.code) {
-  //             case 'InvalidInput':
-  //               ErrorNotify({
-  //                 title: 'Échec du calcul du nouvel itinéraire',
-  //                 message:
-  //                   'La distance entre les deux points est trop grande pour ce mode de transport',
-  //                 autoClose: undefined,
-  //               });
-  //               break;
-  //             case 'NoRoute':
-  //               ErrorNotify({
-  //                 title: 'Échec du calcul du nouvel itinéraire',
-  //                 message: "Aucune route n'a été trouvée entre les deux points",
-  //                 autoClose: undefined,
-  //               });
-  //               break;
-
-  //             default:
-  //               ErrorNotify({
-  //                 title: 'Échec du calcul du nouvel itinéraire',
-  //                 message:
-  //                   "Une erreur est survenue lors du calcul de l'itinéraire entre les deux points de passage. Veuillez réessayer plus tard.",
-  //                 autoClose: undefined,
-  //               });
-  //               break;
-  //           }
-  //           console.error(err);
-  //         },
-  //       );
-
-  //     const addTravelDto: AddTravelDto = {
-  //       transportMode: travelBeforeResponse.transportMode,
-  //       distance: Number(travelBeforeResponse.distance.toFixed(0)),
-  //       duration: Number(travelBeforeResponse.duration.toFixed(0)),
-  //       originStepId: stepBefore.stepId as number,
-  //       destinationStepId: currentStep?.stepId as number,
-  //       travelRoad: travelBeforeResponse.travelRoad,
-  //     };
-  //     await addTravelBetweenStepsMutation.mutateAsync(addTravelDto);
-
-  //     console.log(
-  //       '🚀 ~ handleMoveMarker ~ travelBeforeResponse:',
-  //       travelBeforeResponse,
-  //     );
-  //   }
-
-  //   if (stepAfter && currentStep) {
-  //     const startEndPosition: RoadPositionDto[] = [
-  //       {
-  //         start: [
-  //           updateStateLocationDto.longitude as number,
-  //           updateStateLocationDto.latitude as number,
-  //         ],
-  //         end: [stepAfter?.longitude as number, stepAfter?.latitude as number],
-  //       },
-  //     ];
-
-  //     const travelAfterResponse: CalculateTravelRoadDto = await calculateRoad(
-  //       DirectionMode.DRIVING,
-  //       startEndPosition,
-  //     ).catch(err => {
-  //       switch (err.response?.data?.code) {
-  //         case 'InvalidInput':
-  //           ErrorNotify({
-  //             title: 'Échec du calcul du nouvel itinéraire',
-  //             message:
-  //               'La distance entre les deux points est trop grande pour ce mode de transport',
-  //             autoClose: undefined,
-  //           });
-  //           break;
-  //         case 'NoRoute':
-  //           ErrorNotify({
-  //             title: 'Échec du calcul du nouvel itinéraire',
-  //             message: "Aucune route n'a été trouvée entre les deux points",
-  //             autoClose: undefined,
-  //           });
-  //           break;
-
-  //         default:
-  //           ErrorNotify({
-  //             title: 'Échec du calcul du nouvel itinéraire',
-  //             message:
-  //               "Une erreur est survenue lors du calcul de l'itinéraire entre les deux points de passage. Veuillez réessayer plus tard.",
-  //             autoClose: undefined,
-  //           });
-  //           break;
-  //       }
-  //       console.error(err);
-  //     });
-
-  //     const addTravelDto: AddTravelDto = {
-  //       transportMode: travelAfterResponse.transportMode,
-  //       distance: Number(travelAfterResponse.distance.toFixed(0)),
-  //       duration: Number(travelAfterResponse.duration.toFixed(0)),
-  //       originStepId: currentStep.stepId as number,
-  //       destinationStepId: stepAfter?.stepId as number,
-  //       travelRoad: travelAfterResponse.travelRoad,
-  //     };
-  //     await addTravelBetweenStepsMutation.mutateAsync(addTravelDto);
-
-  //     console.log(
-  //       '🚀 ~ handleMoveMarker ~ travelAfterResponse:',
-  //       travelAfterResponse,
-  //     );
-  //   }
-
-  //   queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
-  // };
+  const handleMoveMarker = async (evt: MarkerDragEvent, stepId: number) => {
+    const updateStateLocationDto: UpdateStepLocationDto = {
+      latitude: evt.lngLat.lat,
+      longitude: evt.lngLat.lng,
+    };
+
+    const currentStep: StepDto | undefined = steps.find(
+      (s: StepDto) => s.stepId === stepId,
+    );
+
+    await updateStepLocationMutation.mutateAsync([
+      stepId,
+      updateStateLocationDto,
+    ]);
+
+    const stepBefore: StepDto | undefined = steps.find(
+      (s: StepDto) => s.order === (currentStep?.order as number) - 1,
+    );
+    const stepAfter: StepDto | undefined = steps.find(
+      (s: StepDto) => s.order === (currentStep?.order as number) + 1,
+    );
+
+    if (stepBefore && currentStep) {
+      const startEndPosition: RoadPositionDto[] = [
+        {
+          start: [
+            stepBefore.longitude as number,
+            stepBefore.latitude as number,
+          ],
+          end: [
+            updateStateLocationDto?.longitude as number,
+            updateStateLocationDto?.latitude as number,
+          ],
+        },
+      ];
+
+      let addTravelDto: AddTravelDto;
+      if (currentStep.transportMode === DirectionMode.PLANE) {
+        const coords: Position[] = startEndPosition.flatMap(
+          ({ start, end }) => [start, end],
+        );
+
+        addTravelDto = {
+          transportMode: DirectionMode.PLANE,
+          distance: -1,
+          duration: -1,
+          originStepId: stepBefore.stepId as number,
+          destinationStepId: currentStep?.stepId as number,
+          travelRoad: JSON.stringify(coords),
+        };
+      } else {
+        const travelBeforeResponse: CalculateTravelRoadDto | undefined =
+          await MapBoxController.calculateRoad(
+            currentStep.transportMode as DirectionMode,
+            startEndPosition,
+          );
+
+        if (!travelBeforeResponse) return;
+        addTravelDto = {
+          transportMode: travelBeforeResponse.transportMode,
+          distance: Number(travelBeforeResponse.distance.toFixed(0)),
+          duration: Number(travelBeforeResponse.duration.toFixed(0)),
+          originStepId: stepBefore.stepId as number,
+          destinationStepId: currentStep?.stepId as number,
+          travelRoad: travelBeforeResponse.travelRoad,
+        };
+      }
+
+      console.log('🚀 ~ handleMoveMarker ~ addTravelDto:', addTravelDto);
+      await addTravelBetweenStepsMutation.mutateAsync(addTravelDto);
+    }
+
+    if (stepAfter && currentStep) {
+      const startEndPosition: RoadPositionDto[] = [
+        {
+          start: [
+            updateStateLocationDto.longitude as number,
+            updateStateLocationDto.latitude as number,
+          ],
+          end: [stepAfter.longitude as number, stepAfter.latitude as number],
+        },
+      ];
+
+      let addTravelDto: AddTravelDto;
+      if (stepAfter.transportMode === DirectionMode.PLANE) {
+        const coords: Position[] = startEndPosition.flatMap(
+          ({ start, end }) => [start, end],
+        );
+
+        addTravelDto = {
+          transportMode: DirectionMode.PLANE,
+          distance: -1,
+          duration: -1,
+          originStepId: currentStep.stepId as number,
+          destinationStepId: stepAfter.stepId as number,
+          travelRoad: JSON.stringify(coords),
+        };
+      } else {
+        const travelAfterResponse: CalculateTravelRoadDto | undefined =
+          await MapBoxController.calculateRoad(
+            currentStep.transportMode as DirectionMode,
+            startEndPosition,
+          );
+
+        if (!travelAfterResponse) return;
+        addTravelDto = {
+          transportMode: travelAfterResponse.transportMode,
+          distance: Number(travelAfterResponse.distance.toFixed(0)),
+          duration: Number(travelAfterResponse.duration.toFixed(0)),
+          originStepId: currentStep.stepId as number,
+          destinationStepId: stepAfter.stepId as number,
+          travelRoad: travelAfterResponse.travelRoad,
+        };
+      }
+
+      console.log('🚀 ~ handleMoveMarker ~ addTravelDto:', addTravelDto);
+      await addTravelBetweenStepsMutation.mutateAsync(addTravelDto);
+    }
+
+    // queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
+  };
 
   const handleAddStepToEnd = () => {
     SetAddStepMode(AddStepMode.END);
diff --git a/src/components/map/stepCard/Menu/StepCardMenu.tsx b/src/components/map/stepCard/Menu/StepCardMenu.tsx
index 17c488d..a228442 100644
--- a/src/components/map/stepCard/Menu/StepCardMenu.tsx
+++ b/src/components/map/stepCard/Menu/StepCardMenu.tsx
@@ -61,6 +61,8 @@ export const StepCardMenu = (props: StepCardMenuProps) => {
     SelectOtherStep(props.stepId);
     SetAddModalIsOpened(true);
   };
+
+  //! BUG Le point ce crée bien après l'étape comme voulu. Le travel before est calculer correctement. Ce pendant le Travel after ne fonctionne pas.
   const handleCreateStepAfter = () => {
     SetAddStepMode(AddStepMode.AFTER);
     SelectOtherStep(props.stepId);
@@ -110,7 +112,8 @@ export const StepCardMenu = (props: StepCardMenuProps) => {
           </Menu.Item>
           <Menu.Item
             leftSection={<IconArrowBarToUp />}
-            onClick={handleCreateStepAfter}>
+            onClick={handleCreateStepAfter}
+            disabled>
             Ajouter Après
           </Menu.Item>
         </Menu.Dropdown>
diff --git a/src/components/map/stepList/StepList.tsx b/src/components/map/stepList/StepList.tsx
index 7188123..688c9d3 100644
--- a/src/components/map/stepList/StepList.tsx
+++ b/src/components/map/stepList/StepList.tsx
@@ -7,6 +7,7 @@ import {
 import { StepCard } from '../stepCard/StepCard';
 import './StepList.scss';
 
+//! FIX Quand des points sont move sur la carte, niveau API tout est bien enregistré, mais niveau FRONT un problème fait que des points qui n'on rien a voir finissent par être relier
 export const StepList = () => {
   //#region Hooks
 
diff --git a/src/pages/map/MapPage.tsx b/src/pages/map/MapPage.tsx
index 79f756b..553341e 100644
--- a/src/pages/map/MapPage.tsx
+++ b/src/pages/map/MapPage.tsx
@@ -10,14 +10,6 @@ interface updateStepLocationMutationProps {
 }
 
 const MapPage = () => {
-  const updateStepLocationMutation = useMutation({
-    mutationFn: async (args: updateStepLocationMutationProps) =>
-      await StepController.updateStepLocationAsyncPATCH(
-        args.stepId,
-        args.updateStateLocationDto,
-      ).catch(err => console.error(err)),
-  });
-
   // const addPoint = async (evt: any) => {
   //   console.log('hello', evt.lngLat.lat, evt.lngLat.lng);
   //   await StepController.addStepAsyncPOST(tripId, {
diff --git a/src/pages/tripDetail/TripDetailPage.tsx b/src/pages/tripDetail/TripDetailPage.tsx
index 4ee6574..e2a25f9 100644
--- a/src/pages/tripDetail/TripDetailPage.tsx
+++ b/src/pages/tripDetail/TripDetailPage.tsx
@@ -54,7 +54,7 @@ const TripDetailPage = () => {
     (state: TripDetailsStore) => state.otherStep,
   );
 
-  const { SetTrip, SetSelectedStep, UnselectCurrentStep } =
+  const { SetTrip, SetCurrentStep, UnSelectCurrentStep } =
     useTripDetailsStore();
 
   const queryClient = useQueryClient();
@@ -79,7 +79,7 @@ const TripDetailPage = () => {
     mutationFn: async (dto: AddStepDto) =>
       StepController.addStepAsyncPOST(tripId, dto),
     onSuccess: res => {
-      SetSelectedStep(res.data);
+      SetCurrentStep(res.data);
       queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
       handleCalculateNewTravel(undefined, res.data);
     },
@@ -89,7 +89,7 @@ const TripDetailPage = () => {
     mutationFn: async ([previousStepId, dto]: [number, AddStepDto]) =>
       StepController.addStepBeforAsyncPOST(tripId, previousStepId, dto),
     onSuccess: async res => {
-      SetSelectedStep(res.data);
+      SetCurrentStep(res.data);
       queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
       await handleCalculateNewTravel(undefined, res.data);
       await handleCalculateNewTravel(res.data, otherStep);
@@ -100,13 +100,9 @@ const TripDetailPage = () => {
     mutationFn: async ([nextStepId, dto]: [number, AddStepDto]) =>
       StepController.addStepAfterAsyncPOST(tripId, nextStepId, dto),
     onSuccess: res => {
-      SetSelectedStep(res.data);
+      SetCurrentStep(res.data);
       queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
       handleCalculateNewTravel(otherStep, res.data);
-      console.log(
-        '==================================================================================================',
-      );
-
       handleCalculateNewTravel(res.data, undefined);
     },
   });
@@ -115,7 +111,7 @@ const TripDetailPage = () => {
     mutationFn: async (addTravelDto: AddTravelDto) =>
       await TravelController.addTravelBetweenStepsPOST(addTravelDto),
     onSuccess: () => {
-      UnselectCurrentStep();
+      UnSelectCurrentStep();
       queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
     },
   });
diff --git a/src/store/useTripDetailsStore.ts b/src/store/useTripDetailsStore.ts
index 20c5794..2401d05 100644
--- a/src/store/useTripDetailsStore.ts
+++ b/src/store/useTripDetailsStore.ts
@@ -27,9 +27,9 @@ export type TripDetailsStore = {
   SetCurrentStepId: (stepId: number) => void;
 
   currentStep: StepDto | undefined;
-  SelectStep: (stepId: number) => void;
-  SetSelectedStep: (step: StepDto) => void;
-  UnselectCurrentStep: () => void;
+  SelectCurrentStep: (stepId: number) => void;
+  SetCurrentStep: (step: StepDto) => void;
+  UnSelectCurrentStep: () => void;
 
   otherStepId: number | undefined;
   SetOtherStepId: (stepId: number) => void;
@@ -50,7 +50,7 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
   addStepMode: AddStepMode.END,
   SetAddStepMode: (mode: AddStepMode) => set({ addStepMode: mode }),
 
-  tripId: 'A8EB1FCE-B9DE-4201-B1FC-08DC4FD48062',
+  tripId: '4C4EB54F-BEDE-468A-BB0A-08DC50B68FE1',
   SetTripId: (tripId: string) => set({ tripId }),
 
   trip: {} as TripDto,
@@ -68,12 +68,12 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
   SetCurrentStepId: (stepId: number) => set({ currentStepId: stepId }),
 
   currentStep: undefined,
-  SetSelectedStep: (step: StepDto) =>
+  SetCurrentStep: (step: StepDto) =>
     set({
       currentStepId: step.stepId,
       currentStep: step,
     }),
-  SelectStep: (stepId: number) =>
+  SelectCurrentStep: (stepId: number) =>
     set((state: TripDetailsStore) => {
       const currentStep = state.steps.find(step => step.stepId === stepId);
       return {
@@ -81,7 +81,7 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
         currentStep: currentStep,
       };
     }),
-  UnselectCurrentStep: () =>
+  UnSelectCurrentStep: () =>
     set({
       currentStep: undefined,
       currentStepId: undefined,

From 2697f9818479ba5c41e1ad78294ad1460e8babf9 Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Sat, 30 Mar 2024 19:16:28 +0100
Subject: [PATCH 23/34] Feat (tripDetail) : [WIP]  Add Detail Modal

---
 src/components/map/editStep/EditStepModal.tsx | 223 ++++++++++++++++++
 .../map/stepCard/Menu/StepCardMenu.tsx        |  18 +-
 src/pages/tripDetail/TripDetailPage.tsx       |   2 +
 src/store/useTripDetailsStore.ts              |   6 +
 4 files changed, 245 insertions(+), 4 deletions(-)
 create mode 100644 src/components/map/editStep/EditStepModal.tsx

diff --git a/src/components/map/editStep/EditStepModal.tsx b/src/components/map/editStep/EditStepModal.tsx
new file mode 100644
index 0000000..4767134
--- /dev/null
+++ b/src/components/map/editStep/EditStepModal.tsx
@@ -0,0 +1,223 @@
+import {
+  StepDto,
+  UpdateStepDateDto,
+  UpdateStepDescriptionDto,
+  UpdateStepLocationDto,
+  UpdateStepNameDto,
+} from '@FullStackMap/from-a2b';
+import { Fieldset, Modal, TextInput } from '@mantine/core';
+import { useForm } from '@mantine/form';
+import { IconX } from '@tabler/icons-react';
+import { zodResolver } from 'mantine-form-zod-resolver';
+import { KeyboardEvent, useEffect } from 'react';
+import { z } from 'zod';
+
+import {
+  TripDetailsStore,
+  useTripDetailsStore,
+} from '../../../store/useTripDetailsStore';
+
+import { useMutation, useQueryClient } from '@tanstack/react-query';
+import useNotify from '../../../hooks/useNotify';
+import { StepController } from '../../../services/BaseApi';
+
+export const EditStepModal = () => {
+  //#region Hooks
+  const queryClient = useQueryClient();
+  const { ErrorNotify } = useNotify();
+
+  const isEditModalOpened = useTripDetailsStore(
+    (state: TripDetailsStore) => state.isEditModalOpened,
+  );
+  const currentStep: StepDto | undefined = useTripDetailsStore(
+    (state: TripDetailsStore) => state.currentStep,
+  );
+
+  const { SetEditModalIsOpened, UnSelectCurrentStep } = useTripDetailsStore();
+  //#endregion
+
+  //#region Queries
+
+  //#endregion
+
+  //#region Mutations
+
+  const stepSaveNameMutation = useMutation({
+    mutationFn: (dto: UpdateStepNameDto) =>
+      StepController.updateStepNameAsyncPATCH(currentStep!.stepId!, dto),
+    onSuccess: () => {
+      //you want to do something after the mutation is successful???
+    },
+  });
+
+  const stepDescriptionMutation = useMutation({
+    mutationFn: (dto: UpdateStepDescriptionDto) =>
+      StepController.updateStepDescriptionAsyncPATCH(currentStep!.stepId!, dto),
+    onSuccess: () => {
+      //you want to do something after the mutation is successful???
+    },
+  });
+
+  const handleSaveStepAdresseMutation = useMutation({
+    mutationFn: (dto: UpdateStepLocationDto) =>
+      StepController.updateStepLocationAsyncPATCH(currentStep!.stepId!, dto),
+    onSuccess: () => {
+      //you want to do something after the mutation is successful???
+    },
+  });
+
+  const handleSaveStepDateMutation = useMutation({
+    mutationFn: (dto: UpdateStepDateDto) =>
+      StepController.updateStepDateAsyncPATCH(currentStep!.stepId!, dto),
+    onSuccess: () => {
+      //you want to do something after the mutation is successful???
+    },
+  });
+
+  //#endregion
+
+  //#region Forms
+  const stepNameSchema = z.object({
+    name: z
+      .string()
+      .min(3, "Le nom de l'étape doit contenir au moins 3 caractères")
+      .max(50, "Le nom de l'étape doit contenir au maximum 50 caractères"),
+  });
+
+  const stepNameFrom = useForm({
+    validateInputOnChange: true,
+    initialValues: {
+      name: currentStep?.name || '',
+    },
+    validate: zodResolver(stepNameSchema),
+  });
+  //#endregion
+
+  //#region Variables
+
+  //#endregion
+
+  //#region States
+
+  //#endregion
+
+  //#region Effects
+  useEffect(() => {
+    if (!currentStep) return;
+
+    stepNameFrom.setFieldValue('name', currentStep.name!);
+  }, [currentStep]);
+  //#endregion
+
+  //#region Handlers
+  //! Fix le invalid query n’invalide pas le cache
+  const handleCloseEditStepModal = () => {
+    queryClient.invalidateQueries({ queryKey: ['Trip', currentStep?.tripId] });
+    UnSelectCurrentStep();
+    SetEditModalIsOpened(false);
+  };
+
+  const handleSaveStepName = () => {
+    if (!stepNameFrom.isValid()) {
+      ErrorNotify({
+        title: 'Erreur',
+        message: "Le nom de l'étape est invalide",
+        autoClose: undefined,
+      });
+      return;
+    }
+
+    const updateName: UpdateStepNameDto = {
+      name: stepNameFrom.values.name,
+    };
+
+    stepSaveNameMutation.mutate(updateName);
+  };
+
+  // don't have the route for this yet
+  const handleSaveStepTransportMode = () => {
+    console.log('SaveName');
+  };
+
+  // don't have the route for this yet
+  const handleSaveStepDistance = () => {
+    console.log('SaveName');
+  };
+
+  // don't have the route for this yet
+  const handleSaveStepTime = () => {
+    console.log('SaveName');
+  };
+
+  const handleSaveStepStartDate = () => {
+    console.log('SaveName');
+  };
+  const handleSaveStepEndDate = () => {
+    console.log('SaveName');
+  };
+
+  //#endregion
+  return (
+    <Modal.Root
+      opened={isEditModalOpened}
+      onClose={handleCloseEditStepModal}
+      centered
+      closeOnClickOutside={false}>
+      <Modal.Overlay backgroundOpacity={0.55} blur={3} />
+      <Modal.Content>
+        <Modal.Header>
+          <Modal.Title>Modification d'une étape</Modal.Title>
+          <Modal.CloseButton icon={<IconX />} />
+        </Modal.Header>
+        <Modal.Body>
+          <Fieldset legend="Détail de l'étape" radius="lg">
+            <TextInput
+              label="Nom de l'étape"
+              placeholder="Nom de votre étape"
+              {...stepNameFrom.getInputProps('name')}
+              onBlur={handleSaveStepName}
+              onKeyDown={(evn: KeyboardEvent<HTMLInputElement>) =>
+                evn.key === 'Enter' && handleSaveStepName
+              }
+            />
+            <TextInput label="Description" placeholder="Email" mt="md" />
+          </Fieldset>
+          <Fieldset legend="Localisation" radius="lg">
+            <TextInput label="Adresse" placeholder="Email" mt="md" />
+          </Fieldset>
+          <Fieldset legend="Mode de transport" radius="lg">
+            <TextInput
+              label="Mode de transport"
+              placeholder="Mode de transport"
+              mt="md"
+            />
+            <TextInput
+              label="Distance"
+              placeholder="Distance"
+              mt="md"
+              disabled={true}
+            />
+            <TextInput
+              label="Temps"
+              placeholder="Temps"
+              mt="md"
+              disabled={true}
+            />
+          </Fieldset>
+          <Fieldset legend="Dates de l'étape" radius="lg">
+            <TextInput
+              label="Date d'arrivée"
+              placeholder="Date d'arrivée"
+              mt="md"
+            />
+            <TextInput
+              label="Date de départ"
+              placeholder="Date de départ"
+              mt="md"
+            />
+          </Fieldset>
+        </Modal.Body>
+      </Modal.Content>
+    </Modal.Root>
+  );
+};
diff --git a/src/components/map/stepCard/Menu/StepCardMenu.tsx b/src/components/map/stepCard/Menu/StepCardMenu.tsx
index a228442..09d4610 100644
--- a/src/components/map/stepCard/Menu/StepCardMenu.tsx
+++ b/src/components/map/stepCard/Menu/StepCardMenu.tsx
@@ -23,8 +23,13 @@ interface StepCardMenuProps {
 export const StepCardMenu = (props: StepCardMenuProps) => {
   //#region Hooks
 
-  const { SetAddStepMode, SetAddModalIsOpened, SelectOtherStep } =
-    useTripDetailsStore();
+  const {
+    SetAddStepMode,
+    SetAddModalIsOpened,
+    SelectOtherStep,
+    SelectCurrentStep,
+    SetEditModalIsOpened,
+  } = useTripDetailsStore();
 
   const [deleteStepModalOpened, deleteStepModalController] =
     useDisclosure(false);
@@ -62,13 +67,18 @@ export const StepCardMenu = (props: StepCardMenuProps) => {
     SetAddModalIsOpened(true);
   };
 
-  //! BUG Le point ce crée bien après l'étape comme voulu. Le travel before est calculer correctement. Ce pendant le Travel after ne fonctionne pas.
+  //! FIX Le point ce crée bien après l'étape comme voulu. Le travel before est calculer correctement. Ce pendant le Travel after ne fonctionne pas. *Possible problème de mutation avec un sync async*
   const handleCreateStepAfter = () => {
     SetAddStepMode(AddStepMode.AFTER);
     SelectOtherStep(props.stepId);
     SetAddModalIsOpened(true);
   };
 
+  const handleEditStepModal = () => {
+    SelectCurrentStep(props.stepId);
+    SetEditModalIsOpened(true);
+  };
+
   //#endregion
 
   return (
@@ -81,7 +91,7 @@ export const StepCardMenu = (props: StepCardMenuProps) => {
         </Menu.Target>
 
         <Menu.Dropdown>
-          <Menu.Item leftSection={<IconEdit />} disabled>
+          <Menu.Item leftSection={<IconEdit />} onClick={handleEditStepModal}>
             Modifier l'étape
           </Menu.Item>
           <Menu.Item
diff --git a/src/pages/tripDetail/TripDetailPage.tsx b/src/pages/tripDetail/TripDetailPage.tsx
index e2a25f9..ca2b98e 100644
--- a/src/pages/tripDetail/TripDetailPage.tsx
+++ b/src/pages/tripDetail/TripDetailPage.tsx
@@ -19,6 +19,7 @@ import { MapComponent } from '../../components/map/MapComponent';
 import { useMutation } from '@tanstack/react-query';
 
 import { CreateStepModal } from '../../components/map/addStep/CreateStepModal.tsx';
+import { EditStepModal } from '../../components/map/editStep/EditStepModal.tsx';
 import { StepList } from '../../components/map/stepList/StepList.tsx';
 import useNotify from '../../hooks/useNotify.tsx';
 import { MapBoxController } from '../../services/api/MapboxController.ts';
@@ -255,6 +256,7 @@ const TripDetailPage = () => {
       <CreateStepModal
         FormSend={(addStepDto: AddStepDto) => handleAddStep(addStepDto)}
       />
+      <EditStepModal />
     </>
   );
 };
diff --git a/src/store/useTripDetailsStore.ts b/src/store/useTripDetailsStore.ts
index 2401d05..6ab31a8 100644
--- a/src/store/useTripDetailsStore.ts
+++ b/src/store/useTripDetailsStore.ts
@@ -14,6 +14,9 @@ export type TripDetailsStore = {
   addStepMode: AddStepMode;
   SetAddStepMode: (mode: AddStepMode) => void;
 
+  isEditModalOpened: boolean;
+  SetEditModalIsOpened: (status: boolean) => void;
+
   tripId: string;
   SetTripId: (tripId: string) => void;
 
@@ -50,6 +53,9 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
   addStepMode: AddStepMode.END,
   SetAddStepMode: (mode: AddStepMode) => set({ addStepMode: mode }),
 
+  isEditModalOpened: false,
+  SetEditModalIsOpened: (status: boolean) => set({ isEditModalOpened: status }),
+
   tripId: '4C4EB54F-BEDE-468A-BB0A-08DC50B68FE1',
   SetTripId: (tripId: string) => set({ tripId }),
 

From 8853b829456372b48b25ffc7f7a96920be2ea966 Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Sun, 31 Mar 2024 00:58:33 +0100
Subject: [PATCH 24/34] Feat (EditStep) : Implement Detail/Update Modal

---
 .../map/addStep/CreateStepModal.tsx           |  25 +-
 src/components/map/editStep/EditStepModal.tsx | 396 +++++++++++++++---
 .../TransportModeSelector.tsx                 |  19 +-
 src/hooks/useTypeConverter.ts                 |  36 ++
 src/pages/tripDetail/TripDetailPage.tsx       |   3 +-
 5 files changed, 400 insertions(+), 79 deletions(-)
 create mode 100644 src/hooks/useTypeConverter.ts

diff --git a/src/components/map/addStep/CreateStepModal.tsx b/src/components/map/addStep/CreateStepModal.tsx
index fd0af6c..3ed417b 100644
--- a/src/components/map/addStep/CreateStepModal.tsx
+++ b/src/components/map/addStep/CreateStepModal.tsx
@@ -13,8 +13,8 @@ import { IconX } from '@tabler/icons-react';
 import { zodResolver } from 'mantine-form-zod-resolver';
 import { useEffect, useState } from 'react';
 import { z } from 'zod';
+import useTypeConverter from '../../../hooks/useTypeConverter';
 import { MapBoxController } from '../../../services/api/MapboxController';
-import DirectionMode from '../../../services/api/Models/MapBoxDirections/DirectionMode';
 import { PlaceDto } from '../../../services/api/Models/PlaceLocation/PlaceLocationDto';
 import {
   AddStepMode,
@@ -40,6 +40,8 @@ export const CreateStepModal = (props: CreateStepModalProps) => {
     (state: TripDetailsStore) => state.isAddModalOpened,
   );
 
+  const { TransportModeToDirectionMode } = useTypeConverter();
+
   const [addressValue, setAddressValue] = useDebouncedState('', 200);
   //#endregion
 
@@ -124,23 +126,9 @@ export const CreateStepModal = (props: CreateStepModalProps) => {
   };
 
   const handleTransportModeSelected = (transportMode: string) => {
-    switch (transportMode) {
-      case TransportMode.Voiture:
-        transportMode = DirectionMode.DRIVING;
-        break;
-      case TransportMode.Vélo:
-        transportMode = DirectionMode.CYCLING;
-        break;
-      case TransportMode.Marche:
-        transportMode = DirectionMode.WALKING;
-        break;
-      case TransportMode.Avion:
-        transportMode = DirectionMode.PLANE;
-        break;
-      case TransportMode.Fusée:
-        transportMode = DirectionMode.PLANE;
-        break;
-    }
+    transportMode = TransportModeToDirectionMode(
+      transportMode as TransportMode,
+    );
     addStepForm.setFieldValue('transportMode', transportMode);
   };
 
@@ -191,6 +179,7 @@ export const CreateStepModal = (props: CreateStepModalProps) => {
               onChange={(event: string) => setAddressValue(event)}
             />
             <TransportModeSelector
+              withLabel
               selectedValue={(transportMode: string) =>
                 handleTransportModeSelected(transportMode)
               }
diff --git a/src/components/map/editStep/EditStepModal.tsx b/src/components/map/editStep/EditStepModal.tsx
index 4767134..ed9a22e 100644
--- a/src/components/map/editStep/EditStepModal.tsx
+++ b/src/components/map/editStep/EditStepModal.tsx
@@ -1,15 +1,17 @@
 import {
+  AddTravelDto,
   StepDto,
-  UpdateStepDateDto,
+  TravelDtoList,
   UpdateStepDescriptionDto,
   UpdateStepLocationDto,
   UpdateStepNameDto,
+  UpdateStepTransportModeDto,
 } from '@FullStackMap/from-a2b';
-import { Fieldset, Modal, TextInput } from '@mantine/core';
+import { Autocomplete, Fieldset, Modal, TextInput } from '@mantine/core';
 import { useForm } from '@mantine/form';
 import { IconX } from '@tabler/icons-react';
 import { zodResolver } from 'mantine-form-zod-resolver';
-import { KeyboardEvent, useEffect } from 'react';
+import { useEffect, useState } from 'react';
 import { z } from 'zod';
 
 import {
@@ -17,23 +19,48 @@ import {
   useTripDetailsStore,
 } from '../../../store/useTripDetailsStore';
 
+import { useDebouncedState } from '@mantine/hooks';
 import { useMutation, useQueryClient } from '@tanstack/react-query';
+import { Position } from 'geojson';
+import useDistance from '../../../hooks/useDistance';
 import useNotify from '../../../hooks/useNotify';
-import { StepController } from '../../../services/BaseApi';
+import useTime from '../../../hooks/useTime';
+import useTypeConverter from '../../../hooks/useTypeConverter';
+import { StepController, TravelController } from '../../../services/BaseApi';
+import { MapBoxController } from '../../../services/api/MapboxController';
+import CalculateTravelRoadDto from '../../../services/api/Models/MapBoxDirections/CalculateTravelRoadDto';
+import DirectionMode from '../../../services/api/Models/MapBoxDirections/DirectionMode';
+import RoadPositionDto from '../../../services/api/Models/MapBoxDirections/RoadPositionDto';
+import { PlaceDto } from '../../../services/api/Models/PlaceLocation/PlaceLocationDto';
+import {
+  TransportMode,
+  TransportModeSelector,
+} from '../transportModeSelector/TransportModeSelector';
 
 export const EditStepModal = () => {
   //#region Hooks
   const queryClient = useQueryClient();
   const { ErrorNotify } = useNotify();
 
+  const travels: TravelDtoList[] = useTripDetailsStore(
+    (state: TripDetailsStore) => state.travels,
+  );
   const isEditModalOpened = useTripDetailsStore(
     (state: TripDetailsStore) => state.isEditModalOpened,
   );
   const currentStep: StepDto | undefined = useTripDetailsStore(
     (state: TripDetailsStore) => state.currentStep,
   );
+  const steps: StepDto[] = useTripDetailsStore(
+    (state: TripDetailsStore) => state.steps,
+  );
 
   const { SetEditModalIsOpened, UnSelectCurrentStep } = useTripDetailsStore();
+
+  const [addressValue, setAddressValue] = useDebouncedState('', 200);
+
+  const { TransportModeToDirectionMode } = useTypeConverter();
+
   //#endregion
 
   //#region Queries
@@ -45,35 +72,34 @@ export const EditStepModal = () => {
   const stepSaveNameMutation = useMutation({
     mutationFn: (dto: UpdateStepNameDto) =>
       StepController.updateStepNameAsyncPATCH(currentStep!.stepId!, dto),
-    onSuccess: () => {
-      //you want to do something after the mutation is successful???
-    },
   });
 
   const stepDescriptionMutation = useMutation({
     mutationFn: (dto: UpdateStepDescriptionDto) =>
       StepController.updateStepDescriptionAsyncPATCH(currentStep!.stepId!, dto),
-    onSuccess: () => {
-      //you want to do something after the mutation is successful???
-    },
   });
 
-  const handleSaveStepAdresseMutation = useMutation({
+  const saveAdresseMutation = useMutation({
     mutationFn: (dto: UpdateStepLocationDto) =>
       StepController.updateStepLocationAsyncPATCH(currentStep!.stepId!, dto),
-    onSuccess: () => {
-      //you want to do something after the mutation is successful???
-    },
   });
 
-  const handleSaveStepDateMutation = useMutation({
-    mutationFn: (dto: UpdateStepDateDto) =>
-      StepController.updateStepDateAsyncPATCH(currentStep!.stepId!, dto),
-    onSuccess: () => {
-      //you want to do something after the mutation is successful???
-    },
+  const saveTransportModeMutation = useMutation({
+    mutationFn: (dto: UpdateStepTransportModeDto) =>
+      StepController.updateStepTransportModeAsyncPATCH(
+        currentStep!.stepId!,
+        dto,
+      ),
+  });
+
+  const addTravelBetweenStepsMutation = useMutation({
+    mutationFn: async (addTravelDto: AddTravelDto) =>
+      await TravelController.addTravelBetweenStepsPOST(addTravelDto),
   });
 
+  const { MetreToDistance } = useDistance();
+  const { SecondeToTime } = useTime();
+
   //#endregion
 
   //#region Forms
@@ -91,6 +117,34 @@ export const EditStepModal = () => {
     },
     validate: zodResolver(stepNameSchema),
   });
+
+  const stepDescriptionSchema = z.object({
+    description: z
+      .string()
+      .max(500, "Le nom de l'étape doit contenir au maximum 500 caractères"),
+  });
+
+  const stepDescriptionFrom = useForm({
+    validateInputOnChange: true,
+    initialValues: {
+      description: currentStep?.description || '',
+    },
+    validate: zodResolver(stepDescriptionSchema),
+  });
+
+  const stepAddressSchema = z.object({
+    latitude: z.number().min(-90).max(90),
+    longitude: z.number().min(-180).max(180),
+  });
+
+  const stepAddressFrom = useForm({
+    validateInputOnChange: true,
+    initialValues: {
+      latitude: currentStep?.latitude || undefined,
+      longitude: currentStep?.longitude || undefined,
+    },
+    validate: zodResolver(stepAddressSchema),
+  });
   //#endregion
 
   //#region Variables
@@ -99,6 +153,8 @@ export const EditStepModal = () => {
 
   //#region States
 
+  const [places, setPlaces] = useState<PlaceDto[]>([]);
+
   //#endregion
 
   //#region Effects
@@ -106,7 +162,46 @@ export const EditStepModal = () => {
     if (!currentStep) return;
 
     stepNameFrom.setFieldValue('name', currentStep.name!);
+    stepDescriptionFrom.setFieldValue('description', currentStep.description!);
+
+    (async () => {
+      const places: PlaceDto[] = await MapBoxController.getPlaces(addressValue);
+      if (places.length === 0) return;
+      setPlaces(places);
+
+      const currentPlace: PlaceDto | undefined = places.find(
+        (place: PlaceDto) => place.place === addressValue,
+      );
+      if (currentPlace) {
+        stepAddressFrom.setFieldValue('latitude', currentPlace.coordinate[1]);
+        stepAddressFrom.setFieldValue('longitude', currentPlace.coordinate[0]);
+      } else {
+        stepAddressFrom.setFieldValue('latitude', currentStep.latitude!);
+        stepAddressFrom.setFieldValue('longitude', currentStep.longitude!);
+      }
+    })();
   }, [currentStep]);
+
+  useEffect(() => {
+    (async () => {
+      const places: PlaceDto[] = await MapBoxController.getPlaces(addressValue);
+
+      if (places.length === 0) return;
+      setPlaces(places);
+
+      const currentPlace: PlaceDto | undefined = places.find(
+        (place: PlaceDto) => place.place === addressValue,
+      );
+      if (currentPlace) {
+        stepAddressFrom.setFieldValue('latitude', currentPlace.coordinate[1]);
+        stepAddressFrom.setFieldValue('longitude', currentPlace.coordinate[0]);
+      } else {
+        stepAddressFrom.setFieldValue('latitude', undefined);
+        stepAddressFrom.setFieldValue('longitude', undefined);
+      }
+    })();
+  }, [addressValue]);
+
   //#endregion
 
   //#region Handlers
@@ -133,27 +228,200 @@ export const EditStepModal = () => {
 
     stepSaveNameMutation.mutate(updateName);
   };
+  const handleSaveStepDescription = () => {
+    if (!stepDescriptionFrom.isValid()) {
+      ErrorNotify({
+        title: 'Erreur',
+        message: "La description de l'étape est invalide",
+        autoClose: undefined,
+      });
+      return;
+    }
 
-  // don't have the route for this yet
-  const handleSaveStepTransportMode = () => {
-    console.log('SaveName');
-  };
+    const updateDto: UpdateStepDescriptionDto = {
+      description: stepDescriptionFrom.values.description,
+    };
 
-  // don't have the route for this yet
-  const handleSaveStepDistance = () => {
-    console.log('SaveName');
+    stepDescriptionMutation.mutate(updateDto);
   };
 
-  // don't have the route for this yet
-  const handleSaveStepTime = () => {
-    console.log('SaveName');
-  };
+  const handleSaveAddress = async () => {
+    if (!stepAddressFrom.isValid()) {
+      ErrorNotify({
+        title: 'Erreur',
+        message: "L'adresse de l'étape est invalide",
+        autoClose: undefined,
+      });
+      return;
+    }
+
+    const updateDto: UpdateStepLocationDto = {
+      latitude: stepAddressFrom.values.latitude,
+      longitude: stepAddressFrom.values.longitude,
+    };
+
+    await saveAdresseMutation.mutateAsync(updateDto);
+
+    const stepBefore: StepDto | undefined = steps.find(
+      (step: StepDto) => step.stepId === currentStep!.stepId! - 1,
+    );
+    const stepAfter: StepDto | undefined = steps.find(
+      (step: StepDto) => step.stepId === currentStep!.stepId! + 1,
+    );
+
+    if (stepBefore && currentStep) {
+      const startEndPosition: RoadPositionDto[] = [
+        {
+          start: [
+            stepBefore.longitude as number,
+            stepBefore.latitude as number,
+          ],
+          end: [updateDto.longitude as number, updateDto.latitude as number],
+        },
+      ];
 
-  const handleSaveStepStartDate = () => {
-    console.log('SaveName');
+      let addTravelDto: AddTravelDto;
+      if (currentStep.transportMode === DirectionMode.PLANE) {
+        const coords: Position[] = startEndPosition.flatMap(
+          ({ start, end }) => [start, end],
+        );
+
+        addTravelDto = {
+          transportMode: DirectionMode.PLANE,
+          distance: -1,
+          duration: -1,
+          originStepId: stepBefore.stepId as number,
+          destinationStepId: currentStep.stepId as number,
+          travelRoad: JSON.stringify(coords),
+        };
+      } else {
+        const travelBeforeResponse: CalculateTravelRoadDto | undefined =
+          await MapBoxController.calculateRoad(
+            currentStep.transportMode as DirectionMode,
+            startEndPosition,
+          );
+
+        if (!travelBeforeResponse) return;
+        addTravelDto = {
+          transportMode: travelBeforeResponse.transportMode,
+          distance: Number(travelBeforeResponse.distance.toFixed(0)),
+          duration: Number(travelBeforeResponse.duration.toFixed(0)),
+          originStepId: stepBefore.stepId as number,
+          destinationStepId: currentStep.stepId as number,
+          travelRoad: travelBeforeResponse.travelRoad,
+        };
+      }
+
+      addTravelBetweenStepsMutation.mutate(addTravelDto);
+    }
+
+    if (stepAfter && currentStep) {
+      const startEndPosition: RoadPositionDto[] = [
+        {
+          start: [updateDto.longitude as number, updateDto.latitude as number],
+          end: [stepAfter.longitude as number, stepAfter.latitude as number],
+        },
+      ];
+
+      let addTravelDto: AddTravelDto;
+      if (stepAfter.transportMode === DirectionMode.PLANE) {
+        const coords: Position[] = startEndPosition.flatMap(
+          ({ start, end }) => [start, end],
+        );
+
+        addTravelDto = {
+          transportMode: DirectionMode.PLANE,
+          distance: -1,
+          duration: -1,
+          originStepId: currentStep.stepId as number,
+          destinationStepId: stepAfter.stepId as number,
+          travelRoad: JSON.stringify(coords),
+        };
+      } else {
+        const travelAfterResponse: CalculateTravelRoadDto | undefined =
+          await MapBoxController.calculateRoad(
+            currentStep.transportMode as DirectionMode,
+            startEndPosition,
+          );
+
+        if (!travelAfterResponse) return;
+        addTravelDto = {
+          transportMode: travelAfterResponse.transportMode,
+          distance: Number(travelAfterResponse.distance.toFixed(0)),
+          duration: Number(travelAfterResponse.duration.toFixed(0)),
+          originStepId: currentStep.stepId as number,
+          destinationStepId: stepAfter.stepId as number,
+          travelRoad: travelAfterResponse.travelRoad,
+        };
+      }
+
+      addTravelBetweenStepsMutation.mutate(addTravelDto);
+    }
   };
-  const handleSaveStepEndDate = () => {
-    console.log('SaveName');
+
+  const handleSaveStepTransportMode = async (transportMode: string) => {
+    transportMode = TransportModeToDirectionMode(
+      transportMode as TransportMode,
+    );
+
+    const updateDto: UpdateStepTransportModeDto = {
+      transportMode: transportMode as DirectionMode,
+    };
+
+    await saveTransportModeMutation.mutateAsync(updateDto);
+
+    const stepBefore: StepDto | undefined = steps.find(
+      (step: StepDto) => step.stepId === currentStep!.stepId! - 1,
+    );
+
+    if (stepBefore && currentStep) {
+      const startEndPosition: RoadPositionDto[] = [
+        {
+          start: [
+            stepBefore.longitude as number,
+            stepBefore.latitude as number,
+          ],
+          end: [
+            currentStep.longitude as number,
+            currentStep.latitude as number,
+          ],
+        },
+      ];
+
+      let addTravelDto: AddTravelDto;
+      if (currentStep.transportMode === DirectionMode.PLANE) {
+        const coords: Position[] = startEndPosition.flatMap(
+          ({ start, end }) => [start, end],
+        );
+
+        addTravelDto = {
+          transportMode: DirectionMode.PLANE,
+          distance: -1,
+          duration: -1,
+          originStepId: stepBefore.stepId as number,
+          destinationStepId: currentStep.stepId as number,
+          travelRoad: JSON.stringify(coords),
+        };
+      } else {
+        const travelBeforeResponse: CalculateTravelRoadDto | undefined =
+          await MapBoxController.calculateRoad(
+            currentStep.transportMode as DirectionMode,
+            startEndPosition,
+          );
+
+        if (!travelBeforeResponse) return;
+        addTravelDto = {
+          transportMode: travelBeforeResponse.transportMode,
+          distance: Number(travelBeforeResponse.distance.toFixed(0)),
+          duration: Number(travelBeforeResponse.duration.toFixed(0)),
+          originStepId: stepBefore.stepId as number,
+          destinationStepId: currentStep.stepId as number,
+          travelRoad: travelBeforeResponse.travelRoad,
+        };
+      }
+
+      addTravelBetweenStepsMutation.mutate(addTravelDto);
+    }
   };
 
   //#endregion
@@ -162,7 +430,7 @@ export const EditStepModal = () => {
       opened={isEditModalOpened}
       onClose={handleCloseEditStepModal}
       centered
-      closeOnClickOutside={false}>
+      closeOnClickOutside={true}>
       <Modal.Overlay backgroundOpacity={0.55} blur={3} />
       <Modal.Content>
         <Modal.Header>
@@ -174,48 +442,62 @@ export const EditStepModal = () => {
             <TextInput
               label="Nom de l'étape"
               placeholder="Nom de votre étape"
+              withAsterisk
               {...stepNameFrom.getInputProps('name')}
               onBlur={handleSaveStepName}
-              onKeyDown={(evn: KeyboardEvent<HTMLInputElement>) =>
-                evn.key === 'Enter' && handleSaveStepName
-              }
             />
-            <TextInput label="Description" placeholder="Email" mt="md" />
+            <TextInput
+              label="Description"
+              placeholder="Description de l'étape"
+              {...stepDescriptionFrom.getInputProps('description')}
+              onBlur={handleSaveStepDescription}
+            />
           </Fieldset>
           <Fieldset legend="Localisation" radius="lg">
-            <TextInput label="Adresse" placeholder="Email" mt="md" />
+            <Autocomplete
+              label="Destination"
+              placeholder="Entrez une adresse"
+              withAsterisk
+              data={places.map(place => place.place)}
+              onChange={(event: string) => setAddressValue(event)}
+              onBlur={handleSaveAddress}
+            />
           </Fieldset>
           <Fieldset legend="Mode de transport" radius="lg">
-            <TextInput
-              label="Mode de transport"
-              placeholder="Mode de transport"
-              mt="md"
+            <TransportModeSelector
+              withLabel={false}
+              defaultValue={currentStep?.transportMode as DirectionMode}
+              selectedValue={handleSaveStepTransportMode}
             />
             <TextInput
               label="Distance"
               placeholder="Distance"
               mt="md"
+              value={MetreToDistance(
+                Number(
+                  (
+                    travels.find(
+                      (travel: TravelDtoList) =>
+                        travel.destinationStepId === currentStep?.stepId,
+                    )?.distance || 0
+                  ).toFixed(0),
+                ),
+              )}
               disabled={true}
             />
             <TextInput
               label="Temps"
               placeholder="Temps"
               mt="md"
+              value={SecondeToTime(
+                travels.find(
+                  (travel: TravelDtoList) =>
+                    travel.destinationStepId === currentStep?.stepId,
+                )?.duration ?? 0,
+              )}
               disabled={true}
             />
           </Fieldset>
-          <Fieldset legend="Dates de l'étape" radius="lg">
-            <TextInput
-              label="Date d'arrivée"
-              placeholder="Date d'arrivée"
-              mt="md"
-            />
-            <TextInput
-              label="Date de départ"
-              placeholder="Date de départ"
-              mt="md"
-            />
-          </Fieldset>
         </Modal.Body>
       </Modal.Content>
     </Modal.Root>
diff --git a/src/components/map/transportModeSelector/TransportModeSelector.tsx b/src/components/map/transportModeSelector/TransportModeSelector.tsx
index abf8c19..ffeb077 100644
--- a/src/components/map/transportModeSelector/TransportModeSelector.tsx
+++ b/src/components/map/transportModeSelector/TransportModeSelector.tsx
@@ -7,6 +7,8 @@ import {
   IconWalk,
 } from '@tabler/icons-react';
 import { useEffect, useState } from 'react';
+import useTypeConverter from '../../../hooks/useTypeConverter';
+import DirectionMode from '../../../services/api/Models/MapBoxDirections/DirectionMode';
 
 export enum TransportMode {
   Voiture = 'Voiture',
@@ -17,6 +19,8 @@ export enum TransportMode {
 }
 
 export type TransportModeSelectorProps = {
+  withLabel: boolean;
+  defaultValue?: DirectionMode | null;
   selectedValue: (value: string) => void;
 };
 
@@ -33,6 +37,7 @@ export const TransportModeSelector = (props: TransportModeSelectorProps) => {
   const combobox = useCombobox({
     onDropdownClose: () => combobox.resetSelectedOption(),
   });
+  const { DirectionModeToTransportMode } = useTypeConverter();
   //#endregion
 
   //#region Queries
@@ -44,15 +49,23 @@ export const TransportModeSelector = (props: TransportModeSelectorProps) => {
   //#endregion
 
   //#region States
-  const [value, setValue] = useState<string | null>(null);
+  const [isLoaded, setIsLoaded] = useState(false);
+
+  const [value, setValue] = useState<string | null>(
+    DirectionModeToTransportMode(props.defaultValue!) || null,
+  );
   //#endregion
 
   //#region Effects
 
   useEffect(() => {
     if (!value) return;
+    setIsLoaded(true);
 
-    props.selectedValue(value);
+    if (props.defaultValue) {
+      if (!isLoaded) return;
+      props.selectedValue(value);
+    } else props.selectedValue(value);
   }, [value]);
 
   //#endregion
@@ -86,7 +99,7 @@ export const TransportModeSelector = (props: TransportModeSelectorProps) => {
         }}>
         <Combobox.Target>
           <InputBase
-            label="Mode de Transport"
+            label={props.withLabel ? 'Mode de transport' : undefined}
             component="button"
             type="button"
             withAsterisk
diff --git a/src/hooks/useTypeConverter.ts b/src/hooks/useTypeConverter.ts
new file mode 100644
index 0000000..00c6b7d
--- /dev/null
+++ b/src/hooks/useTypeConverter.ts
@@ -0,0 +1,36 @@
+import { TransportMode } from '../components/map/transportModeSelector/TransportModeSelector';
+import DirectionMode from '../services/api/Models/MapBoxDirections/DirectionMode';
+
+const useTypeConverter = () => {
+  const TransportModeToDirectionMode = (mode: TransportMode) => {
+    switch (mode) {
+      case TransportMode.Voiture:
+        return DirectionMode.DRIVING;
+      case TransportMode.Marche:
+        return DirectionMode.WALKING;
+      case TransportMode.Vélo:
+        return DirectionMode.CYCLING;
+      case TransportMode.Avion:
+        return DirectionMode.PLANE;
+      case TransportMode.Fusée:
+        return DirectionMode.PLANE;
+    }
+  };
+
+  const DirectionModeToTransportMode = (mode: DirectionMode) => {
+    switch (mode) {
+      case DirectionMode.DRIVING:
+        return TransportMode.Voiture;
+      case DirectionMode.WALKING:
+        return TransportMode.Marche;
+      case DirectionMode.CYCLING:
+        return TransportMode.Vélo;
+      case DirectionMode.PLANE:
+        return TransportMode.Avion;
+    }
+  };
+
+  return { TransportModeToDirectionMode, DirectionModeToTransportMode };
+};
+
+export default useTypeConverter;
diff --git a/src/pages/tripDetail/TripDetailPage.tsx b/src/pages/tripDetail/TripDetailPage.tsx
index ca2b98e..e193ff1 100644
--- a/src/pages/tripDetail/TripDetailPage.tsx
+++ b/src/pages/tripDetail/TripDetailPage.tsx
@@ -254,7 +254,8 @@ const TripDetailPage = () => {
         </Stack>
       </Group>
       <CreateStepModal
-        FormSend={(addStepDto: AddStepDto) => handleAddStep(addStepDto)}
+        // FormSend={(addStepDto: AddStepDto) => handleAddStep(addStepDto)}
+        FormSend={handleAddStep}
       />
       <EditStepModal />
     </>

From 63cd6a86fff8a2fe30919b4d52a423f9e1f224d7 Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Sun, 31 Mar 2024 10:28:57 +0200
Subject: [PATCH 25/34] =?UTF-8?q?feat=20(int=C3=A9gration)=20:=20[WIP]=20i?=
 =?UTF-8?q?nt=C3=A9gration=20du=20dashboard?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../cardCustom/TravelCard/TravelCard.tsx      | 14 ++-
 src/components/feedback/FormFeedback.tsx      | 24 ++---
 src/components/map/MapComponent.tsx           |  4 -
 .../map/stepCard/Menu/StepCardMenu.tsx        | 15 ---
 src/pages/login/LoginPage.tsx                 |  4 +-
 src/pages/showTravels/history/HistoryPage.tsx | 14 +--
 .../myTrips/{MyTrips.tsx => TripsPage.tsx}    | 14 +--
 src/pages/tripDetail/TripDetailPage.tsx       |  4 -
 src/router/Router.tsx                         |  8 +-
 src/services/BaseApi.ts                       | 96 +++++--------------
 src/store/useAuthStore.ts                     |  3 +-
 src/store/useTripDetailsStore.ts              |  2 +-
 12 files changed, 73 insertions(+), 129 deletions(-)
 rename src/pages/showTravels/myTrips/{MyTrips.tsx => TripsPage.tsx} (89%)

diff --git a/src/components/cardCustom/TravelCard/TravelCard.tsx b/src/components/cardCustom/TravelCard/TravelCard.tsx
index 8aa06c8..548b05b 100644
--- a/src/components/cardCustom/TravelCard/TravelCard.tsx
+++ b/src/components/cardCustom/TravelCard/TravelCard.tsx
@@ -4,6 +4,9 @@ import {
   IconHourglassOff,
   IconPlayerPlay,
 } from '@tabler/icons-react';
+import { useQueryClient } from '@tanstack/react-query';
+import { useNavigate } from 'react-router-dom';
+import { useTripDetailsStore } from '../../../store/useTripDetailsStore';
 
 export type TravelCardProps = {
   img: string;
@@ -14,6 +17,10 @@ export type TravelCardProps = {
 };
 
 export const TravelCard = (props: TravelCardProps) => {
+  const queryClient = useQueryClient();
+  const navigate = useNavigate();
+  const { SetTrip, SetTripId } = useTripDetailsStore();
+
   const isInProgress = (startDate: string) => {
     const currentDate = new Date();
     const tripStartDate = new Date(startDate);
@@ -28,6 +35,11 @@ export const TravelCard = (props: TravelCardProps) => {
     }
   };
 
+  const handleViewTrip = () => {
+    SetTripId(props.id);
+    navigate(`/tripDetail`);
+  };
+
   return (
     <Card shadow="sm" padding="lg" radius="md" withBorder>
       <Card.Section>
@@ -40,7 +52,7 @@ export const TravelCard = (props: TravelCardProps) => {
       <Text size="sm" c="dimmed">
         {props.description}
       </Text>
-      <Button color="blue" fullWidth mt="md" radius="md">
+      <Button fullWidth mt="md" radius="md" onClick={handleViewTrip}>
         Voir Plus
       </Button>
     </Card>
diff --git a/src/components/feedback/FormFeedback.tsx b/src/components/feedback/FormFeedback.tsx
index ff2902e..29a8b2a 100644
--- a/src/components/feedback/FormFeedback.tsx
+++ b/src/components/feedback/FormFeedback.tsx
@@ -1,15 +1,15 @@
-import React, { useState } from 'react';
-import { useMediaQuery } from '@mantine/hooks';
-import { Button, Center, Title, Textarea, Text } from '@mantine/core';
+import { AddTestimonialDto } from '@FullStackMap/from-a2b';
+import { Button, Center, Text, Textarea, Title } from '@mantine/core';
 import { useForm } from '@mantine/form';
+import { useMediaQuery } from '@mantine/hooks';
+import { useMutation, useQueryClient } from '@tanstack/react-query';
 import { zodResolver } from 'mantine-form-zod-resolver';
+import React, { useState } from 'react';
 import { z } from 'zod';
-import { StarLikeComponent } from '../starComponent/StarLikeComponent';
 import useNotify, { NotifyDto } from '../../hooks/useNotify';
-import { AuthStore, useAuthStore } from '../../store/useAuthStore';
 import { TestimonialsController } from '../../services/BaseApi';
-import { useMutation, useQueryClient } from '@tanstack/react-query';
-import { AddTestimonialDto } from '@FullStackMap/from-a2b';
+import { AuthStore, useAuthStore } from '../../store/useAuthStore';
+import { StarLikeComponent } from '../starComponent/StarLikeComponent';
 
 export const FormFeedback = () => {
   const MAX_CHARS = 500;
@@ -25,16 +25,16 @@ export const FormFeedback = () => {
       .string()
       .min(10, 'Le commentaire doit contenir au moins 10 caractères')
       .refine(
-        (value) => {
+        value => {
           return !/\s{6,}/.test(value);
         },
         {
           message:
             'Le commentaire ne peut pas contenir plus de 5 espaces de suite',
           path: ['feedBack'],
-        }
+        },
       )
-      .refine((value) => /\S/.test(value), {
+      .refine(value => /\S/.test(value), {
         message:
           'Le commentaire ne peut pas être vide ou contenir uniquement des espaces',
         path: ['feedBack'],
@@ -59,13 +59,13 @@ export const FormFeedback = () => {
     mutationFn: async ([id, dto]: [string, AddTestimonialDto]) =>
       await TestimonialsController.createTestimonialAsyncPOST(id, dto),
     onSuccess: () => {
+      queryClient.invalidateQueries({ queryKey: ['testimonials'] });
       SuccessNotify({
         title: 'Avis envoyé',
         message: 'Votre avis a bien été envoyé, merci !',
         autoClose: 5000,
       } as NotifyDto);
       feedbackForm.reset();
-      queryClient.invalidateQueries({ queryKey: ['testimonials'] });
     },
   });
 
@@ -80,7 +80,7 @@ export const FormFeedback = () => {
   };
 
   const handleCommentChange = (
-    event: React.ChangeEvent<HTMLTextAreaElement>
+    event: React.ChangeEvent<HTMLTextAreaElement>,
   ) => {
     const feedBack = event.target.value;
     setCharCount(feedBack.length);
diff --git a/src/components/map/MapComponent.tsx b/src/components/map/MapComponent.tsx
index 2a0c633..acc0f43 100644
--- a/src/components/map/MapComponent.tsx
+++ b/src/components/map/MapComponent.tsx
@@ -227,8 +227,6 @@ export const MapComponent = () => {
           travelRoad: travelBeforeResponse.travelRoad,
         };
       }
-
-      console.log('🚀 ~ handleMoveMarker ~ addTravelDto:', addTravelDto);
       await addTravelBetweenStepsMutation.mutateAsync(addTravelDto);
     }
 
@@ -274,8 +272,6 @@ export const MapComponent = () => {
           travelRoad: travelAfterResponse.travelRoad,
         };
       }
-
-      console.log('🚀 ~ handleMoveMarker ~ addTravelDto:', addTravelDto);
       await addTravelBetweenStepsMutation.mutateAsync(addTravelDto);
     }
 
diff --git a/src/components/map/stepCard/Menu/StepCardMenu.tsx b/src/components/map/stepCard/Menu/StepCardMenu.tsx
index 09d4610..fd8f192 100644
--- a/src/components/map/stepCard/Menu/StepCardMenu.tsx
+++ b/src/components/map/stepCard/Menu/StepCardMenu.tsx
@@ -3,9 +3,6 @@ import { useDisclosure } from '@mantine/hooks';
 import {
   IconArrowBarToDown,
   IconArrowBarToUp,
-  IconArrowDownBar,
-  IconArrowMoveUp,
-  IconCopy,
   IconDotsVertical,
   IconEdit,
   IconTrash,
@@ -101,20 +98,8 @@ export const StepCardMenu = (props: StepCardMenuProps) => {
             Supprimer l'étape
           </Menu.Item>
 
-          <Menu.Divider />
-          <Menu.Label>Déplacement de l'étape</Menu.Label>
-          <Menu.Item leftSection={<IconArrowMoveUp />} disabled>
-            Déplacer avant
-          </Menu.Item>
-          <Menu.Item leftSection={<IconArrowDownBar />} disabled>
-            Déplacer après
-          </Menu.Item>
-
           <Menu.Divider />
           <Menu.Label>Nouvelle étape</Menu.Label>
-          <Menu.Item leftSection={<IconCopy />} disabled>
-            Dupliquer mon étape
-          </Menu.Item>
           <Menu.Item
             leftSection={<IconArrowBarToDown />}
             onClick={handleCreateStepBefore}>
diff --git a/src/pages/login/LoginPage.tsx b/src/pages/login/LoginPage.tsx
index a16fcd8..1f56555 100644
--- a/src/pages/login/LoginPage.tsx
+++ b/src/pages/login/LoginPage.tsx
@@ -57,7 +57,7 @@ const LoginPage = () => {
           SuccessNotify({
             title: 'Connexion réussie',
             message: 'Vous êtes maintenant connecté!',
-          } as NotifyDto)
+          } as NotifyDto),
         )
         .catch(() => {
           ErrorNotify({
@@ -83,7 +83,7 @@ const LoginPage = () => {
     <>
       <Container>
         <Title order={2} ta="center">
-          Se Connecter
+          Se connecter
         </Title>
         <form onSubmit={handleSubmit} onReset={() => loginForm.reset()}>
           <TextInput
diff --git a/src/pages/showTravels/history/HistoryPage.tsx b/src/pages/showTravels/history/HistoryPage.tsx
index 6511c18..0cbf15f 100644
--- a/src/pages/showTravels/history/HistoryPage.tsx
+++ b/src/pages/showTravels/history/HistoryPage.tsx
@@ -1,23 +1,23 @@
-import { Container, Grid, Loader, Center } from '@mantine/core';
-import { TripController } from '../../../services/BaseApi';
-import { TravelCard } from '../../../components/cardCustom/TravelCard/TravelCard';
-import { AuthStore, useAuthStore } from '../../../store/useAuthStore';
+import { Center, Container, Grid, Loader } from '@mantine/core';
 import { useQuery } from '@tanstack/react-query';
+import { TravelCard } from '../../../components/cardCustom/TravelCard/TravelCard';
 import NoFoundTravels from '../../../components/cardCustom/noFoundTravels/NoFoundTravels';
 import useNotify, { NotifyDto } from '../../../hooks/useNotify';
+import { TripController } from '../../../services/BaseApi';
+import { AuthStore, useAuthStore } from '../../../store/useAuthStore';
 
 const HistoryPage = () => {
   const userId: string | undefined = useAuthStore((s: AuthStore) => s.user?.Id);
   const { ErrorNotify } = useNotify();
 
   const { isPending, data: query } = useQuery({
-    queryKey: ['trips', userId],
+    queryKey: ['users', userId, 'trips'],
     queryFn: async () => {
       if (!userId) {
         return Promise.resolve([]);
       }
       return TripController.getAllTripByUserIdAsyncGET(userId as string)
-        .then((res) => res.data)
+        .then(res => res.data)
         .catch(() => {
           ErrorNotify({
             title: "Une erreur s'est produite",
@@ -43,7 +43,7 @@ const HistoryPage = () => {
 
   const currentDate = new Date();
 
-  const historyTrips = query.filter((trip) => {
+  const historyTrips = query.filter(trip => {
     if (!trip.startDate) return false;
     const tripStartDate = new Date(trip.startDate);
     return tripStartDate < currentDate;
diff --git a/src/pages/showTravels/myTrips/MyTrips.tsx b/src/pages/showTravels/myTrips/TripsPage.tsx
similarity index 89%
rename from src/pages/showTravels/myTrips/MyTrips.tsx
rename to src/pages/showTravels/myTrips/TripsPage.tsx
index 2b968d3..205b66a 100644
--- a/src/pages/showTravels/myTrips/MyTrips.tsx
+++ b/src/pages/showTravels/myTrips/TripsPage.tsx
@@ -1,6 +1,6 @@
 import { useQuery } from '@tanstack/react-query';
-import { TripController } from '../../../services/BaseApi';
-import { AuthStore, useAuthStore } from '../../../store/useAuthStore';
+import { TripController } from '../../../services/BaseApi.ts';
+import { AuthStore, useAuthStore } from '../../../store/useAuthStore.ts';
 
 import NoFoundTravels from '../../../components/cardCustom/noFoundTravels/NoFoundTravels.tsx';
 import { TravelCard } from '../../../components/cardCustom/TravelCard/TravelCard.tsx';
@@ -8,18 +8,18 @@ import { TravelCard } from '../../../components/cardCustom/TravelCard/TravelCard
 import { Center, Container, Grid, Loader } from '@mantine/core';
 import useNotify, { NotifyDto } from '../../../hooks/useNotify.tsx';
 
-const MyTrips = () => {
+const TripsPage = () => {
   const userId: string | undefined = useAuthStore((s: AuthStore) => s.user?.Id);
   const { ErrorNotify } = useNotify();
 
   const { isPending, data: query } = useQuery({
-    queryKey: ['trips', userId],
+    queryKey: ['users', userId, 'trips'],
     queryFn: async () => {
       if (!userId) {
         return Promise.resolve([]);
       }
       return TripController.getAllTripByUserIdAsyncGET(userId as string)
-        .then((res) => res.data)
+        .then(res => res.data)
         .catch(() => {
           ErrorNotify({
             title: "Une erreur s'est produite",
@@ -44,7 +44,7 @@ const MyTrips = () => {
   }
   const currentDate = new Date();
 
-  const trips = query.filter((trip) => {
+  const trips = query.filter(trip => {
     if (!trip.startDate) return false;
     const tripStartDate = new Date(trip.startDate);
     return tripStartDate >= currentDate;
@@ -70,4 +70,4 @@ const MyTrips = () => {
   );
 };
 
-export default MyTrips;
+export default TripsPage;
diff --git a/src/pages/tripDetail/TripDetailPage.tsx b/src/pages/tripDetail/TripDetailPage.tsx
index e193ff1..7511cc2 100644
--- a/src/pages/tripDetail/TripDetailPage.tsx
+++ b/src/pages/tripDetail/TripDetailPage.tsx
@@ -151,8 +151,6 @@ const TripDetailPage = () => {
 
       if (!originStep) return;
     }
-    console.log('🚀 ~ TripDetailPage ~ originStep:', originStep);
-
     if (!destinationStep && originStep) {
       if (!destinationStep && addStepMode === AddStepMode.AFTER)
         destinationStep = steps.find(step => step.order === originStep!.order!);
@@ -163,8 +161,6 @@ const TripDetailPage = () => {
 
       if (!destinationStep) return;
     }
-    console.log('🚀 ~ TripDetailPage ~ destinationStep:', destinationStep);
-
     let travelRoad: CalculateTravelRoadDto | undefined;
 
     if (destinationStep!.transportMode !== DirectionMode.PLANE) {
diff --git a/src/router/Router.tsx b/src/router/Router.tsx
index b693a67..246a038 100644
--- a/src/router/Router.tsx
+++ b/src/router/Router.tsx
@@ -3,6 +3,7 @@ import { Navigate, Route, Routes } from 'react-router-dom';
 import DefaultLayout from '../layout/default/DefaultLayout';
 import LoginLayout from '../layout/login/LoginLayout';
 import MapLayout from '../layout/map/MapLayout.tsx';
+import ShowTravelsLayout from '../layout/showTravels/ShowTravelsLayout';
 import CguPage from '../pages/cgu/CguPage';
 import { ConfirmMailPage } from '../pages/confirmMail/ConfirmMailPage';
 import ContactPage from '../pages/contact/ContactPage';
@@ -14,13 +15,12 @@ import LoginPage from '../pages/login/LoginPage';
 import MapPage from '../pages/map/MapPage';
 import ProfilePage from '../pages/profile/ProfilePage.tsx';
 import { RegisterPage } from '../pages/register/RegisterPage';
+import HistoryPage from '../pages/showTravels/history/HistoryPage';
+import TripsPage from '../pages/showTravels/myTrips/TripsPage.tsx';
 import TestPage from '../pages/test/TestPage.tsx';
 import TripDetailPage from '../pages/tripDetail/TripDetailPage.tsx';
 import { AuthStore, useAuthStore } from '../store/useAuthStore';
 import { PrivateRoute } from './PrivateRoute';
-import ShowTravelsLayout from '../layout/showTravels/ShowTravelsLayout';
-import HistoryPage from '../pages/showTravels/history/HistoryPage';
-import MyTrips from '../pages/showTravels/myTrips/MyTrips';
 
 const Router = () => {
   const loadUser: () => void = useAuthStore((s: AuthStore) => s.loadUser);
@@ -57,7 +57,7 @@ const Router = () => {
             element={<ShowTravelsLayout />}
           />
         }>
-        <Route path="" element={<MyTrips />} />
+        <Route path="" element={<TripsPage />} />
         <Route path="history" element={<HistoryPage />} />
       </Route>
 
diff --git a/src/services/BaseApi.ts b/src/services/BaseApi.ts
index c358b08..d300681 100644
--- a/src/services/BaseApi.ts
+++ b/src/services/BaseApi.ts
@@ -2,86 +2,36 @@ import * as client from '@FullStackMap/from-a2b';
 import axios from 'axios';
 import Cookies from 'js-cookie';
 
-const basePath: string = import.meta.env.VITE_API_URL as string;
-const token: string | undefined = Cookies.get('Auth-Token');
-
-const configAno = new client.Configuration({
-  basePath: basePath,
+const axiosClient = axios.create({
+  baseURL: import.meta.env.VITE_API_URL as string,
 });
-export const AnoAxiosClient = axios.create({
-  baseURL: basePath,
+
+axiosClient.interceptors.request.use(request => {
+  const token: string | undefined = Cookies.get('Auth-Token');
+  if (token) {
+    request.headers.Authorization = `Bearer ${token}`;
+  }
+
+  return request;
 });
 
 const TripControllerFunc = () => {
-  const configLogged = new client.Configuration({
-    basePath: basePath,
-    baseOptions: {
-      headers: {
-        Authorization: `Bearer ${token}`,
-      },
-    },
-  });
-  return client.TripApiFactory(configLogged);
+  return client.TripApiFactory(undefined, undefined, axiosClient);
 };
 const UserControllerFunc = () => {
-  const configLogged = new client.Configuration({
-    basePath: basePath,
-    baseOptions: {
-      headers: {
-        Authorization: `Bearer ${token}`,
-      },
-    },
-  });
-
-  return client.UserApiFactory(configLogged);
+  return client.UserApiFactory(undefined, undefined, axiosClient);
 };
 const StepControllerFunc = () => {
-  const configLogged = new client.Configuration({
-    basePath: basePath,
-    baseOptions: {
-      headers: {
-        Authorization: `Bearer ${token}`,
-      },
-    },
-  });
-  return client.StepApiFactory(configLogged);
+  return client.StepApiFactory(undefined, undefined, axiosClient);
 };
 const TravelControllerFunc = () => {
-  const configLogged = new client.Configuration({
-    basePath: basePath,
-    baseOptions: {
-      headers: {
-        Authorization: `Bearer ${token}`,
-      },
-    },
-  });
-  return client.TravelApiFactory(configLogged);
+  return client.TravelApiFactory(undefined, undefined, axiosClient);
 };
 
 const TestimonialsControllerFunc = () => {
-  const configLogged = new client.Configuration({
-    basePath: basePath,
-    baseOptions: {
-      headers: {
-        Authorization: `Bearer ${token}`,
-      },
-    },
-  });
-
-  return client.TestimonialApiFactory(configLogged);
+  return client.TestimonialApiFactory(undefined, undefined, axiosClient);
 };
 
-export const AnoAxiosClient = axios.create({
-  baseURL: basePath,
-});
-
-export const AxiosClient = axios.create({
-  baseURL: basePath,
-  headers: {
-    Authorization: `Bearer ${token}`,
-  },
-});
-
 export const MapboxClient = axios.create({
   baseURL: 'https://api.mapbox.com',
 });
@@ -90,9 +40,15 @@ export const TripController = TripControllerFunc();
 export const StepController = StepControllerFunc();
 export const TravelController = TravelControllerFunc();
 export const UserController = UserControllerFunc();
-
-export const AnoAuthController = client.AuthApiFactory(configAno);
-
-export const AnoTestimonialsController = client.TestimonialApiFactory(configAno);
-
 export const TestimonialsController = TestimonialsControllerFunc();
+
+export const AnoAuthController = client.AuthApiFactory(
+  undefined,
+  undefined,
+  axiosClient,
+);
+export const AnoTestimonialsController = client.TestimonialApiFactory(
+  undefined,
+  undefined,
+  axiosClient,
+);
diff --git a/src/store/useAuthStore.ts b/src/store/useAuthStore.ts
index a2c8784..73124a8 100644
--- a/src/store/useAuthStore.ts
+++ b/src/store/useAuthStore.ts
@@ -29,10 +29,10 @@ export const useAuthStore: UseBoundStore<StoreApi<AuthStore>> =
         .then(resp => {
           const token: string | null | undefined = resp.data?.token;
           if (token) {
-            const decodeToken = jwtDecode(token) as TokenDecoded;
             Cookies.set('Auth-Token', token, {
               secure: false,
             });
+            const decodeToken = jwtDecode(token) as TokenDecoded;
             const user: AuthUser = {
               Id: decodeToken.Id,
               User: decodeToken.User,
@@ -49,7 +49,6 @@ export const useAuthStore: UseBoundStore<StoreApi<AuthStore>> =
         })
         .catch(err => {
           Cookies.remove('Auth-Token');
-          Cookies.remove('Auth-Token-Expire');
           set({
             token: '',
             expire: -1,
diff --git a/src/store/useTripDetailsStore.ts b/src/store/useTripDetailsStore.ts
index 6ab31a8..4b5730b 100644
--- a/src/store/useTripDetailsStore.ts
+++ b/src/store/useTripDetailsStore.ts
@@ -56,7 +56,7 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
   isEditModalOpened: false,
   SetEditModalIsOpened: (status: boolean) => set({ isEditModalOpened: status }),
 
-  tripId: '4C4EB54F-BEDE-468A-BB0A-08DC50B68FE1',
+  tripId: '',
   SetTripId: (tripId: string) => set({ tripId }),
 
   trip: {} as TripDto,

From 08e22e613018c12cf1a67a97415d83ef3fe840ac Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Sun, 31 Mar 2024 14:20:37 +0200
Subject: [PATCH 26/34] Feat (TripDetailRouter) : Implement id in route

---
 src/components/cardCustom/TravelCard/TravelCard.tsx |  7 +------
 src/pages/tripDetail/TripDetailPage.tsx             | 11 +++++++++--
 src/router/Router.tsx                               |  2 +-
 src/store/useTripDetailsStore.ts                    |  1 +
 4 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/src/components/cardCustom/TravelCard/TravelCard.tsx b/src/components/cardCustom/TravelCard/TravelCard.tsx
index 548b05b..be49035 100644
--- a/src/components/cardCustom/TravelCard/TravelCard.tsx
+++ b/src/components/cardCustom/TravelCard/TravelCard.tsx
@@ -4,9 +4,7 @@ import {
   IconHourglassOff,
   IconPlayerPlay,
 } from '@tabler/icons-react';
-import { useQueryClient } from '@tanstack/react-query';
 import { useNavigate } from 'react-router-dom';
-import { useTripDetailsStore } from '../../../store/useTripDetailsStore';
 
 export type TravelCardProps = {
   img: string;
@@ -17,9 +15,7 @@ export type TravelCardProps = {
 };
 
 export const TravelCard = (props: TravelCardProps) => {
-  const queryClient = useQueryClient();
   const navigate = useNavigate();
-  const { SetTrip, SetTripId } = useTripDetailsStore();
 
   const isInProgress = (startDate: string) => {
     const currentDate = new Date();
@@ -36,8 +32,7 @@ export const TravelCard = (props: TravelCardProps) => {
   };
 
   const handleViewTrip = () => {
-    SetTripId(props.id);
-    navigate(`/tripDetail`);
+    navigate(`/trips/${props.id}`);
   };
 
   return (
diff --git a/src/pages/tripDetail/TripDetailPage.tsx b/src/pages/tripDetail/TripDetailPage.tsx
index 7511cc2..82e8aeb 100644
--- a/src/pages/tripDetail/TripDetailPage.tsx
+++ b/src/pages/tripDetail/TripDetailPage.tsx
@@ -18,6 +18,7 @@ import { MapComponent } from '../../components/map/MapComponent';
 
 import { useMutation } from '@tanstack/react-query';
 
+import { useParams } from 'react-router-dom';
 import { CreateStepModal } from '../../components/map/addStep/CreateStepModal.tsx';
 import { EditStepModal } from '../../components/map/editStep/EditStepModal.tsx';
 import { StepList } from '../../components/map/stepList/StepList.tsx';
@@ -34,6 +35,7 @@ import {
 
 const TripDetailPage = () => {
   //#region Hooks
+  const { routeTripId } = useParams();
 
   const { ErrorNotify } = useNotify();
 
@@ -55,7 +57,7 @@ const TripDetailPage = () => {
     (state: TripDetailsStore) => state.otherStep,
   );
 
-  const { SetTrip, SetCurrentStep, UnSelectCurrentStep } =
+  const { SetTripId, SetTrip, SetCurrentStep, UnSelectCurrentStep } =
     useTripDetailsStore();
 
   const queryClient = useQueryClient();
@@ -69,7 +71,7 @@ const TripDetailPage = () => {
       await TripController.getTripByIdGET(tripId as string).then(
         (res: AxiosResponse<TripDto, any>) => res.data,
       ),
-    enabled: !!tripId,
+    enabled: tripId !== undefined,
   });
 
   //#endregion
@@ -129,6 +131,11 @@ const TripDetailPage = () => {
 
   //#region Effects
 
+  useEffect(() => {
+    if (!routeTripId) return;
+    SetTripId(routeTripId!);
+  }, [routeTripId]);
+
   useEffect(() => {
     if (!tripDto) return;
     SetTrip(tripDto);
diff --git a/src/router/Router.tsx b/src/router/Router.tsx
index 246a038..5b04dde 100644
--- a/src/router/Router.tsx
+++ b/src/router/Router.tsx
@@ -63,7 +63,7 @@ const Router = () => {
 
       <Route element={<MapLayout />}>
         <Route
-          path="/tripDetail"
+          path="/trips/:routeTripId"
           element={
             <PrivateRoute
               authRequired
diff --git a/src/store/useTripDetailsStore.ts b/src/store/useTripDetailsStore.ts
index 4b5730b..20bf89c 100644
--- a/src/store/useTripDetailsStore.ts
+++ b/src/store/useTripDetailsStore.ts
@@ -62,6 +62,7 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
   trip: {} as TripDto,
   SetTrip: (tripDto: TripDto) =>
     set({
+      tripId: tripDto.tripId,
       trip: tripDto,
       steps: tripDto.steps || [],
       travels: tripDto.travels || [],

From 79165ba60564125f3a4d92fcc553e3d729984c7f Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Sun, 31 Mar 2024 14:22:18 +0200
Subject: [PATCH 27/34] Revert "Feat (TripDetailRouter) : Implement id in
 route"

This reverts commit 08e22e613018c12cf1a67a97415d83ef3fe840ac.
---
 src/components/cardCustom/TravelCard/TravelCard.tsx |  7 ++++++-
 src/pages/tripDetail/TripDetailPage.tsx             | 11 ++---------
 src/router/Router.tsx                               |  2 +-
 src/store/useTripDetailsStore.ts                    |  1 -
 4 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/src/components/cardCustom/TravelCard/TravelCard.tsx b/src/components/cardCustom/TravelCard/TravelCard.tsx
index be49035..548b05b 100644
--- a/src/components/cardCustom/TravelCard/TravelCard.tsx
+++ b/src/components/cardCustom/TravelCard/TravelCard.tsx
@@ -4,7 +4,9 @@ import {
   IconHourglassOff,
   IconPlayerPlay,
 } from '@tabler/icons-react';
+import { useQueryClient } from '@tanstack/react-query';
 import { useNavigate } from 'react-router-dom';
+import { useTripDetailsStore } from '../../../store/useTripDetailsStore';
 
 export type TravelCardProps = {
   img: string;
@@ -15,7 +17,9 @@ export type TravelCardProps = {
 };
 
 export const TravelCard = (props: TravelCardProps) => {
+  const queryClient = useQueryClient();
   const navigate = useNavigate();
+  const { SetTrip, SetTripId } = useTripDetailsStore();
 
   const isInProgress = (startDate: string) => {
     const currentDate = new Date();
@@ -32,7 +36,8 @@ export const TravelCard = (props: TravelCardProps) => {
   };
 
   const handleViewTrip = () => {
-    navigate(`/trips/${props.id}`);
+    SetTripId(props.id);
+    navigate(`/tripDetail`);
   };
 
   return (
diff --git a/src/pages/tripDetail/TripDetailPage.tsx b/src/pages/tripDetail/TripDetailPage.tsx
index 82e8aeb..7511cc2 100644
--- a/src/pages/tripDetail/TripDetailPage.tsx
+++ b/src/pages/tripDetail/TripDetailPage.tsx
@@ -18,7 +18,6 @@ import { MapComponent } from '../../components/map/MapComponent';
 
 import { useMutation } from '@tanstack/react-query';
 
-import { useParams } from 'react-router-dom';
 import { CreateStepModal } from '../../components/map/addStep/CreateStepModal.tsx';
 import { EditStepModal } from '../../components/map/editStep/EditStepModal.tsx';
 import { StepList } from '../../components/map/stepList/StepList.tsx';
@@ -35,7 +34,6 @@ import {
 
 const TripDetailPage = () => {
   //#region Hooks
-  const { routeTripId } = useParams();
 
   const { ErrorNotify } = useNotify();
 
@@ -57,7 +55,7 @@ const TripDetailPage = () => {
     (state: TripDetailsStore) => state.otherStep,
   );
 
-  const { SetTripId, SetTrip, SetCurrentStep, UnSelectCurrentStep } =
+  const { SetTrip, SetCurrentStep, UnSelectCurrentStep } =
     useTripDetailsStore();
 
   const queryClient = useQueryClient();
@@ -71,7 +69,7 @@ const TripDetailPage = () => {
       await TripController.getTripByIdGET(tripId as string).then(
         (res: AxiosResponse<TripDto, any>) => res.data,
       ),
-    enabled: tripId !== undefined,
+    enabled: !!tripId,
   });
 
   //#endregion
@@ -131,11 +129,6 @@ const TripDetailPage = () => {
 
   //#region Effects
 
-  useEffect(() => {
-    if (!routeTripId) return;
-    SetTripId(routeTripId!);
-  }, [routeTripId]);
-
   useEffect(() => {
     if (!tripDto) return;
     SetTrip(tripDto);
diff --git a/src/router/Router.tsx b/src/router/Router.tsx
index 5b04dde..246a038 100644
--- a/src/router/Router.tsx
+++ b/src/router/Router.tsx
@@ -63,7 +63,7 @@ const Router = () => {
 
       <Route element={<MapLayout />}>
         <Route
-          path="/trips/:routeTripId"
+          path="/tripDetail"
           element={
             <PrivateRoute
               authRequired
diff --git a/src/store/useTripDetailsStore.ts b/src/store/useTripDetailsStore.ts
index 20bf89c..4b5730b 100644
--- a/src/store/useTripDetailsStore.ts
+++ b/src/store/useTripDetailsStore.ts
@@ -62,7 +62,6 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
   trip: {} as TripDto,
   SetTrip: (tripDto: TripDto) =>
     set({
-      tripId: tripDto.tripId,
       trip: tripDto,
       steps: tripDto.steps || [],
       travels: tripDto.travels || [],

From ec4d0bcb5018207fbc722be5c97424c6f33f6460 Mon Sep 17 00:00:00 2001
From: Baptiste Legat <legatbaptiste@gmail.com>
Date: Sun, 31 Mar 2024 14:25:28 +0200
Subject: [PATCH 28/34] WIP

---
 docker-compose.yml                            |    1 +
 pnpm-lock.yaml                                | 3544 ++++++-----------
 .../noFoundTravels/NoFoundTravels.tsx         |   16 +-
 src/components/footer/DefaultFooter.tsx       |   18 +-
 src/components/header/DefaultHeader.tsx       |    3 +-
 src/components/map/MapComponent.tsx           |   50 +-
 src/components/map/stepList/StepList.scss     |    4 +-
 src/components/map/stepList/StepList.tsx      |   36 +-
 .../DeleteFormModal.tsx                       |    0
 .../resetPasswordFrom/ResetPasswordForm.tsx   |   69 +
 src/components/profileMenu/ProfileMenu.tsx    |    6 +-
 src/layout/map/MapLayout.tsx                  |    4 +-
 src/main.tsx                                  |    4 +-
 src/pages/landing/HeroHeader.tsx              |    8 +-
 src/pages/profile/ProfilePage.tsx             |   34 +-
 src/pages/tripDetail/TripDetailPage.scss      |   13 +
 src/pages/tripDetail/TripDetailPage.tsx       |   70 +-
 src/styles.scss                               |    1 +
 18 files changed, 1382 insertions(+), 2499 deletions(-)
 rename src/components/profile/{DeleteForm => deleteForm}/DeleteFormModal.tsx (100%)
 create mode 100644 src/components/profile/resetPasswordFrom/ResetPasswordForm.tsx
 create mode 100644 src/pages/tripDetail/TripDetailPage.scss

diff --git a/docker-compose.yml b/docker-compose.yml
index fb0f188..40dfff5 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -12,3 +12,4 @@ services:
       - '3000:3000'
     environment:
       VITE_API_URL: ${VITE_API_URL}
+      VITE_MAPBOX_TOKEN: ${VITE_MAPBOX_TOKEN}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c40b20e..d35dcfc 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -10,28 +10,28 @@ dependencies:
     version: 0.21.1-Alpha
   '@mantine/carousel':
     specifier: ^7.6.2
-    version: 7.6.2(@mantine/core@7.6.2)(@mantine/hooks@7.6.2)(embla-carousel-react@7.1.0)(react-dom@18.2.0)(react@18.2.0)
+    version: 7.7.1(@mantine/core@7.7.1)(@mantine/hooks@7.7.1)(embla-carousel-react@7.1.0)(react-dom@18.2.0)(react@18.2.0)
   '@mantine/core':
     specifier: ^7.6.2
-    version: 7.6.2(@mantine/hooks@7.6.2)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0)
+    version: 7.7.1(@mantine/hooks@7.7.1)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
   '@mantine/form':
     specifier: ^7.6.2
-    version: 7.6.2(react@18.2.0)
+    version: 7.7.1(react@18.2.0)
   '@mantine/hooks':
     specifier: ^7.6.2
-    version: 7.6.2(react@18.2.0)
+    version: 7.7.1(react@18.2.0)
   '@mantine/notifications':
     specifier: ^7.6.2
-    version: 7.6.2(@mantine/core@7.6.2)(@mantine/hooks@7.6.2)(react-dom@18.2.0)(react@18.2.0)
+    version: 7.7.1(@mantine/core@7.7.1)(@mantine/hooks@7.7.1)(react-dom@18.2.0)(react@18.2.0)
   '@tabler/icons-react':
     specifier: ^3.1.0
     version: 3.1.0(react@18.2.0)
   '@tanstack/react-query':
     specifier: ^5.28.0
-    version: 5.28.4(react@18.2.0)
+    version: 5.28.9(react@18.2.0)
   '@tanstack/react-query-devtools':
     specifier: ^5.28.0
-    version: 5.28.4(@tanstack/react-query@5.28.4)(react@18.2.0)
+    version: 5.28.10(@tanstack/react-query@5.28.9)(react@18.2.0)
   '@types/geojson':
     specifier: ^7946.0.14
     version: 7946.0.14
@@ -43,19 +43,19 @@ dependencies:
     version: 3.1.0
   '@types/react':
     specifier: ^18.2.66
-    version: 18.2.66
+    version: 18.2.73
   '@types/react-dom':
     specifier: ^18.2.22
-    version: 18.2.22
+    version: 18.2.23
   '@typescript-eslint/eslint-plugin':
     specifier: ^7.2.0
-    version: 7.2.0(@typescript-eslint/parser@7.2.0)(eslint@8.57.0)(typescript@5.4.2)
+    version: 7.4.0(@typescript-eslint/parser@7.4.0)(eslint@8.57.0)(typescript@5.4.3)
   '@typescript-eslint/parser':
     specifier: ^7.2.0
-    version: 7.2.0(eslint@8.57.0)(typescript@5.4.2)
+    version: 7.4.0(eslint@8.57.0)(typescript@5.4.3)
   '@vitejs/plugin-react':
     specifier: ^4.2.1
-    version: 4.2.1(vite@5.1.6)
+    version: 4.2.1(vite@5.2.7)
   axios:
     specifier: ^1.6.7
     version: 1.6.8
@@ -94,19 +94,19 @@ dependencies:
     version: 0.341.0(react@18.2.0)
   mantine-form-zod-resolver:
     specifier: ^1.1.0
-    version: 1.1.0(@mantine/form@7.6.2)(zod@3.22.4)
+    version: 1.1.0(@mantine/form@7.7.1)(zod@3.22.4)
   mapbox-gl:
     specifier: ^3.2.0
     version: 3.2.0
   postcss:
     specifier: ^8.4.35
-    version: 8.4.35
+    version: 8.4.38
   postcss-preset-mantine:
     specifier: ^1.13.0
-    version: 1.13.0(postcss@8.4.35)
+    version: 1.13.0(postcss@8.4.38)
   postcss-simple-vars:
     specifier: ^7.0.1
-    version: 7.0.1(postcss@8.4.35)
+    version: 7.0.1(postcss@8.4.38)
   react:
     specifier: ^18.2.0
     version: 18.2.0
@@ -124,7 +124,7 @@ dependencies:
     version: 6.22.3(react-dom@18.2.0)(react@18.2.0)
   react-scripts:
     specifier: 5.0.1
-    version: 5.0.1(@babel/plugin-syntax-flow@7.24.1)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(react@18.2.0)(sass@1.72.0)(typescript@5.4.2)
+    version: 5.0.1(@babel/plugin-syntax-flow@7.24.1)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(react@18.2.0)(sass@1.72.0)(typescript@5.4.3)
   sass:
     specifier: ^1.71.1
     version: 1.72.0
@@ -133,16 +133,16 @@ dependencies:
     version: 6.1.8(react-dom@18.2.0)(react@18.2.0)
   typescript:
     specifier: ^5.4.2
-    version: 5.4.2
+    version: 5.4.3
   vite:
     specifier: ^5.1.6
-    version: 5.1.6(sass@1.72.0)
+    version: 5.2.7(sass@1.72.0)
   zod:
     specifier: ^3.22.4
     version: 3.22.4
   zustand:
     specifier: ^4.5.1
-    version: 4.5.2(@types/react@18.2.66)(react@18.2.0)
+    version: 4.5.2(@types/react@18.2.73)(react@18.2.0)
 
 devDependencies:
   '@vite-pwa/assets-generator':
@@ -150,10 +150,10 @@ devDependencies:
     version: 0.2.4
   '@vitejs/plugin-basic-ssl':
     specifier: ^1.1.0
-    version: 1.1.0(vite@5.1.6)
+    version: 1.1.0(vite@5.2.7)
   vite-plugin-pwa:
     specifier: ^0.19.7
-    version: 0.19.7(@vite-pwa/assets-generator@0.2.4)(vite@5.1.6)(workbox-build@7.0.0)(workbox-window@7.0.0)
+    version: 0.19.7(@vite-pwa/assets-generator@0.2.4)(vite@5.2.7)(workbox-build@7.0.0)(workbox-window@7.0.0)
 
 packages:
 
@@ -197,52 +197,16 @@ packages:
       jsonpointer: 5.0.1
       leven: 3.1.0
 
-  /@babel/code-frame@7.23.5:
-    resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/highlight': 7.23.4
-      chalk: 2.4.2
-
   /@babel/code-frame@7.24.2:
     resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/highlight': 7.24.2
       picocolors: 1.0.0
-    dev: true
-
-  /@babel/compat-data@7.23.5:
-    resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==}
-    engines: {node: '>=6.9.0'}
 
   /@babel/compat-data@7.24.1:
     resolution: {integrity: sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==}
     engines: {node: '>=6.9.0'}
-    dev: true
-
-  /@babel/core@7.24.0:
-    resolution: {integrity: sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@ampproject/remapping': 2.3.0
-      '@babel/code-frame': 7.23.5
-      '@babel/generator': 7.23.6
-      '@babel/helper-compilation-targets': 7.23.6
-      '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
-      '@babel/helpers': 7.24.0
-      '@babel/parser': 7.24.0
-      '@babel/template': 7.24.0
-      '@babel/traverse': 7.24.0
-      '@babel/types': 7.24.0
-      convert-source-map: 2.0.0
-      debug: 4.3.4
-      gensync: 1.0.0-beta.2
-      json5: 2.2.3
-      semver: 6.3.1
-    transitivePeerDependencies:
-      - supports-color
-    dev: false
 
   /@babel/core@7.24.3:
     resolution: {integrity: sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==}
@@ -265,32 +229,21 @@ packages:
       semver: 6.3.1
     transitivePeerDependencies:
       - supports-color
-    dev: true
 
-  /@babel/eslint-parser@7.23.10(@babel/core@7.24.0)(eslint@8.57.0):
-    resolution: {integrity: sha512-3wSYDPZVnhseRnxRJH6ZVTNknBz76AEnyC+AYYhasjP3Yy23qz0ERR7Fcd2SHmYuSFJ2kY9gaaDd3vyqU09eSw==}
+  /@babel/eslint-parser@7.24.1(@babel/core@7.24.3)(eslint@8.57.0):
+    resolution: {integrity: sha512-d5guuzMlPeDfZIbpQ8+g1NaCNuAGBBGNECh0HVqz1sjOeVLh2CEaifuOysCH18URW6R7pqXINvf5PaR/dC6jLQ==}
     engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0}
     peerDependencies:
       '@babel/core': ^7.11.0
       eslint: ^7.5.0 || ^8.0.0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1
       eslint: 8.57.0
       eslint-visitor-keys: 2.1.0
       semver: 6.3.1
     dev: false
 
-  /@babel/generator@7.23.6:
-    resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/types': 7.24.0
-      '@jridgewell/gen-mapping': 0.3.5
-      '@jridgewell/trace-mapping': 0.3.25
-      jsesc: 2.5.2
-    dev: false
-
   /@babel/generator@7.24.1:
     resolution: {integrity: sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==}
     engines: {node: '>=6.9.0'}
@@ -299,7 +252,6 @@ packages:
       '@jridgewell/gen-mapping': 0.3.5
       '@jridgewell/trace-mapping': 0.3.25
       jsesc: 2.5.2
-    dev: true
 
   /@babel/helper-annotate-as-pure@7.22.5:
     resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==}
@@ -317,30 +269,12 @@ packages:
     resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/compat-data': 7.23.5
+      '@babel/compat-data': 7.24.1
       '@babel/helper-validator-option': 7.23.5
       browserslist: 4.23.0
       lru-cache: 5.1.1
       semver: 6.3.1
 
-  /@babel/helper-create-class-features-plugin@7.24.0(@babel/core@7.24.0):
-    resolution: {integrity: sha512-QAH+vfvts51BCsNZ2PhY6HAggnlS6omLLFTsIpeqZk/MmJ6cW7tgz5yRv0fMJThcr6FmbMrENh1RgrWPTYA76g==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-annotate-as-pure': 7.22.5
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-function-name': 7.23.0
-      '@babel/helper-member-expression-to-functions': 7.23.0
-      '@babel/helper-optimise-call-expression': 7.22.5
-      '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.0)
-      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
-      '@babel/helper-split-export-declaration': 7.22.6
-      semver: 6.3.1
-    dev: false
-
   /@babel/helper-create-class-features-plugin@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==}
     engines: {node: '>=6.9.0'}
@@ -357,19 +291,6 @@ packages:
       '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
       '@babel/helper-split-export-declaration': 7.22.6
       semver: 6.3.1
-    dev: true
-
-  /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.24.0):
-    resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-annotate-as-pure': 7.22.5
-      regexpu-core: 5.3.2
-      semver: 6.3.1
-    dev: false
 
   /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.24.3):
     resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==}
@@ -381,37 +302,6 @@ packages:
       '@babel/helper-annotate-as-pure': 7.22.5
       regexpu-core: 5.3.2
       semver: 6.3.1
-    dev: true
-
-  /@babel/helper-define-polyfill-provider@0.5.0(@babel/core@7.24.0):
-    resolution: {integrity: sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==}
-    peerDependencies:
-      '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-compilation-targets': 7.23.6
-      '@babel/helper-plugin-utils': 7.24.0
-      debug: 4.3.4
-      lodash.debounce: 4.0.8
-      resolve: 1.22.8
-    transitivePeerDependencies:
-      - supports-color
-    dev: false
-
-  /@babel/helper-define-polyfill-provider@0.6.1(@babel/core@7.24.0):
-    resolution: {integrity: sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==}
-    peerDependencies:
-      '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-compilation-targets': 7.23.6
-      '@babel/helper-plugin-utils': 7.24.0
-      debug: 4.3.4
-      lodash.debounce: 4.0.8
-      resolve: 1.22.8
-    transitivePeerDependencies:
-      - supports-color
-    dev: false
 
   /@babel/helper-define-polyfill-provider@0.6.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==}
@@ -426,7 +316,6 @@ packages:
       resolve: 1.22.8
     transitivePeerDependencies:
       - supports-color
-    dev: true
 
   /@babel/helper-environment-visitor@7.22.20:
     resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==}
@@ -451,32 +340,11 @@ packages:
     dependencies:
       '@babel/types': 7.24.0
 
-  /@babel/helper-module-imports@7.22.15:
-    resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/types': 7.24.0
-
   /@babel/helper-module-imports@7.24.3:
     resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/types': 7.24.0
-    dev: true
-
-  /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-module-imports': 7.22.15
-      '@babel/helper-simple-access': 7.22.5
-      '@babel/helper-split-export-declaration': 7.22.6
-      '@babel/helper-validator-identifier': 7.22.20
-    dev: false
 
   /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.3):
     resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==}
@@ -486,11 +354,10 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-module-imports': 7.22.15
+      '@babel/helper-module-imports': 7.24.3
       '@babel/helper-simple-access': 7.22.5
       '@babel/helper-split-export-declaration': 7.22.6
       '@babel/helper-validator-identifier': 7.22.20
-    dev: true
 
   /@babel/helper-optimise-call-expression@7.22.5:
     resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==}
@@ -502,18 +369,6 @@ packages:
     resolution: {integrity: sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==}
     engines: {node: '>=6.9.0'}
 
-  /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.24.0):
-    resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-annotate-as-pure': 7.22.5
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-wrap-function': 7.22.20
-    dev: false
-
   /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.24.3):
     resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==}
     engines: {node: '>=6.9.0'}
@@ -524,19 +379,6 @@ packages:
       '@babel/helper-annotate-as-pure': 7.22.5
       '@babel/helper-environment-visitor': 7.22.20
       '@babel/helper-wrap-function': 7.22.20
-    dev: true
-
-  /@babel/helper-replace-supers@7.22.20(@babel/core@7.24.0):
-    resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-member-expression-to-functions': 7.23.0
-      '@babel/helper-optimise-call-expression': 7.22.5
-    dev: false
 
   /@babel/helper-replace-supers@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==}
@@ -548,7 +390,6 @@ packages:
       '@babel/helper-environment-visitor': 7.22.20
       '@babel/helper-member-expression-to-functions': 7.23.0
       '@babel/helper-optimise-call-expression': 7.22.5
-    dev: true
 
   /@babel/helper-simple-access@7.22.5:
     resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==}
@@ -568,8 +409,8 @@ packages:
     dependencies:
       '@babel/types': 7.24.0
 
-  /@babel/helper-string-parser@7.23.4:
-    resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==}
+  /@babel/helper-string-parser@7.24.1:
+    resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==}
     engines: {node: '>=6.9.0'}
 
   /@babel/helper-validator-identifier@7.22.20:
@@ -588,17 +429,6 @@ packages:
       '@babel/template': 7.24.0
       '@babel/types': 7.24.0
 
-  /@babel/helpers@7.24.0:
-    resolution: {integrity: sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/template': 7.24.0
-      '@babel/traverse': 7.24.0
-      '@babel/types': 7.24.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: false
-
   /@babel/helpers@7.24.1:
     resolution: {integrity: sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==}
     engines: {node: '>=6.9.0'}
@@ -608,15 +438,6 @@ packages:
       '@babel/types': 7.24.0
     transitivePeerDependencies:
       - supports-color
-    dev: true
-
-  /@babel/highlight@7.23.4:
-    resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/helper-validator-identifier': 7.22.20
-      chalk: 2.4.2
-      js-tokens: 4.0.0
 
   /@babel/highlight@7.24.2:
     resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==}
@@ -626,14 +447,6 @@ packages:
       chalk: 2.4.2
       js-tokens: 4.0.0
       picocolors: 1.0.0
-    dev: true
-
-  /@babel/parser@7.24.0:
-    resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==}
-    engines: {node: '>=6.0.0'}
-    hasBin: true
-    dependencies:
-      '@babel/types': 7.24.0
 
   /@babel/parser@7.24.1:
     resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==}
@@ -641,17 +454,6 @@ packages:
     hasBin: true
     dependencies:
       '@babel/types': 7.24.0
-    dev: true
-
-  /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==}
@@ -661,19 +463,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.13.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
-      '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.24.0)
-    dev: false
 
   /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==}
@@ -685,18 +474,6 @@ packages:
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
       '@babel/plugin-transform-optional-chaining': 7.24.1(@babel/core@7.24.3)
-    dev: true
-
-  /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.23.7(@babel/core@7.24.0):
-    resolution: {integrity: sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==}
@@ -707,90 +484,80 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-environment-visitor': 7.22.20
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
 
-  /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.24.0):
+  /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.24.3):
     resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==}
     engines: {node: '>=6.9.0'}
     deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0)
+      '@babel/core': 7.24.3
+      '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
     dev: false
 
-  /@babel/plugin-proposal-decorators@7.24.0(@babel/core@7.24.0):
-    resolution: {integrity: sha512-LiT1RqZWeij7X+wGxCoYh3/3b8nVOX6/7BZ9wiQgAIyjoeQWdROaodJCgT+dwtbjHaz0r7bEbHJzjSbVfcOyjQ==}
+  /@babel/plugin-proposal-decorators@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-zPEvzFijn+hRvJuX2Vu3KbEBN39LN3f7tW3MQO2LsIs57B26KU+kUc82BdAktS1VCM6libzh45eKGI65lg0cpA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0)
+      '@babel/core': 7.24.3
+      '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-decorators': 7.24.0(@babel/core@7.24.0)
+      '@babel/plugin-syntax-decorators': 7.24.1(@babel/core@7.24.3)
     dev: false
 
-  /@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.24.0):
+  /@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.24.3):
     resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==}
     engines: {node: '>=6.9.0'}
     deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0)
+      '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.3)
     dev: false
 
-  /@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.24.0):
+  /@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.24.3):
     resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==}
     engines: {node: '>=6.9.0'}
     deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.0)
+      '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.3)
     dev: false
 
-  /@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.24.0):
+  /@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.24.3):
     resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==}
     engines: {node: '>=6.9.0'}
     deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
-      '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0)
+      '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.3)
     dev: false
 
-  /@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.24.0):
+  /@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.24.3):
     resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==}
     engines: {node: '>=6.9.0'}
     deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0)
+      '@babel/core': 7.24.3
+      '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
     dev: false
 
-  /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.0):
-    resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-    dev: false
-
   /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.3):
     resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==}
     engines: {node: '>=6.9.0'}
@@ -798,29 +565,19 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.24.3
-    dev: true
 
-  /@babel/plugin-proposal-private-property-in-object@7.21.11(@babel/core@7.24.0):
+  /@babel/plugin-proposal-private-property-in-object@7.21.11(@babel/core@7.24.3):
     resolution: {integrity: sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==}
     engines: {node: '>=6.9.0'}
     deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-annotate-as-pure': 7.22.5
-      '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0)
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.0)
-    dev: false
-
-  /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.0):
-    resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
+      '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
+      '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.3)
     dev: false
 
   /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.3):
@@ -830,213 +587,110 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
 
-  /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.0):
+  /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.3):
     resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
     dev: false
 
-  /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.0):
+  /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.3):
     resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
-  /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.3):
-    resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
+  /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.3):
+    resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==}
+    engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
 
-  /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.0):
-    resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==}
+  /@babel/plugin-syntax-decorators@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-05RJdO/cCrtVWuAaSn1tS3bH8jbsJa/Y1uD186u6J4C/1mnHFxseeuWpsqr9anvo7TUulev7tm7GDwRV+VuhDw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
     dev: false
 
-  /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.3):
-    resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==}
-    engines: {node: '>=6.9.0'}
+  /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.3):
+    resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
 
-  /@babel/plugin-syntax-decorators@7.24.0(@babel/core@7.24.0):
-    resolution: {integrity: sha512-MXW3pQCu9gUiVGzqkGqsgiINDVYXoAnrY8FYF/rmb+OfufNF0zHMpHPN4ulRrinxYT8Vk/aZJxYqOKsDECjKAw==}
-    engines: {node: '>=6.9.0'}
+  /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.3):
+    resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
-  /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==}
+  /@babel/plugin-syntax-flow@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-sxi2kLTI5DeW5vDtMUsk4mTPwvlUDbjOnoWayhynCwrw4QXRld4QEYwqzY8JmQXaJUtgUuCIurtSRH5sn4c7mA==}
+    engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
     dev: false
 
-  /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.3):
-    resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==}
+  /@babel/plugin-syntax-import-assertions@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==}
+    engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
 
-  /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
+  /@babel/plugin-syntax-import-attributes@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==}
+    engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
-  /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.3):
-    resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
+  /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.3):
+    resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
 
-  /@babel/plugin-syntax-flow@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==}
-    engines: {node: '>=6.9.0'}
+  /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.3):
+    resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
-  /@babel/plugin-syntax-flow@7.24.1(@babel/core@7.24.0):
-    resolution: {integrity: sha512-sxi2kLTI5DeW5vDtMUsk4mTPwvlUDbjOnoWayhynCwrw4QXRld4QEYwqzY8JmQXaJUtgUuCIurtSRH5sn4c7mA==}
+  /@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
-
-  /@babel/plugin-syntax-import-assertions@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
-
-  /@babel/plugin-syntax-import-assertions@7.24.1(@babel/core@7.24.3):
-    resolution: {integrity: sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.3
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-syntax-import-attributes@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
-
-  /@babel/plugin-syntax-import-attributes@7.24.1(@babel/core@7.24.3):
-    resolution: {integrity: sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.3
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.0):
-    resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
-
-  /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.3):
-    resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.3
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
-
-  /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.3):
-    resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.3
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
-
-  /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.0):
-    resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
     dev: false
 
@@ -1047,16 +701,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.3):
     resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
@@ -1065,16 +709,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.0):
-    resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.3):
     resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
@@ -1083,16 +717,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.3):
     resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
@@ -1101,16 +725,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.3):
     resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
@@ -1119,16 +733,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.3):
     resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
@@ -1137,17 +741,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.0):
-    resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.3):
     resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==}
@@ -1157,17 +750,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.0):
-    resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.3):
     resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
@@ -1177,26 +759,14 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
 
-  /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==}
+  /@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
-
-  /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.0):
-    resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
     dev: false
 
@@ -1209,17 +779,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-arrow-functions@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-arrow-functions@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==}
@@ -1229,20 +788,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-async-generator-functions@7.23.9(@babel/core@7.24.0):
-    resolution: {integrity: sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.0)
-      '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.0)
-    dev: false
 
   /@babel/plugin-transform-async-generator-functions@7.24.3(@babel/core@7.24.3):
     resolution: {integrity: sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==}
@@ -1255,19 +800,6 @@ packages:
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.3)
       '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.3)
-    dev: true
-
-  /@babel/plugin-transform-async-to-generator@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-module-imports': 7.22.15
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.0)
-    dev: false
 
   /@babel/plugin-transform-async-to-generator@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==}
@@ -1279,17 +811,6 @@ packages:
       '@babel/helper-module-imports': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.3)
-    dev: true
-
-  /@babel/plugin-transform-block-scoped-functions@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-block-scoped-functions@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==}
@@ -1299,17 +820,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-block-scoping@7.23.4(@babel/core@7.24.0):
-    resolution: {integrity: sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-block-scoping@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-h71T2QQvDgM2SmT29UYU6ozjMlAt7s7CSs5Hvy8f8cf/GM/Z4a2zMfN+fjVGaieeCrXR3EdQl6C4gQG+OgmbKw==}
@@ -1319,18 +829,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-class-properties@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0)
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-class-properties@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==}
@@ -1341,19 +839,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-class-static-block@7.23.4(@babel/core@7.24.0):
-    resolution: {integrity: sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.12.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0)
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.0)
-    dev: false
 
   /@babel/plugin-transform-class-static-block@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-FUHlKCn6J3ERiu8Dv+4eoz7w8+kFLSyeVG4vDAikwADGjUCoHw/JHokyGtr8OR4UjpwPVivyF+h8Q5iv/JmrtA==}
@@ -1365,24 +850,6 @@ packages:
       '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.3)
-    dev: true
-
-  /@babel/plugin-transform-classes@7.23.8(@babel/core@7.24.0):
-    resolution: {integrity: sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-annotate-as-pure': 7.22.5
-      '@babel/helper-compilation-targets': 7.23.6
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-function-name': 7.23.0
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.0)
-      '@babel/helper-split-export-declaration': 7.22.6
-      globals: 11.12.0
-    dev: false
 
   /@babel/plugin-transform-classes@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==}
@@ -1399,18 +866,6 @@ packages:
       '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.3)
       '@babel/helper-split-export-declaration': 7.22.6
       globals: 11.12.0
-    dev: true
-
-  /@babel/plugin-transform-computed-properties@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/template': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-computed-properties@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==}
@@ -1421,17 +876,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/template': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-destructuring@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-destructuring@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==}
@@ -1441,18 +885,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-dotall-regex@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-dotall-regex@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==}
@@ -1463,17 +895,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-duplicate-keys@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-duplicate-keys@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==}
@@ -1483,18 +904,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-dynamic-import@7.23.4(@babel/core@7.24.0):
-    resolution: {integrity: sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.0)
-    dev: false
 
   /@babel/plugin-transform-dynamic-import@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==}
@@ -1505,18 +914,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.3)
-    dev: true
-
-  /@babel/plugin-transform-exponentiation-operator@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-exponentiation-operator@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==}
@@ -1527,181 +924,86 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-export-namespace-from@7.23.4(@babel/core@7.24.0):
-    resolution: {integrity: sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.0)
-    dev: false
 
   /@babel/plugin-transform-export-namespace-from@7.24.1(@babel/core@7.24.3):
-    resolution: {integrity: sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.3
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.3)
-    dev: true
-
-  /@babel/plugin-transform-flow-strip-types@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.24.0)
-    dev: false
-
-  /@babel/plugin-transform-for-of@7.23.6(@babel/core@7.24.0):
-    resolution: {integrity: sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
-    dev: false
-
-  /@babel/plugin-transform-for-of@7.24.1(@babel/core@7.24.3):
-    resolution: {integrity: sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.3
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
-    dev: true
-
-  /@babel/plugin-transform-function-name@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-compilation-targets': 7.23.6
-      '@babel/helper-function-name': 7.23.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
-
-  /@babel/plugin-transform-function-name@7.24.1(@babel/core@7.24.3):
-    resolution: {integrity: sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.3
-      '@babel/helper-compilation-targets': 7.23.6
-      '@babel/helper-function-name': 7.23.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-json-strings@7.23.4(@babel/core@7.24.0):
-    resolution: {integrity: sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.0)
-    dev: false
-
-  /@babel/plugin-transform-json-strings@7.24.1(@babel/core@7.24.3):
-    resolution: {integrity: sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==}
+    resolution: {integrity: sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.3)
-    dev: true
+      '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.3)
 
-  /@babel/plugin-transform-literals@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==}
+  /@babel/plugin-transform-flow-strip-types@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-iIYPIWt3dUmUKKE10s3W+jsQ3icFkw0JyRVyY1B7G4yK/nngAOHLVx8xlhA6b/Jzl/Y0nis8gjqhqKtRDQqHWQ==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
+      '@babel/plugin-syntax-flow': 7.24.1(@babel/core@7.24.3)
     dev: false
 
-  /@babel/plugin-transform-literals@7.24.1(@babel/core@7.24.3):
-    resolution: {integrity: sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==}
+  /@babel/plugin-transform-for-of@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
+      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
 
-  /@babel/plugin-transform-logical-assignment-operators@7.23.4(@babel/core@7.24.0):
-    resolution: {integrity: sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==}
+  /@babel/plugin-transform-function-name@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
+      '@babel/helper-compilation-targets': 7.23.6
+      '@babel/helper-function-name': 7.23.0
       '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.0)
-    dev: false
 
-  /@babel/plugin-transform-logical-assignment-operators@7.24.1(@babel/core@7.24.3):
-    resolution: {integrity: sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==}
+  /@babel/plugin-transform-json-strings@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.3)
-    dev: true
+      '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.3)
 
-  /@babel/plugin-transform-member-expression-literals@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==}
+  /@babel/plugin-transform-literals@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
-  /@babel/plugin-transform-member-expression-literals@7.24.1(@babel/core@7.24.3):
-    resolution: {integrity: sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==}
+  /@babel/plugin-transform-logical-assignment-operators@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
+      '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.3)
 
-  /@babel/plugin-transform-modules-amd@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==}
+  /@babel/plugin-transform-member-expression-literals@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-modules-amd@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==}
@@ -1712,19 +1014,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/helper-simple-access': 7.22.5
-    dev: false
 
   /@babel/plugin-transform-modules-commonjs@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==}
@@ -1736,20 +1025,6 @@ packages:
       '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-simple-access': 7.22.5
-    dev: true
-
-  /@babel/plugin-transform-modules-systemjs@7.23.9(@babel/core@7.24.0):
-    resolution: {integrity: sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-hoist-variables': 7.22.5
-      '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/helper-validator-identifier': 7.22.20
-    dev: false
 
   /@babel/plugin-transform-modules-systemjs@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==}
@@ -1762,18 +1037,6 @@ packages:
       '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-validator-identifier': 7.22.20
-    dev: true
-
-  /@babel/plugin-transform-modules-umd@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-modules-umd@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==}
@@ -1784,18 +1047,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.24.0):
-    resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.24.3):
     resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==}
@@ -1806,17 +1057,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-new-target@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-new-target@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==}
@@ -1826,18 +1066,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-nullish-coalescing-operator@7.23.4(@babel/core@7.24.0):
-    resolution: {integrity: sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0)
-    dev: false
 
   /@babel/plugin-transform-nullish-coalescing-operator@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==}
@@ -1848,18 +1076,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.3)
-    dev: true
-
-  /@babel/plugin-transform-numeric-separator@7.23.4(@babel/core@7.24.0):
-    resolution: {integrity: sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.0)
-    dev: false
 
   /@babel/plugin-transform-numeric-separator@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==}
@@ -1870,21 +1086,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.3)
-    dev: true
-
-  /@babel/plugin-transform-object-rest-spread@7.24.0(@babel/core@7.24.0):
-    resolution: {integrity: sha512-y/yKMm7buHpFFXfxVFS4Vk1ToRJDilIa6fKRioB9Vjichv58TDGXTvqV0dN7plobAmTW5eSEGXDngE+Mm+uO+w==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/compat-data': 7.23.5
-      '@babel/core': 7.24.0
-      '@babel/helper-compilation-targets': 7.23.6
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.24.0)
-    dev: false
 
   /@babel/plugin-transform-object-rest-spread@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==}
@@ -1897,18 +1098,6 @@ packages:
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.3)
       '@babel/plugin-transform-parameters': 7.24.1(@babel/core@7.24.3)
-    dev: true
-
-  /@babel/plugin-transform-object-super@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/helper-replace-supers': 7.22.20(@babel/core@7.24.0)
-    dev: false
 
   /@babel/plugin-transform-object-super@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==}
@@ -1919,18 +1108,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.3)
-    dev: true
-
-  /@babel/plugin-transform-optional-catch-binding@7.23.4(@babel/core@7.24.0):
-    resolution: {integrity: sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.0)
-    dev: false
 
   /@babel/plugin-transform-optional-catch-binding@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==}
@@ -1941,19 +1118,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.3)
-    dev: true
-
-  /@babel/plugin-transform-optional-chaining@7.23.4(@babel/core@7.24.0):
-    resolution: {integrity: sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
-      '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0)
-    dev: false
 
   /@babel/plugin-transform-optional-chaining@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==}
@@ -1965,17 +1129,6 @@ packages:
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
       '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.3)
-    dev: true
-
-  /@babel/plugin-transform-parameters@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-parameters@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==}
@@ -1985,18 +1138,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-private-methods@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0)
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-private-methods@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==}
@@ -2007,20 +1148,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-private-property-in-object@7.23.4(@babel/core@7.24.0):
-    resolution: {integrity: sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-annotate-as-pure': 7.22.5
-      '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0)
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.0)
-    dev: false
 
   /@babel/plugin-transform-private-property-in-object@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==}
@@ -2033,17 +1160,6 @@ packages:
       '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.3)
-    dev: true
-
-  /@babel/plugin-transform-property-literals@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-property-literals@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==}
@@ -2053,94 +1169,82 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
 
-  /@babel/plugin-transform-react-constant-elements@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-zP0QKq/p6O42OL94udMgSfKXyse4RyJ0JqbQ34zDAONWjyrEsghYEyTSK5FIpmXmCpB55SHokL1cRRKHv8L2Qw==}
+  /@babel/plugin-transform-react-constant-elements@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-QXp1U9x0R7tkiGB0FOk8o74jhnap0FlZ5gNkRIWdG3eP+SvMFg118e1zaWewDzgABb106QSKpVsD3Wgd8t6ifA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
     dev: false
 
-  /@babel/plugin-transform-react-display-name@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==}
+  /@babel/plugin-transform-react-display-name@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-mvoQg2f9p2qlpDQRBC7M3c3XTr0k7cp/0+kFKKO/7Gtu0LSw16eKB+Fabe2bDT/UpsyasTBBkAnbdsLrkD5XMw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
     dev: false
 
-  /@babel/plugin-transform-react-jsx-development@7.22.5(@babel/core@7.24.0):
+  /@babel/plugin-transform-react-jsx-development@7.22.5(@babel/core@7.24.3):
     resolution: {integrity: sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.24.0)
+      '@babel/core': 7.24.3
+      '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.24.3)
     dev: false
 
-  /@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==}
+  /@babel/plugin-transform-react-jsx-self@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-kDJgnPujTmAZ/9q2CN4m2/lRsUUPDvsG3+tSHWUJIzMGTt5U/b/fwWd3RO3n+5mjLrsBrVa5eKFRVSQbi3dF1w==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
     dev: false
 
-  /@babel/plugin-transform-react-jsx-source@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==}
+  /@babel/plugin-transform-react-jsx-source@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-1v202n7aUq4uXAieRTKcwPzNyphlCuqHHDcdSNc+vdhoTEZcFMh+L5yZuCmGaIO7bs1nJUNfHB89TZyoL48xNA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
     dev: false
 
-  /@babel/plugin-transform-react-jsx@7.23.4(@babel/core@7.24.0):
+  /@babel/plugin-transform-react-jsx@7.23.4(@babel/core@7.24.3):
     resolution: {integrity: sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-annotate-as-pure': 7.22.5
-      '@babel/helper-module-imports': 7.22.15
+      '@babel/helper-module-imports': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.24.0)
+      '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.3)
       '@babel/types': 7.24.0
     dev: false
 
-  /@babel/plugin-transform-react-pure-annotations@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==}
+  /@babel/plugin-transform-react-pure-annotations@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-+pWEAaDJvSm9aFvJNpLiM2+ktl2Sn2U5DdyiWdZBxmLc6+xGt88dvFqsHiAiDS+8WqUwbDfkKz9jRxK3M0k+kA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-annotate-as-pure': 7.22.5
       '@babel/helper-plugin-utils': 7.24.0
     dev: false
 
-  /@babel/plugin-transform-regenerator@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-      regenerator-transform: 0.15.2
-    dev: false
-
   /@babel/plugin-transform-regenerator@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==}
     engines: {node: '>=6.9.0'}
@@ -2150,17 +1254,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
       regenerator-transform: 0.15.2
-    dev: true
-
-  /@babel/plugin-transform-reserved-words@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-reserved-words@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==}
@@ -2170,35 +1263,24 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
 
-  /@babel/plugin-transform-runtime@7.24.0(@babel/core@7.24.0):
-    resolution: {integrity: sha512-zc0GA5IitLKJrSfXlXmp8KDqLrnGECK7YRfQBmEKg1NmBOQ7e+KuclBEKJgzifQeUYLdNiAw4B4bjyvzWVLiSA==}
+  /@babel/plugin-transform-runtime@7.24.3(@babel/core@7.24.3):
+    resolution: {integrity: sha512-J0BuRPNlNqlMTRJ72eVptpt9VcInbxO6iP3jaxr+1NPhC0UkKL+6oeX6VXMEYdADnuqmMmsBspt4d5w8Y/TCbQ==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-module-imports': 7.22.15
+      '@babel/core': 7.24.3
+      '@babel/helper-module-imports': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-      babel-plugin-polyfill-corejs2: 0.4.10(@babel/core@7.24.0)
-      babel-plugin-polyfill-corejs3: 0.9.0(@babel/core@7.24.0)
-      babel-plugin-polyfill-regenerator: 0.5.5(@babel/core@7.24.0)
+      babel-plugin-polyfill-corejs2: 0.4.10(@babel/core@7.24.3)
+      babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.3)
+      babel-plugin-polyfill-regenerator: 0.6.1(@babel/core@7.24.3)
       semver: 6.3.1
     transitivePeerDependencies:
       - supports-color
     dev: false
 
-  /@babel/plugin-transform-shorthand-properties@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
-
   /@babel/plugin-transform-shorthand-properties@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==}
     engines: {node: '>=6.9.0'}
@@ -2207,18 +1289,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-spread@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
-    dev: false
 
   /@babel/plugin-transform-spread@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==}
@@ -2229,17 +1299,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
-    dev: true
-
-  /@babel/plugin-transform-sticky-regex@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-sticky-regex@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==}
@@ -2249,17 +1308,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-template-literals@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-template-literals@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==}
@@ -2269,17 +1317,6 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-typeof-symbol@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-typeof-symbol@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==}
@@ -2289,51 +1326,28 @@ packages:
     dependencies:
       '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
 
-  /@babel/plugin-transform-typescript@7.23.6(@babel/core@7.24.0):
-    resolution: {integrity: sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==}
+  /@babel/plugin-transform-typescript@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-liYSESjX2fZ7JyBFkYG78nfvHlMKE6IpNdTVnxmlYUR+j5ZLsitFbaAE+eJSK2zPPkNWNw4mXL51rQ8WrvdK0w==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-annotate-as-pure': 7.22.5
-      '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0)
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.24.0)
-    dev: false
-
-  /@babel/plugin-transform-unicode-escapes@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
+      '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
+      '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.3)
     dev: false
 
-  /@babel/plugin-transform-unicode-escapes@7.24.1(@babel/core@7.24.3):
-    resolution: {integrity: sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.3
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-unicode-property-regex@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==}
+  /@babel/plugin-transform-unicode-escapes@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-unicode-property-regex@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==}
@@ -2344,18 +1358,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-unicode-regex@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-unicode-regex@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==}
@@ -2366,18 +1368,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/plugin-transform-unicode-sets-regex@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.0)
-      '@babel/helper-plugin-utils': 7.24.0
-    dev: false
 
   /@babel/plugin-transform-unicode-sets-regex@7.24.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==}
@@ -2388,98 +1378,6 @@ packages:
       '@babel/core': 7.24.3
       '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3)
       '@babel/helper-plugin-utils': 7.24.0
-    dev: true
-
-  /@babel/preset-env@7.24.0(@babel/core@7.24.0):
-    resolution: {integrity: sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/compat-data': 7.23.5
-      '@babel/core': 7.24.0
-      '@babel/helper-compilation-targets': 7.23.6
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/helper-validator-option': 7.23.5
-      '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.23.7(@babel/core@7.24.0)
-      '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.0)
-      '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.0)
-      '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.0)
-      '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.0)
-      '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.0)
-      '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.0)
-      '@babel/plugin-syntax-import-assertions': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-syntax-import-attributes': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.0)
-      '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.0)
-      '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.0)
-      '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0)
-      '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.0)
-      '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.0)
-      '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.0)
-      '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0)
-      '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.0)
-      '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.0)
-      '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.0)
-      '@babel/plugin-transform-arrow-functions': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-async-generator-functions': 7.23.9(@babel/core@7.24.0)
-      '@babel/plugin-transform-async-to-generator': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-block-scoped-functions': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-block-scoping': 7.23.4(@babel/core@7.24.0)
-      '@babel/plugin-transform-class-properties': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-class-static-block': 7.23.4(@babel/core@7.24.0)
-      '@babel/plugin-transform-classes': 7.23.8(@babel/core@7.24.0)
-      '@babel/plugin-transform-computed-properties': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-destructuring': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-dotall-regex': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-duplicate-keys': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-dynamic-import': 7.23.4(@babel/core@7.24.0)
-      '@babel/plugin-transform-exponentiation-operator': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-export-namespace-from': 7.23.4(@babel/core@7.24.0)
-      '@babel/plugin-transform-for-of': 7.23.6(@babel/core@7.24.0)
-      '@babel/plugin-transform-function-name': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-json-strings': 7.23.4(@babel/core@7.24.0)
-      '@babel/plugin-transform-literals': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-logical-assignment-operators': 7.23.4(@babel/core@7.24.0)
-      '@babel/plugin-transform-member-expression-literals': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-modules-amd': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-modules-systemjs': 7.23.9(@babel/core@7.24.0)
-      '@babel/plugin-transform-modules-umd': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.24.0)
-      '@babel/plugin-transform-new-target': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-nullish-coalescing-operator': 7.23.4(@babel/core@7.24.0)
-      '@babel/plugin-transform-numeric-separator': 7.23.4(@babel/core@7.24.0)
-      '@babel/plugin-transform-object-rest-spread': 7.24.0(@babel/core@7.24.0)
-      '@babel/plugin-transform-object-super': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-optional-catch-binding': 7.23.4(@babel/core@7.24.0)
-      '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.24.0)
-      '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-private-property-in-object': 7.23.4(@babel/core@7.24.0)
-      '@babel/plugin-transform-property-literals': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-regenerator': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-reserved-words': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-shorthand-properties': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-spread': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-sticky-regex': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-template-literals': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-typeof-symbol': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-unicode-escapes': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-unicode-property-regex': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-unicode-regex': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-unicode-sets-regex': 7.23.3(@babel/core@7.24.0)
-      '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.0)
-      babel-plugin-polyfill-corejs2: 0.4.10(@babel/core@7.24.0)
-      babel-plugin-polyfill-corejs3: 0.9.0(@babel/core@7.24.0)
-      babel-plugin-polyfill-regenerator: 0.5.5(@babel/core@7.24.0)
-      core-js-compat: 3.36.0
-      semver: 6.3.1
-    transitivePeerDependencies:
-      - supports-color
-    dev: false
 
   /@babel/preset-env@7.24.3(@babel/core@7.24.3):
     resolution: {integrity: sha512-fSk430k5c2ff8536JcPvPWK4tZDwehWLGlBp0wrsBUjZVdeQV6lePbwKWZaZfK2vnh/1kQX1PzAJWsnBmVgGJA==}
@@ -2570,18 +1468,6 @@ packages:
       semver: 6.3.1
     transitivePeerDependencies:
       - supports-color
-    dev: true
-
-  /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.0):
-    resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-plugin-utils': 7.24.0
-      '@babel/types': 7.24.0
-      esutils: 2.0.3
-    dev: false
 
   /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.3):
     resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==}
@@ -2592,78 +1478,52 @@ packages:
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/types': 7.24.0
       esutils: 2.0.3
-    dev: true
 
-  /@babel/preset-react@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==}
+  /@babel/preset-react@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-eFa8up2/8cZXLIpkafhaADTXSnl7IsUFCYenRWrARBz0/qZwcT0RBXpys0LJU4+WfPoF2ZG6ew6s2V6izMCwRA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-validator-option': 7.23.5
-      '@babel/plugin-transform-react-display-name': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.24.0)
-      '@babel/plugin-transform-react-jsx-development': 7.22.5(@babel/core@7.24.0)
-      '@babel/plugin-transform-react-pure-annotations': 7.23.3(@babel/core@7.24.0)
+      '@babel/plugin-transform-react-display-name': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.24.3)
+      '@babel/plugin-transform-react-jsx-development': 7.22.5(@babel/core@7.24.3)
+      '@babel/plugin-transform-react-pure-annotations': 7.24.1(@babel/core@7.24.3)
     dev: false
 
-  /@babel/preset-typescript@7.23.3(@babel/core@7.24.0):
-    resolution: {integrity: sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==}
+  /@babel/preset-typescript@7.24.1(@babel/core@7.24.3):
+    resolution: {integrity: sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@babel/helper-plugin-utils': 7.24.0
       '@babel/helper-validator-option': 7.23.5
-      '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-typescript': 7.23.6(@babel/core@7.24.0)
+      '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-typescript': 7.24.1(@babel/core@7.24.3)
     dev: false
 
   /@babel/regjsgen@0.8.0:
     resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==}
 
-  /@babel/runtime@7.24.0:
-    resolution: {integrity: sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      regenerator-runtime: 0.14.1
-
   /@babel/runtime@7.24.1:
     resolution: {integrity: sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==}
     engines: {node: '>=6.9.0'}
     dependencies:
       regenerator-runtime: 0.14.1
-    dev: true
 
   /@babel/template@7.24.0:
     resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/code-frame': 7.23.5
-      '@babel/parser': 7.24.0
-      '@babel/types': 7.24.0
-
-  /@babel/traverse@7.24.0:
-    resolution: {integrity: sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/code-frame': 7.23.5
-      '@babel/generator': 7.23.6
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-function-name': 7.23.0
-      '@babel/helper-hoist-variables': 7.22.5
-      '@babel/helper-split-export-declaration': 7.22.6
-      '@babel/parser': 7.24.0
+      '@babel/code-frame': 7.24.2
+      '@babel/parser': 7.24.1
       '@babel/types': 7.24.0
-      debug: 4.3.4
-      globals: 11.12.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: false
 
   /@babel/traverse@7.24.1:
     resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==}
@@ -2681,13 +1541,12 @@ packages:
       globals: 11.12.0
     transitivePeerDependencies:
       - supports-color
-    dev: true
 
   /@babel/types@7.24.0:
     resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/helper-string-parser': 7.23.4
+      '@babel/helper-string-parser': 7.24.1
       '@babel/helper-validator-identifier': 7.22.20
       to-fast-properties: 2.0.0
 
@@ -2703,148 +1562,148 @@ packages:
     resolution: {integrity: sha512-YAYeJ+Xqh7fUou1d1j9XHl44BmsuThiTr4iNrgCQ3J27IbhXsxXDGZ1cXv8Qvs99d4rBbLiSKy3+WZiet32PcQ==}
     dev: false
 
-  /@csstools/postcss-cascade-layers@1.1.1(postcss@8.4.35):
+  /@csstools/postcss-cascade-layers@1.1.1(postcss@8.4.38):
     resolution: {integrity: sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
       '@csstools/selector-specificity': 2.2.0(postcss-selector-parser@6.0.16)
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
-  /@csstools/postcss-color-function@1.1.1(postcss@8.4.35):
+  /@csstools/postcss-color-function@1.1.1(postcss@8.4.38):
     resolution: {integrity: sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.35)
-      postcss: 8.4.35
+      '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.38)
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /@csstools/postcss-font-format-keywords@1.0.1(postcss@8.4.35):
+  /@csstools/postcss-font-format-keywords@1.0.1(postcss@8.4.38):
     resolution: {integrity: sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /@csstools/postcss-hwb-function@1.0.2(postcss@8.4.35):
+  /@csstools/postcss-hwb-function@1.0.2(postcss@8.4.38):
     resolution: {integrity: sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /@csstools/postcss-ic-unit@1.0.1(postcss@8.4.35):
+  /@csstools/postcss-ic-unit@1.0.1(postcss@8.4.38):
     resolution: {integrity: sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.35)
-      postcss: 8.4.35
+      '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.38)
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /@csstools/postcss-is-pseudo-class@2.0.7(postcss@8.4.35):
+  /@csstools/postcss-is-pseudo-class@2.0.7(postcss@8.4.38):
     resolution: {integrity: sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
       '@csstools/selector-specificity': 2.2.0(postcss-selector-parser@6.0.16)
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
-  /@csstools/postcss-nested-calc@1.0.0(postcss@8.4.35):
+  /@csstools/postcss-nested-calc@1.0.0(postcss@8.4.38):
     resolution: {integrity: sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /@csstools/postcss-normalize-display-values@1.0.1(postcss@8.4.35):
+  /@csstools/postcss-normalize-display-values@1.0.1(postcss@8.4.38):
     resolution: {integrity: sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /@csstools/postcss-oklab-function@1.1.1(postcss@8.4.35):
+  /@csstools/postcss-oklab-function@1.1.1(postcss@8.4.38):
     resolution: {integrity: sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.35)
-      postcss: 8.4.35
+      '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.38)
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /@csstools/postcss-progressive-custom-properties@1.3.0(postcss@8.4.35):
+  /@csstools/postcss-progressive-custom-properties@1.3.0(postcss@8.4.38):
     resolution: {integrity: sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.3
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /@csstools/postcss-stepped-value-functions@1.0.1(postcss@8.4.35):
+  /@csstools/postcss-stepped-value-functions@1.0.1(postcss@8.4.38):
     resolution: {integrity: sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /@csstools/postcss-text-decoration-shorthand@1.0.0(postcss@8.4.35):
+  /@csstools/postcss-text-decoration-shorthand@1.0.0(postcss@8.4.38):
     resolution: {integrity: sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /@csstools/postcss-trigonometric-functions@1.0.2(postcss@8.4.35):
+  /@csstools/postcss-trigonometric-functions@1.0.2(postcss@8.4.38):
     resolution: {integrity: sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==}
     engines: {node: ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /@csstools/postcss-unset-value@1.0.2(postcss@8.4.35):
+  /@csstools/postcss-unset-value@1.0.2(postcss@8.4.38):
     resolution: {integrity: sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
   /@csstools/selector-specificity@2.2.0(postcss-selector-parser@6.0.16):
@@ -2870,184 +1729,184 @@ packages:
     resolution: {integrity: sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==}
     dev: false
 
-  /@esbuild/aix-ppc64@0.19.12:
-    resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==}
+  /@esbuild/aix-ppc64@0.20.2:
+    resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==}
     engines: {node: '>=12'}
     cpu: [ppc64]
     os: [aix]
     requiresBuild: true
     optional: true
 
-  /@esbuild/android-arm64@0.19.12:
-    resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==}
+  /@esbuild/android-arm64@0.20.2:
+    resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [android]
     requiresBuild: true
     optional: true
 
-  /@esbuild/android-arm@0.19.12:
-    resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==}
+  /@esbuild/android-arm@0.20.2:
+    resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==}
     engines: {node: '>=12'}
     cpu: [arm]
     os: [android]
     requiresBuild: true
     optional: true
 
-  /@esbuild/android-x64@0.19.12:
-    resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==}
+  /@esbuild/android-x64@0.20.2:
+    resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [android]
     requiresBuild: true
     optional: true
 
-  /@esbuild/darwin-arm64@0.19.12:
-    resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==}
+  /@esbuild/darwin-arm64@0.20.2:
+    resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [darwin]
     requiresBuild: true
     optional: true
 
-  /@esbuild/darwin-x64@0.19.12:
-    resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==}
+  /@esbuild/darwin-x64@0.20.2:
+    resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [darwin]
     requiresBuild: true
     optional: true
 
-  /@esbuild/freebsd-arm64@0.19.12:
-    resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==}
+  /@esbuild/freebsd-arm64@0.20.2:
+    resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [freebsd]
     requiresBuild: true
     optional: true
 
-  /@esbuild/freebsd-x64@0.19.12:
-    resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==}
+  /@esbuild/freebsd-x64@0.20.2:
+    resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [freebsd]
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-arm64@0.19.12:
-    resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==}
+  /@esbuild/linux-arm64@0.20.2:
+    resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [linux]
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-arm@0.19.12:
-    resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==}
+  /@esbuild/linux-arm@0.20.2:
+    resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==}
     engines: {node: '>=12'}
     cpu: [arm]
     os: [linux]
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-ia32@0.19.12:
-    resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==}
+  /@esbuild/linux-ia32@0.20.2:
+    resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==}
     engines: {node: '>=12'}
     cpu: [ia32]
     os: [linux]
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-loong64@0.19.12:
-    resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==}
+  /@esbuild/linux-loong64@0.20.2:
+    resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==}
     engines: {node: '>=12'}
     cpu: [loong64]
     os: [linux]
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-mips64el@0.19.12:
-    resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==}
+  /@esbuild/linux-mips64el@0.20.2:
+    resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==}
     engines: {node: '>=12'}
     cpu: [mips64el]
     os: [linux]
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-ppc64@0.19.12:
-    resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==}
+  /@esbuild/linux-ppc64@0.20.2:
+    resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==}
     engines: {node: '>=12'}
     cpu: [ppc64]
     os: [linux]
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-riscv64@0.19.12:
-    resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==}
+  /@esbuild/linux-riscv64@0.20.2:
+    resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==}
     engines: {node: '>=12'}
     cpu: [riscv64]
     os: [linux]
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-s390x@0.19.12:
-    resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==}
+  /@esbuild/linux-s390x@0.20.2:
+    resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==}
     engines: {node: '>=12'}
     cpu: [s390x]
     os: [linux]
     requiresBuild: true
     optional: true
 
-  /@esbuild/linux-x64@0.19.12:
-    resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==}
+  /@esbuild/linux-x64@0.20.2:
+    resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [linux]
     requiresBuild: true
     optional: true
 
-  /@esbuild/netbsd-x64@0.19.12:
-    resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==}
+  /@esbuild/netbsd-x64@0.20.2:
+    resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [netbsd]
     requiresBuild: true
     optional: true
 
-  /@esbuild/openbsd-x64@0.19.12:
-    resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==}
+  /@esbuild/openbsd-x64@0.20.2:
+    resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [openbsd]
     requiresBuild: true
     optional: true
 
-  /@esbuild/sunos-x64@0.19.12:
-    resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==}
+  /@esbuild/sunos-x64@0.20.2:
+    resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [sunos]
     requiresBuild: true
     optional: true
 
-  /@esbuild/win32-arm64@0.19.12:
-    resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==}
+  /@esbuild/win32-arm64@0.20.2:
+    resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [win32]
     requiresBuild: true
     optional: true
 
-  /@esbuild/win32-ia32@0.19.12:
-    resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==}
+  /@esbuild/win32-ia32@0.20.2:
+    resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==}
     engines: {node: '>=12'}
     cpu: [ia32]
     os: [win32]
     requiresBuild: true
     optional: true
 
-  /@esbuild/win32-x64@0.19.12:
-    resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==}
+  /@esbuild/win32-x64@0.20.2:
+    resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [win32]
@@ -3115,8 +1974,8 @@ packages:
       react-dom: 18.2.0(react@18.2.0)
     dev: false
 
-  /@floating-ui/react@0.26.9(react-dom@18.2.0)(react@18.2.0):
-    resolution: {integrity: sha512-p86wynZJVEkEq2BBjY/8p2g3biQ6TlgT4o/3KgFKyTWoJLU1GZ8wpctwRqtkEl2tseYA+kw7dBAIDFcednfI5w==}
+  /@floating-ui/react@0.26.10(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-sh6f9gVvWQdEzLObrWbJ97c0clJObiALsFe0LiR/kb3tDRKwEhObASEH2QyfdoO/ZBPzwxa9j+nYFo+sqgbioA==}
     peerDependencies:
       react: '>=16.8.0'
       react-dom: '>=16.8.0'
@@ -3185,7 +2044,7 @@ packages:
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
       '@jest/types': 27.5.1
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       chalk: 4.1.2
       jest-message-util: 27.5.1
       jest-util: 27.5.1
@@ -3197,7 +2056,7 @@ packages:
     engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
     dependencies:
       '@jest/types': 28.1.3
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       chalk: 4.1.2
       jest-message-util: 28.1.3
       jest-util: 28.1.3
@@ -3218,7 +2077,7 @@ packages:
       '@jest/test-result': 27.5.1
       '@jest/transform': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       ansi-escapes: 4.3.2
       chalk: 4.1.2
       emittery: 0.8.1
@@ -3255,7 +2114,7 @@ packages:
     dependencies:
       '@jest/fake-timers': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       jest-mock: 27.5.1
     dev: false
 
@@ -3265,7 +2124,7 @@ packages:
     dependencies:
       '@jest/types': 27.5.1
       '@sinonjs/fake-timers': 8.1.0
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       jest-message-util: 27.5.1
       jest-mock: 27.5.1
       jest-util: 27.5.1
@@ -3294,7 +2153,7 @@ packages:
       '@jest/test-result': 27.5.1
       '@jest/transform': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       chalk: 4.1.2
       collect-v8-coverage: 1.0.2
       exit: 0.1.2
@@ -3370,7 +2229,7 @@ packages:
     resolution: {integrity: sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==}
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@jest/types': 27.5.1
       babel-plugin-istanbul: 6.1.1
       chalk: 4.1.2
@@ -3395,7 +2254,7 @@ packages:
     dependencies:
       '@types/istanbul-lib-coverage': 2.0.6
       '@types/istanbul-reports': 3.0.4
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       '@types/yargs': 16.0.9
       chalk: 4.1.2
     dev: false
@@ -3407,7 +2266,7 @@ packages:
       '@jest/schemas': 28.1.3
       '@types/istanbul-lib-coverage': 2.0.6
       '@types/istanbul-reports': 3.0.4
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       '@types/yargs': 17.0.32
       chalk: 4.1.2
     dev: false
@@ -3443,48 +2302,48 @@ packages:
       '@jridgewell/resolve-uri': 3.1.2
       '@jridgewell/sourcemap-codec': 1.4.15
 
-  /@leichtgewicht/ip-codec@2.0.4:
-    resolution: {integrity: sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==}
+  /@leichtgewicht/ip-codec@2.0.5:
+    resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==}
     dev: false
 
-  /@mantine/carousel@7.6.2(@mantine/core@7.6.2)(@mantine/hooks@7.6.2)(embla-carousel-react@7.1.0)(react-dom@18.2.0)(react@18.2.0):
-    resolution: {integrity: sha512-Iy0ffVyJz+5zNhiNhVALhXne0reQ/PhF7BFmyLDj/LKBrJG9aPNDiYZehOUeBOuXHsdhX5yIb/kuEKxd+3fMlA==}
+  /@mantine/carousel@7.7.1(@mantine/core@7.7.1)(@mantine/hooks@7.7.1)(embla-carousel-react@7.1.0)(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-q26molnpYv4dQcQhxOqCZFPBERacWd2IUcWzl5WLdAb5XbfFJuHK8ivELrdYxPVsYKYBt734o+v7VGJZzh09gg==}
     peerDependencies:
-      '@mantine/core': 7.6.2
-      '@mantine/hooks': 7.6.2
+      '@mantine/core': 7.7.1
+      '@mantine/hooks': 7.7.1
       embla-carousel-react: '>=7.0.0'
       react: ^18.2.0
       react-dom: ^18.2.0
     dependencies:
-      '@mantine/core': 7.6.2(@mantine/hooks@7.6.2)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0)
-      '@mantine/hooks': 7.6.2(react@18.2.0)
+      '@mantine/core': 7.7.1(@mantine/hooks@7.7.1)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+      '@mantine/hooks': 7.7.1(react@18.2.0)
       embla-carousel-react: 7.1.0(react@18.2.0)
       react: 18.2.0
       react-dom: 18.2.0(react@18.2.0)
     dev: false
 
-  /@mantine/core@7.6.2(@mantine/hooks@7.6.2)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0):
-    resolution: {integrity: sha512-qmZhmQVc7ZZ8EKKhPkGuZbfBnLXR0xE45ikxfx+1E6/8hLY5Ypr4nWqh5Pk6p3b+K71yYnBqlbNXbtHLQH0h3g==}
+  /@mantine/core@7.7.1(@mantine/hooks@7.7.1)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-SdPzjvqvEK7uHFuVD3a8w3OZyQVoCwIXLSUfOtRNouDMQgsq6Ac7QjKXBBOk3wNweOWFVOU1vATLHobSmow0lQ==}
     peerDependencies:
-      '@mantine/hooks': 7.6.2
+      '@mantine/hooks': 7.7.1
       react: ^18.2.0
       react-dom: ^18.2.0
     dependencies:
-      '@floating-ui/react': 0.26.9(react-dom@18.2.0)(react@18.2.0)
-      '@mantine/hooks': 7.6.2(react@18.2.0)
+      '@floating-ui/react': 0.26.10(react-dom@18.2.0)(react@18.2.0)
+      '@mantine/hooks': 7.7.1(react@18.2.0)
       clsx: 2.1.0
       react: 18.2.0
       react-dom: 18.2.0(react@18.2.0)
-      react-number-format: 5.3.3(react-dom@18.2.0)(react@18.2.0)
-      react-remove-scroll: 2.5.7(@types/react@18.2.66)(react@18.2.0)
-      react-textarea-autosize: 8.5.3(@types/react@18.2.66)(react@18.2.0)
-      type-fest: 4.12.0
+      react-number-format: 5.3.4(react-dom@18.2.0)(react@18.2.0)
+      react-remove-scroll: 2.5.9(@types/react@18.2.73)(react@18.2.0)
+      react-textarea-autosize: 8.5.3(@types/react@18.2.73)(react@18.2.0)
+      type-fest: 4.14.0
     transitivePeerDependencies:
       - '@types/react'
     dev: false
 
-  /@mantine/form@7.6.2(react@18.2.0):
-    resolution: {integrity: sha512-a5jHPdU3UXvqeAsAvv+OBrwAy/dxiAxCsMlyRrc9JyKCMLEkQ5cQ6FAiHx5vkGG49hy+VgFWLLt8+kWlgqphsQ==}
+  /@mantine/form@7.7.1(react@18.2.0):
+    resolution: {integrity: sha512-NRbVdHsbs634dZIq6IQhqL0uCtF4nYK3OPuPhkBzQ3faqri7TZvYgVQU4KGFTMqPl0UdwC6TkrnnqTZBK6HJMw==}
     peerDependencies:
       react: ^18.2.0
     dependencies:
@@ -3493,32 +2352,32 @@ packages:
       react: 18.2.0
     dev: false
 
-  /@mantine/hooks@7.6.2(react@18.2.0):
-    resolution: {integrity: sha512-ZrOgrZHoIGCDKrr2/9njDgK0al+jjusYQFlmR0YyEFyRtgY6eNSI4zuYLcAPx1haHmUm5RsLBrqY6Iy/TLdGXA==}
+  /@mantine/hooks@7.7.1(react@18.2.0):
+    resolution: {integrity: sha512-3YH2FzKMlg840tb04PBDcDXyBCi9puFOxEBVgc6Y/pN6KFqfOoAnQE/YvgOtwSNXZlbTWyDlQoYj+3je7pA7og==}
     peerDependencies:
       react: ^18.2.0
     dependencies:
       react: 18.2.0
     dev: false
 
-  /@mantine/notifications@7.6.2(@mantine/core@7.6.2)(@mantine/hooks@7.6.2)(react-dom@18.2.0)(react@18.2.0):
-    resolution: {integrity: sha512-vLs6Y5nnxHipGkA5TSsxgjeus0N9uS+0+E9KZ5OG5QEtz7BdOsKPtNmytsQzBN8P8fjttFImhhoSUOLpYv0xtA==}
+  /@mantine/notifications@7.7.1(@mantine/core@7.7.1)(@mantine/hooks@7.7.1)(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-UGs3r4CU2hy1Vt0TVtdorDufpI7LWCd4P7qZP0US+mXVeeZqHkNTCiwRTwlledhfaIdqERmmQn9OD2lJu8Wblg==}
     peerDependencies:
-      '@mantine/core': 7.6.2
-      '@mantine/hooks': 7.6.2
+      '@mantine/core': 7.7.1
+      '@mantine/hooks': 7.7.1
       react: ^18.2.0
       react-dom: ^18.2.0
     dependencies:
-      '@mantine/core': 7.6.2(@mantine/hooks@7.6.2)(@types/react@18.2.66)(react-dom@18.2.0)(react@18.2.0)
-      '@mantine/hooks': 7.6.2(react@18.2.0)
-      '@mantine/store': 7.6.2(react@18.2.0)
+      '@mantine/core': 7.7.1(@mantine/hooks@7.7.1)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+      '@mantine/hooks': 7.7.1(react@18.2.0)
+      '@mantine/store': 7.7.1(react@18.2.0)
       react: 18.2.0
       react-dom: 18.2.0(react@18.2.0)
       react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0)
     dev: false
 
-  /@mantine/store@7.6.2(react@18.2.0):
-    resolution: {integrity: sha512-IEGbyIs7LIXYQtjR87GQPiw12klgsiKiqplGu9LekJb8uW/7XSRNs31ggqKmdF+cMWO/WyQhEXZdpWNib6tVOw==}
+  /@mantine/store@7.7.1(react@18.2.0):
+    resolution: {integrity: sha512-dmuCOLCFlVHYhZARFsi5YckFQR2Vr4giOgs0X1hczqCVUnRDRIgRusAO5GjUhQrtNxfN0EWwFywjLdcrLkA6Lg==}
     peerDependencies:
       react: ^18.2.0
     dependencies:
@@ -3608,7 +2467,7 @@ packages:
     dev: false
     optional: true
 
-  /@pmmmwh/react-refresh-webpack-plugin@0.5.11(react-refresh@0.11.0)(webpack-dev-server@4.15.1)(webpack@5.90.3):
+  /@pmmmwh/react-refresh-webpack-plugin@0.5.11(react-refresh@0.11.0)(webpack-dev-server@4.15.2)(webpack@5.91.0):
     resolution: {integrity: sha512-7j/6vdTym0+qZ6u4XbSAxrWBGYSdCfTzySkj7WAFgDLmSyWlOrWvpyzxlFh5jtw9dn0oL/jtW+06XfFiisN3JQ==}
     engines: {node: '>= 10.13'}
     peerDependencies:
@@ -3636,7 +2495,7 @@ packages:
     dependencies:
       ansi-html-community: 0.0.8
       common-path-prefix: 3.0.0
-      core-js-pure: 3.36.0
+      core-js-pure: 3.36.1
       error-stack-parser: 2.1.4
       find-up: 5.0.0
       html-entities: 2.5.2
@@ -3644,8 +2503,8 @@ packages:
       react-refresh: 0.11.0
       schema-utils: 3.3.0
       source-map: 0.7.4
-      webpack: 5.90.3
-      webpack-dev-server: 4.15.1(webpack@5.90.3)
+      webpack: 5.91.0
+      webpack-dev-server: 4.15.2(webpack@5.91.0)
     dev: false
 
   /@remix-run/router@1.15.3:
@@ -3653,23 +2512,6 @@ packages:
     engines: {node: '>=14.0.0'}
     dev: false
 
-  /@rollup/plugin-babel@5.3.1(@babel/core@7.24.0)(rollup@2.79.1):
-    resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
-    engines: {node: '>= 10.0.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-      '@types/babel__core': ^7.1.9
-      rollup: ^1.20.0||^2.0.0
-    peerDependenciesMeta:
-      '@types/babel__core':
-        optional: true
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-module-imports': 7.22.15
-      '@rollup/pluginutils': 3.1.0(rollup@2.79.1)
-      rollup: 2.79.1
-    dev: false
-
   /@rollup/plugin-babel@5.3.1(@babel/core@7.24.3)(rollup@2.79.1):
     resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
     engines: {node: '>= 10.0.0'}
@@ -3682,10 +2524,9 @@ packages:
         optional: true
     dependencies:
       '@babel/core': 7.24.3
-      '@babel/helper-module-imports': 7.22.15
+      '@babel/helper-module-imports': 7.24.3
       '@rollup/pluginutils': 3.1.0(rollup@2.79.1)
       rollup: 2.79.1
-    dev: true
 
   /@rollup/plugin-node-resolve@11.2.1(rollup@2.79.1):
     resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==}
@@ -3721,99 +2562,113 @@ packages:
       picomatch: 2.3.1
       rollup: 2.79.1
 
-  /@rollup/rollup-android-arm-eabi@4.13.0:
-    resolution: {integrity: sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==}
+  /@rollup/rollup-android-arm-eabi@4.13.2:
+    resolution: {integrity: sha512-3XFIDKWMFZrMnao1mJhnOT1h2g0169Os848NhhmGweEcfJ4rCi+3yMCOLG4zA61rbJdkcrM/DjVZm9Hg5p5w7g==}
     cpu: [arm]
     os: [android]
     requiresBuild: true
     optional: true
 
-  /@rollup/rollup-android-arm64@4.13.0:
-    resolution: {integrity: sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==}
+  /@rollup/rollup-android-arm64@4.13.2:
+    resolution: {integrity: sha512-GdxxXbAuM7Y/YQM9/TwwP+L0omeE/lJAR1J+olu36c3LqqZEBdsIWeQ91KBe6nxwOnb06Xh7JS2U5ooWU5/LgQ==}
     cpu: [arm64]
     os: [android]
     requiresBuild: true
     optional: true
 
-  /@rollup/rollup-darwin-arm64@4.13.0:
-    resolution: {integrity: sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==}
+  /@rollup/rollup-darwin-arm64@4.13.2:
+    resolution: {integrity: sha512-mCMlpzlBgOTdaFs83I4XRr8wNPveJiJX1RLfv4hggyIVhfB5mJfN4P8Z6yKh+oE4Luz+qq1P3kVdWrCKcMYrrA==}
     cpu: [arm64]
     os: [darwin]
     requiresBuild: true
     optional: true
 
-  /@rollup/rollup-darwin-x64@4.13.0:
-    resolution: {integrity: sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==}
+  /@rollup/rollup-darwin-x64@4.13.2:
+    resolution: {integrity: sha512-yUoEvnH0FBef/NbB1u6d3HNGyruAKnN74LrPAfDQL3O32e3k3OSfLrPgSJmgb3PJrBZWfPyt6m4ZhAFa2nZp2A==}
     cpu: [x64]
     os: [darwin]
     requiresBuild: true
     optional: true
 
-  /@rollup/rollup-linux-arm-gnueabihf@4.13.0:
-    resolution: {integrity: sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==}
+  /@rollup/rollup-linux-arm-gnueabihf@4.13.2:
+    resolution: {integrity: sha512-GYbLs5ErswU/Xs7aGXqzc3RrdEjKdmoCrgzhJWyFL0r5fL3qd1NPcDKDowDnmcoSiGJeU68/Vy+OMUluRxPiLQ==}
     cpu: [arm]
     os: [linux]
     requiresBuild: true
     optional: true
 
-  /@rollup/rollup-linux-arm64-gnu@4.13.0:
-    resolution: {integrity: sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==}
+  /@rollup/rollup-linux-arm64-gnu@4.13.2:
+    resolution: {integrity: sha512-L1+D8/wqGnKQIlh4Zre9i4R4b4noxzH5DDciyahX4oOz62CphY7WDWqJoQ66zNR4oScLNOqQJfNSIAe/6TPUmQ==}
     cpu: [arm64]
     os: [linux]
     requiresBuild: true
     optional: true
 
-  /@rollup/rollup-linux-arm64-musl@4.13.0:
-    resolution: {integrity: sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==}
+  /@rollup/rollup-linux-arm64-musl@4.13.2:
+    resolution: {integrity: sha512-tK5eoKFkXdz6vjfkSTCupUzCo40xueTOiOO6PeEIadlNBkadH1wNOH8ILCPIl8by/Gmb5AGAeQOFeLev7iZDOA==}
     cpu: [arm64]
     os: [linux]
     requiresBuild: true
     optional: true
 
-  /@rollup/rollup-linux-riscv64-gnu@4.13.0:
-    resolution: {integrity: sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==}
+  /@rollup/rollup-linux-powerpc64le-gnu@4.13.2:
+    resolution: {integrity: sha512-zvXvAUGGEYi6tYhcDmb9wlOckVbuD+7z3mzInCSTACJ4DQrdSLPNUeDIcAQW39M3q6PDquqLWu7pnO39uSMRzQ==}
+    cpu: [ppc64le]
+    os: [linux]
+    requiresBuild: true
+    optional: true
+
+  /@rollup/rollup-linux-riscv64-gnu@4.13.2:
+    resolution: {integrity: sha512-C3GSKvMtdudHCN5HdmAMSRYR2kkhgdOfye4w0xzyii7lebVr4riCgmM6lRiSCnJn2w1Xz7ZZzHKuLrjx5620kw==}
     cpu: [riscv64]
     os: [linux]
     requiresBuild: true
     optional: true
 
-  /@rollup/rollup-linux-x64-gnu@4.13.0:
-    resolution: {integrity: sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==}
+  /@rollup/rollup-linux-s390x-gnu@4.13.2:
+    resolution: {integrity: sha512-l4U0KDFwzD36j7HdfJ5/TveEQ1fUTjFFQP5qIt9gBqBgu1G8/kCaq5Ok05kd5TG9F8Lltf3MoYsUMw3rNlJ0Yg==}
+    cpu: [s390x]
+    os: [linux]
+    requiresBuild: true
+    optional: true
+
+  /@rollup/rollup-linux-x64-gnu@4.13.2:
+    resolution: {integrity: sha512-xXMLUAMzrtsvh3cZ448vbXqlUa7ZL8z0MwHp63K2IIID2+DeP5iWIT6g1SN7hg1VxPzqx0xZdiDM9l4n9LRU1A==}
     cpu: [x64]
     os: [linux]
     requiresBuild: true
     optional: true
 
-  /@rollup/rollup-linux-x64-musl@4.13.0:
-    resolution: {integrity: sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==}
+  /@rollup/rollup-linux-x64-musl@4.13.2:
+    resolution: {integrity: sha512-M/JYAWickafUijWPai4ehrjzVPKRCyDb1SLuO+ZyPfoXgeCEAlgPkNXewFZx0zcnoIe3ay4UjXIMdXQXOZXWqA==}
     cpu: [x64]
     os: [linux]
     requiresBuild: true
     optional: true
 
-  /@rollup/rollup-win32-arm64-msvc@4.13.0:
-    resolution: {integrity: sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==}
+  /@rollup/rollup-win32-arm64-msvc@4.13.2:
+    resolution: {integrity: sha512-2YWwoVg9KRkIKaXSh0mz3NmfurpmYoBBTAXA9qt7VXk0Xy12PoOP40EFuau+ajgALbbhi4uTj3tSG3tVseCjuA==}
     cpu: [arm64]
     os: [win32]
     requiresBuild: true
     optional: true
 
-  /@rollup/rollup-win32-ia32-msvc@4.13.0:
-    resolution: {integrity: sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==}
+  /@rollup/rollup-win32-ia32-msvc@4.13.2:
+    resolution: {integrity: sha512-2FSsE9aQ6OWD20E498NYKEQLneShWes0NGMPQwxWOdws35qQXH+FplabOSP5zEe1pVjurSDOGEVCE2agFwSEsw==}
     cpu: [ia32]
     os: [win32]
     requiresBuild: true
     optional: true
 
-  /@rollup/rollup-win32-x64-msvc@4.13.0:
-    resolution: {integrity: sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==}
+  /@rollup/rollup-win32-x64-msvc@4.13.2:
+    resolution: {integrity: sha512-7h7J2nokcdPePdKykd8wtc8QqqkqxIrUz7MHj6aNr8waBRU//NLDVnNjQnqQO6fqtjrtCdftpbTuOKAyrAQETQ==}
     cpu: [x64]
     os: [win32]
     requiresBuild: true
     optional: true
 
-  /@rushstack/eslint-patch@1.7.2:
-    resolution: {integrity: sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA==}
+  /@rushstack/eslint-patch@1.10.1:
+    resolution: {integrity: sha512-S3Kq8e7LqxkA9s7HKLqXGTGck1uwis5vAXan3FnU5yw1Ec5hsSGnq4s/UCaSqABPOnOTg7zASLyst7+ohgWexg==}
     dev: false
 
   /@sinclair/typebox@0.24.51:
@@ -3838,7 +2693,7 @@ packages:
       ejs: 3.1.9
       json5: 2.2.3
       magic-string: 0.25.9
-      string.prototype.matchall: 4.0.10
+      string.prototype.matchall: 4.0.11
 
   /@svgr/babel-plugin-add-jsx-attribute@5.4.0:
     resolution: {integrity: sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==}
@@ -3916,7 +2771,7 @@ packages:
     resolution: {integrity: sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==}
     engines: {node: '>=10'}
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@svgr/babel-preset': 5.5.0
       '@svgr/hast-util-to-babel-ast': 5.5.0
       svg-parser: 2.0.4
@@ -3937,10 +2792,10 @@ packages:
     resolution: {integrity: sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==}
     engines: {node: '>=10'}
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/plugin-transform-react-constant-elements': 7.23.3(@babel/core@7.24.0)
-      '@babel/preset-env': 7.24.0(@babel/core@7.24.0)
-      '@babel/preset-react': 7.23.3(@babel/core@7.24.0)
+      '@babel/core': 7.24.3
+      '@babel/plugin-transform-react-constant-elements': 7.24.1(@babel/core@7.24.3)
+      '@babel/preset-env': 7.24.3(@babel/core@7.24.3)
+      '@babel/preset-react': 7.24.1(@babel/core@7.24.3)
       '@svgr/core': 5.5.0
       '@svgr/plugin-jsx': 5.5.0
       '@svgr/plugin-svgo': 5.5.0
@@ -3962,31 +2817,31 @@ packages:
     resolution: {integrity: sha512-CpZGyS1IVJKFcv88yZ2sYZIpWWhQ6oy76BQKQ5SF0fGgOqgyqKdBGG/YGyyMW632on37MX7VqQIMTzN/uQqmFg==}
     dev: false
 
-  /@tanstack/query-core@5.28.4:
-    resolution: {integrity: sha512-uQZqOFqLWUvXNIQZ63XdKzg22NtHzgCBUfDmjDHi3BoF+nUYeBNvMi/xFPtFrMhqRzG2Ir4mYaGsWZzmiEjXpA==}
+  /@tanstack/query-core@5.28.9:
+    resolution: {integrity: sha512-hNlfCiqZevr3GRVPXS3MhaGW5hjcxvCsIQ4q6ff7EPlvFwYZaS+0d9EIIgofnegDaU2BbCDlyURoYfRl5rmzow==}
     dev: false
 
-  /@tanstack/query-devtools@5.28.3:
-    resolution: {integrity: sha512-Kxch05PVnxLUAyRiz2gXYQhXATHfXbQQwvz858YPjYYQyi7yk8SyS9Z5hyw90bRb0pd3rjelXyGFCsNMWvEghw==}
+  /@tanstack/query-devtools@5.28.10:
+    resolution: {integrity: sha512-5UN629fKa5/1K/2Pd26gaU7epxRrYiT1gy+V+pW5K6hnf1DeUKK3pANSb2eHKlecjIKIhTwyF7k9XdyE2gREvQ==}
     dev: false
 
-  /@tanstack/react-query-devtools@5.28.4(@tanstack/react-query@5.28.4)(react@18.2.0):
-    resolution: {integrity: sha512-oS+3INjCIX4Nkh0IAV6LH2mgLqJjkcd/DDxp8dwdWCGloLrz6IBj+bOuuI2wD0zb8r7l45wIAYIhl4Z6XyTupQ==}
+  /@tanstack/react-query-devtools@5.28.10(@tanstack/react-query@5.28.9)(react@18.2.0):
+    resolution: {integrity: sha512-D+SiHZTWhK2sNgBYj+xIvUOqonsKy74OLU/YHmRB5OZVLLTiekvZd12C3rKlU+WM69jid0hjEjuFqkULOMwc3A==}
     peerDependencies:
-      '@tanstack/react-query': ^5.28.4
+      '@tanstack/react-query': ^5.28.9
       react: ^18.0.0
     dependencies:
-      '@tanstack/query-devtools': 5.28.3
-      '@tanstack/react-query': 5.28.4(react@18.2.0)
+      '@tanstack/query-devtools': 5.28.10
+      '@tanstack/react-query': 5.28.9(react@18.2.0)
       react: 18.2.0
     dev: false
 
-  /@tanstack/react-query@5.28.4(react@18.2.0):
-    resolution: {integrity: sha512-BErcoB/QQG6YwLSUKnaGxF+lSc270RH2w3kMBpG0i4YzDCsFs2pdxPX1WVknQvFk9bNgukMb158hc2Zb4SdwSA==}
+  /@tanstack/react-query@5.28.9(react@18.2.0):
+    resolution: {integrity: sha512-vwifBkGXsydsLxFOBMe3+f8kvtDoqDRDwUNjPHVDDt+FoBetCbOWAUHgZn4k+CVeZgLmy7bx6aKeDbe3e8koOQ==}
     peerDependencies:
       react: ^18.0.0
     dependencies:
-      '@tanstack/query-core': 5.28.4
+      '@tanstack/query-core': 5.28.9
       react: 18.2.0
     dev: false
 
@@ -4003,7 +2858,7 @@ packages:
   /@types/babel__core@7.20.5:
     resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
     dependencies:
-      '@babel/parser': 7.24.0
+      '@babel/parser': 7.24.1
       '@babel/types': 7.24.0
       '@types/babel__generator': 7.6.8
       '@types/babel__template': 7.4.4
@@ -4019,7 +2874,7 @@ packages:
   /@types/babel__template@7.4.4:
     resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
     dependencies:
-      '@babel/parser': 7.24.0
+      '@babel/parser': 7.24.1
       '@babel/types': 7.24.0
     dev: false
 
@@ -4033,37 +2888,37 @@ packages:
     resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==}
     dependencies:
       '@types/connect': 3.4.38
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
     dev: false
 
   /@types/bonjour@3.5.13:
     resolution: {integrity: sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==}
     dependencies:
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
     dev: false
 
   /@types/connect-history-api-fallback@1.5.4:
     resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==}
     dependencies:
       '@types/express-serve-static-core': 4.17.43
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
     dev: false
 
   /@types/connect@3.4.38:
     resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==}
     dependencies:
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
     dev: false
 
   /@types/eslint-scope@3.7.7:
     resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==}
     dependencies:
-      '@types/eslint': 8.56.5
+      '@types/eslint': 8.56.6
       '@types/estree': 1.0.5
     dev: false
 
-  /@types/eslint@8.56.5:
-    resolution: {integrity: sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==}
+  /@types/eslint@8.56.6:
+    resolution: {integrity: sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==}
     dependencies:
       '@types/estree': 1.0.5
       '@types/json-schema': 7.0.15
@@ -4078,8 +2933,8 @@ packages:
   /@types/express-serve-static-core@4.17.43:
     resolution: {integrity: sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==}
     dependencies:
-      '@types/node': 20.11.28
-      '@types/qs': 6.9.12
+      '@types/node': 20.12.2
+      '@types/qs': 6.9.14
       '@types/range-parser': 1.2.7
       '@types/send': 0.17.4
     dev: false
@@ -4089,7 +2944,7 @@ packages:
     dependencies:
       '@types/body-parser': 1.19.5
       '@types/express-serve-static-core': 4.17.43
-      '@types/qs': 6.9.12
+      '@types/qs': 6.9.14
       '@types/serve-static': 1.15.5
     dev: false
 
@@ -4100,7 +2955,7 @@ packages:
   /@types/graceful-fs@4.1.9:
     resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==}
     dependencies:
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
     dev: false
 
   /@types/html-minifier-terser@6.1.0:
@@ -4114,7 +2969,7 @@ packages:
   /@types/http-proxy@1.17.14:
     resolution: {integrity: sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==}
     dependencies:
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
     dev: false
 
   /@types/istanbul-lib-coverage@2.0.6:
@@ -4155,18 +3010,21 @@ packages:
     resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==}
     dev: false
 
-  /@types/mime@3.0.4:
-    resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==}
+  /@types/mime@4.0.0:
+    resolution: {integrity: sha512-5eEkJZ/BLvTE3vXGKkWlyTSUVZuzj23Wj8PoyOq2lt5I3CYbiLBOPb3XmCW6QcuOibIUE6emHXHt9E/F/rCa6w==}
+    deprecated: This is a stub types definition. mime provides its own type definitions, so you do not need this installed.
+    dependencies:
+      mime: 4.0.1
     dev: false
 
   /@types/node-forge@1.3.11:
     resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==}
     dependencies:
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
     dev: false
 
-  /@types/node@20.11.28:
-    resolution: {integrity: sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==}
+  /@types/node@20.12.2:
+    resolution: {integrity: sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ==}
     dependencies:
       undici-types: 5.26.5
 
@@ -4178,49 +3036,44 @@ packages:
     resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==}
     dev: false
 
-  /@types/prop-types@15.7.11:
-    resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==}
+  /@types/prop-types@15.7.12:
+    resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==}
     dev: false
 
   /@types/q@1.5.8:
     resolution: {integrity: sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==}
     dev: false
 
-  /@types/qs@6.9.12:
-    resolution: {integrity: sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg==}
+  /@types/qs@6.9.14:
+    resolution: {integrity: sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==}
     dev: false
 
   /@types/range-parser@1.2.7:
     resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
     dev: false
 
-  /@types/react-dom@18.2.22:
-    resolution: {integrity: sha512-fHkBXPeNtfvri6gdsMYyW+dW7RXFo6Ad09nLFK0VQWR7yGLai/Cyvyj696gbwYvBnhGtevUG9cET0pmUbMtoPQ==}
+  /@types/react-dom@18.2.23:
+    resolution: {integrity: sha512-ZQ71wgGOTmDYpnav2knkjr3qXdAFu0vsk8Ci5w3pGAIdj7/kKAyn+VsQDhXsmzzzepAiI9leWMmubXz690AI/A==}
     dependencies:
-      '@types/react': 18.2.66
+      '@types/react': 18.2.73
     dev: false
 
-  /@types/react@18.2.66:
-    resolution: {integrity: sha512-OYTmMI4UigXeFMF/j4uv0lBBEbongSgptPrHBxqME44h9+yNov+oL6Z3ocJKo0WyXR84sQUNeyIp9MRfckvZpg==}
+  /@types/react@18.2.73:
+    resolution: {integrity: sha512-XcGdod0Jjv84HOC7N5ziY3x+qL0AfmubvKOZ9hJjJ2yd5EE+KYjWhdOjt387e9HPheHkdggF9atTifMRtyAaRA==}
     dependencies:
-      '@types/prop-types': 15.7.11
-      '@types/scheduler': 0.16.8
+      '@types/prop-types': 15.7.12
       csstype: 3.1.3
     dev: false
 
   /@types/resolve@1.17.1:
     resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
     dependencies:
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
 
   /@types/retry@0.12.0:
     resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==}
     dev: false
 
-  /@types/scheduler@0.16.8:
-    resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==}
-    dev: false
-
   /@types/semver@7.5.8:
     resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
     dev: false
@@ -4229,7 +3082,7 @@ packages:
     resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==}
     dependencies:
       '@types/mime': 1.3.5
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
     dev: false
 
   /@types/serve-index@1.9.4:
@@ -4242,14 +3095,14 @@ packages:
     resolution: {integrity: sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==}
     dependencies:
       '@types/http-errors': 2.0.4
-      '@types/mime': 3.0.4
-      '@types/node': 20.11.28
+      '@types/mime': 4.0.0
+      '@types/node': 20.12.2
     dev: false
 
   /@types/sockjs@0.3.36:
     resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==}
     dependencies:
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
     dev: false
 
   /@types/stack-utils@2.0.3:
@@ -4266,7 +3119,7 @@ packages:
   /@types/ws@8.5.10:
     resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==}
     dependencies:
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
     dev: false
 
   /@types/yargs-parser@21.0.3:
@@ -4285,7 +3138,7 @@ packages:
       '@types/yargs-parser': 21.0.3
     dev: false
 
-  /@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)(typescript@5.4.2):
+  /@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)(typescript@5.4.3):
     resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
@@ -4297,25 +3150,25 @@ packages:
         optional: true
     dependencies:
       '@eslint-community/regexpp': 4.10.0
-      '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.4.2)
+      '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.4.3)
       '@typescript-eslint/scope-manager': 5.62.0
-      '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.0)(typescript@5.4.2)
-      '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.4.2)
+      '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.0)(typescript@5.4.3)
+      '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.4.3)
       debug: 4.3.4
       eslint: 8.57.0
       graphemer: 1.4.0
       ignore: 5.3.1
       natural-compare-lite: 1.4.0
       semver: 7.6.0
-      tsutils: 3.21.0(typescript@5.4.2)
-      typescript: 5.4.2
+      tsutils: 3.21.0(typescript@5.4.3)
+      typescript: 5.4.3
     transitivePeerDependencies:
       - supports-color
     dev: false
 
-  /@typescript-eslint/eslint-plugin@7.2.0(@typescript-eslint/parser@7.2.0)(eslint@8.57.0)(typescript@5.4.2):
-    resolution: {integrity: sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==}
-    engines: {node: ^16.0.0 || >=18.0.0}
+  /@typescript-eslint/eslint-plugin@7.4.0(@typescript-eslint/parser@7.4.0)(eslint@8.57.0)(typescript@5.4.3):
+    resolution: {integrity: sha512-yHMQ/oFaM7HZdVrVm/M2WHaNPgyuJH4WelkSVEWSSsir34kxW2kDJCxlXRhhGWEsMN0WAW/vLpKfKVcm8k+MPw==}
+    engines: {node: ^18.18.0 || >=20.0.0}
     peerDependencies:
       '@typescript-eslint/parser': ^7.0.0
       eslint: ^8.56.0
@@ -4325,37 +3178,37 @@ packages:
         optional: true
     dependencies:
       '@eslint-community/regexpp': 4.10.0
-      '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.4.2)
-      '@typescript-eslint/scope-manager': 7.2.0
-      '@typescript-eslint/type-utils': 7.2.0(eslint@8.57.0)(typescript@5.4.2)
-      '@typescript-eslint/utils': 7.2.0(eslint@8.57.0)(typescript@5.4.2)
-      '@typescript-eslint/visitor-keys': 7.2.0
+      '@typescript-eslint/parser': 7.4.0(eslint@8.57.0)(typescript@5.4.3)
+      '@typescript-eslint/scope-manager': 7.4.0
+      '@typescript-eslint/type-utils': 7.4.0(eslint@8.57.0)(typescript@5.4.3)
+      '@typescript-eslint/utils': 7.4.0(eslint@8.57.0)(typescript@5.4.3)
+      '@typescript-eslint/visitor-keys': 7.4.0
       debug: 4.3.4
       eslint: 8.57.0
       graphemer: 1.4.0
       ignore: 5.3.1
       natural-compare: 1.4.0
       semver: 7.6.0
-      ts-api-utils: 1.3.0(typescript@5.4.2)
-      typescript: 5.4.2
+      ts-api-utils: 1.3.0(typescript@5.4.3)
+      typescript: 5.4.3
     transitivePeerDependencies:
       - supports-color
     dev: false
 
-  /@typescript-eslint/experimental-utils@5.62.0(eslint@8.57.0)(typescript@5.4.2):
+  /@typescript-eslint/experimental-utils@5.62.0(eslint@8.57.0)(typescript@5.4.3):
     resolution: {integrity: sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
     dependencies:
-      '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.4.2)
+      '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.4.3)
       eslint: 8.57.0
     transitivePeerDependencies:
       - supports-color
       - typescript
     dev: false
 
-  /@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.4.2):
+  /@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.4.3):
     resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
@@ -4367,17 +3220,17 @@ packages:
     dependencies:
       '@typescript-eslint/scope-manager': 5.62.0
       '@typescript-eslint/types': 5.62.0
-      '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.4.2)
+      '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.4.3)
       debug: 4.3.4
       eslint: 8.57.0
-      typescript: 5.4.2
+      typescript: 5.4.3
     transitivePeerDependencies:
       - supports-color
     dev: false
 
-  /@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.2):
-    resolution: {integrity: sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==}
-    engines: {node: ^16.0.0 || >=18.0.0}
+  /@typescript-eslint/parser@7.4.0(eslint@8.57.0)(typescript@5.4.3):
+    resolution: {integrity: sha512-ZvKHxHLusweEUVwrGRXXUVzFgnWhigo4JurEj0dGF1tbcGh6buL+ejDdjxOQxv6ytcY1uhun1p2sm8iWStlgLQ==}
+    engines: {node: ^18.18.0 || >=20.0.0}
     peerDependencies:
       eslint: ^8.56.0
       typescript: '*'
@@ -4385,13 +3238,13 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/scope-manager': 7.2.0
-      '@typescript-eslint/types': 7.2.0
-      '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.2)
-      '@typescript-eslint/visitor-keys': 7.2.0
+      '@typescript-eslint/scope-manager': 7.4.0
+      '@typescript-eslint/types': 7.4.0
+      '@typescript-eslint/typescript-estree': 7.4.0(typescript@5.4.3)
+      '@typescript-eslint/visitor-keys': 7.4.0
       debug: 4.3.4
       eslint: 8.57.0
-      typescript: 5.4.2
+      typescript: 5.4.3
     transitivePeerDependencies:
       - supports-color
     dev: false
@@ -4404,15 +3257,15 @@ packages:
       '@typescript-eslint/visitor-keys': 5.62.0
     dev: false
 
-  /@typescript-eslint/scope-manager@7.2.0:
-    resolution: {integrity: sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==}
-    engines: {node: ^16.0.0 || >=18.0.0}
+  /@typescript-eslint/scope-manager@7.4.0:
+    resolution: {integrity: sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==}
+    engines: {node: ^18.18.0 || >=20.0.0}
     dependencies:
-      '@typescript-eslint/types': 7.2.0
-      '@typescript-eslint/visitor-keys': 7.2.0
+      '@typescript-eslint/types': 7.4.0
+      '@typescript-eslint/visitor-keys': 7.4.0
     dev: false
 
-  /@typescript-eslint/type-utils@5.62.0(eslint@8.57.0)(typescript@5.4.2):
+  /@typescript-eslint/type-utils@5.62.0(eslint@8.57.0)(typescript@5.4.3):
     resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
@@ -4422,19 +3275,19 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.4.2)
-      '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.4.2)
+      '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.4.3)
+      '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.4.3)
       debug: 4.3.4
       eslint: 8.57.0
-      tsutils: 3.21.0(typescript@5.4.2)
-      typescript: 5.4.2
+      tsutils: 3.21.0(typescript@5.4.3)
+      typescript: 5.4.3
     transitivePeerDependencies:
       - supports-color
     dev: false
 
-  /@typescript-eslint/type-utils@7.2.0(eslint@8.57.0)(typescript@5.4.2):
-    resolution: {integrity: sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA==}
-    engines: {node: ^16.0.0 || >=18.0.0}
+  /@typescript-eslint/type-utils@7.4.0(eslint@8.57.0)(typescript@5.4.3):
+    resolution: {integrity: sha512-247ETeHgr9WTRMqHbbQdzwzhuyaJ8dPTuyuUEMANqzMRB1rj/9qFIuIXK7l0FX9i9FXbHeBQl/4uz6mYuCE7Aw==}
+    engines: {node: ^18.18.0 || >=20.0.0}
     peerDependencies:
       eslint: ^8.56.0
       typescript: '*'
@@ -4442,12 +3295,12 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.2)
-      '@typescript-eslint/utils': 7.2.0(eslint@8.57.0)(typescript@5.4.2)
+      '@typescript-eslint/typescript-estree': 7.4.0(typescript@5.4.3)
+      '@typescript-eslint/utils': 7.4.0(eslint@8.57.0)(typescript@5.4.3)
       debug: 4.3.4
       eslint: 8.57.0
-      ts-api-utils: 1.3.0(typescript@5.4.2)
-      typescript: 5.4.2
+      ts-api-utils: 1.3.0(typescript@5.4.3)
+      typescript: 5.4.3
     transitivePeerDependencies:
       - supports-color
     dev: false
@@ -4457,12 +3310,12 @@ packages:
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dev: false
 
-  /@typescript-eslint/types@7.2.0:
-    resolution: {integrity: sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==}
-    engines: {node: ^16.0.0 || >=18.0.0}
+  /@typescript-eslint/types@7.4.0:
+    resolution: {integrity: sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==}
+    engines: {node: ^18.18.0 || >=20.0.0}
     dev: false
 
-  /@typescript-eslint/typescript-estree@5.62.0(typescript@5.4.2):
+  /@typescript-eslint/typescript-estree@5.62.0(typescript@5.4.3):
     resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
@@ -4477,35 +3330,35 @@ packages:
       globby: 11.1.0
       is-glob: 4.0.3
       semver: 7.6.0
-      tsutils: 3.21.0(typescript@5.4.2)
-      typescript: 5.4.2
+      tsutils: 3.21.0(typescript@5.4.3)
+      typescript: 5.4.3
     transitivePeerDependencies:
       - supports-color
     dev: false
 
-  /@typescript-eslint/typescript-estree@7.2.0(typescript@5.4.2):
-    resolution: {integrity: sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==}
-    engines: {node: ^16.0.0 || >=18.0.0}
+  /@typescript-eslint/typescript-estree@7.4.0(typescript@5.4.3):
+    resolution: {integrity: sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==}
+    engines: {node: ^18.18.0 || >=20.0.0}
     peerDependencies:
       typescript: '*'
     peerDependenciesMeta:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/types': 7.2.0
-      '@typescript-eslint/visitor-keys': 7.2.0
+      '@typescript-eslint/types': 7.4.0
+      '@typescript-eslint/visitor-keys': 7.4.0
       debug: 4.3.4
       globby: 11.1.0
       is-glob: 4.0.3
       minimatch: 9.0.3
       semver: 7.6.0
-      ts-api-utils: 1.3.0(typescript@5.4.2)
-      typescript: 5.4.2
+      ts-api-utils: 1.3.0(typescript@5.4.3)
+      typescript: 5.4.3
     transitivePeerDependencies:
       - supports-color
     dev: false
 
-  /@typescript-eslint/utils@5.62.0(eslint@8.57.0)(typescript@5.4.2):
+  /@typescript-eslint/utils@5.62.0(eslint@8.57.0)(typescript@5.4.3):
     resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
@@ -4516,7 +3369,7 @@ packages:
       '@types/semver': 7.5.8
       '@typescript-eslint/scope-manager': 5.62.0
       '@typescript-eslint/types': 5.62.0
-      '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.4.2)
+      '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.4.3)
       eslint: 8.57.0
       eslint-scope: 5.1.1
       semver: 7.6.0
@@ -4525,18 +3378,18 @@ packages:
       - typescript
     dev: false
 
-  /@typescript-eslint/utils@7.2.0(eslint@8.57.0)(typescript@5.4.2):
-    resolution: {integrity: sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==}
-    engines: {node: ^16.0.0 || >=18.0.0}
+  /@typescript-eslint/utils@7.4.0(eslint@8.57.0)(typescript@5.4.3):
+    resolution: {integrity: sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg==}
+    engines: {node: ^18.18.0 || >=20.0.0}
     peerDependencies:
       eslint: ^8.56.0
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
       '@types/json-schema': 7.0.15
       '@types/semver': 7.5.8
-      '@typescript-eslint/scope-manager': 7.2.0
-      '@typescript-eslint/types': 7.2.0
-      '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.2)
+      '@typescript-eslint/scope-manager': 7.4.0
+      '@typescript-eslint/types': 7.4.0
+      '@typescript-eslint/typescript-estree': 7.4.0(typescript@5.4.3)
       eslint: 8.57.0
       semver: 7.6.0
     transitivePeerDependencies:
@@ -4552,11 +3405,11 @@ packages:
       eslint-visitor-keys: 3.4.3
     dev: false
 
-  /@typescript-eslint/visitor-keys@7.2.0:
-    resolution: {integrity: sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==}
-    engines: {node: ^16.0.0 || >=18.0.0}
+  /@typescript-eslint/visitor-keys@7.4.0:
+    resolution: {integrity: sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==}
+    engines: {node: ^18.18.0 || >=20.0.0}
     dependencies:
-      '@typescript-eslint/types': 7.2.0
+      '@typescript-eslint/types': 7.4.0
       eslint-visitor-keys: 3.4.3
     dev: false
 
@@ -4577,27 +3430,27 @@ packages:
       unconfig: 0.3.11
     dev: true
 
-  /@vitejs/plugin-basic-ssl@1.1.0(vite@5.1.6):
+  /@vitejs/plugin-basic-ssl@1.1.0(vite@5.2.7):
     resolution: {integrity: sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==}
     engines: {node: '>=14.6.0'}
     peerDependencies:
       vite: ^3.0.0 || ^4.0.0 || ^5.0.0
     dependencies:
-      vite: 5.1.6(sass@1.72.0)
+      vite: 5.2.7(sass@1.72.0)
     dev: true
 
-  /@vitejs/plugin-react@4.2.1(vite@5.1.6):
+  /@vitejs/plugin-react@4.2.1(vite@5.2.7):
     resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==}
     engines: {node: ^14.18.0 || >=16.0.0}
     peerDependencies:
       vite: ^4.2.0 || ^5.0.0
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.24.0)
+      '@babel/core': 7.24.3
+      '@babel/plugin-transform-react-jsx-self': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.24.3)
       '@types/babel__core': 7.20.5
       react-refresh: 0.14.0
-      vite: 5.1.6(sass@1.72.0)
+      vite: 5.2.7(sass@1.72.0)
     transitivePeerDependencies:
       - supports-color
     dev: false
@@ -4927,13 +3780,14 @@ packages:
     resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==}
     dev: false
 
-  /array-includes@3.1.7:
-    resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==}
+  /array-includes@3.1.8:
+    resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
+      es-object-atoms: 1.0.0
       get-intrinsic: 1.2.4
       is-string: 1.0.7
     dev: false
@@ -4943,36 +3797,27 @@ packages:
     engines: {node: '>=8'}
     dev: false
 
-  /array.prototype.filter@1.0.3:
-    resolution: {integrity: sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==}
-    engines: {node: '>= 0.4'}
-    dependencies:
-      call-bind: 1.0.7
-      define-properties: 1.2.1
-      es-abstract: 1.22.5
-      es-array-method-boxes-properly: 1.0.0
-      is-string: 1.0.7
-    dev: false
-
-  /array.prototype.findlast@1.2.4:
-    resolution: {integrity: sha512-BMtLxpV+8BD+6ZPFIWmnUBpQoy+A+ujcg4rhp2iwCRJYA7PEh2MS4NL3lz8EiDlLrJPp2hg9qWihr5pd//jcGw==}
+  /array.prototype.findlast@1.2.5:
+    resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
       es-errors: 1.3.0
+      es-object-atoms: 1.0.0
       es-shim-unscopables: 1.0.2
     dev: false
 
-  /array.prototype.findlastindex@1.2.4:
-    resolution: {integrity: sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==}
+  /array.prototype.findlastindex@1.2.5:
+    resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
       es-errors: 1.3.0
+      es-object-atoms: 1.0.0
       es-shim-unscopables: 1.0.2
     dev: false
 
@@ -4982,7 +3827,7 @@ packages:
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
       es-shim-unscopables: 1.0.2
     dev: false
 
@@ -4992,18 +3837,20 @@ packages:
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
       es-shim-unscopables: 1.0.2
     dev: false
 
-  /array.prototype.reduce@1.0.6:
-    resolution: {integrity: sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg==}
+  /array.prototype.reduce@1.0.7:
+    resolution: {integrity: sha512-mzmiUCVwtiD4lgxYP8g7IYy8El8p2CSMePvIbTS7gchKir/L1fgJrk0yDKmAX6mnRQFKNADYIk8nNlTris5H1Q==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
       es-array-method-boxes-properly: 1.0.0
+      es-errors: 1.3.0
+      es-object-atoms: 1.0.0
       is-string: 1.0.7
     dev: false
 
@@ -5012,7 +3859,7 @@ packages:
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
       es-shim-unscopables: 1.0.2
     dev: false
 
@@ -5021,7 +3868,7 @@ packages:
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
       es-errors: 1.3.0
       es-shim-unscopables: 1.0.2
     dev: false
@@ -5033,7 +3880,7 @@ packages:
       array-buffer-byte-length: 1.0.1
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
       es-errors: 1.3.0
       get-intrinsic: 1.2.4
       is-array-buffer: 3.0.4
@@ -5063,19 +3910,19 @@ packages:
     resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
     engines: {node: '>= 4.0.0'}
 
-  /autoprefixer@10.4.18(postcss@8.4.35):
-    resolution: {integrity: sha512-1DKbDfsr6KUElM6wg+0zRNkB/Q7WcKYAaK+pzXn+Xqmszm/5Xa9coeNdtP88Vi+dPzZnMjhge8GIV49ZQkDa+g==}
+  /autoprefixer@10.4.19(postcss@8.4.38):
+    resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==}
     engines: {node: ^10 || ^12 || >=14}
     hasBin: true
     peerDependencies:
       postcss: ^8.1.0
     dependencies:
       browserslist: 4.23.0
-      caniuse-lite: 1.0.30001597
+      caniuse-lite: 1.0.30001603
       fraction.js: 4.3.7
       normalize-range: 0.1.2
       picocolors: 1.0.0
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
@@ -5110,18 +3957,18 @@ packages:
     resolution: {integrity: sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==}
     dev: true
 
-  /babel-jest@27.5.1(@babel/core@7.24.0):
+  /babel-jest@27.5.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==}
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     peerDependencies:
       '@babel/core': ^7.8.0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@jest/transform': 27.5.1
       '@jest/types': 27.5.1
       '@types/babel__core': 7.20.5
       babel-plugin-istanbul: 6.1.1
-      babel-preset-jest: 27.5.1(@babel/core@7.24.0)
+      babel-preset-jest: 27.5.1(@babel/core@7.24.3)
       chalk: 4.1.2
       graceful-fs: 4.2.11
       slash: 3.0.0
@@ -5129,19 +3976,19 @@ packages:
       - supports-color
     dev: false
 
-  /babel-loader@8.3.0(@babel/core@7.24.0)(webpack@5.90.3):
+  /babel-loader@8.3.0(@babel/core@7.24.3)(webpack@5.91.0):
     resolution: {integrity: sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==}
     engines: {node: '>= 8.9'}
     peerDependencies:
       '@babel/core': ^7.0.0
       webpack: '>=2'
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       find-cache-dir: 3.3.2
       loader-utils: 2.0.4
       make-dir: 3.1.0
       schema-utils: 2.7.1
-      webpack: 5.90.3
+      webpack: 5.91.0
     dev: false
 
   /babel-plugin-istanbul@6.1.1:
@@ -5171,30 +4018,17 @@ packages:
     resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==}
     engines: {node: '>=10', npm: '>=6'}
     dependencies:
-      '@babel/runtime': 7.24.0
+      '@babel/runtime': 7.24.1
       cosmiconfig: 7.1.0
       resolve: 1.22.8
     dev: false
 
-  /babel-plugin-named-asset-import@0.3.8(@babel/core@7.24.0):
+  /babel-plugin-named-asset-import@0.3.8(@babel/core@7.24.3):
     resolution: {integrity: sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==}
     peerDependencies:
       '@babel/core': ^7.1.0
     dependencies:
-      '@babel/core': 7.24.0
-    dev: false
-
-  /babel-plugin-polyfill-corejs2@0.4.10(@babel/core@7.24.0):
-    resolution: {integrity: sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==}
-    peerDependencies:
-      '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
-    dependencies:
-      '@babel/compat-data': 7.23.5
-      '@babel/core': 7.24.0
-      '@babel/helper-define-polyfill-provider': 0.6.1(@babel/core@7.24.0)
-      semver: 6.3.1
-    transitivePeerDependencies:
-      - supports-color
+      '@babel/core': 7.24.3
     dev: false
 
   /babel-plugin-polyfill-corejs2@0.4.10(@babel/core@7.24.3):
@@ -5202,13 +4036,12 @@ packages:
     peerDependencies:
       '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
     dependencies:
-      '@babel/compat-data': 7.23.5
+      '@babel/compat-data': 7.24.1
       '@babel/core': 7.24.3
       '@babel/helper-define-polyfill-provider': 0.6.1(@babel/core@7.24.3)
       semver: 6.3.1
     transitivePeerDependencies:
       - supports-color
-    dev: true
 
   /babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.24.3):
     resolution: {integrity: sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==}
@@ -5220,30 +4053,6 @@ packages:
       core-js-compat: 3.36.1
     transitivePeerDependencies:
       - supports-color
-    dev: true
-
-  /babel-plugin-polyfill-corejs3@0.9.0(@babel/core@7.24.0):
-    resolution: {integrity: sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==}
-    peerDependencies:
-      '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-define-polyfill-provider': 0.5.0(@babel/core@7.24.0)
-      core-js-compat: 3.36.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: false
-
-  /babel-plugin-polyfill-regenerator@0.5.5(@babel/core@7.24.0):
-    resolution: {integrity: sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==}
-    peerDependencies:
-      '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
-    dependencies:
-      '@babel/core': 7.24.0
-      '@babel/helper-define-polyfill-provider': 0.5.0(@babel/core@7.24.0)
-    transitivePeerDependencies:
-      - supports-color
-    dev: false
 
   /babel-plugin-polyfill-regenerator@0.6.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==}
@@ -5254,61 +4063,60 @@ packages:
       '@babel/helper-define-polyfill-provider': 0.6.1(@babel/core@7.24.3)
     transitivePeerDependencies:
       - supports-color
-    dev: true
 
   /babel-plugin-transform-react-remove-prop-types@0.4.24:
     resolution: {integrity: sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==}
     dev: false
 
-  /babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.0):
+  /babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==}
     peerDependencies:
       '@babel/core': ^7.0.0
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.0)
-      '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.0)
-      '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.0)
-      '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.0)
-      '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.0)
-      '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.0)
-      '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0)
-      '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.0)
-      '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.0)
-      '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.0)
-      '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0)
-      '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.0)
-    dev: false
-
-  /babel-preset-jest@27.5.1(@babel/core@7.24.0):
+      '@babel/core': 7.24.3
+      '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.3)
+      '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.3)
+      '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.3)
+      '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.3)
+      '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.3)
+      '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.3)
+      '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.3)
+      '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.3)
+      '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.3)
+      '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.3)
+      '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.3)
+      '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.3)
+    dev: false
+
+  /babel-preset-jest@27.5.1(@babel/core@7.24.3):
     resolution: {integrity: sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==}
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     peerDependencies:
       '@babel/core': ^7.0.0
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       babel-plugin-jest-hoist: 27.5.1
-      babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.0)
+      babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.3)
     dev: false
 
   /babel-preset-react-app@10.0.1:
     resolution: {integrity: sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==}
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.24.0)
-      '@babel/plugin-proposal-decorators': 7.24.0(@babel/core@7.24.0)
-      '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.24.0)
-      '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.24.0)
-      '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.24.0)
-      '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.24.0)
-      '@babel/plugin-proposal-private-property-in-object': 7.21.11(@babel/core@7.24.0)
-      '@babel/plugin-transform-flow-strip-types': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-react-display-name': 7.23.3(@babel/core@7.24.0)
-      '@babel/plugin-transform-runtime': 7.24.0(@babel/core@7.24.0)
-      '@babel/preset-env': 7.24.0(@babel/core@7.24.0)
-      '@babel/preset-react': 7.23.3(@babel/core@7.24.0)
-      '@babel/preset-typescript': 7.23.3(@babel/core@7.24.0)
-      '@babel/runtime': 7.24.0
+      '@babel/core': 7.24.3
+      '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.24.3)
+      '@babel/plugin-proposal-decorators': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.24.3)
+      '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.24.3)
+      '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.24.3)
+      '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.24.3)
+      '@babel/plugin-proposal-private-property-in-object': 7.21.11(@babel/core@7.24.3)
+      '@babel/plugin-transform-flow-strip-types': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-react-display-name': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-runtime': 7.24.3(@babel/core@7.24.3)
+      '@babel/preset-env': 7.24.3(@babel/core@7.24.3)
+      '@babel/preset-react': 7.24.1(@babel/core@7.24.3)
+      '@babel/preset-typescript': 7.24.1(@babel/core@7.24.3)
+      '@babel/runtime': 7.24.1
       babel-plugin-macros: 3.1.0
       babel-plugin-transform-react-remove-prop-types: 0.4.24
     transitivePeerDependencies:
@@ -5445,8 +4253,8 @@ packages:
     engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
     hasBin: true
     dependencies:
-      caniuse-lite: 1.0.30001597
-      electron-to-chromium: 1.4.708
+      caniuse-lite: 1.0.30001603
+      electron-to-chromium: 1.4.722
       node-releases: 2.0.14
       update-browserslist-db: 1.0.13(browserslist@4.23.0)
 
@@ -5543,13 +4351,13 @@ packages:
     resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==}
     dependencies:
       browserslist: 4.23.0
-      caniuse-lite: 1.0.30001597
+      caniuse-lite: 1.0.30001603
       lodash.memoize: 4.1.2
       lodash.uniq: 4.5.0
     dev: false
 
-  /caniuse-lite@1.0.30001597:
-    resolution: {integrity: sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==}
+  /caniuse-lite@1.0.30001603:
+    resolution: {integrity: sha512-iL2iSS0eDILMb9n5yKQoTBim9jMZ0Yrk8g0N9K7UzYyWnfIKzXBZD5ngpM37ZcL/cv0Mli8XtVMRYMQAfFpi5Q==}
 
   /case-sensitive-paths-webpack-plugin@2.4.0:
     resolution: {integrity: sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==}
@@ -5797,30 +4605,23 @@ packages:
     resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
     dev: false
 
-  /cookie@0.5.0:
-    resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
+  /cookie@0.6.0:
+    resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
     engines: {node: '>= 0.6'}
     dev: false
 
-  /core-js-compat@3.36.0:
-    resolution: {integrity: sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==}
-    dependencies:
-      browserslist: 4.23.0
-    dev: false
-
   /core-js-compat@3.36.1:
     resolution: {integrity: sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==}
     dependencies:
       browserslist: 4.23.0
-    dev: true
 
-  /core-js-pure@3.36.0:
-    resolution: {integrity: sha512-cN28qmhRNgbMZZMc/RFu5w8pK9VJzpb2rJVR/lHuZJKwmXnoWOpXmMkxqBB514igkp1Hu8WGROsiOAzUcKdHOQ==}
+  /core-js-pure@3.36.1:
+    resolution: {integrity: sha512-NXCvHvSVYSrewP0L5OhltzXeWFJLo2AL2TYnj6iLV3Bw8mM62wAQMNgUCRI6EBu6hVVpbCxmOPlxh1Ikw2PfUA==}
     requiresBuild: true
     dev: false
 
-  /core-js@3.36.0:
-    resolution: {integrity: sha512-mt7+TUBbTFg5+GngsAxeKBTl5/VS0guFeJacYge9OmHb+m058UwwIm41SE9T4Den7ClatV57B6TYTuJ0CX1MAw==}
+  /core-js@3.36.1:
+    resolution: {integrity: sha512-BTvUrwxVBezj5SZ3f10ImnX2oRByMxql3EimVqMysepbC9EeMUOpLwdy6Eoili2x6E4kf+ZUB5k/+Jv55alPfA==}
     requiresBuild: true
     dev: false
 
@@ -5863,14 +4664,14 @@ packages:
     resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==}
     engines: {node: '>=8'}
 
-  /css-blank-pseudo@3.0.3(postcss@8.4.35):
+  /css-blank-pseudo@3.0.3(postcss@8.4.38):
     resolution: {integrity: sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==}
     engines: {node: ^12 || ^14 || >=16}
     hasBin: true
     peerDependencies:
       postcss: ^8.4
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
@@ -5879,27 +4680,27 @@ packages:
     engines: {node: '>=4'}
     dev: false
 
-  /css-declaration-sorter@6.4.1(postcss@8.4.35):
+  /css-declaration-sorter@6.4.1(postcss@8.4.38):
     resolution: {integrity: sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==}
     engines: {node: ^10 || ^12 || >=14}
     peerDependencies:
       postcss: ^8.0.9
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /css-has-pseudo@3.0.4(postcss@8.4.35):
+  /css-has-pseudo@3.0.4(postcss@8.4.38):
     resolution: {integrity: sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==}
     engines: {node: ^12 || ^14 || >=16}
     hasBin: true
     peerDependencies:
       postcss: ^8.4
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
-  /css-loader@6.10.0(webpack@5.90.3):
+  /css-loader@6.10.0(webpack@5.91.0):
     resolution: {integrity: sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==}
     engines: {node: '>= 12.13.0'}
     peerDependencies:
@@ -5911,18 +4712,18 @@ packages:
       webpack:
         optional: true
     dependencies:
-      icss-utils: 5.1.0(postcss@8.4.35)
-      postcss: 8.4.35
-      postcss-modules-extract-imports: 3.0.0(postcss@8.4.35)
-      postcss-modules-local-by-default: 4.0.4(postcss@8.4.35)
-      postcss-modules-scope: 3.1.1(postcss@8.4.35)
-      postcss-modules-values: 4.0.0(postcss@8.4.35)
+      icss-utils: 5.1.0(postcss@8.4.38)
+      postcss: 8.4.38
+      postcss-modules-extract-imports: 3.0.0(postcss@8.4.38)
+      postcss-modules-local-by-default: 4.0.4(postcss@8.4.38)
+      postcss-modules-scope: 3.1.1(postcss@8.4.38)
+      postcss-modules-values: 4.0.0(postcss@8.4.38)
       postcss-value-parser: 4.2.0
       semver: 7.6.0
-      webpack: 5.90.3
+      webpack: 5.91.0
     dev: false
 
-  /css-minimizer-webpack-plugin@3.4.1(webpack@5.90.3):
+  /css-minimizer-webpack-plugin@3.4.1(webpack@5.91.0):
     resolution: {integrity: sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==}
     engines: {node: '>= 12.13.0'}
     peerDependencies:
@@ -5941,23 +4742,23 @@ packages:
       esbuild:
         optional: true
     dependencies:
-      cssnano: 5.1.15(postcss@8.4.35)
+      cssnano: 5.1.15(postcss@8.4.38)
       jest-worker: 27.5.1
-      postcss: 8.4.35
+      postcss: 8.4.38
       schema-utils: 4.2.0
       serialize-javascript: 6.0.2
       source-map: 0.6.1
-      webpack: 5.90.3
+      webpack: 5.91.0
     dev: false
 
-  /css-prefers-color-scheme@6.0.3(postcss@8.4.35):
+  /css-prefers-color-scheme@6.0.3(postcss@8.4.38):
     resolution: {integrity: sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==}
     engines: {node: ^12 || ^14 || >=16}
     hasBin: true
     peerDependencies:
       postcss: ^8.4
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
   /css-select-base-adapter@0.1.1:
@@ -6031,62 +4832,62 @@ packages:
     hasBin: true
     dev: false
 
-  /cssnano-preset-default@5.2.14(postcss@8.4.35):
+  /cssnano-preset-default@5.2.14(postcss@8.4.38):
     resolution: {integrity: sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      css-declaration-sorter: 6.4.1(postcss@8.4.35)
-      cssnano-utils: 3.1.0(postcss@8.4.35)
-      postcss: 8.4.35
-      postcss-calc: 8.2.4(postcss@8.4.35)
-      postcss-colormin: 5.3.1(postcss@8.4.35)
-      postcss-convert-values: 5.1.3(postcss@8.4.35)
-      postcss-discard-comments: 5.1.2(postcss@8.4.35)
-      postcss-discard-duplicates: 5.1.0(postcss@8.4.35)
-      postcss-discard-empty: 5.1.1(postcss@8.4.35)
-      postcss-discard-overridden: 5.1.0(postcss@8.4.35)
-      postcss-merge-longhand: 5.1.7(postcss@8.4.35)
-      postcss-merge-rules: 5.1.4(postcss@8.4.35)
-      postcss-minify-font-values: 5.1.0(postcss@8.4.35)
-      postcss-minify-gradients: 5.1.1(postcss@8.4.35)
-      postcss-minify-params: 5.1.4(postcss@8.4.35)
-      postcss-minify-selectors: 5.2.1(postcss@8.4.35)
-      postcss-normalize-charset: 5.1.0(postcss@8.4.35)
-      postcss-normalize-display-values: 5.1.0(postcss@8.4.35)
-      postcss-normalize-positions: 5.1.1(postcss@8.4.35)
-      postcss-normalize-repeat-style: 5.1.1(postcss@8.4.35)
-      postcss-normalize-string: 5.1.0(postcss@8.4.35)
-      postcss-normalize-timing-functions: 5.1.0(postcss@8.4.35)
-      postcss-normalize-unicode: 5.1.1(postcss@8.4.35)
-      postcss-normalize-url: 5.1.0(postcss@8.4.35)
-      postcss-normalize-whitespace: 5.1.1(postcss@8.4.35)
-      postcss-ordered-values: 5.1.3(postcss@8.4.35)
-      postcss-reduce-initial: 5.1.2(postcss@8.4.35)
-      postcss-reduce-transforms: 5.1.0(postcss@8.4.35)
-      postcss-svgo: 5.1.0(postcss@8.4.35)
-      postcss-unique-selectors: 5.1.1(postcss@8.4.35)
-    dev: false
-
-  /cssnano-utils@3.1.0(postcss@8.4.35):
+      css-declaration-sorter: 6.4.1(postcss@8.4.38)
+      cssnano-utils: 3.1.0(postcss@8.4.38)
+      postcss: 8.4.38
+      postcss-calc: 8.2.4(postcss@8.4.38)
+      postcss-colormin: 5.3.1(postcss@8.4.38)
+      postcss-convert-values: 5.1.3(postcss@8.4.38)
+      postcss-discard-comments: 5.1.2(postcss@8.4.38)
+      postcss-discard-duplicates: 5.1.0(postcss@8.4.38)
+      postcss-discard-empty: 5.1.1(postcss@8.4.38)
+      postcss-discard-overridden: 5.1.0(postcss@8.4.38)
+      postcss-merge-longhand: 5.1.7(postcss@8.4.38)
+      postcss-merge-rules: 5.1.4(postcss@8.4.38)
+      postcss-minify-font-values: 5.1.0(postcss@8.4.38)
+      postcss-minify-gradients: 5.1.1(postcss@8.4.38)
+      postcss-minify-params: 5.1.4(postcss@8.4.38)
+      postcss-minify-selectors: 5.2.1(postcss@8.4.38)
+      postcss-normalize-charset: 5.1.0(postcss@8.4.38)
+      postcss-normalize-display-values: 5.1.0(postcss@8.4.38)
+      postcss-normalize-positions: 5.1.1(postcss@8.4.38)
+      postcss-normalize-repeat-style: 5.1.1(postcss@8.4.38)
+      postcss-normalize-string: 5.1.0(postcss@8.4.38)
+      postcss-normalize-timing-functions: 5.1.0(postcss@8.4.38)
+      postcss-normalize-unicode: 5.1.1(postcss@8.4.38)
+      postcss-normalize-url: 5.1.0(postcss@8.4.38)
+      postcss-normalize-whitespace: 5.1.1(postcss@8.4.38)
+      postcss-ordered-values: 5.1.3(postcss@8.4.38)
+      postcss-reduce-initial: 5.1.2(postcss@8.4.38)
+      postcss-reduce-transforms: 5.1.0(postcss@8.4.38)
+      postcss-svgo: 5.1.0(postcss@8.4.38)
+      postcss-unique-selectors: 5.1.1(postcss@8.4.38)
+    dev: false
+
+  /cssnano-utils@3.1.0(postcss@8.4.38):
     resolution: {integrity: sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /cssnano@5.1.15(postcss@8.4.35):
+  /cssnano@5.1.15(postcss@8.4.38):
     resolution: {integrity: sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      cssnano-preset-default: 5.2.14(postcss@8.4.35)
+      cssnano-preset-default: 5.2.14(postcss@8.4.38)
       lilconfig: 2.1.0
-      postcss: 8.4.35
+      postcss: 8.4.38
       yaml: 1.10.2
     dev: false
 
@@ -6140,7 +4941,6 @@ packages:
       call-bind: 1.0.7
       es-errors: 1.3.0
       is-data-view: 1.0.1
-    dev: false
 
   /data-view-byte-length@1.0.1:
     resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==}
@@ -6149,7 +4949,6 @@ packages:
       call-bind: 1.0.7
       es-errors: 1.3.0
       is-data-view: 1.0.1
-    dev: false
 
   /data-view-byte-offset@1.0.0:
     resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==}
@@ -6158,7 +4957,6 @@ packages:
       call-bind: 1.0.7
       es-errors: 1.3.0
       is-data-view: 1.0.1
-    dev: false
 
   /debug@2.6.9:
     resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
@@ -6348,7 +5146,7 @@ packages:
     resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==}
     engines: {node: '>=6'}
     dependencies:
-      '@leichtgewicht/ip-codec': 2.0.4
+      '@leichtgewicht/ip-codec': 2.0.5
     dev: false
 
   /doctrine@2.1.0:
@@ -6374,7 +5172,7 @@ packages:
   /dom-helpers@5.2.1:
     resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==}
     dependencies:
-      '@babel/runtime': 7.24.0
+      '@babel/runtime': 7.24.1
       csstype: 3.1.3
     dev: false
 
@@ -6470,8 +5268,8 @@ packages:
     dependencies:
       jake: 10.8.7
 
-  /electron-to-chromium@1.4.708:
-    resolution: {integrity: sha512-iWgEEvREL4GTXXHKohhh33+6Y8XkPI5eHihDmm8zUk5Zo7HICEW+wI/j5kJ2tbuNUCXJ/sNXa03ajW635DiJXA==}
+  /electron-to-chromium@1.4.722:
+    resolution: {integrity: sha512-5nLE0TWFFpZ80Crhtp4pIp8LXCztjYX41yUcV6b+bKR2PqzjskTMOOlBi1VjBHlvHwS+4gar7kNKOrsbsewEZQ==}
 
   /embla-carousel-autoplay@7.1.0(embla-carousel@7.1.0):
     resolution: {integrity: sha512-nYfgSGn3ek44OzwO0t/Ptuxq4PNPD5l7Y9X7JjLYI/DN1uGjqxz9L73YYqR6YCRDnTYJ88s9fep48dzBnSG4vQ==}
@@ -6552,54 +5350,8 @@ packages:
       stackframe: 1.3.4
     dev: false
 
-  /es-abstract@1.22.5:
-    resolution: {integrity: sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==}
-    engines: {node: '>= 0.4'}
-    dependencies:
-      array-buffer-byte-length: 1.0.1
-      arraybuffer.prototype.slice: 1.0.3
-      available-typed-arrays: 1.0.7
-      call-bind: 1.0.7
-      es-define-property: 1.0.0
-      es-errors: 1.3.0
-      es-set-tostringtag: 2.0.3
-      es-to-primitive: 1.2.1
-      function.prototype.name: 1.1.6
-      get-intrinsic: 1.2.4
-      get-symbol-description: 1.0.2
-      globalthis: 1.0.3
-      gopd: 1.0.1
-      has-property-descriptors: 1.0.2
-      has-proto: 1.0.3
-      has-symbols: 1.0.3
-      hasown: 2.0.2
-      internal-slot: 1.0.7
-      is-array-buffer: 3.0.4
-      is-callable: 1.2.7
-      is-negative-zero: 2.0.3
-      is-regex: 1.1.4
-      is-shared-array-buffer: 1.0.3
-      is-string: 1.0.7
-      is-typed-array: 1.1.13
-      is-weakref: 1.0.2
-      object-inspect: 1.13.1
-      object-keys: 1.1.1
-      object.assign: 4.1.5
-      regexp.prototype.flags: 1.5.2
-      safe-array-concat: 1.1.2
-      safe-regex-test: 1.0.3
-      string.prototype.trim: 1.2.8
-      string.prototype.trimend: 1.0.7
-      string.prototype.trimstart: 1.0.7
-      typed-array-buffer: 1.0.2
-      typed-array-byte-length: 1.0.1
-      typed-array-byte-offset: 1.0.2
-      typed-array-length: 1.0.5
-      unbox-primitive: 1.0.2
-      which-typed-array: 1.1.15
-
-  /es-abstract@1.23.0:
-    resolution: {integrity: sha512-vmuE7Uoevk2xkwu5Gwa7RfJk/ebVV6xRv7KuZNbUglmJHhWPMbLL20ztreVpBbdxBZijETx3Aml3NssX4SFMvQ==}
+  /es-abstract@1.23.3:
+    resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==}
     engines: {node: '>= 0.4'}
     dependencies:
       array-buffer-byte-length: 1.0.1
@@ -6611,6 +5363,7 @@ packages:
       data-view-byte-offset: 1.0.0
       es-define-property: 1.0.0
       es-errors: 1.3.0
+      es-object-atoms: 1.0.0
       es-set-tostringtag: 2.0.3
       es-to-primitive: 1.2.1
       function.prototype.name: 1.1.6
@@ -6638,16 +5391,15 @@ packages:
       regexp.prototype.flags: 1.5.2
       safe-array-concat: 1.1.2
       safe-regex-test: 1.0.3
-      string.prototype.trim: 1.2.8
-      string.prototype.trimend: 1.0.7
-      string.prototype.trimstart: 1.0.7
+      string.prototype.trim: 1.2.9
+      string.prototype.trimend: 1.0.8
+      string.prototype.trimstart: 1.0.8
       typed-array-buffer: 1.0.2
       typed-array-byte-length: 1.0.1
       typed-array-byte-offset: 1.0.2
-      typed-array-length: 1.0.5
+      typed-array-length: 1.0.6
       unbox-primitive: 1.0.2
       which-typed-array: 1.1.15
-    dev: false
 
   /es-array-method-boxes-properly@1.0.0:
     resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==}
@@ -6669,7 +5421,7 @@ packages:
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.23.0
+      es-abstract: 1.23.3
       es-errors: 1.3.0
       es-set-tostringtag: 2.0.3
       function-bind: 1.1.2
@@ -6683,10 +5435,16 @@ packages:
       safe-array-concat: 1.1.2
     dev: false
 
-  /es-module-lexer@1.4.1:
-    resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==}
+  /es-module-lexer@1.5.0:
+    resolution: {integrity: sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==}
     dev: false
 
+  /es-object-atoms@1.0.0:
+    resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      es-errors: 1.3.0
+
   /es-set-tostringtag@2.0.3:
     resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==}
     engines: {node: '>= 0.4'}
@@ -6709,35 +5467,35 @@ packages:
       is-date-object: 1.0.5
       is-symbol: 1.0.4
 
-  /esbuild@0.19.12:
-    resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==}
+  /esbuild@0.20.2:
+    resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==}
     engines: {node: '>=12'}
     hasBin: true
     requiresBuild: true
     optionalDependencies:
-      '@esbuild/aix-ppc64': 0.19.12
-      '@esbuild/android-arm': 0.19.12
-      '@esbuild/android-arm64': 0.19.12
-      '@esbuild/android-x64': 0.19.12
-      '@esbuild/darwin-arm64': 0.19.12
-      '@esbuild/darwin-x64': 0.19.12
-      '@esbuild/freebsd-arm64': 0.19.12
-      '@esbuild/freebsd-x64': 0.19.12
-      '@esbuild/linux-arm': 0.19.12
-      '@esbuild/linux-arm64': 0.19.12
-      '@esbuild/linux-ia32': 0.19.12
-      '@esbuild/linux-loong64': 0.19.12
-      '@esbuild/linux-mips64el': 0.19.12
-      '@esbuild/linux-ppc64': 0.19.12
-      '@esbuild/linux-riscv64': 0.19.12
-      '@esbuild/linux-s390x': 0.19.12
-      '@esbuild/linux-x64': 0.19.12
-      '@esbuild/netbsd-x64': 0.19.12
-      '@esbuild/openbsd-x64': 0.19.12
-      '@esbuild/sunos-x64': 0.19.12
-      '@esbuild/win32-arm64': 0.19.12
-      '@esbuild/win32-ia32': 0.19.12
-      '@esbuild/win32-x64': 0.19.12
+      '@esbuild/aix-ppc64': 0.20.2
+      '@esbuild/android-arm': 0.20.2
+      '@esbuild/android-arm64': 0.20.2
+      '@esbuild/android-x64': 0.20.2
+      '@esbuild/darwin-arm64': 0.20.2
+      '@esbuild/darwin-x64': 0.20.2
+      '@esbuild/freebsd-arm64': 0.20.2
+      '@esbuild/freebsd-x64': 0.20.2
+      '@esbuild/linux-arm': 0.20.2
+      '@esbuild/linux-arm64': 0.20.2
+      '@esbuild/linux-ia32': 0.20.2
+      '@esbuild/linux-loong64': 0.20.2
+      '@esbuild/linux-mips64el': 0.20.2
+      '@esbuild/linux-ppc64': 0.20.2
+      '@esbuild/linux-riscv64': 0.20.2
+      '@esbuild/linux-s390x': 0.20.2
+      '@esbuild/linux-x64': 0.20.2
+      '@esbuild/netbsd-x64': 0.20.2
+      '@esbuild/openbsd-x64': 0.20.2
+      '@esbuild/sunos-x64': 0.20.2
+      '@esbuild/win32-arm64': 0.20.2
+      '@esbuild/win32-ia32': 0.20.2
+      '@esbuild/win32-x64': 0.20.2
 
   /escalade@3.1.2:
     resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
@@ -6786,7 +5544,7 @@ packages:
       source-map: 0.6.1
     dev: false
 
-  /eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.24.1)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(jest@27.5.1)(typescript@5.4.2):
+  /eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.24.1)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(jest@27.5.1)(typescript@5.4.3):
     resolution: {integrity: sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
@@ -6796,22 +5554,22 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/eslint-parser': 7.23.10(@babel/core@7.24.0)(eslint@8.57.0)
-      '@rushstack/eslint-patch': 1.7.2
-      '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)(typescript@5.4.2)
-      '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.4.2)
+      '@babel/core': 7.24.3
+      '@babel/eslint-parser': 7.24.1(@babel/core@7.24.3)(eslint@8.57.0)
+      '@rushstack/eslint-patch': 1.10.1
+      '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)(typescript@5.4.3)
+      '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.4.3)
       babel-preset-react-app: 10.0.1
       confusing-browser-globals: 1.0.11
       eslint: 8.57.0
       eslint-plugin-flowtype: 8.0.3(@babel/plugin-syntax-flow@7.24.1)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)
       eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)
-      eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.62.0)(eslint@8.57.0)(jest@27.5.1)(typescript@5.4.2)
+      eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.62.0)(eslint@8.57.0)(jest@27.5.1)(typescript@5.4.3)
       eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0)
       eslint-plugin-react: 7.34.1(eslint@8.57.0)
       eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0)
-      eslint-plugin-testing-library: 5.11.1(eslint@8.57.0)(typescript@5.4.2)
-      typescript: 5.4.2
+      eslint-plugin-testing-library: 5.11.1(eslint@8.57.0)(typescript@5.4.3)
+      typescript: 5.4.3
     transitivePeerDependencies:
       - '@babel/plugin-syntax-flow'
       - '@babel/plugin-transform-react-jsx'
@@ -6852,7 +5610,7 @@ packages:
       eslint-import-resolver-webpack:
         optional: true
     dependencies:
-      '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.4.2)
+      '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.4.3)
       debug: 3.2.7
       eslint: 8.57.0
       eslint-import-resolver-node: 0.3.9
@@ -6868,8 +5626,8 @@ packages:
       '@babel/plugin-transform-react-jsx': ^7.14.9
       eslint: ^8.1.0
     dependencies:
-      '@babel/plugin-syntax-flow': 7.24.1(@babel/core@7.24.0)
-      '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.24.0)
+      '@babel/plugin-syntax-flow': 7.24.1(@babel/core@7.24.3)
+      '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.24.3)
       eslint: 8.57.0
       lodash: 4.17.21
       string-natural-compare: 3.0.1
@@ -6885,9 +5643,9 @@ packages:
       '@typescript-eslint/parser':
         optional: true
     dependencies:
-      '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.4.2)
-      array-includes: 3.1.7
-      array.prototype.findlastindex: 1.2.4
+      '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.4.3)
+      array-includes: 3.1.8
+      array.prototype.findlastindex: 1.2.5
       array.prototype.flat: 1.3.2
       array.prototype.flatmap: 1.3.2
       debug: 3.2.7
@@ -6899,9 +5657,9 @@ packages:
       is-core-module: 2.13.1
       is-glob: 4.0.3
       minimatch: 3.1.2
-      object.fromentries: 2.0.7
-      object.groupby: 1.0.2
-      object.values: 1.1.7
+      object.fromentries: 2.0.8
+      object.groupby: 1.0.3
+      object.values: 1.2.0
       semver: 6.3.1
       tsconfig-paths: 3.15.0
     transitivePeerDependencies:
@@ -6910,7 +5668,7 @@ packages:
       - supports-color
     dev: false
 
-  /eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.62.0)(eslint@8.57.0)(jest@27.5.1)(typescript@5.4.2):
+  /eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.62.0)(eslint@8.57.0)(jest@27.5.1)(typescript@5.4.3):
     resolution: {integrity: sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==}
     engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
     peerDependencies:
@@ -6923,8 +5681,8 @@ packages:
       jest:
         optional: true
     dependencies:
-      '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)(typescript@5.4.2)
-      '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.0)(typescript@5.4.2)
+      '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.57.0)(typescript@5.4.3)
+      '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.0)(typescript@5.4.3)
       eslint: 8.57.0
       jest: 27.5.1
     transitivePeerDependencies:
@@ -6938,9 +5696,9 @@ packages:
     peerDependencies:
       eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
     dependencies:
-      '@babel/runtime': 7.24.0
+      '@babel/runtime': 7.24.1
       aria-query: 5.3.0
-      array-includes: 3.1.7
+      array-includes: 3.1.8
       array.prototype.flatmap: 1.3.2
       ast-types-flow: 0.0.8
       axe-core: 4.7.0
@@ -6953,8 +5711,8 @@ packages:
       jsx-ast-utils: 3.3.5
       language-tags: 1.0.9
       minimatch: 3.1.2
-      object.entries: 1.1.7
-      object.fromentries: 2.0.7
+      object.entries: 1.1.8
+      object.fromentries: 2.0.8
     dev: false
 
   /eslint-plugin-react-hooks@4.6.0(eslint@8.57.0):
@@ -6980,8 +5738,8 @@ packages:
     peerDependencies:
       eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
     dependencies:
-      array-includes: 3.1.7
-      array.prototype.findlast: 1.2.4
+      array-includes: 3.1.8
+      array.prototype.findlast: 1.2.5
       array.prototype.flatmap: 1.3.2
       array.prototype.toreversed: 1.1.2
       array.prototype.tosorted: 1.1.3
@@ -6991,23 +5749,23 @@ packages:
       estraverse: 5.3.0
       jsx-ast-utils: 3.3.5
       minimatch: 3.1.2
-      object.entries: 1.1.7
-      object.fromentries: 2.0.7
-      object.hasown: 1.1.3
-      object.values: 1.1.7
+      object.entries: 1.1.8
+      object.fromentries: 2.0.8
+      object.hasown: 1.1.4
+      object.values: 1.2.0
       prop-types: 15.8.1
       resolve: 2.0.0-next.5
       semver: 6.3.1
-      string.prototype.matchall: 4.0.10
+      string.prototype.matchall: 4.0.11
     dev: false
 
-  /eslint-plugin-testing-library@5.11.1(eslint@8.57.0)(typescript@5.4.2):
+  /eslint-plugin-testing-library@5.11.1(eslint@8.57.0)(typescript@5.4.3):
     resolution: {integrity: sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0, npm: '>=6'}
     peerDependencies:
       eslint: ^7.5.0 || ^8.0.0
     dependencies:
-      '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.4.2)
+      '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.4.3)
       eslint: 8.57.0
     transitivePeerDependencies:
       - supports-color
@@ -7040,20 +5798,20 @@ packages:
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dev: false
 
-  /eslint-webpack-plugin@3.2.0(eslint@8.57.0)(webpack@5.90.3):
+  /eslint-webpack-plugin@3.2.0(eslint@8.57.0)(webpack@5.91.0):
     resolution: {integrity: sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==}
     engines: {node: '>= 12.13.0'}
     peerDependencies:
       eslint: ^7.0.0 || ^8.0.0
       webpack: ^5.0.0
     dependencies:
-      '@types/eslint': 8.56.5
+      '@types/eslint': 8.56.6
       eslint: 8.57.0
       jest-worker: 28.1.3
       micromatch: 4.0.5
       normalize-path: 3.0.0
       schema-utils: 4.2.0
-      webpack: 5.90.3
+      webpack: 5.91.0
     dev: false
 
   /eslint@8.57.0:
@@ -7204,8 +5962,8 @@ packages:
       jest-message-util: 27.5.1
     dev: false
 
-  /express@4.18.3:
-    resolution: {integrity: sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==}
+  /express@4.19.2:
+    resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==}
     engines: {node: '>= 0.10.0'}
     dependencies:
       accepts: 1.3.8
@@ -7213,7 +5971,7 @@ packages:
       body-parser: 1.20.2
       content-disposition: 0.5.4
       content-type: 1.0.5
-      cookie: 0.5.0
+      cookie: 0.6.0
       cookie-signature: 1.0.6
       debug: 2.6.9
       depd: 2.0.0
@@ -7307,7 +6065,7 @@ packages:
       flat-cache: 3.2.0
     dev: false
 
-  /file-loader@6.2.0(webpack@5.90.3):
+  /file-loader@6.2.0(webpack@5.91.0):
     resolution: {integrity: sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==}
     engines: {node: '>= 10.13.0'}
     peerDependencies:
@@ -7315,7 +6073,7 @@ packages:
     dependencies:
       loader-utils: 2.0.4
       schema-utils: 3.3.0
-      webpack: 5.90.3
+      webpack: 5.91.0
     dev: false
 
   /filelist@1.0.4:
@@ -7417,7 +6175,7 @@ packages:
       signal-exit: 4.1.0
     dev: false
 
-  /fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.0)(typescript@5.4.2)(webpack@5.90.3):
+  /fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.0)(typescript@5.4.3)(webpack@5.91.0):
     resolution: {integrity: sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==}
     engines: {node: '>=10', yarn: '>=1.0.0'}
     peerDependencies:
@@ -7431,7 +6189,7 @@ packages:
       vue-template-compiler:
         optional: true
     dependencies:
-      '@babel/code-frame': 7.23.5
+      '@babel/code-frame': 7.24.2
       '@types/json-schema': 7.0.15
       chalk: 4.1.2
       chokidar: 3.6.0
@@ -7445,8 +6203,8 @@ packages:
       schema-utils: 2.7.0
       semver: 7.6.0
       tapable: 1.1.3
-      typescript: 5.4.2
-      webpack: 5.90.3
+      typescript: 5.4.3
+      webpack: 5.91.0
     dev: false
 
   /form-data@3.0.1:
@@ -7526,7 +6284,7 @@ packages:
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
       functions-have-names: 1.2.3
 
   /functions-have-names@1.2.3:
@@ -7616,16 +6374,16 @@ packages:
     resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
     dev: false
 
-  /glob@10.3.10:
-    resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==}
+  /glob@10.3.12:
+    resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==}
     engines: {node: '>=16 || 14 >=14.17'}
     hasBin: true
     dependencies:
       foreground-child: 3.1.1
       jackspeak: 2.3.6
-      minimatch: 9.0.3
+      minimatch: 9.0.4
       minipass: 7.0.4
-      path-scurry: 1.10.1
+      path-scurry: 1.10.2
     dev: false
 
   /glob@7.2.3:
@@ -7795,10 +6553,10 @@ packages:
       he: 1.2.0
       param-case: 3.0.4
       relateurl: 0.2.7
-      terser: 5.29.2
+      terser: 5.30.0
     dev: false
 
-  /html-webpack-plugin@5.6.0(webpack@5.90.3):
+  /html-webpack-plugin@5.6.0(webpack@5.91.0):
     resolution: {integrity: sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==}
     engines: {node: '>=10.13.0'}
     peerDependencies:
@@ -7815,7 +6573,7 @@ packages:
       lodash: 4.17.21
       pretty-error: 4.0.0
       tapable: 2.2.1
-      webpack: 5.90.3
+      webpack: 5.91.0
     dev: false
 
   /htmlparser2@6.1.0:
@@ -7930,13 +6688,13 @@ packages:
       safer-buffer: 2.1.2
     dev: false
 
-  /icss-utils@5.1.0(postcss@8.4.35):
+  /icss-utils@5.1.0(postcss@8.4.38):
     resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==}
     engines: {node: ^10 || ^12 || >= 14}
     peerDependencies:
       postcss: ^8.1.0
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
   /idb@7.1.1:
@@ -8080,7 +6838,6 @@ packages:
     engines: {node: '>= 0.4'}
     dependencies:
       is-typed-array: 1.1.13
-    dev: false
 
   /is-date-object@1.0.5:
     resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
@@ -8289,8 +7046,8 @@ packages:
     resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==}
     engines: {node: '>=8'}
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/parser': 7.24.0
+      '@babel/core': 7.24.3
+      '@babel/parser': 7.24.1
       '@istanbuljs/schema': 0.1.3
       istanbul-lib-coverage: 3.2.2
       semver: 6.3.1
@@ -8332,7 +7089,7 @@ packages:
       define-properties: 1.2.1
       get-intrinsic: 1.2.4
       has-symbols: 1.0.3
-      reflect.getprototypeof: 1.0.5
+      reflect.getprototypeof: 1.0.6
       set-function-name: 2.0.2
     dev: false
 
@@ -8371,7 +7128,7 @@ packages:
       '@jest/environment': 27.5.1
       '@jest/test-result': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       chalk: 4.1.2
       co: 4.6.0
       dedent: 0.7.0
@@ -8430,10 +7187,10 @@ packages:
       ts-node:
         optional: true
     dependencies:
-      '@babel/core': 7.24.0
+      '@babel/core': 7.24.3
       '@jest/test-sequencer': 27.5.1
       '@jest/types': 27.5.1
-      babel-jest: 27.5.1(@babel/core@7.24.0)
+      babel-jest: 27.5.1(@babel/core@7.24.3)
       chalk: 4.1.2
       ci-info: 3.9.0
       deepmerge: 4.3.1
@@ -8496,7 +7253,7 @@ packages:
       '@jest/environment': 27.5.1
       '@jest/fake-timers': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       jest-mock: 27.5.1
       jest-util: 27.5.1
       jsdom: 16.7.0
@@ -8514,7 +7271,7 @@ packages:
       '@jest/environment': 27.5.1
       '@jest/fake-timers': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       jest-mock: 27.5.1
       jest-util: 27.5.1
     dev: false
@@ -8530,7 +7287,7 @@ packages:
     dependencies:
       '@jest/types': 27.5.1
       '@types/graceful-fs': 4.1.9
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       anymatch: 3.1.3
       fb-watchman: 2.0.2
       graceful-fs: 4.2.11
@@ -8552,7 +7309,7 @@ packages:
       '@jest/source-map': 27.5.1
       '@jest/test-result': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       chalk: 4.1.2
       co: 4.6.0
       expect: 27.5.1
@@ -8591,7 +7348,7 @@ packages:
     resolution: {integrity: sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==}
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      '@babel/code-frame': 7.23.5
+      '@babel/code-frame': 7.24.2
       '@jest/types': 27.5.1
       '@types/stack-utils': 2.0.3
       chalk: 4.1.2
@@ -8606,7 +7363,7 @@ packages:
     resolution: {integrity: sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==}
     engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
     dependencies:
-      '@babel/code-frame': 7.23.5
+      '@babel/code-frame': 7.24.2
       '@jest/types': 28.1.3
       '@types/stack-utils': 2.0.3
       chalk: 4.1.2
@@ -8622,7 +7379,7 @@ packages:
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
       '@jest/types': 27.5.1
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
     dev: false
 
   /jest-pnp-resolver@1.2.3(jest-resolve@27.5.1):
@@ -8683,7 +7440,7 @@ packages:
       '@jest/test-result': 27.5.1
       '@jest/transform': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       chalk: 4.1.2
       emittery: 0.8.1
       graceful-fs: 4.2.11
@@ -8740,7 +7497,7 @@ packages:
     resolution: {integrity: sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==}
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       graceful-fs: 4.2.11
     dev: false
 
@@ -8748,16 +7505,16 @@ packages:
     resolution: {integrity: sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==}
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      '@babel/core': 7.24.0
-      '@babel/generator': 7.23.6
-      '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.24.0)
-      '@babel/traverse': 7.24.0
+      '@babel/core': 7.24.3
+      '@babel/generator': 7.24.1
+      '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.3)
+      '@babel/traverse': 7.24.1
       '@babel/types': 7.24.0
       '@jest/transform': 27.5.1
       '@jest/types': 27.5.1
       '@types/babel__traverse': 7.20.5
       '@types/prettier': 2.7.3
-      babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.0)
+      babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.3)
       chalk: 4.1.2
       expect: 27.5.1
       graceful-fs: 4.2.11
@@ -8779,7 +7536,7 @@ packages:
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
       '@jest/types': 27.5.1
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       chalk: 4.1.2
       ci-info: 3.9.0
       graceful-fs: 4.2.11
@@ -8791,7 +7548,7 @@ packages:
     engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
     dependencies:
       '@jest/types': 28.1.3
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       chalk: 4.1.2
       ci-info: 3.9.0
       graceful-fs: 4.2.11
@@ -8832,7 +7589,7 @@ packages:
     dependencies:
       '@jest/test-result': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       ansi-escapes: 4.3.2
       chalk: 4.1.2
       jest-util: 27.5.1
@@ -8845,7 +7602,7 @@ packages:
     dependencies:
       '@jest/test-result': 28.1.3
       '@jest/types': 28.1.3
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       ansi-escapes: 4.3.2
       chalk: 4.1.2
       emittery: 0.10.2
@@ -8857,7 +7614,7 @@ packages:
     resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==}
     engines: {node: '>= 10.13.0'}
     dependencies:
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       merge-stream: 2.0.0
       supports-color: 7.2.0
 
@@ -8865,7 +7622,7 @@ packages:
     resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
     engines: {node: '>= 10.13.0'}
     dependencies:
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       merge-stream: 2.0.0
       supports-color: 8.1.1
     dev: false
@@ -8874,7 +7631,7 @@ packages:
     resolution: {integrity: sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==}
     engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
     dependencies:
-      '@types/node': 20.11.28
+      '@types/node': 20.12.2
       merge-stream: 2.0.0
       supports-color: 8.1.1
     dev: false
@@ -9047,10 +7804,10 @@ packages:
     resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
     engines: {node: '>=4.0'}
     dependencies:
-      array-includes: 3.1.7
+      array-includes: 3.1.8
       array.prototype.flat: 1.3.2
       object.assign: 4.1.5
-      object.values: 1.1.7
+      object.values: 1.2.0
     dev: false
 
   /jwt-decode@4.0.0:
@@ -9263,14 +8020,14 @@ packages:
       tmpl: 1.0.5
     dev: false
 
-  /mantine-form-zod-resolver@1.1.0(@mantine/form@7.6.2)(zod@3.22.4):
+  /mantine-form-zod-resolver@1.1.0(@mantine/form@7.7.1)(zod@3.22.4):
     resolution: {integrity: sha512-hidTuYq6agSF5XbkcVVcr0mkGs9ki/x8OC9ldZMxGLVGja6bdl+x4k1hCNrigCG90DBoMDnu0bo3hprGBBlUZA==}
     engines: {node: '>=16.6.0'}
     peerDependencies:
       '@mantine/form': '>=7.0.0'
       zod: '>=3.0.0'
     dependencies:
-      '@mantine/form': 7.6.2(react@18.2.0)
+      '@mantine/form': 7.7.1(react@18.2.0)
       zod: 3.22.4
     dev: false
 
@@ -9366,6 +8123,12 @@ packages:
     hasBin: true
     dev: false
 
+  /mime@4.0.1:
+    resolution: {integrity: sha512-5lZ5tyrIfliMXzFtkYyekWbtRXObT9OWa8IwQ5uxTBDHucNNwniRqo0yInflj+iYi5CBa6qxadGzGarDfuEOxA==}
+    engines: {node: '>=16'}
+    hasBin: true
+    dev: false
+
   /mimic-fn@2.1.0:
     resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
     engines: {node: '>=6'}
@@ -9376,7 +8139,7 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
-  /mini-css-extract-plugin@2.8.1(webpack@5.90.3):
+  /mini-css-extract-plugin@2.8.1(webpack@5.91.0):
     resolution: {integrity: sha512-/1HDlyFRxWIZPI1ZpgqlZ8jMw/1Dp/dl3P0L1jtZ+zVcHqwPhGwaJwKL00WVgfnBy6PWCde9W65or7IIETImuA==}
     engines: {node: '>= 12.13.0'}
     peerDependencies:
@@ -9384,7 +8147,7 @@ packages:
     dependencies:
       schema-utils: 4.2.0
       tapable: 2.2.1
-      webpack: 5.90.3
+      webpack: 5.91.0
     dev: false
 
   /minimalistic-assert@1.0.1:
@@ -9409,6 +8172,13 @@ packages:
       brace-expansion: 2.0.1
     dev: false
 
+  /minimatch@9.0.4:
+    resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==}
+    engines: {node: '>=16 || 14 >=14.17'}
+    dependencies:
+      brace-expansion: 2.0.1
+    dev: false
+
   /minimist@1.2.8:
     resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
 
@@ -9587,59 +8357,63 @@ packages:
       has-symbols: 1.0.3
       object-keys: 1.1.1
 
-  /object.entries@1.1.7:
-    resolution: {integrity: sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==}
+  /object.entries@1.1.8:
+    resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-object-atoms: 1.0.0
     dev: false
 
-  /object.fromentries@2.0.7:
-    resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==}
+  /object.fromentries@2.0.8:
+    resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
+      es-object-atoms: 1.0.0
     dev: false
 
-  /object.getownpropertydescriptors@2.1.7:
-    resolution: {integrity: sha512-PrJz0C2xJ58FNn11XV2lr4Jt5Gzl94qpy9Lu0JlfEj14z88sqbSBJCBEzdlNUCzY2gburhbrwOZ5BHCmuNUy0g==}
+  /object.getownpropertydescriptors@2.1.8:
+    resolution: {integrity: sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A==}
     engines: {node: '>= 0.8'}
     dependencies:
-      array.prototype.reduce: 1.0.6
+      array.prototype.reduce: 1.0.7
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
+      es-object-atoms: 1.0.0
+      gopd: 1.0.1
       safe-array-concat: 1.1.2
     dev: false
 
-  /object.groupby@1.0.2:
-    resolution: {integrity: sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==}
+  /object.groupby@1.0.3:
+    resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==}
+    engines: {node: '>= 0.4'}
     dependencies:
-      array.prototype.filter: 1.0.3
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
-      es-errors: 1.3.0
+      es-abstract: 1.23.3
     dev: false
 
-  /object.hasown@1.1.3:
-    resolution: {integrity: sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==}
+  /object.hasown@1.1.4:
+    resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==}
+    engines: {node: '>= 0.4'}
     dependencies:
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
+      es-object-atoms: 1.0.0
     dev: false
 
-  /object.values@1.1.7:
-    resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==}
+  /object.values@1.2.0:
+    resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-object-atoms: 1.0.0
     dev: false
 
   /obuf@1.1.2:
@@ -9769,7 +8543,7 @@ packages:
     resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
     engines: {node: '>=8'}
     dependencies:
-      '@babel/code-frame': 7.23.5
+      '@babel/code-frame': 7.24.2
       error-ex: 1.3.2
       json-parse-even-better-errors: 2.3.1
       lines-and-columns: 1.2.4
@@ -9813,8 +8587,8 @@ packages:
   /path-parse@1.0.7:
     resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
 
-  /path-scurry@1.10.1:
-    resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==}
+  /path-scurry@1.10.2:
+    resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==}
     engines: {node: '>=16 || 14 >=14.17'}
     dependencies:
       lru-cache: 10.2.0
@@ -9893,17 +8667,17 @@ packages:
     resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
     engines: {node: '>= 0.4'}
 
-  /postcss-attribute-case-insensitive@5.0.2(postcss@8.4.35):
+  /postcss-attribute-case-insensitive@5.0.2(postcss@8.4.38):
     resolution: {integrity: sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
-  /postcss-browser-comments@4.0.0(browserslist@4.23.0)(postcss@8.4.35):
+  /postcss-browser-comments@4.0.0(browserslist@4.23.0)(postcss@8.4.38):
     resolution: {integrity: sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==}
     engines: {node: '>=8'}
     peerDependencies:
@@ -9911,60 +8685,60 @@ packages:
       postcss: '>=8'
     dependencies:
       browserslist: 4.23.0
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-calc@8.2.4(postcss@8.4.35):
+  /postcss-calc@8.2.4(postcss@8.4.38):
     resolution: {integrity: sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==}
     peerDependencies:
       postcss: ^8.2.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-clamp@4.1.0(postcss@8.4.35):
+  /postcss-clamp@4.1.0(postcss@8.4.38):
     resolution: {integrity: sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==}
     engines: {node: '>=7.6.0'}
     peerDependencies:
       postcss: ^8.4.6
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-color-functional-notation@4.2.4(postcss@8.4.35):
+  /postcss-color-functional-notation@4.2.4(postcss@8.4.38):
     resolution: {integrity: sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-color-hex-alpha@8.0.4(postcss@8.4.35):
+  /postcss-color-hex-alpha@8.0.4(postcss@8.4.38):
     resolution: {integrity: sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.4
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-color-rebeccapurple@7.1.1(postcss@8.4.35):
+  /postcss-color-rebeccapurple@7.1.1(postcss@8.4.38):
     resolution: {integrity: sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-colormin@5.3.1(postcss@8.4.35):
+  /postcss-colormin@5.3.1(postcss@8.4.38):
     resolution: {integrity: sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
@@ -9973,215 +8747,215 @@ packages:
       browserslist: 4.23.0
       caniuse-api: 3.0.0
       colord: 2.9.3
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-convert-values@5.1.3(postcss@8.4.35):
+  /postcss-convert-values@5.1.3(postcss@8.4.38):
     resolution: {integrity: sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
       browserslist: 4.23.0
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-custom-media@8.0.2(postcss@8.4.35):
+  /postcss-custom-media@8.0.2(postcss@8.4.38):
     resolution: {integrity: sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.3
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-custom-properties@12.1.11(postcss@8.4.35):
+  /postcss-custom-properties@12.1.11(postcss@8.4.38):
     resolution: {integrity: sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-custom-selectors@6.0.3(postcss@8.4.35):
+  /postcss-custom-selectors@6.0.3(postcss@8.4.38):
     resolution: {integrity: sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.3
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
-  /postcss-dir-pseudo-class@6.0.5(postcss@8.4.35):
+  /postcss-dir-pseudo-class@6.0.5(postcss@8.4.38):
     resolution: {integrity: sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
-  /postcss-discard-comments@5.1.2(postcss@8.4.35):
+  /postcss-discard-comments@5.1.2(postcss@8.4.38):
     resolution: {integrity: sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-discard-duplicates@5.1.0(postcss@8.4.35):
+  /postcss-discard-duplicates@5.1.0(postcss@8.4.38):
     resolution: {integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-discard-empty@5.1.1(postcss@8.4.35):
+  /postcss-discard-empty@5.1.1(postcss@8.4.38):
     resolution: {integrity: sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-discard-overridden@5.1.0(postcss@8.4.35):
+  /postcss-discard-overridden@5.1.0(postcss@8.4.38):
     resolution: {integrity: sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-double-position-gradients@3.1.2(postcss@8.4.35):
+  /postcss-double-position-gradients@3.1.2(postcss@8.4.38):
     resolution: {integrity: sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.35)
-      postcss: 8.4.35
+      '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.38)
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-env-function@4.0.6(postcss@8.4.35):
+  /postcss-env-function@4.0.6(postcss@8.4.38):
     resolution: {integrity: sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.4
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-flexbugs-fixes@5.0.2(postcss@8.4.35):
+  /postcss-flexbugs-fixes@5.0.2(postcss@8.4.38):
     resolution: {integrity: sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==}
     peerDependencies:
       postcss: ^8.1.4
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-focus-visible@6.0.4(postcss@8.4.35):
+  /postcss-focus-visible@6.0.4(postcss@8.4.38):
     resolution: {integrity: sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.4
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
-  /postcss-focus-within@5.0.4(postcss@8.4.35):
+  /postcss-focus-within@5.0.4(postcss@8.4.38):
     resolution: {integrity: sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.4
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
-  /postcss-font-variant@5.0.0(postcss@8.4.35):
+  /postcss-font-variant@5.0.0(postcss@8.4.38):
     resolution: {integrity: sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==}
     peerDependencies:
       postcss: ^8.1.0
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-gap-properties@3.0.5(postcss@8.4.35):
+  /postcss-gap-properties@3.0.5(postcss@8.4.38):
     resolution: {integrity: sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-image-set-function@4.0.7(postcss@8.4.35):
+  /postcss-image-set-function@4.0.7(postcss@8.4.38):
     resolution: {integrity: sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-import@15.1.0(postcss@8.4.35):
+  /postcss-import@15.1.0(postcss@8.4.38):
     resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
       postcss: ^8.0.0
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
       read-cache: 1.0.0
       resolve: 1.22.8
     dev: false
 
-  /postcss-initial@4.0.1(postcss@8.4.35):
+  /postcss-initial@4.0.1(postcss@8.4.38):
     resolution: {integrity: sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==}
     peerDependencies:
       postcss: ^8.0.0
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-js@4.0.1(postcss@8.4.35):
+  /postcss-js@4.0.1(postcss@8.4.38):
     resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
     engines: {node: ^12 || ^14 || >= 16}
     peerDependencies:
       postcss: ^8.4.21
     dependencies:
       camelcase-css: 2.0.1
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-lab-function@4.2.1(postcss@8.4.35):
+  /postcss-lab-function@4.2.1(postcss@8.4.38):
     resolution: {integrity: sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.35)
-      postcss: 8.4.35
+      '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.38)
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-load-config@4.0.2(postcss@8.4.35):
+  /postcss-load-config@4.0.2(postcss@8.4.38):
     resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
     engines: {node: '>= 14'}
     peerDependencies:
@@ -10194,11 +8968,11 @@ packages:
         optional: true
     dependencies:
       lilconfig: 3.1.1
-      postcss: 8.4.35
+      postcss: 8.4.38
       yaml: 2.4.1
     dev: false
 
-  /postcss-loader@6.2.1(postcss@8.4.35)(webpack@5.90.3):
+  /postcss-loader@6.2.1(postcss@8.4.38)(webpack@5.91.0):
     resolution: {integrity: sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==}
     engines: {node: '>= 12.13.0'}
     peerDependencies:
@@ -10207,41 +8981,41 @@ packages:
     dependencies:
       cosmiconfig: 7.1.0
       klona: 2.0.6
-      postcss: 8.4.35
+      postcss: 8.4.38
       semver: 7.6.0
-      webpack: 5.90.3
+      webpack: 5.91.0
     dev: false
 
-  /postcss-logical@5.0.4(postcss@8.4.35):
+  /postcss-logical@5.0.4(postcss@8.4.38):
     resolution: {integrity: sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.4
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-media-minmax@5.0.0(postcss@8.4.35):
+  /postcss-media-minmax@5.0.0(postcss@8.4.38):
     resolution: {integrity: sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==}
     engines: {node: '>=10.0.0'}
     peerDependencies:
       postcss: ^8.1.0
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-merge-longhand@5.1.7(postcss@8.4.35):
+  /postcss-merge-longhand@5.1.7(postcss@8.4.38):
     resolution: {integrity: sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
-      stylehacks: 5.1.1(postcss@8.4.35)
+      stylehacks: 5.1.1(postcss@8.4.38)
     dev: false
 
-  /postcss-merge-rules@5.1.4(postcss@8.4.35):
+  /postcss-merge-rules@5.1.4(postcss@8.4.38):
     resolution: {integrity: sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
@@ -10249,222 +9023,222 @@ packages:
     dependencies:
       browserslist: 4.23.0
       caniuse-api: 3.0.0
-      cssnano-utils: 3.1.0(postcss@8.4.35)
-      postcss: 8.4.35
+      cssnano-utils: 3.1.0(postcss@8.4.38)
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
-  /postcss-minify-font-values@5.1.0(postcss@8.4.35):
+  /postcss-minify-font-values@5.1.0(postcss@8.4.38):
     resolution: {integrity: sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-minify-gradients@5.1.1(postcss@8.4.35):
+  /postcss-minify-gradients@5.1.1(postcss@8.4.38):
     resolution: {integrity: sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
       colord: 2.9.3
-      cssnano-utils: 3.1.0(postcss@8.4.35)
-      postcss: 8.4.35
+      cssnano-utils: 3.1.0(postcss@8.4.38)
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-minify-params@5.1.4(postcss@8.4.35):
+  /postcss-minify-params@5.1.4(postcss@8.4.38):
     resolution: {integrity: sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
       browserslist: 4.23.0
-      cssnano-utils: 3.1.0(postcss@8.4.35)
-      postcss: 8.4.35
+      cssnano-utils: 3.1.0(postcss@8.4.38)
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-minify-selectors@5.2.1(postcss@8.4.35):
+  /postcss-minify-selectors@5.2.1(postcss@8.4.38):
     resolution: {integrity: sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
-  /postcss-mixins@9.0.4(postcss@8.4.35):
+  /postcss-mixins@9.0.4(postcss@8.4.38):
     resolution: {integrity: sha512-XVq5jwQJDRu5M1XGkdpgASqLk37OqkH4JCFDXl/Dn7janOJjCTEKL+36cnRVy7bMtoBzALfO7bV7nTIsFnUWLA==}
     engines: {node: '>=14.0'}
     peerDependencies:
       postcss: ^8.2.14
     dependencies:
       fast-glob: 3.3.2
-      postcss: 8.4.35
-      postcss-js: 4.0.1(postcss@8.4.35)
-      postcss-simple-vars: 7.0.1(postcss@8.4.35)
-      sugarss: 4.0.1(postcss@8.4.35)
+      postcss: 8.4.38
+      postcss-js: 4.0.1(postcss@8.4.38)
+      postcss-simple-vars: 7.0.1(postcss@8.4.38)
+      sugarss: 4.0.1(postcss@8.4.38)
     dev: false
 
-  /postcss-modules-extract-imports@3.0.0(postcss@8.4.35):
+  /postcss-modules-extract-imports@3.0.0(postcss@8.4.38):
     resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==}
     engines: {node: ^10 || ^12 || >= 14}
     peerDependencies:
       postcss: ^8.1.0
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-modules-local-by-default@4.0.4(postcss@8.4.35):
+  /postcss-modules-local-by-default@4.0.4(postcss@8.4.38):
     resolution: {integrity: sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==}
     engines: {node: ^10 || ^12 || >= 14}
     peerDependencies:
       postcss: ^8.1.0
     dependencies:
-      icss-utils: 5.1.0(postcss@8.4.35)
-      postcss: 8.4.35
+      icss-utils: 5.1.0(postcss@8.4.38)
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-modules-scope@3.1.1(postcss@8.4.35):
+  /postcss-modules-scope@3.1.1(postcss@8.4.38):
     resolution: {integrity: sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==}
     engines: {node: ^10 || ^12 || >= 14}
     peerDependencies:
       postcss: ^8.1.0
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
-  /postcss-modules-values@4.0.0(postcss@8.4.35):
+  /postcss-modules-values@4.0.0(postcss@8.4.38):
     resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==}
     engines: {node: ^10 || ^12 || >= 14}
     peerDependencies:
       postcss: ^8.1.0
     dependencies:
-      icss-utils: 5.1.0(postcss@8.4.35)
-      postcss: 8.4.35
+      icss-utils: 5.1.0(postcss@8.4.38)
+      postcss: 8.4.38
     dev: false
 
-  /postcss-nested@6.0.1(postcss@8.4.35):
+  /postcss-nested@6.0.1(postcss@8.4.38):
     resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==}
     engines: {node: '>=12.0'}
     peerDependencies:
       postcss: ^8.2.14
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
-  /postcss-nesting@10.2.0(postcss@8.4.35):
+  /postcss-nesting@10.2.0(postcss@8.4.38):
     resolution: {integrity: sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
       '@csstools/selector-specificity': 2.2.0(postcss-selector-parser@6.0.16)
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
-  /postcss-normalize-charset@5.1.0(postcss@8.4.35):
+  /postcss-normalize-charset@5.1.0(postcss@8.4.38):
     resolution: {integrity: sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-normalize-display-values@5.1.0(postcss@8.4.35):
+  /postcss-normalize-display-values@5.1.0(postcss@8.4.38):
     resolution: {integrity: sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-normalize-positions@5.1.1(postcss@8.4.35):
+  /postcss-normalize-positions@5.1.1(postcss@8.4.38):
     resolution: {integrity: sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-normalize-repeat-style@5.1.1(postcss@8.4.35):
+  /postcss-normalize-repeat-style@5.1.1(postcss@8.4.38):
     resolution: {integrity: sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-normalize-string@5.1.0(postcss@8.4.35):
+  /postcss-normalize-string@5.1.0(postcss@8.4.38):
     resolution: {integrity: sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-normalize-timing-functions@5.1.0(postcss@8.4.35):
+  /postcss-normalize-timing-functions@5.1.0(postcss@8.4.38):
     resolution: {integrity: sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-normalize-unicode@5.1.1(postcss@8.4.35):
+  /postcss-normalize-unicode@5.1.1(postcss@8.4.38):
     resolution: {integrity: sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
       browserslist: 4.23.0
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-normalize-url@5.1.0(postcss@8.4.35):
+  /postcss-normalize-url@5.1.0(postcss@8.4.38):
     resolution: {integrity: sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
       normalize-url: 6.1.0
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-normalize-whitespace@5.1.1(postcss@8.4.35):
+  /postcss-normalize-whitespace@5.1.1(postcss@8.4.38):
     resolution: {integrity: sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-normalize@10.0.1(browserslist@4.23.0)(postcss@8.4.35):
+  /postcss-normalize@10.0.1(browserslist@4.23.0)(postcss@8.4.38):
     resolution: {integrity: sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==}
     engines: {node: '>= 12'}
     peerDependencies:
@@ -10473,138 +9247,138 @@ packages:
     dependencies:
       '@csstools/normalize.css': 12.1.1
       browserslist: 4.23.0
-      postcss: 8.4.35
-      postcss-browser-comments: 4.0.0(browserslist@4.23.0)(postcss@8.4.35)
+      postcss: 8.4.38
+      postcss-browser-comments: 4.0.0(browserslist@4.23.0)(postcss@8.4.38)
       sanitize.css: 13.0.0
     dev: false
 
-  /postcss-opacity-percentage@1.1.3(postcss@8.4.35):
+  /postcss-opacity-percentage@1.1.3(postcss@8.4.38):
     resolution: {integrity: sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-ordered-values@5.1.3(postcss@8.4.35):
+  /postcss-ordered-values@5.1.3(postcss@8.4.38):
     resolution: {integrity: sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      cssnano-utils: 3.1.0(postcss@8.4.35)
-      postcss: 8.4.35
+      cssnano-utils: 3.1.0(postcss@8.4.38)
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-overflow-shorthand@3.0.4(postcss@8.4.35):
+  /postcss-overflow-shorthand@3.0.4(postcss@8.4.38):
     resolution: {integrity: sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-page-break@3.0.4(postcss@8.4.35):
+  /postcss-page-break@3.0.4(postcss@8.4.38):
     resolution: {integrity: sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==}
     peerDependencies:
       postcss: ^8
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-place@7.0.5(postcss@8.4.35):
+  /postcss-place@7.0.5(postcss@8.4.38):
     resolution: {integrity: sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-preset-env@7.8.3(postcss@8.4.35):
+  /postcss-preset-env@7.8.3(postcss@8.4.38):
     resolution: {integrity: sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      '@csstools/postcss-cascade-layers': 1.1.1(postcss@8.4.35)
-      '@csstools/postcss-color-function': 1.1.1(postcss@8.4.35)
-      '@csstools/postcss-font-format-keywords': 1.0.1(postcss@8.4.35)
-      '@csstools/postcss-hwb-function': 1.0.2(postcss@8.4.35)
-      '@csstools/postcss-ic-unit': 1.0.1(postcss@8.4.35)
-      '@csstools/postcss-is-pseudo-class': 2.0.7(postcss@8.4.35)
-      '@csstools/postcss-nested-calc': 1.0.0(postcss@8.4.35)
-      '@csstools/postcss-normalize-display-values': 1.0.1(postcss@8.4.35)
-      '@csstools/postcss-oklab-function': 1.1.1(postcss@8.4.35)
-      '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.35)
-      '@csstools/postcss-stepped-value-functions': 1.0.1(postcss@8.4.35)
-      '@csstools/postcss-text-decoration-shorthand': 1.0.0(postcss@8.4.35)
-      '@csstools/postcss-trigonometric-functions': 1.0.2(postcss@8.4.35)
-      '@csstools/postcss-unset-value': 1.0.2(postcss@8.4.35)
-      autoprefixer: 10.4.18(postcss@8.4.35)
+      '@csstools/postcss-cascade-layers': 1.1.1(postcss@8.4.38)
+      '@csstools/postcss-color-function': 1.1.1(postcss@8.4.38)
+      '@csstools/postcss-font-format-keywords': 1.0.1(postcss@8.4.38)
+      '@csstools/postcss-hwb-function': 1.0.2(postcss@8.4.38)
+      '@csstools/postcss-ic-unit': 1.0.1(postcss@8.4.38)
+      '@csstools/postcss-is-pseudo-class': 2.0.7(postcss@8.4.38)
+      '@csstools/postcss-nested-calc': 1.0.0(postcss@8.4.38)
+      '@csstools/postcss-normalize-display-values': 1.0.1(postcss@8.4.38)
+      '@csstools/postcss-oklab-function': 1.1.1(postcss@8.4.38)
+      '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.38)
+      '@csstools/postcss-stepped-value-functions': 1.0.1(postcss@8.4.38)
+      '@csstools/postcss-text-decoration-shorthand': 1.0.0(postcss@8.4.38)
+      '@csstools/postcss-trigonometric-functions': 1.0.2(postcss@8.4.38)
+      '@csstools/postcss-unset-value': 1.0.2(postcss@8.4.38)
+      autoprefixer: 10.4.19(postcss@8.4.38)
       browserslist: 4.23.0
-      css-blank-pseudo: 3.0.3(postcss@8.4.35)
-      css-has-pseudo: 3.0.4(postcss@8.4.35)
-      css-prefers-color-scheme: 6.0.3(postcss@8.4.35)
+      css-blank-pseudo: 3.0.3(postcss@8.4.38)
+      css-has-pseudo: 3.0.4(postcss@8.4.38)
+      css-prefers-color-scheme: 6.0.3(postcss@8.4.38)
       cssdb: 7.11.2
-      postcss: 8.4.35
-      postcss-attribute-case-insensitive: 5.0.2(postcss@8.4.35)
-      postcss-clamp: 4.1.0(postcss@8.4.35)
-      postcss-color-functional-notation: 4.2.4(postcss@8.4.35)
-      postcss-color-hex-alpha: 8.0.4(postcss@8.4.35)
-      postcss-color-rebeccapurple: 7.1.1(postcss@8.4.35)
-      postcss-custom-media: 8.0.2(postcss@8.4.35)
-      postcss-custom-properties: 12.1.11(postcss@8.4.35)
-      postcss-custom-selectors: 6.0.3(postcss@8.4.35)
-      postcss-dir-pseudo-class: 6.0.5(postcss@8.4.35)
-      postcss-double-position-gradients: 3.1.2(postcss@8.4.35)
-      postcss-env-function: 4.0.6(postcss@8.4.35)
-      postcss-focus-visible: 6.0.4(postcss@8.4.35)
-      postcss-focus-within: 5.0.4(postcss@8.4.35)
-      postcss-font-variant: 5.0.0(postcss@8.4.35)
-      postcss-gap-properties: 3.0.5(postcss@8.4.35)
-      postcss-image-set-function: 4.0.7(postcss@8.4.35)
-      postcss-initial: 4.0.1(postcss@8.4.35)
-      postcss-lab-function: 4.2.1(postcss@8.4.35)
-      postcss-logical: 5.0.4(postcss@8.4.35)
-      postcss-media-minmax: 5.0.0(postcss@8.4.35)
-      postcss-nesting: 10.2.0(postcss@8.4.35)
-      postcss-opacity-percentage: 1.1.3(postcss@8.4.35)
-      postcss-overflow-shorthand: 3.0.4(postcss@8.4.35)
-      postcss-page-break: 3.0.4(postcss@8.4.35)
-      postcss-place: 7.0.5(postcss@8.4.35)
-      postcss-pseudo-class-any-link: 7.1.6(postcss@8.4.35)
-      postcss-replace-overflow-wrap: 4.0.0(postcss@8.4.35)
-      postcss-selector-not: 6.0.1(postcss@8.4.35)
+      postcss: 8.4.38
+      postcss-attribute-case-insensitive: 5.0.2(postcss@8.4.38)
+      postcss-clamp: 4.1.0(postcss@8.4.38)
+      postcss-color-functional-notation: 4.2.4(postcss@8.4.38)
+      postcss-color-hex-alpha: 8.0.4(postcss@8.4.38)
+      postcss-color-rebeccapurple: 7.1.1(postcss@8.4.38)
+      postcss-custom-media: 8.0.2(postcss@8.4.38)
+      postcss-custom-properties: 12.1.11(postcss@8.4.38)
+      postcss-custom-selectors: 6.0.3(postcss@8.4.38)
+      postcss-dir-pseudo-class: 6.0.5(postcss@8.4.38)
+      postcss-double-position-gradients: 3.1.2(postcss@8.4.38)
+      postcss-env-function: 4.0.6(postcss@8.4.38)
+      postcss-focus-visible: 6.0.4(postcss@8.4.38)
+      postcss-focus-within: 5.0.4(postcss@8.4.38)
+      postcss-font-variant: 5.0.0(postcss@8.4.38)
+      postcss-gap-properties: 3.0.5(postcss@8.4.38)
+      postcss-image-set-function: 4.0.7(postcss@8.4.38)
+      postcss-initial: 4.0.1(postcss@8.4.38)
+      postcss-lab-function: 4.2.1(postcss@8.4.38)
+      postcss-logical: 5.0.4(postcss@8.4.38)
+      postcss-media-minmax: 5.0.0(postcss@8.4.38)
+      postcss-nesting: 10.2.0(postcss@8.4.38)
+      postcss-opacity-percentage: 1.1.3(postcss@8.4.38)
+      postcss-overflow-shorthand: 3.0.4(postcss@8.4.38)
+      postcss-page-break: 3.0.4(postcss@8.4.38)
+      postcss-place: 7.0.5(postcss@8.4.38)
+      postcss-pseudo-class-any-link: 7.1.6(postcss@8.4.38)
+      postcss-replace-overflow-wrap: 4.0.0(postcss@8.4.38)
+      postcss-selector-not: 6.0.1(postcss@8.4.38)
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-preset-mantine@1.13.0(postcss@8.4.35):
+  /postcss-preset-mantine@1.13.0(postcss@8.4.38):
     resolution: {integrity: sha512-1bv/mQz2K+/FixIMxYd83BYH7PusDZaI7LpUtKbb1l/5N5w6t1p/V9ONHfRJeeAZyfa6Xc+AtR+95VKdFXRH1g==}
     peerDependencies:
       postcss: '>=8.0.0'
     dependencies:
-      postcss: 8.4.35
-      postcss-mixins: 9.0.4(postcss@8.4.35)
-      postcss-nested: 6.0.1(postcss@8.4.35)
+      postcss: 8.4.38
+      postcss-mixins: 9.0.4(postcss@8.4.38)
+      postcss-nested: 6.0.1(postcss@8.4.38)
     dev: false
 
-  /postcss-pseudo-class-any-link@7.1.6(postcss@8.4.35):
+  /postcss-pseudo-class-any-link@7.1.6(postcss@8.4.38):
     resolution: {integrity: sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
-  /postcss-reduce-initial@5.1.2(postcss@8.4.35):
+  /postcss-reduce-initial@5.1.2(postcss@8.4.38):
     resolution: {integrity: sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
@@ -10612,34 +9386,34 @@ packages:
     dependencies:
       browserslist: 4.23.0
       caniuse-api: 3.0.0
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-reduce-transforms@5.1.0(postcss@8.4.35):
+  /postcss-reduce-transforms@5.1.0(postcss@8.4.38):
     resolution: {integrity: sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
     dev: false
 
-  /postcss-replace-overflow-wrap@4.0.0(postcss@8.4.35):
+  /postcss-replace-overflow-wrap@4.0.0(postcss@8.4.38):
     resolution: {integrity: sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==}
     peerDependencies:
       postcss: ^8.0.3
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-selector-not@6.0.1(postcss@8.4.35):
+  /postcss-selector-not@6.0.1(postcss@8.4.38):
     resolution: {integrity: sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==}
     engines: {node: ^12 || ^14 || >=16}
     peerDependencies:
       postcss: ^8.2
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
@@ -10651,33 +9425,33 @@ packages:
       util-deprecate: 1.0.2
     dev: false
 
-  /postcss-simple-vars@7.0.1(postcss@8.4.35):
+  /postcss-simple-vars@7.0.1(postcss@8.4.38):
     resolution: {integrity: sha512-5GLLXaS8qmzHMOjVxqkk1TZPf1jMqesiI7qLhnlyERalG0sMbHIbJqrcnrpmZdKCLglHnRHoEBB61RtGTsj++A==}
     engines: {node: '>=14.0'}
     peerDependencies:
       postcss: ^8.2.1
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
-  /postcss-svgo@5.1.0(postcss@8.4.35):
+  /postcss-svgo@5.1.0(postcss@8.4.38):
     resolution: {integrity: sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-value-parser: 4.2.0
       svgo: 2.8.0
     dev: false
 
-  /postcss-unique-selectors@5.1.1(postcss@8.4.35):
+  /postcss-unique-selectors@5.1.1(postcss@8.4.38):
     resolution: {integrity: sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
@@ -10699,16 +9473,16 @@ packages:
     dependencies:
       nanoid: 3.3.7
       picocolors: 1.0.0
-      source-map-js: 1.0.2
+      source-map-js: 1.2.0
     dev: false
 
-  /postcss@8.4.35:
-    resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==}
+  /postcss@8.4.38:
+    resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==}
     engines: {node: ^10 || ^12 || >=14}
     dependencies:
       nanoid: 3.3.7
       picocolors: 1.0.0
-      source-map-js: 1.0.2
+      source-map-js: 1.2.0
 
   /potpack@2.0.0:
     resolution: {integrity: sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==}
@@ -10903,7 +9677,7 @@ packages:
     resolution: {integrity: sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==}
     engines: {node: '>=14'}
     dependencies:
-      core-js: 3.36.0
+      core-js: 3.36.1
       object-assign: 4.1.1
       promise: 8.3.0
       raf: 3.4.1
@@ -10911,7 +9685,7 @@ packages:
       whatwg-fetch: 3.6.20
     dev: false
 
-  /react-dev-utils@12.0.1(eslint@8.57.0)(typescript@5.4.2)(webpack@5.90.3):
+  /react-dev-utils@12.0.1(eslint@8.57.0)(typescript@5.4.3)(webpack@5.91.0):
     resolution: {integrity: sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==}
     engines: {node: '>=14'}
     peerDependencies:
@@ -10921,7 +9695,7 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@babel/code-frame': 7.23.5
+      '@babel/code-frame': 7.24.2
       address: 1.2.2
       browserslist: 4.23.0
       chalk: 4.1.2
@@ -10930,7 +9704,7 @@ packages:
       escape-string-regexp: 4.0.0
       filesize: 8.0.7
       find-up: 5.0.0
-      fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.0)(typescript@5.4.2)(webpack@5.90.3)
+      fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.0)(typescript@5.4.3)(webpack@5.91.0)
       global-modules: 2.0.0
       globby: 11.1.0
       gzip-size: 6.0.0
@@ -10945,8 +9719,8 @@ packages:
       shell-quote: 1.8.1
       strip-ansi: 6.0.1
       text-table: 0.2.0
-      typescript: 5.4.2
-      webpack: 5.90.3
+      typescript: 5.4.3
+      webpack: 5.91.0
     transitivePeerDependencies:
       - eslint
       - supports-color
@@ -11007,8 +9781,8 @@ packages:
       react-dom: 18.2.0(react@18.2.0)
     dev: false
 
-  /react-number-format@5.3.3(react-dom@18.2.0)(react@18.2.0):
-    resolution: {integrity: sha512-maGHWmOvwYzyeRIpL0YC6drWqYaX6iFqjisdJXpZ+HzEtSEJsL6nqw4azTpF5Sm6SAvwUeAr7JY924Ebqq8EdA==}
+  /react-number-format@5.3.4(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-2hHN5mbLuCDUx19bv0Q8wet67QqYK6xmtLQeY5xx+h7UXiMmRtaCwqko4mMPoKXLc6xAzwRrutg8XbTRlsfjRg==}
     peerDependencies:
       react: ^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
       react-dom: ^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
@@ -11028,7 +9802,7 @@ packages:
     engines: {node: '>=0.10.0'}
     dev: false
 
-  /react-remove-scroll-bar@2.3.6(@types/react@18.2.66)(react@18.2.0):
+  /react-remove-scroll-bar@2.3.6(@types/react@18.2.73)(react@18.2.0):
     resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==}
     engines: {node: '>=10'}
     peerDependencies:
@@ -11038,14 +9812,14 @@ packages:
       '@types/react':
         optional: true
     dependencies:
-      '@types/react': 18.2.66
+      '@types/react': 18.2.73
       react: 18.2.0
-      react-style-singleton: 2.2.1(@types/react@18.2.66)(react@18.2.0)
+      react-style-singleton: 2.2.1(@types/react@18.2.73)(react@18.2.0)
       tslib: 2.6.2
     dev: false
 
-  /react-remove-scroll@2.5.7(@types/react@18.2.66)(react@18.2.0):
-    resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==}
+  /react-remove-scroll@2.5.9(@types/react@18.2.73)(react@18.2.0):
+    resolution: {integrity: sha512-bvHCLBrFfM2OgcrpPY2YW84sPdS2o2HKWJUf1xGyGLnSoEnOTOBpahIarjRuYtN0ryahCeP242yf+5TrBX/pZA==}
     engines: {node: '>=10'}
     peerDependencies:
       '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
@@ -11054,13 +9828,13 @@ packages:
       '@types/react':
         optional: true
     dependencies:
-      '@types/react': 18.2.66
+      '@types/react': 18.2.73
       react: 18.2.0
-      react-remove-scroll-bar: 2.3.6(@types/react@18.2.66)(react@18.2.0)
-      react-style-singleton: 2.2.1(@types/react@18.2.66)(react@18.2.0)
+      react-remove-scroll-bar: 2.3.6(@types/react@18.2.73)(react@18.2.0)
+      react-style-singleton: 2.2.1(@types/react@18.2.73)(react@18.2.0)
       tslib: 2.6.2
-      use-callback-ref: 1.3.1(@types/react@18.2.66)(react@18.2.0)
-      use-sidecar: 1.1.2(@types/react@18.2.66)(react@18.2.0)
+      use-callback-ref: 1.3.2(@types/react@18.2.73)(react@18.2.0)
+      use-sidecar: 1.1.2(@types/react@18.2.73)(react@18.2.0)
     dev: false
 
   /react-router-dom@6.22.3(react-dom@18.2.0)(react@18.2.0):
@@ -11086,7 +9860,7 @@ packages:
       react: 18.2.0
     dev: false
 
-  /react-scripts@5.0.1(@babel/plugin-syntax-flow@7.24.1)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(react@18.2.0)(sass@1.72.0)(typescript@5.4.2):
+  /react-scripts@5.0.1(@babel/plugin-syntax-flow@7.24.1)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(react@18.2.0)(sass@1.72.0)(typescript@5.4.3):
     resolution: {integrity: sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==}
     engines: {node: '>=14.0.0'}
     hasBin: true
@@ -11098,55 +9872,55 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@babel/core': 7.24.0
-      '@pmmmwh/react-refresh-webpack-plugin': 0.5.11(react-refresh@0.11.0)(webpack-dev-server@4.15.1)(webpack@5.90.3)
+      '@babel/core': 7.24.3
+      '@pmmmwh/react-refresh-webpack-plugin': 0.5.11(react-refresh@0.11.0)(webpack-dev-server@4.15.2)(webpack@5.91.0)
       '@svgr/webpack': 5.5.0
-      babel-jest: 27.5.1(@babel/core@7.24.0)
-      babel-loader: 8.3.0(@babel/core@7.24.0)(webpack@5.90.3)
-      babel-plugin-named-asset-import: 0.3.8(@babel/core@7.24.0)
+      babel-jest: 27.5.1(@babel/core@7.24.3)
+      babel-loader: 8.3.0(@babel/core@7.24.3)(webpack@5.91.0)
+      babel-plugin-named-asset-import: 0.3.8(@babel/core@7.24.3)
       babel-preset-react-app: 10.0.1
       bfj: 7.1.0
       browserslist: 4.23.0
       camelcase: 6.3.0
       case-sensitive-paths-webpack-plugin: 2.4.0
-      css-loader: 6.10.0(webpack@5.90.3)
-      css-minimizer-webpack-plugin: 3.4.1(webpack@5.90.3)
+      css-loader: 6.10.0(webpack@5.91.0)
+      css-minimizer-webpack-plugin: 3.4.1(webpack@5.91.0)
       dotenv: 10.0.0
       dotenv-expand: 5.1.0
       eslint: 8.57.0
-      eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.24.1)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(jest@27.5.1)(typescript@5.4.2)
-      eslint-webpack-plugin: 3.2.0(eslint@8.57.0)(webpack@5.90.3)
-      file-loader: 6.2.0(webpack@5.90.3)
+      eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.24.1)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(jest@27.5.1)(typescript@5.4.3)
+      eslint-webpack-plugin: 3.2.0(eslint@8.57.0)(webpack@5.91.0)
+      file-loader: 6.2.0(webpack@5.91.0)
       fs-extra: 10.1.0
-      html-webpack-plugin: 5.6.0(webpack@5.90.3)
+      html-webpack-plugin: 5.6.0(webpack@5.91.0)
       identity-obj-proxy: 3.0.0
       jest: 27.5.1
       jest-resolve: 27.5.1
       jest-watch-typeahead: 1.1.0(jest@27.5.1)
-      mini-css-extract-plugin: 2.8.1(webpack@5.90.3)
-      postcss: 8.4.35
-      postcss-flexbugs-fixes: 5.0.2(postcss@8.4.35)
-      postcss-loader: 6.2.1(postcss@8.4.35)(webpack@5.90.3)
-      postcss-normalize: 10.0.1(browserslist@4.23.0)(postcss@8.4.35)
-      postcss-preset-env: 7.8.3(postcss@8.4.35)
+      mini-css-extract-plugin: 2.8.1(webpack@5.91.0)
+      postcss: 8.4.38
+      postcss-flexbugs-fixes: 5.0.2(postcss@8.4.38)
+      postcss-loader: 6.2.1(postcss@8.4.38)(webpack@5.91.0)
+      postcss-normalize: 10.0.1(browserslist@4.23.0)(postcss@8.4.38)
+      postcss-preset-env: 7.8.3(postcss@8.4.38)
       prompts: 2.4.2
       react: 18.2.0
       react-app-polyfill: 3.0.0
-      react-dev-utils: 12.0.1(eslint@8.57.0)(typescript@5.4.2)(webpack@5.90.3)
+      react-dev-utils: 12.0.1(eslint@8.57.0)(typescript@5.4.3)(webpack@5.91.0)
       react-refresh: 0.11.0
       resolve: 1.22.8
       resolve-url-loader: 4.0.0
-      sass-loader: 12.6.0(sass@1.72.0)(webpack@5.90.3)
+      sass-loader: 12.6.0(sass@1.72.0)(webpack@5.91.0)
       semver: 7.6.0
-      source-map-loader: 3.0.2(webpack@5.90.3)
-      style-loader: 3.3.4(webpack@5.90.3)
-      tailwindcss: 3.4.1
-      terser-webpack-plugin: 5.3.10(webpack@5.90.3)
-      typescript: 5.4.2
-      webpack: 5.90.3
-      webpack-dev-server: 4.15.1(webpack@5.90.3)
-      webpack-manifest-plugin: 4.1.1(webpack@5.90.3)
-      workbox-webpack-plugin: 6.6.0(webpack@5.90.3)
+      source-map-loader: 3.0.2(webpack@5.91.0)
+      style-loader: 3.3.4(webpack@5.91.0)
+      tailwindcss: 3.4.3
+      terser-webpack-plugin: 5.3.10(webpack@5.91.0)
+      typescript: 5.4.3
+      webpack: 5.91.0
+      webpack-dev-server: 4.15.2(webpack@5.91.0)
+      webpack-manifest-plugin: 4.1.1(webpack@5.91.0)
+      workbox-webpack-plugin: 6.6.0(webpack@5.91.0)
     optionalDependencies:
       fsevents: 2.3.3
     transitivePeerDependencies:
@@ -11184,7 +9958,7 @@ packages:
       - webpack-plugin-serve
     dev: false
 
-  /react-style-singleton@2.2.1(@types/react@18.2.66)(react@18.2.0):
+  /react-style-singleton@2.2.1(@types/react@18.2.73)(react@18.2.0):
     resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==}
     engines: {node: '>=10'}
     peerDependencies:
@@ -11194,23 +9968,23 @@ packages:
       '@types/react':
         optional: true
     dependencies:
-      '@types/react': 18.2.66
+      '@types/react': 18.2.73
       get-nonce: 1.0.1
       invariant: 2.2.4
       react: 18.2.0
       tslib: 2.6.2
     dev: false
 
-  /react-textarea-autosize@8.5.3(@types/react@18.2.66)(react@18.2.0):
+  /react-textarea-autosize@8.5.3(@types/react@18.2.73)(react@18.2.0):
     resolution: {integrity: sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==}
     engines: {node: '>=10'}
     peerDependencies:
       react: ^16.8.0 || ^17.0.0 || ^18.0.0
     dependencies:
-      '@babel/runtime': 7.24.0
+      '@babel/runtime': 7.24.1
       react: 18.2.0
       use-composed-ref: 1.3.0(react@18.2.0)
-      use-latest: 1.2.1(@types/react@18.2.66)(react@18.2.0)
+      use-latest: 1.2.1(@types/react@18.2.73)(react@18.2.0)
     transitivePeerDependencies:
       - '@types/react'
     dev: false
@@ -11221,7 +9995,7 @@ packages:
       react: '>=16.6.0'
       react-dom: '>=16.6.0'
     dependencies:
-      '@babel/runtime': 7.24.0
+      '@babel/runtime': 7.24.1
       dom-helpers: 5.2.1
       loose-envify: 1.4.0
       prop-types: 15.8.1
@@ -11275,13 +10049,13 @@ packages:
       minimatch: 3.1.2
     dev: false
 
-  /reflect.getprototypeof@1.0.5:
-    resolution: {integrity: sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==}
+  /reflect.getprototypeof@1.0.6:
+    resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.23.0
+      es-abstract: 1.23.3
       es-errors: 1.3.0
       get-intrinsic: 1.2.4
       globalthis: 1.0.3
@@ -11307,7 +10081,7 @@ packages:
   /regenerator-transform@0.15.2:
     resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==}
     dependencies:
-      '@babel/runtime': 7.24.0
+      '@babel/runtime': 7.24.1
 
   /regex-parser@2.3.0:
     resolution: {integrity: sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==}
@@ -11453,11 +10227,11 @@ packages:
     peerDependencies:
       rollup: ^2.0.0
     dependencies:
-      '@babel/code-frame': 7.23.5
+      '@babel/code-frame': 7.24.2
       jest-worker: 26.6.2
       rollup: 2.79.1
       serialize-javascript: 4.0.0
-      terser: 5.29.2
+      terser: 5.30.0
 
   /rollup@2.79.1:
     resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==}
@@ -11466,26 +10240,28 @@ packages:
     optionalDependencies:
       fsevents: 2.3.3
 
-  /rollup@4.13.0:
-    resolution: {integrity: sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==}
+  /rollup@4.13.2:
+    resolution: {integrity: sha512-MIlLgsdMprDBXC+4hsPgzWUasLO9CE4zOkj/u6j+Z6j5A4zRY+CtiXAdJyPtgCsc42g658Aeh1DlrdVEJhsL2g==}
     engines: {node: '>=18.0.0', npm: '>=8.0.0'}
     hasBin: true
     dependencies:
       '@types/estree': 1.0.5
     optionalDependencies:
-      '@rollup/rollup-android-arm-eabi': 4.13.0
-      '@rollup/rollup-android-arm64': 4.13.0
-      '@rollup/rollup-darwin-arm64': 4.13.0
-      '@rollup/rollup-darwin-x64': 4.13.0
-      '@rollup/rollup-linux-arm-gnueabihf': 4.13.0
-      '@rollup/rollup-linux-arm64-gnu': 4.13.0
-      '@rollup/rollup-linux-arm64-musl': 4.13.0
-      '@rollup/rollup-linux-riscv64-gnu': 4.13.0
-      '@rollup/rollup-linux-x64-gnu': 4.13.0
-      '@rollup/rollup-linux-x64-musl': 4.13.0
-      '@rollup/rollup-win32-arm64-msvc': 4.13.0
-      '@rollup/rollup-win32-ia32-msvc': 4.13.0
-      '@rollup/rollup-win32-x64-msvc': 4.13.0
+      '@rollup/rollup-android-arm-eabi': 4.13.2
+      '@rollup/rollup-android-arm64': 4.13.2
+      '@rollup/rollup-darwin-arm64': 4.13.2
+      '@rollup/rollup-darwin-x64': 4.13.2
+      '@rollup/rollup-linux-arm-gnueabihf': 4.13.2
+      '@rollup/rollup-linux-arm64-gnu': 4.13.2
+      '@rollup/rollup-linux-arm64-musl': 4.13.2
+      '@rollup/rollup-linux-powerpc64le-gnu': 4.13.2
+      '@rollup/rollup-linux-riscv64-gnu': 4.13.2
+      '@rollup/rollup-linux-s390x-gnu': 4.13.2
+      '@rollup/rollup-linux-x64-gnu': 4.13.2
+      '@rollup/rollup-linux-x64-musl': 4.13.2
+      '@rollup/rollup-win32-arm64-msvc': 4.13.2
+      '@rollup/rollup-win32-ia32-msvc': 4.13.2
+      '@rollup/rollup-win32-x64-msvc': 4.13.2
       fsevents: 2.3.3
 
   /run-parallel@1.2.0:
@@ -11529,7 +10305,7 @@ packages:
     resolution: {integrity: sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==}
     dev: false
 
-  /sass-loader@12.6.0(sass@1.72.0)(webpack@5.90.3):
+  /sass-loader@12.6.0(sass@1.72.0)(webpack@5.91.0):
     resolution: {integrity: sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==}
     engines: {node: '>= 12.13.0'}
     peerDependencies:
@@ -11551,7 +10327,7 @@ packages:
       klona: 2.0.6
       neo-async: 2.6.2
       sass: 1.72.0
-      webpack: 5.90.3
+      webpack: 5.91.0
     dev: false
 
   /sass@1.72.0:
@@ -11561,7 +10337,7 @@ packages:
     dependencies:
       chokidar: 3.6.0
       immutable: 4.3.5
-      source-map-js: 1.0.2
+      source-map-js: 1.2.0
 
   /sax@1.2.4:
     resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==}
@@ -11869,11 +10645,11 @@ packages:
     resolution: {integrity: sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==}
     dev: false
 
-  /source-map-js@1.0.2:
-    resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
+  /source-map-js@1.2.0:
+    resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
     engines: {node: '>=0.10.0'}
 
-  /source-map-loader@3.0.2(webpack@5.90.3):
+  /source-map-loader@3.0.2(webpack@5.91.0):
     resolution: {integrity: sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg==}
     engines: {node: '>= 12.13.0'}
     peerDependencies:
@@ -11881,8 +10657,8 @@ packages:
     dependencies:
       abab: 2.0.6
       iconv-lite: 0.6.3
-      source-map-js: 1.0.2
-      webpack: 5.90.3
+      source-map-js: 1.2.0
+      webpack: 5.91.0
     dev: false
 
   /source-map-support@0.5.21:
@@ -12026,40 +10802,46 @@ packages:
       strip-ansi: 7.1.0
     dev: false
 
-  /string.prototype.matchall@4.0.10:
-    resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==}
+  /string.prototype.matchall@4.0.11:
+    resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==}
+    engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
+      es-errors: 1.3.0
+      es-object-atoms: 1.0.0
       get-intrinsic: 1.2.4
+      gopd: 1.0.1
       has-symbols: 1.0.3
       internal-slot: 1.0.7
       regexp.prototype.flags: 1.5.2
       set-function-name: 2.0.2
       side-channel: 1.0.6
 
-  /string.prototype.trim@1.2.8:
-    resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==}
+  /string.prototype.trim@1.2.9:
+    resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
+      es-object-atoms: 1.0.0
 
-  /string.prototype.trimend@1.0.7:
-    resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==}
+  /string.prototype.trimend@1.0.8:
+    resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==}
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-object-atoms: 1.0.0
 
-  /string.prototype.trimstart@1.0.7:
-    resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==}
+  /string.prototype.trimstart@1.0.8:
+    resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
+    engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.7
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-object-atoms: 1.0.0
 
   /string_decoder@1.1.1:
     resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
@@ -12123,13 +10905,13 @@ packages:
     engines: {node: '>=8'}
     dev: false
 
-  /style-loader@3.3.4(webpack@5.90.3):
+  /style-loader@3.3.4(webpack@5.91.0):
     resolution: {integrity: sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==}
     engines: {node: '>= 12.13.0'}
     peerDependencies:
       webpack: ^5.0.0
     dependencies:
-      webpack: 5.90.3
+      webpack: 5.91.0
     dev: false
 
   /styled-components@6.1.8(react-dom@18.2.0)(react@18.2.0):
@@ -12152,14 +10934,14 @@ packages:
       tslib: 2.5.0
     dev: false
 
-  /stylehacks@5.1.1(postcss@8.4.35):
+  /stylehacks@5.1.1(postcss@8.4.38):
     resolution: {integrity: sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==}
     engines: {node: ^10 || ^12 || >=14.0}
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
       browserslist: 4.23.0
-      postcss: 8.4.35
+      postcss: 8.4.38
       postcss-selector-parser: 6.0.16
     dev: false
 
@@ -12174,20 +10956,20 @@ packages:
     dependencies:
       '@jridgewell/gen-mapping': 0.3.5
       commander: 4.1.1
-      glob: 10.3.10
+      glob: 10.3.12
       lines-and-columns: 1.2.4
       mz: 2.7.0
       pirates: 4.0.6
       ts-interface-checker: 0.1.13
     dev: false
 
-  /sugarss@4.0.1(postcss@8.4.35):
+  /sugarss@4.0.1(postcss@8.4.38):
     resolution: {integrity: sha512-WCjS5NfuVJjkQzK10s8WOBY+hhDxxNt/N6ZaGwxFZ+wN3/lKKFSaaKUNecULcTTvE4urLcKaZFQD8vO0mOZujw==}
     engines: {node: '>=12.0'}
     peerDependencies:
       postcss: ^8.3.3
     dependencies:
-      postcss: 8.4.35
+      postcss: 8.4.38
     dev: false
 
   /supercluster@8.0.1:
@@ -12245,7 +11027,7 @@ packages:
       csso: 4.2.0
       js-yaml: 3.14.1
       mkdirp: 0.5.6
-      object.values: 1.1.7
+      object.values: 1.2.0
       sax: 1.2.4
       stable: 0.1.8
       unquote: 1.1.1
@@ -12274,8 +11056,8 @@ packages:
     resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
     dev: false
 
-  /tailwindcss@3.4.1:
-    resolution: {integrity: sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==}
+  /tailwindcss@3.4.3:
+    resolution: {integrity: sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==}
     engines: {node: '>=14.0.0'}
     hasBin: true
     dependencies:
@@ -12293,11 +11075,11 @@ packages:
       normalize-path: 3.0.0
       object-hash: 3.0.0
       picocolors: 1.0.0
-      postcss: 8.4.35
-      postcss-import: 15.1.0(postcss@8.4.35)
-      postcss-js: 4.0.1(postcss@8.4.35)
-      postcss-load-config: 4.0.2(postcss@8.4.35)
-      postcss-nested: 6.0.1(postcss@8.4.35)
+      postcss: 8.4.38
+      postcss-import: 15.1.0(postcss@8.4.38)
+      postcss-js: 4.0.1(postcss@8.4.38)
+      postcss-load-config: 4.0.2(postcss@8.4.38)
+      postcss-nested: 6.0.1(postcss@8.4.38)
       postcss-selector-parser: 6.0.16
       resolve: 1.22.8
       sucrase: 3.35.0
@@ -12374,7 +11156,7 @@ packages:
       supports-hyperlinks: 2.3.0
     dev: false
 
-  /terser-webpack-plugin@5.3.10(webpack@5.90.3):
+  /terser-webpack-plugin@5.3.10(webpack@5.91.0):
     resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==}
     engines: {node: '>= 10.13.0'}
     peerDependencies:
@@ -12394,12 +11176,12 @@ packages:
       jest-worker: 27.5.1
       schema-utils: 3.3.0
       serialize-javascript: 6.0.2
-      terser: 5.29.2
-      webpack: 5.90.3
+      terser: 5.30.0
+      webpack: 5.91.0
     dev: false
 
-  /terser@5.29.2:
-    resolution: {integrity: sha512-ZiGkhUBIM+7LwkNjXYJq8svgkd+QK3UUr0wJqY4MieaezBSAIPgbSPZyIx0idM6XWK5CMzSWa8MJIzmRcB8Caw==}
+  /terser@5.30.0:
+    resolution: {integrity: sha512-Y/SblUl5kEyEFzhMAQdsxVHh+utAxd4IuRNJzKywY/4uzSogh3G219jqbDDxYu4MXO9CzY3tSEqmZvW6AoEDJw==}
     engines: {node: '>=10'}
     hasBin: true
     dependencies:
@@ -12495,13 +11277,13 @@ packages:
     resolution: {integrity: sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==}
     dev: false
 
-  /ts-api-utils@1.3.0(typescript@5.4.2):
+  /ts-api-utils@1.3.0(typescript@5.4.3):
     resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==}
     engines: {node: '>=16'}
     peerDependencies:
       typescript: '>=4.2.0'
     dependencies:
-      typescript: 5.4.2
+      typescript: 5.4.3
     dev: false
 
   /ts-interface-checker@0.1.13:
@@ -12529,14 +11311,14 @@ packages:
     resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
     dev: false
 
-  /tsutils@3.21.0(typescript@5.4.2):
+  /tsutils@3.21.0(typescript@5.4.3):
     resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
     engines: {node: '>= 6'}
     peerDependencies:
       typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
     dependencies:
       tslib: 1.14.1
-      typescript: 5.4.2
+      typescript: 5.4.3
     dev: false
 
   /tunnel-agent@0.6.0:
@@ -12582,8 +11364,8 @@ packages:
     engines: {node: '>=10'}
     dev: false
 
-  /type-fest@4.12.0:
-    resolution: {integrity: sha512-5Y2/pp2wtJk8o08G0CMkuFPCO354FGwk/vbidxrdhRGZfd0tFnb4Qb8anp9XxXriwBgVPjdWbKpGl4J9lJY2jQ==}
+  /type-fest@4.14.0:
+    resolution: {integrity: sha512-on5/Cw89wwqGZQu+yWO0gGMGu8VNxsaW9SB2HE8yJjllEk7IDTwnSN1dUVldYILhYPN5HzD7WAaw2cc/jBfn0Q==}
     engines: {node: '>=16'}
     dev: false
 
@@ -12624,8 +11406,8 @@ packages:
       has-proto: 1.0.3
       is-typed-array: 1.1.13
 
-  /typed-array-length@1.0.5:
-    resolution: {integrity: sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==}
+  /typed-array-length@1.0.6:
+    resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.7
@@ -12641,8 +11423,8 @@ packages:
       is-typedarray: 1.0.0
     dev: false
 
-  /typescript@5.4.2:
-    resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==}
+  /typescript@5.4.3:
+    resolution: {integrity: sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==}
     engines: {node: '>=14.17'}
     hasBin: true
     dev: false
@@ -12764,8 +11546,8 @@ packages:
       requires-port: 1.0.0
     dev: false
 
-  /use-callback-ref@1.3.1(@types/react@18.2.66)(react@18.2.0):
-    resolution: {integrity: sha512-Lg4Vx1XZQauB42Hw3kK7JM6yjVjgFmFC5/Ab797s79aARomD2nEErc4mCgM8EZrARLmmbWpi5DGCadmK50DcAQ==}
+  /use-callback-ref@1.3.2(@types/react@18.2.73)(react@18.2.0):
+    resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==}
     engines: {node: '>=10'}
     peerDependencies:
       '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
@@ -12774,7 +11556,7 @@ packages:
       '@types/react':
         optional: true
     dependencies:
-      '@types/react': 18.2.66
+      '@types/react': 18.2.73
       react: 18.2.0
       tslib: 2.6.2
     dev: false
@@ -12787,7 +11569,7 @@ packages:
       react: 18.2.0
     dev: false
 
-  /use-isomorphic-layout-effect@1.1.2(@types/react@18.2.66)(react@18.2.0):
+  /use-isomorphic-layout-effect@1.1.2(@types/react@18.2.73)(react@18.2.0):
     resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==}
     peerDependencies:
       '@types/react': '*'
@@ -12796,11 +11578,11 @@ packages:
       '@types/react':
         optional: true
     dependencies:
-      '@types/react': 18.2.66
+      '@types/react': 18.2.73
       react: 18.2.0
     dev: false
 
-  /use-latest@1.2.1(@types/react@18.2.66)(react@18.2.0):
+  /use-latest@1.2.1(@types/react@18.2.73)(react@18.2.0):
     resolution: {integrity: sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==}
     peerDependencies:
       '@types/react': '*'
@@ -12809,12 +11591,12 @@ packages:
       '@types/react':
         optional: true
     dependencies:
-      '@types/react': 18.2.66
+      '@types/react': 18.2.73
       react: 18.2.0
-      use-isomorphic-layout-effect: 1.1.2(@types/react@18.2.66)(react@18.2.0)
+      use-isomorphic-layout-effect: 1.1.2(@types/react@18.2.73)(react@18.2.0)
     dev: false
 
-  /use-sidecar@1.1.2(@types/react@18.2.66)(react@18.2.0):
+  /use-sidecar@1.1.2(@types/react@18.2.73)(react@18.2.0):
     resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==}
     engines: {node: '>=10'}
     peerDependencies:
@@ -12824,7 +11606,7 @@ packages:
       '@types/react':
         optional: true
     dependencies:
-      '@types/react': 18.2.66
+      '@types/react': 18.2.73
       detect-node-es: 1.1.0
       react: 18.2.0
       tslib: 2.6.2
@@ -12845,9 +11627,9 @@ packages:
     resolution: {integrity: sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==}
     dependencies:
       define-properties: 1.2.1
-      es-abstract: 1.22.5
+      es-abstract: 1.23.3
       has-symbols: 1.0.3
-      object.getownpropertydescriptors: 2.1.7
+      object.getownpropertydescriptors: 2.1.8
     dev: false
 
   /utila@0.4.0:
@@ -12878,7 +11660,7 @@ packages:
     engines: {node: '>= 0.8'}
     dev: false
 
-  /vite-plugin-pwa@0.19.7(@vite-pwa/assets-generator@0.2.4)(vite@5.1.6)(workbox-build@7.0.0)(workbox-window@7.0.0):
+  /vite-plugin-pwa@0.19.7(@vite-pwa/assets-generator@0.2.4)(vite@5.2.7)(workbox-build@7.0.0)(workbox-window@7.0.0):
     resolution: {integrity: sha512-18TECxoGPQE7tVZzKxbf5Icrl5688n1JGMPSgGotTsh89vLDxevY7ICfD3CFVfonZXh8ckuyJXg0NXE5+FAl2A==}
     engines: {node: '>=16.0.0'}
     peerDependencies:
@@ -12894,15 +11676,15 @@ packages:
       debug: 4.3.4
       fast-glob: 3.3.2
       pretty-bytes: 6.1.1
-      vite: 5.1.6(sass@1.72.0)
+      vite: 5.2.7(sass@1.72.0)
       workbox-build: 7.0.0
       workbox-window: 7.0.0
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /vite@5.1.6(sass@1.72.0):
-    resolution: {integrity: sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==}
+  /vite@5.2.7(sass@1.72.0):
+    resolution: {integrity: sha512-k14PWOKLI6pMaSzAuGtT+Cf0YmIx12z9YGon39onaJNy8DLBfBJrzg9FQEmkAM5lpHBZs9wksWAsyF/HkpEwJA==}
     engines: {node: ^18.0.0 || >=20.0.0}
     hasBin: true
     peerDependencies:
@@ -12929,9 +11711,9 @@ packages:
       terser:
         optional: true
     dependencies:
-      esbuild: 0.19.12
-      postcss: 8.4.35
-      rollup: 4.13.0
+      esbuild: 0.20.2
+      postcss: 8.4.38
+      rollup: 4.13.2
       sass: 1.72.0
     optionalDependencies:
       fsevents: 2.3.3
@@ -12991,8 +11773,8 @@ packages:
     engines: {node: '>=10.4'}
     dev: false
 
-  /webpack-dev-middleware@5.3.3(webpack@5.90.3):
-    resolution: {integrity: sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==}
+  /webpack-dev-middleware@5.3.4(webpack@5.91.0):
+    resolution: {integrity: sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==}
     engines: {node: '>= 12.13.0'}
     peerDependencies:
       webpack: ^4.0.0 || ^5.0.0
@@ -13002,11 +11784,11 @@ packages:
       mime-types: 2.1.35
       range-parser: 1.2.1
       schema-utils: 4.2.0
-      webpack: 5.90.3
+      webpack: 5.91.0
     dev: false
 
-  /webpack-dev-server@4.15.1(webpack@5.90.3):
-    resolution: {integrity: sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==}
+  /webpack-dev-server@4.15.2(webpack@5.91.0):
+    resolution: {integrity: sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==}
     engines: {node: '>= 12.13.0'}
     hasBin: true
     peerDependencies:
@@ -13032,7 +11814,7 @@ packages:
       compression: 1.7.4
       connect-history-api-fallback: 2.0.0
       default-gateway: 6.0.3
-      express: 4.18.3
+      express: 4.19.2
       graceful-fs: 4.2.11
       html-entities: 2.5.2
       http-proxy-middleware: 2.0.6(@types/express@4.17.21)
@@ -13046,8 +11828,8 @@ packages:
       serve-index: 1.9.1
       sockjs: 0.3.24
       spdy: 4.0.2
-      webpack: 5.90.3
-      webpack-dev-middleware: 5.3.3(webpack@5.90.3)
+      webpack: 5.91.0
+      webpack-dev-middleware: 5.3.4(webpack@5.91.0)
       ws: 8.16.0
     transitivePeerDependencies:
       - bufferutil
@@ -13056,14 +11838,14 @@ packages:
       - utf-8-validate
     dev: false
 
-  /webpack-manifest-plugin@4.1.1(webpack@5.90.3):
+  /webpack-manifest-plugin@4.1.1(webpack@5.91.0):
     resolution: {integrity: sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==}
     engines: {node: '>=12.22.0'}
     peerDependencies:
       webpack: ^4.44.2 || ^5.47.0
     dependencies:
       tapable: 2.2.1
-      webpack: 5.90.3
+      webpack: 5.91.0
       webpack-sources: 2.3.1
     dev: false
 
@@ -13087,8 +11869,8 @@ packages:
     engines: {node: '>=10.13.0'}
     dev: false
 
-  /webpack@5.90.3:
-    resolution: {integrity: sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==}
+  /webpack@5.91.0:
+    resolution: {integrity: sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==}
     engines: {node: '>=10.13.0'}
     hasBin: true
     peerDependencies:
@@ -13107,7 +11889,7 @@ packages:
       browserslist: 4.23.0
       chrome-trace-event: 1.0.3
       enhanced-resolve: 5.16.0
-      es-module-lexer: 1.4.1
+      es-module-lexer: 1.5.0
       eslint-scope: 5.1.1
       events: 3.3.0
       glob-to-regexp: 0.4.1
@@ -13118,7 +11900,7 @@ packages:
       neo-async: 2.6.2
       schema-utils: 3.3.0
       tapable: 2.2.1
-      terser-webpack-plugin: 5.3.10(webpack@5.90.3)
+      terser-webpack-plugin: 5.3.10(webpack@5.91.0)
       watchpack: 2.4.1
       webpack-sources: 3.2.3
     transitivePeerDependencies:
@@ -13269,10 +12051,10 @@ packages:
     engines: {node: '>=10.0.0'}
     dependencies:
       '@apideck/better-ajv-errors': 0.3.6(ajv@8.12.0)
-      '@babel/core': 7.24.0
-      '@babel/preset-env': 7.24.0(@babel/core@7.24.0)
-      '@babel/runtime': 7.24.0
-      '@rollup/plugin-babel': 5.3.1(@babel/core@7.24.0)(rollup@2.79.1)
+      '@babel/core': 7.24.3
+      '@babel/preset-env': 7.24.3(@babel/core@7.24.3)
+      '@babel/runtime': 7.24.1
+      '@rollup/plugin-babel': 5.3.1(@babel/core@7.24.3)(rollup@2.79.1)
       '@rollup/plugin-node-resolve': 11.2.1(rollup@2.79.1)
       '@rollup/plugin-replace': 2.4.2(rollup@2.79.1)
       '@surma/rollup-plugin-off-main-thread': 2.2.3
@@ -13519,7 +12301,7 @@ packages:
     resolution: {integrity: sha512-SWfEouQfjRiZ7GNABzHUKUyj8pCoe+RwjfOIajcx6J5mtgKkN+t8UToHnpaJL5UVVOf5YhJh+OHhbVNIHe+LVA==}
     dev: true
 
-  /workbox-webpack-plugin@6.6.0(webpack@5.90.3):
+  /workbox-webpack-plugin@6.6.0(webpack@5.91.0):
     resolution: {integrity: sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==}
     engines: {node: '>=10.0.0'}
     peerDependencies:
@@ -13528,7 +12310,7 @@ packages:
       fast-json-stable-stringify: 2.1.0
       pretty-bytes: 5.6.0
       upath: 1.2.0
-      webpack: 5.90.3
+      webpack: 5.91.0
       webpack-sources: 1.4.3
       workbox-build: 6.6.0
     transitivePeerDependencies:
@@ -13663,7 +12445,7 @@ packages:
     resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==}
     dev: false
 
-  /zustand@4.5.2(@types/react@18.2.66)(react@18.2.0):
+  /zustand@4.5.2(@types/react@18.2.73)(react@18.2.0):
     resolution: {integrity: sha512-2cN1tPkDVkwCy5ickKrI7vijSjPksFRfqS6237NzT0vqSsztTNnQdHw9mmN7uBdk3gceVXU0a+21jFzFzAc9+g==}
     engines: {node: '>=12.7.0'}
     peerDependencies:
@@ -13678,7 +12460,7 @@ packages:
       react:
         optional: true
     dependencies:
-      '@types/react': 18.2.66
+      '@types/react': 18.2.73
       react: 18.2.0
       use-sync-external-store: 1.2.0(react@18.2.0)
     dev: false
diff --git a/src/components/cardCustom/noFoundTravels/NoFoundTravels.tsx b/src/components/cardCustom/noFoundTravels/NoFoundTravels.tsx
index 4794498..f5c1d8d 100644
--- a/src/components/cardCustom/noFoundTravels/NoFoundTravels.tsx
+++ b/src/components/cardCustom/noFoundTravels/NoFoundTravels.tsx
@@ -1,26 +1,30 @@
 import { Image, Button, Container, Flex, Title } from '@mantine/core';
+import { useMediaQuery } from '@mantine/hooks';
 import { IconSquareRoundedPlusFilled } from '@tabler/icons-react';
 
 const NoFoundTravels = () => {
+  const isMobile = useMediaQuery('(max-width: 768px)');
+
   return (
     <Container size="xl" pt="xl">
       <Flex
         gap="md"
-        justify="flex-start"
+        justify="center"
         align="center"
         direction="column"
         wrap="wrap">
-        <Title mt="sm" size="sm" c="teal">
-          Vous avez actuellement aucun voyage prévue, en cours ou terminé
+        <Title mt="sm" size="sm" c="teal" ta="center">
+          Vous n'avez actuellement aucun voyage prévu, en cours ou terminé
         </Title>
         <Image
-          h={500}
-          w={600}
+          h={300}
+          w={isMobile ? '100%' : 500}
           src="https://img.lemde.fr/2020/08/06/0/153/2480/1653/1440/960/60/0/8214e3b_835252256-dossier_univ_shanghai_2020_bonhomme_05-copie.jpg"
         />
         <Button
           variant="light"
-          rightSection={<IconSquareRoundedPlusFilled size={14} />}>
+          rightSection={<IconSquareRoundedPlusFilled size={14} />}
+          mt="md">
           Créer un nouveau voyage
         </Button>
       </Flex>
diff --git a/src/components/footer/DefaultFooter.tsx b/src/components/footer/DefaultFooter.tsx
index 0d008be..79ba147 100644
--- a/src/components/footer/DefaultFooter.tsx
+++ b/src/components/footer/DefaultFooter.tsx
@@ -6,17 +6,16 @@ import { useMediaQuery } from '@mantine/hooks';
 
 const data = [
   {
-    title: 'Voyages',
+    title: 'Votre compte',
     links: [
-      { label: 'Planifiez votre voyage', url: '#' },
-      { label: 'Avis', url: '/feedback' },
+      { label: 'Voir mon profil', url: '/profile' },
+      { label: 'Mes voyages', url: '/trips' },
     ],
   },
   {
-    title: 'Votre compte',
+    title: 'Informations',
     links: [
-      { label: 'Voir mon profil', url: '/profile' },
-      { label: 'Mes voyages', url: '#' },
+      { label: 'Avis', url: '/feedback' },
       { label: 'CGU', url: '/cgu' },
     ],
   },
@@ -37,11 +36,12 @@ const DefaultFooter = () => {
     navigate('/');
   };
 
-  const groups = data.map(group => {
+  const groups = data.map((group) => {
     const links = group.links.map((link, index) => (
       <Text
         key={index}
         className="footer__link"
+        ta="center"
         pt={5}
         onClick={() => navigate(link.url)}>
         {link.label}
@@ -50,7 +50,9 @@ const DefaultFooter = () => {
 
     return (
       <div key={group.title}>
-        <Text className="footer__title">{group.title}</Text>
+        <Text className="footer__title" ta="center">
+          {group.title}
+        </Text>
         {links}
       </div>
     );
diff --git a/src/components/header/DefaultHeader.tsx b/src/components/header/DefaultHeader.tsx
index 4113443..1c78475 100644
--- a/src/components/header/DefaultHeader.tsx
+++ b/src/components/header/DefaultHeader.tsx
@@ -67,10 +67,11 @@ const DefaultHeader = (props: DefaultHeaderProps) => {
         <Image
           src="/logo.svg"
           alt="Logo du site"
-          onClick={handleClickLogo}
           className="cursor-pointer"
           height={40}
           width={40}
+          ms="md"
+          onClick={handleClickLogo}
         />
         <Group>
           <OfflineComponent />
diff --git a/src/components/map/MapComponent.tsx b/src/components/map/MapComponent.tsx
index acc0f43..0ec8635 100644
--- a/src/components/map/MapComponent.tsx
+++ b/src/components/map/MapComponent.tsx
@@ -4,7 +4,7 @@ import {
   TravelDtoList,
   UpdateStepLocationDto,
 } from '@FullStackMap/from-a2b';
-import { ActionIcon, Box, LoadingOverlay } from '@mantine/core';
+import { ActionIcon, Box, Grid, LoadingOverlay, Paper } from '@mantine/core';
 import { FeatureCollection, Position } from 'geojson';
 import {
   GeolocateControl,
@@ -17,7 +17,7 @@ import {
   Source,
 } from 'react-map-gl';
 
-import { useDisclosure } from '@mantine/hooks';
+import { useDisclosure, useMediaQuery } from '@mantine/hooks';
 import { IconCirclePlus, IconPinnedFilled } from '@tabler/icons-react';
 import { useMutation, useQueryClient } from '@tanstack/react-query';
 import React, { useMemo } from 'react';
@@ -39,13 +39,13 @@ export const MapComponent = () => {
     useTripDetailsStore();
 
   const tripId: string = useTripDetailsStore(
-    (state: TripDetailsStore) => state.tripId,
+    (state: TripDetailsStore) => state.tripId
   );
   const steps: StepDto[] = useTripDetailsStore(
-    (state: TripDetailsStore) => state.steps,
+    (state: TripDetailsStore) => state.steps
   );
   const travels: TravelDtoList[] = useTripDetailsStore(
-    (state: TripDetailsStore) => state.travels,
+    (state: TripDetailsStore) => state.travels
   );
 
   const [isMapLoading, { toggle: toggleIsMapLoading }] = useDisclosure(true);
@@ -85,8 +85,8 @@ export const MapComponent = () => {
         type: 'Feature',
         geometry: {
           type: 'LineString',
-          coordinates: travels.flatMap(road =>
-            JSON.parse(road.travelRoad?.roadCoordinates as string),
+          coordinates: travels.flatMap((road) =>
+            JSON.parse(road.travelRoad?.roadCoordinates as string)
           ),
         },
         properties: {},
@@ -167,7 +167,7 @@ export const MapComponent = () => {
     };
 
     const currentStep: StepDto | undefined = steps.find(
-      (s: StepDto) => s.stepId === stepId,
+      (s: StepDto) => s.stepId === stepId
     );
 
     await updateStepLocationMutation.mutateAsync([
@@ -176,10 +176,10 @@ export const MapComponent = () => {
     ]);
 
     const stepBefore: StepDto | undefined = steps.find(
-      (s: StepDto) => s.order === (currentStep?.order as number) - 1,
+      (s: StepDto) => s.order === (currentStep?.order as number) - 1
     );
     const stepAfter: StepDto | undefined = steps.find(
-      (s: StepDto) => s.order === (currentStep?.order as number) + 1,
+      (s: StepDto) => s.order === (currentStep?.order as number) + 1
     );
 
     if (stepBefore && currentStep) {
@@ -199,7 +199,7 @@ export const MapComponent = () => {
       let addTravelDto: AddTravelDto;
       if (currentStep.transportMode === DirectionMode.PLANE) {
         const coords: Position[] = startEndPosition.flatMap(
-          ({ start, end }) => [start, end],
+          ({ start, end }) => [start, end]
         );
 
         addTravelDto = {
@@ -214,7 +214,7 @@ export const MapComponent = () => {
         const travelBeforeResponse: CalculateTravelRoadDto | undefined =
           await MapBoxController.calculateRoad(
             currentStep.transportMode as DirectionMode,
-            startEndPosition,
+            startEndPosition
           );
 
         if (!travelBeforeResponse) return;
@@ -244,7 +244,7 @@ export const MapComponent = () => {
       let addTravelDto: AddTravelDto;
       if (stepAfter.transportMode === DirectionMode.PLANE) {
         const coords: Position[] = startEndPosition.flatMap(
-          ({ start, end }) => [start, end],
+          ({ start, end }) => [start, end]
         );
 
         addTravelDto = {
@@ -259,7 +259,7 @@ export const MapComponent = () => {
         const travelAfterResponse: CalculateTravelRoadDto | undefined =
           await MapBoxController.calculateRoad(
             currentStep.transportMode as DirectionMode,
-            startEndPosition,
+            startEndPosition
           );
 
         if (!travelAfterResponse) return;
@@ -285,8 +285,13 @@ export const MapComponent = () => {
 
   //#endregion
 
+  const isMobile = useMediaQuery('(max-width: 768px)');
+
   return (
-    <Box pos={'relative'}>
+    <Box
+      pos="relative"
+      h={isMobile ? '50vh' : '92.5vh'}
+      w={isMobile ? '100vw' : '50vw'}>
       <LoadingOverlay
         visible={isMapLoading}
         zIndex={1000}
@@ -295,25 +300,28 @@ export const MapComponent = () => {
       <Map
         {...viewState}
         onLoad={() => toggleIsMapLoading()}
-        onMove={evt => setViewState(evt.viewState)}
+        onMove={(evt) => setViewState(evt.viewState)}
         minZoom={2}
         dragRotate={true}
         mapStyle="mapbox://styles/mapbox/streets-v12"
         mapboxAccessToken={import.meta.env.VITE_MAPBOX_TOKEN}
         attributionControl={true}
         style={{
-          height: '94vh',
-          width: '60vw',
+          height: '100%',
+          width: '100%',
         }}>
         {pins}
         <Source id="routeSource" type="geojson" data={geojson}>
           <Layer {...routeLineStyle} />
         </Source>
-
         <GeolocateControl />
         <ScaleControl />
-        <ActionIcon radius={'xl'} onClick={handleAddStepToEnd}>
-          <IconCirclePlus size={48} />
+        <ActionIcon
+          radius={'xl'}
+          onClick={handleAddStepToEnd}
+          size={isMobile ? 32 : 48}
+          style={{ position: 'absolute', bottom: '20px', right: '20px' }}>
+          <IconCirclePlus size={isMobile ? 32 : 48} />
         </ActionIcon>
       </Map>
     </Box>
diff --git a/src/components/map/stepList/StepList.scss b/src/components/map/stepList/StepList.scss
index 134a505..ed241c6 100644
--- a/src/components/map/stepList/StepList.scss
+++ b/src/components/map/stepList/StepList.scss
@@ -1,6 +1,6 @@
-#map_step_list {
+.map_step_list {
   align-items: center;
-  height: 93vh;
+  height: 100%;
   overflow-y: scroll;
   padding: 0 1rem;
 }
diff --git a/src/components/map/stepList/StepList.tsx b/src/components/map/stepList/StepList.tsx
index 688c9d3..982c074 100644
--- a/src/components/map/stepList/StepList.tsx
+++ b/src/components/map/stepList/StepList.tsx
@@ -12,31 +12,29 @@ export const StepList = () => {
   //#region Hooks
 
   const steps: StepDto[] = useTripDetailsStore(
-    (state: TripDetailsStore) => state.steps,
+    (state: TripDetailsStore) => state.steps
   );
   const travels: TravelDtoList[] = useTripDetailsStore(
-    (state: TripDetailsStore) => state.travels,
+    (state: TripDetailsStore) => state.travels
   );
 
   //#endregion
 
   return (
-    <>
-      <Stack id="map_step_list">
-        {steps
-          .sort((a: StepDto, b: StepDto) => a.order! - b.order!)
-          .map((step: StepDto) => (
-            <StepCard
-              key={step.stepId}
-              step={step}
-              travel={
-                travels.filter(
-                  (t: TravelDtoList) => t.destinationStepId == step.stepId,
-                )[0]
-              }
-            />
-          ))}
-      </Stack>
-    </>
+    <Stack className="map_step_list">
+      {steps
+        .sort((a: StepDto, b: StepDto) => a.order! - b.order!)
+        .map((step: StepDto) => (
+          <StepCard
+            key={step.stepId}
+            step={step}
+            travel={
+              travels.filter(
+                (t: TravelDtoList) => t.destinationStepId == step.stepId
+              )[0]
+            }
+          />
+        ))}
+    </Stack>
   );
 };
diff --git a/src/components/profile/DeleteForm/DeleteFormModal.tsx b/src/components/profile/deleteForm/DeleteFormModal.tsx
similarity index 100%
rename from src/components/profile/DeleteForm/DeleteFormModal.tsx
rename to src/components/profile/deleteForm/DeleteFormModal.tsx
diff --git a/src/components/profile/resetPasswordFrom/ResetPasswordForm.tsx b/src/components/profile/resetPasswordFrom/ResetPasswordForm.tsx
new file mode 100644
index 0000000..3f4d74a
--- /dev/null
+++ b/src/components/profile/resetPasswordFrom/ResetPasswordForm.tsx
@@ -0,0 +1,69 @@
+import { ForgotPasswordDto } from '@FullStackMap/from-a2b';
+import { Button, Container, Group, TextInput } from '@mantine/core';
+import { useForm } from '@mantine/form';
+import { useMutation } from '@tanstack/react-query';
+import { zodResolver } from 'mantine-form-zod-resolver';
+import React from 'react';
+import { z } from 'zod';
+import useNotify, { NotifyDto } from '../../../hooks/useNotify';
+import { AnoAuthController } from '../../../services/BaseApi';
+
+export const ResetPasswordForm = () => {
+  const { SuccessNotify } = useNotify();
+
+  const changeEmailSchema = z.object({
+    email: z.string().email('Un email valide est requis'),
+  });
+
+  const resetPasswordRequestForm = useForm({
+    validateInputOnChange: true,
+    initialValues: {
+      email: '',
+    },
+    validate: zodResolver(changeEmailSchema),
+  });
+
+  const forgotPasswordMutation = useMutation({
+    mutationFn: async (dto: ForgotPasswordDto) =>
+      await AnoAuthController.forgotPasswordPOST(dto),
+    onSuccess: () => {
+      SuccessNotify({
+        title: 'Votre requête a bien été prise en compte',
+        message:
+          'Si un compte est associé à cet email, vous recevrez un email de réinitialisation de mot de passe.',
+        autoClose: 5000,
+      } as NotifyDto);
+    },
+  });
+
+  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
+    event.preventDefault();
+    if (!resetPasswordRequestForm.isValid()) return;
+    forgotPasswordMutation.mutate(
+      resetPasswordRequestForm.values as ForgotPasswordDto
+    );
+  };
+
+  return (
+    <Container mx="auto">
+      <form
+        onSubmit={handleSubmit}
+        onReset={() => resetPasswordRequestForm.reset()}>
+        <TextInput
+          label="Email"
+          placeholder="Veuillez renseignez votre email"
+          required
+          {...resetPasswordRequestForm.getInputProps('email')}
+        />
+        <Group justify="flex-end" mt="md">
+          <Button
+            type="submit"
+            loading={forgotPasswordMutation.isPending}
+            disabled={!resetPasswordRequestForm.isValid()}>
+            Envoyer
+          </Button>
+        </Group>
+      </form>
+    </Container>
+  );
+};
diff --git a/src/components/profileMenu/ProfileMenu.tsx b/src/components/profileMenu/ProfileMenu.tsx
index d71958f..7b494d3 100644
--- a/src/components/profileMenu/ProfileMenu.tsx
+++ b/src/components/profileMenu/ProfileMenu.tsx
@@ -89,7 +89,11 @@ const ProfileMenu = () => {
       ) : (
         <>
           <Menu.Target>
-            <ActionIcon variant="outline" aria-label="Settings" radius="xl">
+            <ActionIcon
+              variant="outline"
+              aria-label="Settings"
+              radius="xl"
+              me="md">
               <IconLogin />
             </ActionIcon>
           </Menu.Target>
diff --git a/src/layout/map/MapLayout.tsx b/src/layout/map/MapLayout.tsx
index 4d18b5a..268b30a 100644
--- a/src/layout/map/MapLayout.tsx
+++ b/src/layout/map/MapLayout.tsx
@@ -19,9 +19,7 @@ const MapLayout = () => {
       </AppShell.Header>
 
       <AppShell.Main>
-        <div>
-          <Outlet />
-        </div>
+        <Outlet />
       </AppShell.Main>
     </AppShell>
   );
diff --git a/src/main.tsx b/src/main.tsx
index 52391d9..29e3b15 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -58,12 +58,12 @@ root.render(
     <BrowserRouter>
       <UseScrollTop />
       <MantineProvider defaultColorScheme="auto" theme={theme}>
-        <Notifications limit={5} position="top-right" />
+        <Notifications limit={5} position="bottom-right" />
         <QueryClientProvider client={queryClient}>
           <App />
           <ReactQueryDevtools initialIsOpen={false} />
         </QueryClientProvider>
       </MantineProvider>
     </BrowserRouter>
-  </React.StrictMode>,
+  </React.StrictMode>
 );
diff --git a/src/pages/landing/HeroHeader.tsx b/src/pages/landing/HeroHeader.tsx
index 6770d72..902c47e 100644
--- a/src/pages/landing/HeroHeader.tsx
+++ b/src/pages/landing/HeroHeader.tsx
@@ -1,26 +1,26 @@
 import { Button, Container, Overlay, Text, Title } from '@mantine/core';
 import './HeroImageBackground.scss';
+import { useNavigate } from 'react-router-dom';
 
 const HeroImageBackground = () => {
+  const navigate = useNavigate();
   return (
     <div className="hero__wrapper">
       <Overlay color="#000" opacity={0.65} zIndex={1} />
-
       <div className="hero__inner">
         <Title className="hero__title">Créez votre voyage de rêve</Title>
-
         <Container size={640}>
           <Text size="lg" className="hero__description">
             Explorez, planifiez et réservez votre prochaine aventure
           </Text>
         </Container>
-
         <div className="hero__controls">
           <Button
             className="hero__control"
             variant="outline"
             color="white"
-            size="lg">
+            size="lg"
+            onClick={() => navigate('/trips')}>
             Commencer
           </Button>
         </div>
diff --git a/src/pages/profile/ProfilePage.tsx b/src/pages/profile/ProfilePage.tsx
index 03d7786..3902ddd 100644
--- a/src/pages/profile/ProfilePage.tsx
+++ b/src/pages/profile/ProfilePage.tsx
@@ -11,17 +11,17 @@ import {
   IconTrash,
   IconUser,
 } from '@tabler/icons-react';
-import { RequestResetPasswordModal } from '../../components/passwordReset/RequestResetPasswordModal';
-import { DeleteFormModal } from '../../components/profile/DeleteForm/DeleteFormModal.tsx';
+import { DeleteFormModal } from '../../components/profile/deleteForm/DeleteFormModal.tsx';
 import { ChangeEmailForm } from '../../components/profile/changeEmailForm/ChangeEmailForm.tsx';
 import { ProfileForm } from '../../components/profile/profileForm/ProfileForm.tsx';
+import { ResetPasswordForm } from '../../components/profile/resetPasswordFrom/ResetPasswordForm.tsx';
 
 const data = [
-  { icon: IconUser, label: 'Mon Compte' },
-  { icon: IconLock, label: 'Changer Mon Mot De Passe' },
-  { icon: IconMail, label: 'Changer Mon Email' },
-  { icon: IconFileText, label: "Condition Générale D'utilisation" },
-  { icon: IconTrash, label: 'Supprimer Mon Compte' },
+  { icon: IconUser, label: 'Mon compte' },
+  { icon: IconLock, label: 'Changer mon mot de passe' },
+  { icon: IconMail, label: 'Changer mon email' },
+  { icon: IconFileText, label: "Condition générale d'utilisation" },
+  { icon: IconTrash, label: 'Supprimer mon compte' },
 ];
 
 const ProfilePage = () => {
@@ -39,16 +39,6 @@ const ProfilePage = () => {
     navigate('/cgu');
   };
 
-  const [
-    resetPasswordRequestModalIsOpen,
-    { toggle: toggleResetPasswordRequestModalIsOpen },
-  ] = useDisclosure(false);
-
-  const handleCloseResetPasswordModal = () => {
-    toggleResetPasswordRequestModalIsOpen();
-    selectForm(0);
-  };
-
   const [deleteFormModalIsOpen, { toggle: toggleDeleteFormModalIsOpen }] =
     useDisclosure(false);
 
@@ -67,9 +57,6 @@ const ProfilePage = () => {
       onClick={() => {
         if (index === 3) {
           navigateToCGU();
-        } else if (index === 1) {
-          toggleResetPasswordRequestModalIsOpen();
-          selectForm(1);
         } else if (index === 4) {
           toggleDeleteFormModalIsOpen();
           selectForm(4);
@@ -96,12 +83,7 @@ const ProfilePage = () => {
           </Grid.Col>
           <Grid.Col span={9}>
             {actualForm === 0 && <ProfileForm />}
-            {actualForm === 1 && (
-              <RequestResetPasswordModal
-                isOpen={resetPasswordRequestModalIsOpen}
-                close={handleCloseResetPasswordModal}
-              />
-            )}
+            {actualForm === 1 && <ResetPasswordForm />}
             {actualForm === 2 && <ChangeEmailForm />}
             {actualForm === 4 && (
               <DeleteFormModal
diff --git a/src/pages/tripDetail/TripDetailPage.scss b/src/pages/tripDetail/TripDetailPage.scss
new file mode 100644
index 0000000..cbeecb2
--- /dev/null
+++ b/src/pages/tripDetail/TripDetailPage.scss
@@ -0,0 +1,13 @@
+.mantine-Grid-col {
+  padding: 0;
+  margin: 0;
+  width: 100%;
+}
+
+.grid-mobile {
+  .mantine-Grid-inner {
+    padding: 0;
+      margin: 0;
+      width: 100%;
+  }
+}
diff --git a/src/pages/tripDetail/TripDetailPage.tsx b/src/pages/tripDetail/TripDetailPage.tsx
index 7511cc2..bb88fe9 100644
--- a/src/pages/tripDetail/TripDetailPage.tsx
+++ b/src/pages/tripDetail/TripDetailPage.tsx
@@ -4,7 +4,7 @@ import {
   StepDto,
   TripDto,
 } from '@FullStackMap/from-a2b';
-import { Group, Stack } from '@mantine/core';
+import { Container, Grid, Group, Paper, Stack } from '@mantine/core';
 import { useQuery, useQueryClient } from '@tanstack/react-query';
 import { AxiosResponse } from 'axios';
 import {
@@ -31,6 +31,8 @@ import {
   TripDetailsStore,
   useTripDetailsStore,
 } from '../../store/useTripDetailsStore';
+import './TripDetailPage.scss';
+import { useMediaQuery } from '@mantine/hooks';
 
 const TripDetailPage = () => {
   //#region Hooks
@@ -38,21 +40,21 @@ const TripDetailPage = () => {
   const { ErrorNotify } = useNotify();
 
   const tripId: string | undefined = useTripDetailsStore(
-    (state: TripDetailsStore) => state.tripId,
+    (state: TripDetailsStore) => state.tripId
   );
   const steps: StepDto[] = useTripDetailsStore(
-    (state: TripDetailsStore) => state.steps,
+    (state: TripDetailsStore) => state.steps
   );
 
   const addStepMode: AddStepMode = useTripDetailsStore(
-    (state: TripDetailsStore) => state.addStepMode,
+    (state: TripDetailsStore) => state.addStepMode
   );
 
   const otherStepId: number | undefined = useTripDetailsStore(
-    (state: TripDetailsStore) => state.otherStepId,
+    (state: TripDetailsStore) => state.otherStepId
   );
   const otherStep: StepDto | undefined = useTripDetailsStore(
-    (state: TripDetailsStore) => state.otherStep,
+    (state: TripDetailsStore) => state.otherStep
   );
 
   const { SetTrip, SetCurrentStep, UnSelectCurrentStep } =
@@ -67,7 +69,7 @@ const TripDetailPage = () => {
     queryKey: ['Trip', tripId],
     queryFn: async () =>
       await TripController.getTripByIdGET(tripId as string).then(
-        (res: AxiosResponse<TripDto, any>) => res.data,
+        (res: AxiosResponse<TripDto, any>) => res.data
       ),
     enabled: !!tripId,
   });
@@ -79,7 +81,7 @@ const TripDetailPage = () => {
   const createStepMutation = useMutation({
     mutationFn: async (dto: AddStepDto) =>
       StepController.addStepAsyncPOST(tripId, dto),
-    onSuccess: res => {
+    onSuccess: (res) => {
       SetCurrentStep(res.data);
       queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
       handleCalculateNewTravel(undefined, res.data);
@@ -89,7 +91,7 @@ const TripDetailPage = () => {
   const createStepBeforeMutation = useMutation({
     mutationFn: async ([previousStepId, dto]: [number, AddStepDto]) =>
       StepController.addStepBeforAsyncPOST(tripId, previousStepId, dto),
-    onSuccess: async res => {
+    onSuccess: async (res) => {
       SetCurrentStep(res.data);
       queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
       await handleCalculateNewTravel(undefined, res.data);
@@ -100,7 +102,7 @@ const TripDetailPage = () => {
   const createStepAfterMutation = useMutation({
     mutationFn: async ([nextStepId, dto]: [number, AddStepDto]) =>
       StepController.addStepAfterAsyncPOST(tripId, nextStepId, dto),
-    onSuccess: res => {
+    onSuccess: (res) => {
       SetCurrentStep(res.data);
       queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
       handleCalculateNewTravel(otherStep, res.data);
@@ -140,23 +142,25 @@ const TripDetailPage = () => {
 
   const handleCalculateNewTravel = async (
     originStep: StepDto | undefined,
-    destinationStep: StepDto | undefined,
+    destinationStep: StepDto | undefined
   ) => {
     if (!originStep && !destinationStep) return;
 
     if (!originStep && destinationStep) {
       originStep = steps.find(
-        step => step.order === destinationStep!.order! - 1,
+        (step) => step.order === destinationStep!.order! - 1
       );
 
       if (!originStep) return;
     }
     if (!destinationStep && originStep) {
       if (!destinationStep && addStepMode === AddStepMode.AFTER)
-        destinationStep = steps.find(step => step.order === originStep!.order!);
+        destinationStep = steps.find(
+          (step) => step.order === originStep!.order!
+        );
 
       destinationStep = steps.find(
-        step => step.order === originStep!.order! + 1,
+        (step) => step.order === originStep!.order! + 1
       );
 
       if (!destinationStep) return;
@@ -181,7 +185,7 @@ const TripDetailPage = () => {
         const res: CalculateTravelRoadDto | undefined =
           await MapBoxController.calculateRoad(
             destinationStep!.transportMode as DirectionMode,
-            startEndPosition,
+            startEndPosition
           );
 
         travelRoad = res;
@@ -241,20 +245,36 @@ const TripDetailPage = () => {
 
   //#endregion
 
+  const isMobile = useMediaQuery('(max-width: 768px)');
+
   return (
-    <>
-      <Group justify="space-between">
-        <StepList />
-        <Stack>
-          <MapComponent />
-        </Stack>
-      </Group>
-      <CreateStepModal
-        // FormSend={(addStepDto: AddStepDto) => handleAddStep(addStepDto)}
+    <Container p={0}>
+      <Grid className={isMobile ? 'grid-mobile' : ''}>
+        {isMobile ? (
+          <>
+            <Grid.Col span={12}>
+              <MapComponent />
+            </Grid.Col>
+            <Grid.Col span={12}>
+              <StepList />
+            </Grid.Col>
+          </>
+        ) : (
+          <>
+            <Grid.Col span={6}>
+              <StepList />
+            </Grid.Col>
+            <Grid.Col span={6}>
+              <MapComponent />
+            </Grid.Col>
+          </>
+        )}
+      </Grid>
+      <CreateStepModal // FormSend={(addStepDto: AddStepDto) => handleAddStep(addStepDto)}
         FormSend={handleAddStep}
       />
       <EditStepModal />
-    </>
+    </Container>
   );
 };
 
diff --git a/src/styles.scss b/src/styles.scss
index c931a80..bdfe34f 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -12,4 +12,5 @@ body,
 
 .cursor-pointer {
   cursor: pointer;
+  object-fit: fill;
 }

From e591876a5e14187a3d92dd6f1f4a26a7ac248914 Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Sun, 31 Mar 2024 14:34:15 +0200
Subject: [PATCH 29/34] feat (TripsPage) : Add SetTripId when click on card

---
 src/components/cardCustom/TravelCard/TravelCard.tsx | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/components/cardCustom/TravelCard/TravelCard.tsx b/src/components/cardCustom/TravelCard/TravelCard.tsx
index be49035..e978544 100644
--- a/src/components/cardCustom/TravelCard/TravelCard.tsx
+++ b/src/components/cardCustom/TravelCard/TravelCard.tsx
@@ -5,6 +5,7 @@ import {
   IconPlayerPlay,
 } from '@tabler/icons-react';
 import { useNavigate } from 'react-router-dom';
+import { useTripDetailsStore } from '../../../store/useTripDetailsStore';
 
 export type TravelCardProps = {
   img: string;
@@ -16,6 +17,7 @@ export type TravelCardProps = {
 
 export const TravelCard = (props: TravelCardProps) => {
   const navigate = useNavigate();
+  const { SetTripId } = useTripDetailsStore();
 
   const isInProgress = (startDate: string) => {
     const currentDate = new Date();
@@ -33,6 +35,7 @@ export const TravelCard = (props: TravelCardProps) => {
 
   const handleViewTrip = () => {
     navigate(`/trips/${props.id}`);
+    SetTripId(props.id);
   };
 
   return (

From 5fccaa6ef308e83e8686fef3488c8becd6c55944 Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Sun, 31 Mar 2024 14:39:20 +0200
Subject: [PATCH 30/34] GitRevert

---
 src/components/cardCustom/TravelCard/TravelCard.tsx |  2 ++
 src/pages/tripDetail/TripDetailPage.tsx             | 11 ++---------
 src/router/Router.tsx                               |  2 +-
 src/store/useTripDetailsStore.ts                    |  1 -
 4 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/src/components/cardCustom/TravelCard/TravelCard.tsx b/src/components/cardCustom/TravelCard/TravelCard.tsx
index e978544..a74984c 100644
--- a/src/components/cardCustom/TravelCard/TravelCard.tsx
+++ b/src/components/cardCustom/TravelCard/TravelCard.tsx
@@ -4,6 +4,7 @@ import {
   IconHourglassOff,
   IconPlayerPlay,
 } from '@tabler/icons-react';
+import { useQueryClient } from '@tanstack/react-query';
 import { useNavigate } from 'react-router-dom';
 import { useTripDetailsStore } from '../../../store/useTripDetailsStore';
 
@@ -16,6 +17,7 @@ export type TravelCardProps = {
 };
 
 export const TravelCard = (props: TravelCardProps) => {
+  const queryClient = useQueryClient();
   const navigate = useNavigate();
   const { SetTripId } = useTripDetailsStore();
 
diff --git a/src/pages/tripDetail/TripDetailPage.tsx b/src/pages/tripDetail/TripDetailPage.tsx
index 82e8aeb..7511cc2 100644
--- a/src/pages/tripDetail/TripDetailPage.tsx
+++ b/src/pages/tripDetail/TripDetailPage.tsx
@@ -18,7 +18,6 @@ import { MapComponent } from '../../components/map/MapComponent';
 
 import { useMutation } from '@tanstack/react-query';
 
-import { useParams } from 'react-router-dom';
 import { CreateStepModal } from '../../components/map/addStep/CreateStepModal.tsx';
 import { EditStepModal } from '../../components/map/editStep/EditStepModal.tsx';
 import { StepList } from '../../components/map/stepList/StepList.tsx';
@@ -35,7 +34,6 @@ import {
 
 const TripDetailPage = () => {
   //#region Hooks
-  const { routeTripId } = useParams();
 
   const { ErrorNotify } = useNotify();
 
@@ -57,7 +55,7 @@ const TripDetailPage = () => {
     (state: TripDetailsStore) => state.otherStep,
   );
 
-  const { SetTripId, SetTrip, SetCurrentStep, UnSelectCurrentStep } =
+  const { SetTrip, SetCurrentStep, UnSelectCurrentStep } =
     useTripDetailsStore();
 
   const queryClient = useQueryClient();
@@ -71,7 +69,7 @@ const TripDetailPage = () => {
       await TripController.getTripByIdGET(tripId as string).then(
         (res: AxiosResponse<TripDto, any>) => res.data,
       ),
-    enabled: tripId !== undefined,
+    enabled: !!tripId,
   });
 
   //#endregion
@@ -131,11 +129,6 @@ const TripDetailPage = () => {
 
   //#region Effects
 
-  useEffect(() => {
-    if (!routeTripId) return;
-    SetTripId(routeTripId!);
-  }, [routeTripId]);
-
   useEffect(() => {
     if (!tripDto) return;
     SetTrip(tripDto);
diff --git a/src/router/Router.tsx b/src/router/Router.tsx
index 5b04dde..246a038 100644
--- a/src/router/Router.tsx
+++ b/src/router/Router.tsx
@@ -63,7 +63,7 @@ const Router = () => {
 
       <Route element={<MapLayout />}>
         <Route
-          path="/trips/:routeTripId"
+          path="/tripDetail"
           element={
             <PrivateRoute
               authRequired
diff --git a/src/store/useTripDetailsStore.ts b/src/store/useTripDetailsStore.ts
index 20bf89c..4b5730b 100644
--- a/src/store/useTripDetailsStore.ts
+++ b/src/store/useTripDetailsStore.ts
@@ -62,7 +62,6 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
   trip: {} as TripDto,
   SetTrip: (tripDto: TripDto) =>
     set({
-      tripId: tripDto.tripId,
       trip: tripDto,
       steps: tripDto.steps || [],
       travels: tripDto.travels || [],

From 8b448cb7da0d9e0a92bb4b50f2679a2154079f18 Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Sun, 31 Mar 2024 14:40:37 +0200
Subject: [PATCH 31/34] Revert the Revert

---
 src/components/cardCustom/TravelCard/TravelCard.tsx |  2 --
 src/pages/tripDetail/TripDetailPage.tsx             | 11 +++++++++--
 src/router/Router.tsx                               |  2 +-
 src/store/useTripDetailsStore.ts                    |  1 +
 4 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/components/cardCustom/TravelCard/TravelCard.tsx b/src/components/cardCustom/TravelCard/TravelCard.tsx
index a74984c..e978544 100644
--- a/src/components/cardCustom/TravelCard/TravelCard.tsx
+++ b/src/components/cardCustom/TravelCard/TravelCard.tsx
@@ -4,7 +4,6 @@ import {
   IconHourglassOff,
   IconPlayerPlay,
 } from '@tabler/icons-react';
-import { useQueryClient } from '@tanstack/react-query';
 import { useNavigate } from 'react-router-dom';
 import { useTripDetailsStore } from '../../../store/useTripDetailsStore';
 
@@ -17,7 +16,6 @@ export type TravelCardProps = {
 };
 
 export const TravelCard = (props: TravelCardProps) => {
-  const queryClient = useQueryClient();
   const navigate = useNavigate();
   const { SetTripId } = useTripDetailsStore();
 
diff --git a/src/pages/tripDetail/TripDetailPage.tsx b/src/pages/tripDetail/TripDetailPage.tsx
index 7511cc2..82e8aeb 100644
--- a/src/pages/tripDetail/TripDetailPage.tsx
+++ b/src/pages/tripDetail/TripDetailPage.tsx
@@ -18,6 +18,7 @@ import { MapComponent } from '../../components/map/MapComponent';
 
 import { useMutation } from '@tanstack/react-query';
 
+import { useParams } from 'react-router-dom';
 import { CreateStepModal } from '../../components/map/addStep/CreateStepModal.tsx';
 import { EditStepModal } from '../../components/map/editStep/EditStepModal.tsx';
 import { StepList } from '../../components/map/stepList/StepList.tsx';
@@ -34,6 +35,7 @@ import {
 
 const TripDetailPage = () => {
   //#region Hooks
+  const { routeTripId } = useParams();
 
   const { ErrorNotify } = useNotify();
 
@@ -55,7 +57,7 @@ const TripDetailPage = () => {
     (state: TripDetailsStore) => state.otherStep,
   );
 
-  const { SetTrip, SetCurrentStep, UnSelectCurrentStep } =
+  const { SetTripId, SetTrip, SetCurrentStep, UnSelectCurrentStep } =
     useTripDetailsStore();
 
   const queryClient = useQueryClient();
@@ -69,7 +71,7 @@ const TripDetailPage = () => {
       await TripController.getTripByIdGET(tripId as string).then(
         (res: AxiosResponse<TripDto, any>) => res.data,
       ),
-    enabled: !!tripId,
+    enabled: tripId !== undefined,
   });
 
   //#endregion
@@ -129,6 +131,11 @@ const TripDetailPage = () => {
 
   //#region Effects
 
+  useEffect(() => {
+    if (!routeTripId) return;
+    SetTripId(routeTripId!);
+  }, [routeTripId]);
+
   useEffect(() => {
     if (!tripDto) return;
     SetTrip(tripDto);
diff --git a/src/router/Router.tsx b/src/router/Router.tsx
index 246a038..5b04dde 100644
--- a/src/router/Router.tsx
+++ b/src/router/Router.tsx
@@ -63,7 +63,7 @@ const Router = () => {
 
       <Route element={<MapLayout />}>
         <Route
-          path="/tripDetail"
+          path="/trips/:routeTripId"
           element={
             <PrivateRoute
               authRequired
diff --git a/src/store/useTripDetailsStore.ts b/src/store/useTripDetailsStore.ts
index 4b5730b..20bf89c 100644
--- a/src/store/useTripDetailsStore.ts
+++ b/src/store/useTripDetailsStore.ts
@@ -62,6 +62,7 @@ export const useTripDetailsStore = create<TripDetailsStore>(set => ({
   trip: {} as TripDto,
   SetTrip: (tripDto: TripDto) =>
     set({
+      tripId: tripDto.tripId,
       trip: tripDto,
       steps: tripDto.steps || [],
       travels: tripDto.travels || [],

From 2b5287276234536b5df129f63329c13f01412cb5 Mon Sep 17 00:00:00 2001
From: Baptiste Legat <legatbaptiste@gmail.com>
Date: Sun, 31 Mar 2024 16:07:51 +0200
Subject: [PATCH 32/34] features: design travel and step and somes fix

---
 src/components/map/editStep/EditStepModal.tsx | 92 ++++++++++---------
 src/components/map/stepCard/StepCard.tsx      | 41 ++++-----
 src/components/map/stepList/StepList.scss     |  6 --
 src/components/map/stepList/StepList.tsx      |  7 +-
 src/pages/tripDetail/TripDetailPage.tsx       |  2 +-
 5 files changed, 68 insertions(+), 80 deletions(-)
 delete mode 100644 src/components/map/stepList/StepList.scss

diff --git a/src/components/map/editStep/EditStepModal.tsx b/src/components/map/editStep/EditStepModal.tsx
index ed9a22e..3b8e494 100644
--- a/src/components/map/editStep/EditStepModal.tsx
+++ b/src/components/map/editStep/EditStepModal.tsx
@@ -43,16 +43,16 @@ export const EditStepModal = () => {
   const { ErrorNotify } = useNotify();
 
   const travels: TravelDtoList[] = useTripDetailsStore(
-    (state: TripDetailsStore) => state.travels,
+    (state: TripDetailsStore) => state.travels
   );
   const isEditModalOpened = useTripDetailsStore(
-    (state: TripDetailsStore) => state.isEditModalOpened,
+    (state: TripDetailsStore) => state.isEditModalOpened
   );
   const currentStep: StepDto | undefined = useTripDetailsStore(
-    (state: TripDetailsStore) => state.currentStep,
+    (state: TripDetailsStore) => state.currentStep
   );
   const steps: StepDto[] = useTripDetailsStore(
-    (state: TripDetailsStore) => state.steps,
+    (state: TripDetailsStore) => state.steps
   );
 
   const { SetEditModalIsOpened, UnSelectCurrentStep } = useTripDetailsStore();
@@ -88,7 +88,7 @@ export const EditStepModal = () => {
     mutationFn: (dto: UpdateStepTransportModeDto) =>
       StepController.updateStepTransportModeAsyncPATCH(
         currentStep!.stepId!,
-        dto,
+        dto
       ),
   });
 
@@ -170,7 +170,7 @@ export const EditStepModal = () => {
       setPlaces(places);
 
       const currentPlace: PlaceDto | undefined = places.find(
-        (place: PlaceDto) => place.place === addressValue,
+        (place: PlaceDto) => place.place === addressValue
       );
       if (currentPlace) {
         stepAddressFrom.setFieldValue('latitude', currentPlace.coordinate[1]);
@@ -190,7 +190,7 @@ export const EditStepModal = () => {
       setPlaces(places);
 
       const currentPlace: PlaceDto | undefined = places.find(
-        (place: PlaceDto) => place.place === addressValue,
+        (place: PlaceDto) => place.place === addressValue
       );
       if (currentPlace) {
         stepAddressFrom.setFieldValue('latitude', currentPlace.coordinate[1]);
@@ -263,10 +263,10 @@ export const EditStepModal = () => {
     await saveAdresseMutation.mutateAsync(updateDto);
 
     const stepBefore: StepDto | undefined = steps.find(
-      (step: StepDto) => step.stepId === currentStep!.stepId! - 1,
+      (step: StepDto) => step.stepId === currentStep!.stepId! - 1
     );
     const stepAfter: StepDto | undefined = steps.find(
-      (step: StepDto) => step.stepId === currentStep!.stepId! + 1,
+      (step: StepDto) => step.stepId === currentStep!.stepId! + 1
     );
 
     if (stepBefore && currentStep) {
@@ -283,7 +283,7 @@ export const EditStepModal = () => {
       let addTravelDto: AddTravelDto;
       if (currentStep.transportMode === DirectionMode.PLANE) {
         const coords: Position[] = startEndPosition.flatMap(
-          ({ start, end }) => [start, end],
+          ({ start, end }) => [start, end]
         );
 
         addTravelDto = {
@@ -298,7 +298,7 @@ export const EditStepModal = () => {
         const travelBeforeResponse: CalculateTravelRoadDto | undefined =
           await MapBoxController.calculateRoad(
             currentStep.transportMode as DirectionMode,
-            startEndPosition,
+            startEndPosition
           );
 
         if (!travelBeforeResponse) return;
@@ -326,7 +326,7 @@ export const EditStepModal = () => {
       let addTravelDto: AddTravelDto;
       if (stepAfter.transportMode === DirectionMode.PLANE) {
         const coords: Position[] = startEndPosition.flatMap(
-          ({ start, end }) => [start, end],
+          ({ start, end }) => [start, end]
         );
 
         addTravelDto = {
@@ -341,7 +341,7 @@ export const EditStepModal = () => {
         const travelAfterResponse: CalculateTravelRoadDto | undefined =
           await MapBoxController.calculateRoad(
             currentStep.transportMode as DirectionMode,
-            startEndPosition,
+            startEndPosition
           );
 
         if (!travelAfterResponse) return;
@@ -361,7 +361,7 @@ export const EditStepModal = () => {
 
   const handleSaveStepTransportMode = async (transportMode: string) => {
     transportMode = TransportModeToDirectionMode(
-      transportMode as TransportMode,
+      transportMode as TransportMode
     );
 
     const updateDto: UpdateStepTransportModeDto = {
@@ -371,7 +371,7 @@ export const EditStepModal = () => {
     await saveTransportModeMutation.mutateAsync(updateDto);
 
     const stepBefore: StepDto | undefined = steps.find(
-      (step: StepDto) => step.stepId === currentStep!.stepId! - 1,
+      (step: StepDto) => step.stepId === currentStep!.stepId! - 1
     );
 
     if (stepBefore && currentStep) {
@@ -391,7 +391,7 @@ export const EditStepModal = () => {
       let addTravelDto: AddTravelDto;
       if (currentStep.transportMode === DirectionMode.PLANE) {
         const coords: Position[] = startEndPosition.flatMap(
-          ({ start, end }) => [start, end],
+          ({ start, end }) => [start, end]
         );
 
         addTravelDto = {
@@ -406,7 +406,7 @@ export const EditStepModal = () => {
         const travelBeforeResponse: CalculateTravelRoadDto | undefined =
           await MapBoxController.calculateRoad(
             currentStep.transportMode as DirectionMode,
-            startEndPosition,
+            startEndPosition
           );
 
         if (!travelBeforeResponse) return;
@@ -458,7 +458,7 @@ export const EditStepModal = () => {
               label="Destination"
               placeholder="Entrez une adresse"
               withAsterisk
-              data={places.map(place => place.place)}
+              data={places.map((place) => place.place)}
               onChange={(event: string) => setAddressValue(event)}
               onBlur={handleSaveAddress}
             />
@@ -469,34 +469,38 @@ export const EditStepModal = () => {
               defaultValue={currentStep?.transportMode as DirectionMode}
               selectedValue={handleSaveStepTransportMode}
             />
-            <TextInput
-              label="Distance"
-              placeholder="Distance"
-              mt="md"
-              value={MetreToDistance(
-                Number(
-                  (
+            {currentStep?.transportMode != DirectionMode.PLANE && (
+              <>
+                <TextInput
+                  label="Distance"
+                  placeholder="Distance"
+                  mt="md"
+                  value={MetreToDistance(
+                    Number(
+                      (
+                        travels.find(
+                          (travel: TravelDtoList) =>
+                            travel.destinationStepId === currentStep?.stepId
+                        )?.distance || 0
+                      ).toFixed(0)
+                    )
+                  )}
+                  disabled={true}
+                />
+                <TextInput
+                  label="Temps"
+                  placeholder="Temps"
+                  mt="md"
+                  value={SecondeToTime(
                     travels.find(
                       (travel: TravelDtoList) =>
-                        travel.destinationStepId === currentStep?.stepId,
-                    )?.distance || 0
-                  ).toFixed(0),
-                ),
-              )}
-              disabled={true}
-            />
-            <TextInput
-              label="Temps"
-              placeholder="Temps"
-              mt="md"
-              value={SecondeToTime(
-                travels.find(
-                  (travel: TravelDtoList) =>
-                    travel.destinationStepId === currentStep?.stepId,
-                )?.duration ?? 0,
-              )}
-              disabled={true}
-            />
+                        travel.destinationStepId === currentStep?.stepId
+                    )?.duration ?? 0
+                  )}
+                  disabled={true}
+                />
+              </>
+            )}
           </Fieldset>
         </Modal.Body>
       </Modal.Content>
diff --git a/src/components/map/stepCard/StepCard.tsx b/src/components/map/stepCard/StepCard.tsx
index 8cac3b5..6d3883a 100644
--- a/src/components/map/stepCard/StepCard.tsx
+++ b/src/components/map/stepCard/StepCard.tsx
@@ -1,7 +1,5 @@
 import { StepDto, TravelDtoList } from '@FullStackMap/from-a2b';
-import { Paper, Text } from '@mantine/core';
-import useDistance from '../../../hooks/useDistance';
-import useTime from '../../../hooks/useTime';
+import { Avatar, Flex, Paper, Text } from '@mantine/core';
 import DirectionMode from '../../../services/api/Models/MapBoxDirections/DirectionMode';
 import { TransportModeIcon } from '../../transportModeIcon/TransportModeIcon';
 import { StepCardMenu } from './Menu/StepCardMenu';
@@ -13,29 +11,22 @@ interface StepCardProps {
 }
 
 export const StepCard = (props: StepCardProps) => {
-  const { MetreToDistance } = useDistance();
-  const { SecondeToTime } = useTime();
-
   return (
-    <Paper className="card">
-      <Text>StepName : {props.step.name}</Text>
-      <Text>StepId : {props.step.stepId}</Text>
-      <Text>StepOrder : {props.step.order}</Text>
-      <TransportModeIcon
-        transportMode={props.step.transportMode as DirectionMode}
-      />
-      {props.step.order !== 1 && props.travel && (
-        <>
-          <Text>
-            TravelDistance :{' '}
-            {MetreToDistance(Number((props.travel.distance || 0).toFixed(0)))}
-          </Text>
-          <Text>
-            TravelDuration : {SecondeToTime(props.travel.duration ?? 0)}
-          </Text>
-        </>
-      )}
-      <StepCardMenu stepId={props.step.stepId!} />
+    <Paper shadow="md" radius="md" withBorder p="md" mx="lg" my="xs">
+      <Flex align="center" gap="lg" justify="space-between">
+        <Flex align="center" gap="lg">
+          <Avatar color="teal" radius="xl">
+            {props.step.order}
+          </Avatar>
+          <Text>{props.step.name}</Text>
+        </Flex>
+        <Flex align="center" gap="lg">
+          <TransportModeIcon
+            transportMode={props.step.transportMode as DirectionMode}
+          />
+          <StepCardMenu stepId={props.step.stepId!} />
+        </Flex>
+      </Flex>
     </Paper>
   );
 };
diff --git a/src/components/map/stepList/StepList.scss b/src/components/map/stepList/StepList.scss
deleted file mode 100644
index ed241c6..0000000
--- a/src/components/map/stepList/StepList.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-.map_step_list {
-  align-items: center;
-  height: 100%;
-  overflow-y: scroll;
-  padding: 0 1rem;
-}
diff --git a/src/components/map/stepList/StepList.tsx b/src/components/map/stepList/StepList.tsx
index 982c074..4498abb 100644
--- a/src/components/map/stepList/StepList.tsx
+++ b/src/components/map/stepList/StepList.tsx
@@ -1,11 +1,10 @@
 import { StepDto, TravelDtoList } from '@FullStackMap/from-a2b';
-import { Stack } from '@mantine/core';
+import { ScrollArea } from '@mantine/core';
 import {
   TripDetailsStore,
   useTripDetailsStore,
 } from '../../../store/useTripDetailsStore';
 import { StepCard } from '../stepCard/StepCard';
-import './StepList.scss';
 
 //! FIX Quand des points sont move sur la carte, niveau API tout est bien enregistré, mais niveau FRONT un problème fait que des points qui n'on rien a voir finissent par être relier
 export const StepList = () => {
@@ -21,7 +20,7 @@ export const StepList = () => {
   //#endregion
 
   return (
-    <Stack className="map_step_list">
+    <ScrollArea.Autosize mah={630} py="xs">
       {steps
         .sort((a: StepDto, b: StepDto) => a.order! - b.order!)
         .map((step: StepDto) => (
@@ -35,6 +34,6 @@ export const StepList = () => {
             }
           />
         ))}
-    </Stack>
+    </ScrollArea.Autosize>
   );
 };
diff --git a/src/pages/tripDetail/TripDetailPage.tsx b/src/pages/tripDetail/TripDetailPage.tsx
index 0a94430..cc18242 100644
--- a/src/pages/tripDetail/TripDetailPage.tsx
+++ b/src/pages/tripDetail/TripDetailPage.tsx
@@ -255,7 +255,7 @@ const TripDetailPage = () => {
   const isMobile = useMediaQuery('(max-width: 768px)');
 
   return (
-    <Container p={0}>
+    <Container size={1500} p={0}>
       <Grid className={isMobile ? 'grid-mobile' : ''}>
         {isMobile ? (
           <>

From 5c9e12ac1e0195a1e7fd5da6fe61207dde741c32 Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Sun, 31 Mar 2024 16:07:56 +0200
Subject: [PATCH 33/34] feat (tripCard) : Add Prefetch

---
 .../cardCustom/TravelCard/TravelCard.tsx      | 27 +++++++++++++++++--
 src/components/map/MapComponent.tsx           | 14 +++++++---
 src/components/map/editStep/EditStepModal.tsx |  9 +++++++
 src/services/api/MapboxController.ts          |  3 +--
 4 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/src/components/cardCustom/TravelCard/TravelCard.tsx b/src/components/cardCustom/TravelCard/TravelCard.tsx
index e978544..492be44 100644
--- a/src/components/cardCustom/TravelCard/TravelCard.tsx
+++ b/src/components/cardCustom/TravelCard/TravelCard.tsx
@@ -1,10 +1,14 @@
+import { TripDto } from '@FullStackMap/from-a2b';
 import { Button, Card, Group, Image, Text } from '@mantine/core';
 import {
   IconHourglassEmpty,
   IconHourglassOff,
   IconPlayerPlay,
 } from '@tabler/icons-react';
+import { useQueryClient } from '@tanstack/react-query';
+import { AxiosResponse } from 'axios';
 import { useNavigate } from 'react-router-dom';
+import { TripController } from '../../../services/BaseApi';
 import { useTripDetailsStore } from '../../../store/useTripDetailsStore';
 
 export type TravelCardProps = {
@@ -17,7 +21,8 @@ export type TravelCardProps = {
 
 export const TravelCard = (props: TravelCardProps) => {
   const navigate = useNavigate();
-  const { SetTripId } = useTripDetailsStore();
+  const { SetTripId, SetTrip } = useTripDetailsStore();
+  const queryClient = useQueryClient();
 
   const isInProgress = (startDate: string) => {
     const currentDate = new Date();
@@ -38,6 +43,19 @@ export const TravelCard = (props: TravelCardProps) => {
     SetTripId(props.id);
   };
 
+  const handlePrefetchViewTrip = () => {
+    queryClient.prefetchQuery({
+      queryKey: ['Trip', props.id],
+      queryFn: () =>
+        TripController.getTripByIdGET(props.id).then(
+          (res: AxiosResponse<TripDto, any>) => {
+            SetTrip(res.data);
+            return res.data;
+          },
+        ),
+    });
+  };
+
   return (
     <Card shadow="sm" padding="lg" radius="md" withBorder>
       <Card.Section>
@@ -50,7 +68,12 @@ export const TravelCard = (props: TravelCardProps) => {
       <Text size="sm" c="dimmed">
         {props.description}
       </Text>
-      <Button fullWidth mt="md" radius="md" onClick={handleViewTrip}>
+      <Button
+        fullWidth
+        mt="md"
+        radius="md"
+        onClick={handleViewTrip}
+        onMouseEnter={handlePrefetchViewTrip}>
         Voir Plus
       </Button>
     </Card>
diff --git a/src/components/map/MapComponent.tsx b/src/components/map/MapComponent.tsx
index acc0f43..9089ca2 100644
--- a/src/components/map/MapComponent.tsx
+++ b/src/components/map/MapComponent.tsx
@@ -148,8 +148,9 @@ export const MapComponent = () => {
           }
           latitude={step.latitude ?? 0}
           longitude={step.longitude ?? 0}
-          pitchAlignment="viewport"
-          rotationAlignment="viewport">
+          offset={[12, 0]}
+          pitchAlignment="auto"
+          rotationAlignment="auto">
           <IconPinnedFilled color="teal" size={32} stroke={2} />
         </Marker>
       );
@@ -165,6 +166,10 @@ export const MapComponent = () => {
       latitude: evt.lngLat.lat,
       longitude: evt.lngLat.lng,
     };
+    console.log(
+      '🚀 ~ handleMoveMarker ~ updateStateLocationDto:',
+      updateStateLocationDto,
+    );
 
     const currentStep: StepDto | undefined = steps.find(
       (s: StepDto) => s.stepId === stepId,
@@ -242,7 +247,8 @@ export const MapComponent = () => {
       ];
 
       let addTravelDto: AddTravelDto;
-      if (stepAfter.transportMode === DirectionMode.PLANE) {
+      console.log('🚀 ~ handleMoveMarker ~ stepAfter:', stepAfter);
+      if (stepAfter.transportMode == DirectionMode.PLANE) {
         const coords: Position[] = startEndPosition.flatMap(
           ({ start, end }) => [start, end],
         );
@@ -258,7 +264,7 @@ export const MapComponent = () => {
       } else {
         const travelAfterResponse: CalculateTravelRoadDto | undefined =
           await MapBoxController.calculateRoad(
-            currentStep.transportMode as DirectionMode,
+            stepAfter.transportMode as DirectionMode,
             startEndPosition,
           );
 
diff --git a/src/components/map/editStep/EditStepModal.tsx b/src/components/map/editStep/EditStepModal.tsx
index ed9a22e..87b6837 100644
--- a/src/components/map/editStep/EditStepModal.tsx
+++ b/src/components/map/editStep/EditStepModal.tsx
@@ -387,7 +387,16 @@ export const EditStepModal = () => {
           ],
         },
       ];
+      console.log(
+        '🚀 ~ handleSaveStepTransportMode ~ startEndPosition:',
+        startEndPosition,
+      );
 
+      console.log('🚀 ~ handleSaveStepTransportMode ~ stepBefore:', stepBefore);
+      console.log(
+        '🚀 ~ handleSaveStepTransportMode ~ currentStep:',
+        currentStep,
+      );
       let addTravelDto: AddTravelDto;
       if (currentStep.transportMode === DirectionMode.PLANE) {
         const coords: Position[] = startEndPosition.flatMap(
diff --git a/src/services/api/MapboxController.ts b/src/services/api/MapboxController.ts
index eaf6465..37318dd 100644
--- a/src/services/api/MapboxController.ts
+++ b/src/services/api/MapboxController.ts
@@ -28,8 +28,7 @@ export class MapBoxController {
       case 'InvalidInput':
         ErrorNotify({
           title: 'Échec du calcul du nouvel itinéraire',
-          message:
-            'La distance entre les deux points est trop grande pour ce mode de transport',
+          message: response?.data?.message,
           autoClose: undefined,
         });
         throw new Error('InvalidInput');

From 333dedbdbaf68f3410ec245750f8bd65de4a8389 Mon Sep 17 00:00:00 2001
From: Dercraker <antoine.capitain@gmail.com>
Date: Sun, 31 Mar 2024 16:34:19 +0200
Subject: [PATCH 34/34] Fix PR

---
 package.json                                  |   2 +-
 pnpm-lock.yaml                                |   8 +-
 src/components/map/MapComponent.tsx           |  26 +-
 .../mapStepEditor/MapStepEditor.tsx           | 279 ------------------
 src/pages/map/MapPage.tsx                     |  29 --
 src/pages/test/TestPage.tsx                   |  23 --
 src/pages/test/components/TestModal.tsx       |  26 --
 src/pages/tripDetail/TripDetailPage.tsx       |  36 ++-
 src/router/Router.tsx                         |  13 -
 9 files changed, 35 insertions(+), 407 deletions(-)
 delete mode 100644 src/components/mapStepEditor/MapStepEditor.tsx
 delete mode 100644 src/pages/map/MapPage.tsx
 delete mode 100644 src/pages/test/TestPage.tsx
 delete mode 100644 src/pages/test/components/TestModal.tsx

diff --git a/package.json b/package.json
index 66144f3..54ba6ea 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
     "updateClientApi": "pnpm update @FullStackMap/from-a2b"
   },
   "dependencies": {
-    "@FullStackMap/from-a2b": "0.21.1-Alpha",
+    "@FullStackMap/from-a2b": "0.24.0-Beta",
     "@mantine/carousel": "^7.6.2",
     "@mantine/core": "^7.6.2",
     "@mantine/form": "^7.6.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d35dcfc..c8e1adb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -6,8 +6,8 @@ settings:
 
 dependencies:
   '@FullStackMap/from-a2b':
-    specifier: 0.21.1-Alpha
-    version: 0.21.1-Alpha
+    specifier: 0.24.0-Beta
+    version: 0.24.0-Beta
   '@mantine/carousel':
     specifier: ^7.6.2
     version: 7.7.1(@mantine/core@7.7.1)(@mantine/hooks@7.7.1)(embla-carousel-react@7.1.0)(react-dom@18.2.0)(react@18.2.0)
@@ -157,8 +157,8 @@ devDependencies:
 
 packages:
 
-  /@FullStackMap/from-a2b@0.21.1-Alpha:
-    resolution: {integrity: sha512-Wrybc+kBUJsRLSDT/8rD0gYvddubTYoyJnr9NLj4ZN9WueOlcazXeOUZz4hpxIWIhxMgeRfKpH8kt5VUZAlTVQ==, tarball: https://npm.pkg.github.com/download/@FullStackMap/from-a2b/0.21.1-Alpha/41d182cff1111a4b0f3b91067875207a9c31a2e9}
+  /@FullStackMap/from-a2b@0.24.0-Beta:
+    resolution: {integrity: sha512-RPDaHhTvgGe6vfxVlysUXx/CRjo3/ZhZnVyTchAjdsc8DaifrxSt9YUBb2YW+leGA95w8JrVmqCLWNmApz4G+A==, tarball: https://npm.pkg.github.com/download/@FullStackMap/from-a2b/0.24.0-Beta/4744efee7972a3cac3613d622c72ddca00fcaa20}
     dependencies:
       axios: 1.6.8
     transitivePeerDependencies:
diff --git a/src/components/map/MapComponent.tsx b/src/components/map/MapComponent.tsx
index 4c01452..6e111fa 100644
--- a/src/components/map/MapComponent.tsx
+++ b/src/components/map/MapComponent.tsx
@@ -4,7 +4,7 @@ import {
   TravelDtoList,
   UpdateStepLocationDto,
 } from '@FullStackMap/from-a2b';
-import { ActionIcon, Box, Grid, LoadingOverlay, Paper } from '@mantine/core';
+import { ActionIcon, Box, LoadingOverlay } from '@mantine/core';
 import { FeatureCollection, Position } from 'geojson';
 import {
   GeolocateControl,
@@ -39,13 +39,13 @@ export const MapComponent = () => {
     useTripDetailsStore();
 
   const tripId: string = useTripDetailsStore(
-    (state: TripDetailsStore) => state.tripId
+    (state: TripDetailsStore) => state.tripId,
   );
   const steps: StepDto[] = useTripDetailsStore(
-    (state: TripDetailsStore) => state.steps
+    (state: TripDetailsStore) => state.steps,
   );
   const travels: TravelDtoList[] = useTripDetailsStore(
-    (state: TripDetailsStore) => state.travels
+    (state: TripDetailsStore) => state.travels,
   );
 
   const [isMapLoading, { toggle: toggleIsMapLoading }] = useDisclosure(true);
@@ -85,8 +85,8 @@ export const MapComponent = () => {
         type: 'Feature',
         geometry: {
           type: 'LineString',
-          coordinates: travels.flatMap((road) =>
-            JSON.parse(road.travelRoad?.roadCoordinates as string)
+          coordinates: travels.flatMap(road =>
+            JSON.parse(road.travelRoad?.roadCoordinates as string),
           ),
         },
         properties: {},
@@ -172,7 +172,7 @@ export const MapComponent = () => {
     );
 
     const currentStep: StepDto | undefined = steps.find(
-      (s: StepDto) => s.stepId === stepId
+      (s: StepDto) => s.stepId === stepId,
     );
 
     await updateStepLocationMutation.mutateAsync([
@@ -181,10 +181,10 @@ export const MapComponent = () => {
     ]);
 
     const stepBefore: StepDto | undefined = steps.find(
-      (s: StepDto) => s.order === (currentStep?.order as number) - 1
+      (s: StepDto) => s.order === (currentStep?.order as number) - 1,
     );
     const stepAfter: StepDto | undefined = steps.find(
-      (s: StepDto) => s.order === (currentStep?.order as number) + 1
+      (s: StepDto) => s.order === (currentStep?.order as number) + 1,
     );
 
     if (stepBefore && currentStep) {
@@ -204,7 +204,7 @@ export const MapComponent = () => {
       let addTravelDto: AddTravelDto;
       if (currentStep.transportMode === DirectionMode.PLANE) {
         const coords: Position[] = startEndPosition.flatMap(
-          ({ start, end }) => [start, end]
+          ({ start, end }) => [start, end],
         );
 
         addTravelDto = {
@@ -219,7 +219,7 @@ export const MapComponent = () => {
         const travelBeforeResponse: CalculateTravelRoadDto | undefined =
           await MapBoxController.calculateRoad(
             currentStep.transportMode as DirectionMode,
-            startEndPosition
+            startEndPosition,
           );
 
         if (!travelBeforeResponse) return;
@@ -250,7 +250,7 @@ export const MapComponent = () => {
       console.log('🚀 ~ handleMoveMarker ~ stepAfter:', stepAfter);
       if (stepAfter.transportMode == DirectionMode.PLANE) {
         const coords: Position[] = startEndPosition.flatMap(
-          ({ start, end }) => [start, end]
+          ({ start, end }) => [start, end],
         );
 
         addTravelDto = {
@@ -306,7 +306,7 @@ export const MapComponent = () => {
       <Map
         {...viewState}
         onLoad={() => toggleIsMapLoading()}
-        onMove={(evt) => setViewState(evt.viewState)}
+        onMove={evt => setViewState(evt.viewState)}
         minZoom={2}
         dragRotate={true}
         mapStyle="mapbox://styles/mapbox/streets-v12"
diff --git a/src/components/mapStepEditor/MapStepEditor.tsx b/src/components/mapStepEditor/MapStepEditor.tsx
deleted file mode 100644
index a6a7c3d..0000000
--- a/src/components/mapStepEditor/MapStepEditor.tsx
+++ /dev/null
@@ -1,279 +0,0 @@
-import {
-  StepDto,
-  StepDtoList,
-  TravelDtoList,
-  TripDto,
-  UpdateStepLocationDto,
-} from '@FullStackMap/from-a2b';
-import { Button } from '@mantine/core';
-import { useDocumentTitle } from '@mantine/hooks';
-import { IconPinnedFilled } from '@tabler/icons-react';
-import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
-import { AxiosResponse } from 'axios';
-import { FeatureCollection, Position } from 'geojson';
-import React, { useEffect, useMemo, useState } from 'react';
-import {
-  GeolocateControl,
-  Layer,
-  LayerProps,
-  Map,
-  Marker,
-  MarkerDragEvent,
-  ScaleControl,
-  Source,
-} from 'react-map-gl';
-import { StepController, TripController } from '../../services/BaseApi';
-import { calculateRoad } from '../../services/api/MapboxController';
-
-import { useStepStore } from '../../store/useStepStore.ts';
-
-interface updateStepLocationMutationProps {
-  stepId: number;
-  updateStateLocationDto: UpdateStepLocationDto;
-}
-
-export const MapStepEditor = () => {
-  useDocumentTitle('From A2B - Map');
-
-  const setIsStepModalOpen = useStepStore(state => state.setStatus);
-
-  const handleCreateStep = () => {
-    setIsStepModalOpen(true);
-  };
-
-  //#region UseQuery
-
-  const queryClient = useQueryClient();
-
-  const tripId = 'E92913FE-5115-46BB-7A9C-08DC4E850E01';
-  const { data: trips } = useQuery({
-    queryKey: ['Trip', tripId],
-    queryFn: async () =>
-      await TripController.getTripByIdGET(tripId).then(
-        (res: AxiosResponse<TripDto, any>) => res.data,
-      ),
-  });
-
-  // const deleteStepMutation = useMutation({
-  //   mutationFn: async (stepId: number) =>
-  //     await StepController.deleteStepByIdAsyncDELETE(stepId),
-  //   onSuccess: () => {
-  //     queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
-  //   },
-  // });
-
-  const updateStepLocationMutation = useMutation({
-    mutationFn: async (args: updateStepLocationMutationProps) =>
-      await StepController.updateStepLocationAsyncPATCH(
-        args.stepId,
-        args.updateStateLocationDto,
-      ).catch(err => console.error(err)),
-    onSuccess: () => {
-      queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
-    },
-  });
-
-  //#endregion
-
-  //#region States
-  //Point de vu de l'utilisateur sur la carte, les valeurs renseignées seront l'endroit où la carte se positionnera au chargement de la page
-  const [viewState, setViewState] = React.useState({
-    longitude: 4.860200783597507,
-    latitude: 45.73050608112574,
-    zoom: 2,
-    pitch: 30,
-    bearing: 0,
-  });
-
-  //Ensemble des points de passage du voyage
-  const [steps, setSteps] = useState<StepDto[]>([]);
-  const [roads, setRoads] = useState<TravelDtoList[]>([]);
-
-  const [dto, setDto] = useState([
-    // {
-    //   start: [4.860200783597507, 45.73050608112574],
-    //   end: [5.079252160492843, 45.71892384847893],
-    // },
-    // Ajoutez d'autres coordonnées initiales ici si nécessaire
-  ]);
-
-  //#endregion
-
-  //#region Effects
-  useEffect(() => {
-    if (!trips) return;
-    setSteps(
-      trips.steps?.sort(
-        (a: StepDtoList, b: StepDtoList) => a.order! - b.order!,
-      ) as StepDto[],
-    );
-    setRoads(trips.travels as TravelDtoList[]);
-  }, [trips]);
-
-  useEffect(() => {
-    (async () => {
-      //Calcul de l'itinéraire entre les points de passage
-      //Doit être utilisé que si nécessaire, car il y a un quota de requêtes
-      //l'ensemble des itinéraires sont stockés dans la base de données
-      console.log('les dto pour le road', dto[dto.length - 1]);
-      if (dto.length > 0) {
-        const lastDto = [dto[dto.length - 1]];
-        const road: Position[] = await calculateRoad(
-          DirectionMode.DRIVING,
-          lastDto,
-        );
-        console.log('road', road);
-        setRoads(prevRoads => prevRoads.concat(road));
-        console.log('roads', roads);
-      }
-      // const road: Position[] = await calculateRoad('driving', dto);
-      // setRoads(road);
-      // console.log("roads", roads)
-    })();
-  }, [dto]);
-  //#endregion
-
-  //#region Memos
-
-  const removePoint = (index: number) => {
-    console.log('remove', index);
-  };
-
-  const handleMoveMarker = (evt: MarkerDragEvent, stepId: number) => {
-    const updateStateLocationDto: UpdateStepLocationDto = {
-      latitude: evt.lngLat.lat,
-      longitude: evt.lngLat.lng,
-    };
-
-    updateStepLocationMutation.mutate({
-      stepId: stepId,
-      updateStateLocationDto,
-    });
-  };
-
-  //Création des pins sur la carte pour chaque étape du voyage
-  const pins = useMemo(() => {
-    return steps.map((step, index) => {
-      return (
-        <Marker
-          key={step.stepId}
-          draggable
-          onDragEnd={(evn: MarkerDragEvent) =>
-            handleMoveMarker(evn, step.stepId as number)
-          }
-          latitude={step.latitude ?? 0}
-          longitude={step.longitude ?? 0}
-          pitchAlignment="viewport"
-          rotationAlignment="viewport">
-          <IconPinnedFilled
-            color="teal"
-            size={32}
-            stroke={2}
-            onClick={() => removePoint(index)}
-          />
-        </Marker>
-      );
-    });
-  }, [steps]);
-
-  //#endregion
-
-  //#region Variables
-
-  const geojson: FeatureCollection = {
-    type: 'FeatureCollection',
-    features: [
-      {
-        type: 'Feature',
-        geometry: {
-          type: 'LineString',
-          coordinates: roads.flatMap(road =>
-            JSON.parse(road.travelRoad?.roadCoordinates as string),
-          ),
-        },
-        properties: {},
-      },
-    ],
-  };
-
-  const routeLineStyle: LayerProps = {
-    id: 'roadLayer',
-    type: 'line',
-    layout: {
-      'line-join': 'round',
-      'line-cap': 'round',
-    },
-    paint: {
-      'line-color': '#3887be',
-      'line-width': 5,
-      'line-opacity': 0.75,
-    },
-  };
-
-  // const addPoint = (evt: any) => {
-  //   console.log('hello', evt.lngLat);
-  //   // @ts-ignore
-  //   setSteps([
-  //     ...steps,
-  //     { latitude: evt.lngLat.lat, longitude: evt.lngLat.lng },
-  //   ]);
-  //   console.log('steps', steps);
-  //   // @ts-ignore
-  //   if (steps.length > 0) {
-  //     setDto([
-  //       ...dto,
-  //       {
-  //         start: [
-  //           steps[steps.length - 1].longitude,
-  //           steps[steps.length - 1].latitude,
-  //         ],
-  //         end: [evt.lngLat.lng, evt.lngLat.lat],
-  //       },
-  //     ]);
-  //     console.log('ddto', dto);
-  //   }
-  // };
-
-  //#endregion
-  return (
-    <>
-      <ul>
-        {steps.map(step => (
-          <li key={step.stepId}>
-            {step.stepId} - {step.name} - {step.latitude} - {step.longitude}
-          </li>
-        ))}
-      </ul>
-
-      <Map
-        {...viewState}
-        onMove={evt => setViewState(evt.viewState)}
-        // onClick={addPoint}
-        minZoom={2}
-        dragRotate={true}
-        mapStyle="mapbox://styles/mapbox/streets-v12"
-        mapboxAccessToken="pk.eyJ1IjoiZGVyY3Jha2VyIiwiYSI6ImNsdHVnczc4dTB6N2QyanFwZDR1N2c2eHoifQ.arP7tBErlINY3-uiwfb7Ww"
-        attributionControl={true}
-        style={{
-          height: '80vh',
-          width: '80vw',
-        }}>
-        {pins}
-        <Source id="routeSource" type="geojson" data={geojson}>
-          <Layer {...routeLineStyle} />
-        </Source>
-
-        <GeolocateControl />
-        <ScaleControl />
-      </Map>
-      <Button
-        variant="outline"
-        color="yellow"
-        size="lg"
-        radius="xl"
-        onClick={handleCreateStep}>
-        ADD
-      </Button>
-    </>
-  );
-};
diff --git a/src/pages/map/MapPage.tsx b/src/pages/map/MapPage.tsx
deleted file mode 100644
index 553341e..0000000
--- a/src/pages/map/MapPage.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { AddTravelDto, UpdateStepLocationDto } from '@FullStackMap/from-a2b';
-import { Group } from '@mantine/core';
-import { useMutation } from '@tanstack/react-query';
-import { StepController, TravelController } from '../../services/BaseApi';
-1;
-
-interface updateStepLocationMutationProps {
-  stepId: number;
-  updateStateLocationDto: UpdateStepLocationDto;
-}
-
-const MapPage = () => {
-  // const addPoint = async (evt: any) => {
-  //   console.log('hello', evt.lngLat.lat, evt.lngLat.lng);
-  //   await StepController.addStepAsyncPOST(tripId, {
-  //     name: 'Nouvelle étape',
-  //     description: 'Description de la nouvelle étape',
-  //     latitude: evt.lngLat.lat,
-  //     longitude: evt.lngLat.lng,
-  //   } as AddStepDto).then(() =>
-  //     queryClient.invalidateQueries({ queryKey: ['Trip', tripId] }),
-  //   );
-  // };
-
-  //#endregion
-  return <Group justify="space-between"></Group>;
-};
-
-export default MapPage;
diff --git a/src/pages/test/TestPage.tsx b/src/pages/test/TestPage.tsx
deleted file mode 100644
index 91a35c4..0000000
--- a/src/pages/test/TestPage.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import { Button } from '@mantine/core';
-import { useDisclosure } from '@mantine/hooks';
-import { TestModal, testDto } from './components/TestModal';
-
-const TestPage = () => {
-  const [isModalOpenned, ModalController] = useDisclosure(false);
-
-  const handleModalClose = (dto: testDto) => {
-    console.log(dto);
-    ModalController.close();
-  };
-  return (
-    <>
-      <Button onClick={() => ModalController.open()}>Open Modal</Button>
-      <TestModal
-        isOpenned={isModalOpenned}
-        handleClose={dto => handleModalClose(dto)}
-      />
-    </>
-  );
-};
-
-export default TestPage;
diff --git a/src/pages/test/components/TestModal.tsx b/src/pages/test/components/TestModal.tsx
deleted file mode 100644
index 454cc29..0000000
--- a/src/pages/test/components/TestModal.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { Button, Modal } from '@mantine/core';
-import { useState } from 'react';
-
-export interface testDto {
-  id: number;
-  name: string;
-}
-
-export type TestModalProps = {
-  isOpenned: boolean;
-  handleClose: (dto: testDto) => void;
-};
-
-export const TestModal = (props: TestModalProps) => {
-  const [dto, setDto] = useState<testDto>({});
-
-  return (
-    <Modal opened={props.isOpenned} onClose={() => props.handleClose(dto)}>
-      <div>
-        <h1>Test Modal</h1>
-        <button onClick={() => setDto({ id: 1, name: 'test' })}>Set dto</button>
-      </div>
-      <Button onClick={() => props.handleClose(dto)}>Add Step</Button>
-    </Modal>
-  );
-};
diff --git a/src/pages/tripDetail/TripDetailPage.tsx b/src/pages/tripDetail/TripDetailPage.tsx
index cc18242..97f0ca8 100644
--- a/src/pages/tripDetail/TripDetailPage.tsx
+++ b/src/pages/tripDetail/TripDetailPage.tsx
@@ -4,7 +4,7 @@ import {
   StepDto,
   TripDto,
 } from '@FullStackMap/from-a2b';
-import { Container, Grid, Group, Paper, Stack } from '@mantine/core';
+import { Container, Grid } from '@mantine/core';
 import { useQuery, useQueryClient } from '@tanstack/react-query';
 import { AxiosResponse } from 'axios';
 import {
@@ -18,6 +18,7 @@ import { MapComponent } from '../../components/map/MapComponent';
 
 import { useMutation } from '@tanstack/react-query';
 
+import { useMediaQuery } from '@mantine/hooks';
 import { useParams } from 'react-router-dom';
 import { CreateStepModal } from '../../components/map/addStep/CreateStepModal.tsx';
 import { EditStepModal } from '../../components/map/editStep/EditStepModal.tsx';
@@ -33,7 +34,6 @@ import {
   useTripDetailsStore,
 } from '../../store/useTripDetailsStore';
 import './TripDetailPage.scss';
-import { useMediaQuery } from '@mantine/hooks';
 
 const TripDetailPage = () => {
   //#region Hooks
@@ -42,21 +42,21 @@ const TripDetailPage = () => {
   const { ErrorNotify } = useNotify();
 
   const tripId: string | undefined = useTripDetailsStore(
-    (state: TripDetailsStore) => state.tripId
+    (state: TripDetailsStore) => state.tripId,
   );
   const steps: StepDto[] = useTripDetailsStore(
-    (state: TripDetailsStore) => state.steps
+    (state: TripDetailsStore) => state.steps,
   );
 
   const addStepMode: AddStepMode = useTripDetailsStore(
-    (state: TripDetailsStore) => state.addStepMode
+    (state: TripDetailsStore) => state.addStepMode,
   );
 
   const otherStepId: number | undefined = useTripDetailsStore(
-    (state: TripDetailsStore) => state.otherStepId
+    (state: TripDetailsStore) => state.otherStepId,
   );
   const otherStep: StepDto | undefined = useTripDetailsStore(
-    (state: TripDetailsStore) => state.otherStep
+    (state: TripDetailsStore) => state.otherStep,
   );
 
   const { SetTripId, SetTrip, SetCurrentStep, UnSelectCurrentStep } =
@@ -71,7 +71,7 @@ const TripDetailPage = () => {
     queryKey: ['Trip', tripId],
     queryFn: async () =>
       await TripController.getTripByIdGET(tripId as string).then(
-        (res: AxiosResponse<TripDto, any>) => res.data
+        (res: AxiosResponse<TripDto, any>) => res.data,
       ),
     enabled: tripId !== undefined,
   });
@@ -83,7 +83,7 @@ const TripDetailPage = () => {
   const createStepMutation = useMutation({
     mutationFn: async (dto: AddStepDto) =>
       StepController.addStepAsyncPOST(tripId, dto),
-    onSuccess: (res) => {
+    onSuccess: res => {
       SetCurrentStep(res.data);
       queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
       handleCalculateNewTravel(undefined, res.data);
@@ -92,8 +92,8 @@ const TripDetailPage = () => {
 
   const createStepBeforeMutation = useMutation({
     mutationFn: async ([previousStepId, dto]: [number, AddStepDto]) =>
-      StepController.addStepBeforAsyncPOST(tripId, previousStepId, dto),
-    onSuccess: async (res) => {
+      StepController.addStepBeforeAsyncPOST(tripId, previousStepId, dto),
+    onSuccess: async res => {
       SetCurrentStep(res.data);
       queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
       await handleCalculateNewTravel(undefined, res.data);
@@ -104,7 +104,7 @@ const TripDetailPage = () => {
   const createStepAfterMutation = useMutation({
     mutationFn: async ([nextStepId, dto]: [number, AddStepDto]) =>
       StepController.addStepAfterAsyncPOST(tripId, nextStepId, dto),
-    onSuccess: (res) => {
+    onSuccess: res => {
       SetCurrentStep(res.data);
       queryClient.invalidateQueries({ queryKey: ['Trip', tripId] });
       handleCalculateNewTravel(otherStep, res.data);
@@ -149,25 +149,23 @@ const TripDetailPage = () => {
 
   const handleCalculateNewTravel = async (
     originStep: StepDto | undefined,
-    destinationStep: StepDto | undefined
+    destinationStep: StepDto | undefined,
   ) => {
     if (!originStep && !destinationStep) return;
 
     if (!originStep && destinationStep) {
       originStep = steps.find(
-        (step) => step.order === destinationStep!.order! - 1
+        step => step.order === destinationStep!.order! - 1,
       );
 
       if (!originStep) return;
     }
     if (!destinationStep && originStep) {
       if (!destinationStep && addStepMode === AddStepMode.AFTER)
-        destinationStep = steps.find(
-          (step) => step.order === originStep!.order!
-        );
+        destinationStep = steps.find(step => step.order === originStep!.order!);
 
       destinationStep = steps.find(
-        (step) => step.order === originStep!.order! + 1
+        step => step.order === originStep!.order! + 1,
       );
 
       if (!destinationStep) return;
@@ -192,7 +190,7 @@ const TripDetailPage = () => {
         const res: CalculateTravelRoadDto | undefined =
           await MapBoxController.calculateRoad(
             destinationStep!.transportMode as DirectionMode,
-            startEndPosition
+            startEndPosition,
           );
 
         travelRoad = res;
diff --git a/src/router/Router.tsx b/src/router/Router.tsx
index 5b04dde..4f0747d 100644
--- a/src/router/Router.tsx
+++ b/src/router/Router.tsx
@@ -12,12 +12,10 @@ import FeedbackPage from '../pages/feedback/FeedbackPage';
 import { ForgotPasswordPage } from '../pages/forgotPassword/ForgotPasswordPage';
 import LandingPage from '../pages/landing/LandingPage';
 import LoginPage from '../pages/login/LoginPage';
-import MapPage from '../pages/map/MapPage';
 import ProfilePage from '../pages/profile/ProfilePage.tsx';
 import { RegisterPage } from '../pages/register/RegisterPage';
 import HistoryPage from '../pages/showTravels/history/HistoryPage';
 import TripsPage from '../pages/showTravels/myTrips/TripsPage.tsx';
-import TestPage from '../pages/test/TestPage.tsx';
 import TripDetailPage from '../pages/tripDetail/TripDetailPage.tsx';
 import { AuthStore, useAuthStore } from '../store/useAuthStore';
 import { PrivateRoute } from './PrivateRoute';
@@ -34,7 +32,6 @@ const Router = () => {
         <Route path="/cgu" element={<CguPage />} />
         <Route path="/contact" element={<ContactPage />} />
         <Route path="/faq" element={<FaqPage />} />
-        <Route path="/t" element={<TestPage />} />
 
         <Route
           path="/profile"
@@ -72,16 +69,6 @@ const Router = () => {
             />
           }
         />
-        <Route
-          path="/map"
-          element={
-            <PrivateRoute
-              authRequired
-              redirectPath="/login"
-              element={<MapPage />}
-            />
-          }
-        />
       </Route>
 
       <Route element={<LoginLayout />}>