diff --git a/package.json b/package.json index f2838883..7126f652 100755 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "@frontend/squzanswerer": "^1.0.6", "@mui/icons-material": "^5.10.14", "@mui/material": "^5.10.14", + "@mui/x-charts": "^6.19.5", "@mui/x-date-pickers": "^6.16.1", "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^13.0.0", @@ -48,6 +49,7 @@ "react-error-boundary": "^4.0.11", "react-image-crop": "^10.1.5", "react-image-file-resizer": "^0.4.8", + "react-lazily": "^0.9.2", "react-rnd": "^10.4.1", "react-router-dom": "^6.6.2", "react-scripts": "5.0.1", diff --git a/src/App.tsx b/src/App.tsx index 0c1096a0..00332eb7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,11 +1,10 @@ +import { Suspense, lazy } from "react"; +import { lazily } from "react-lazily"; import ContactFormModal from "@ui_kit/ContactForm"; -import ImageCrop from "@ui_kit/Modal/ImageCrop"; import dayjs from "dayjs"; import "dayjs/locale/ru"; import SigninDialog from "./pages/auth/Signin"; import SignupDialog from "./pages/auth/Signup"; -import ViewPage from "./pages/ViewPublicationPage"; -import { DesignPage } from "./pages/DesignPage/DesignPage"; import { Route, Routes, @@ -14,16 +13,8 @@ import { Navigate, } from "react-router-dom"; import "./index.css"; -import ContactFormPage from "./pages/ContactFormPage/ContactFormPage"; -import InstallQuiz from "./pages/InstallQuiz/InstallQuiz"; import Landing from "./pages/Landing/Landing"; -import QuestionsPage from "./pages/Questions/QuestionsPage"; -import { Result } from "./pages/ResultPage/Result"; -import { ResultSettings } from "./pages/ResultPage/ResultSettings"; -import MyQuizzesFull from "./pages/createQuize/MyQuizzesFull"; import Main from "./pages/main"; -import EditPage from "./pages/startPage/EditPage"; -import { Tariffs } from "./pages/Tariffs/Tariffs"; import { clearAuthToken, getMessageFromFetchError, @@ -50,12 +41,48 @@ import { isAxiosError } from "axios"; import { useEffect, useLayoutEffect, useRef } from "react"; import RecoverPassword from "./pages/auth/RecoverPassword"; import OutdatedLink from "./pages/auth/OutdatedLink"; -import { QuizAnswersPage } from "./pages/QuizAnswersPage/QuizAnswersPage"; import type { OriginalUserAccount } from "@root/user"; -import ChatImageNewWindow from "@ui_kit/FloatingSupportChat/ChatImageNewWindow"; -export function useUserAccountFetcher({ +import type { SuspenseProps } from "react"; + +const MyQuizzesFull = lazy(() => import("./pages/createQuize/MyQuizzesFull")); +const ViewPage = lazy(() => import("./pages/ViewPublicationPage")); +const Analytics = lazy(() => import("./pages/Analytics/Analytics")); +const EditPage = lazy(() => import("./pages/startPage/EditPage")); +const { Tariffs } = lazily(() => import("./pages/Tariffs/Tariffs")); +const { DesignPage } = lazily(() => import("./pages/DesignPage/DesignPage")); +const { QuizAnswersPage } = lazily( + () => import("./pages/QuizAnswersPage/QuizAnswersPage"), +); +const ChatImageNewWindow = lazy( + () => import("@ui_kit/FloatingSupportChat/ChatImageNewWindow"), +); + +dayjs.locale("ru"); + +const routeslink = [ + { + path: "/edit", + page: EditPage, + header: true, + sidebar: true, + footer: true, + }, + { + path: "/design", + page: DesignPage, + header: true, + sidebar: true, + footer: true, + }, +] as const; + +const LazyLoading = ({ children, fallback }: SuspenseProps) => ( + }>{children} +); + +function useUserAccountFetcher({ onError, onNewUserAccount, url, @@ -107,25 +134,6 @@ export function useUserAccountFetcher({ }, [url, userId]); } -dayjs.locale("ru"); - -const routeslink = [ - { - path: "/edit", - page: EditPage, - header: true, - sidebar: true, - footer: true, - }, - { - path: "/design", - page: DesignPage, - header: true, - sidebar: true, - footer: true, - }, -] as const; - export default function App() { const userId = useUserStore((state) => state.userId); const location = useLocation(); @@ -239,10 +247,26 @@ export default function App() { /> } /> - } /> - } /> - } /> - } /> + } />} + /> + } />} + /> + } />} + /> + } />} + /> + } />} + /> }> } /> {routeslink.map((e, i) => ( @@ -250,11 +274,15 @@ export default function App() { key={i} path={e.path} element={ -
+ } /> } /> diff --git a/src/api/statistic.ts b/src/api/statistic.ts new file mode 100644 index 00000000..2782fe8d --- /dev/null +++ b/src/api/statistic.ts @@ -0,0 +1,81 @@ +import { makeRequest } from "@frontend/kitui"; + +import { parseAxiosError } from "@utils/parse-error"; + +const apiUrl = process.env.REACT_APP_DOMAIN + "/squiz/statistic"; + +export type DevicesResponse = { + device: Record; + os: Record; + browser: Record; +}; + +export type GeneralResponse = { + open: Record; + result: Record; + avtime: Record; + conversation: Record; +}; + +export type QuestionsResponse = { + funnel: number[]; + results: Record; + questions: Record>; +}; + +export const getDevices = async ( + quizId: string, +): Promise<[DevicesResponse | null, string?]> => { + try { + const devicesResponse = await makeRequest({ + method: "POST", + url: `${apiUrl}/${quizId}/devices`, + useToken: false, + withCredentials: true, + }); + + return [devicesResponse]; + } catch (nativeError) { + const [error] = parseAxiosError(nativeError); + + return [null, `Не удалось получить статистику о девайсах. ${error}`]; + } +}; + +export const getGeneral = async ( + quizId: string, +): Promise<[GeneralResponse | null, string?]> => { + try { + const generalResponse = await makeRequest({ + method: "POST", + url: `${apiUrl}/${quizId}/general`, + useToken: false, + withCredentials: true, + }); + + return [generalResponse]; + } catch (nativeError) { + const [error] = parseAxiosError(nativeError); + + return [null, `Не удалось получить ключевые метрики. ${error}`]; + } +}; + +export const getQuestions = async ( + quizId: string, +): Promise<[QuestionsResponse | null, string?]> => { + try { + const questionsResponse = await makeRequest({ + method: "POST", + url: `${apiUrl}/${quizId}/questions`, + useToken: false, + withCredentials: true, + }); + + return [questionsResponse]; + } catch (nativeError) { + const [error] = parseAxiosError(nativeError); + + return [null, `Не удалось получить статистику по результатам. ${error}`]; + } +}; diff --git a/src/assets/icons/Analytics/doubleCheck.svg b/src/assets/icons/Analytics/doubleCheck.svg new file mode 100644 index 00000000..a0cdbba4 --- /dev/null +++ b/src/assets/icons/Analytics/doubleCheck.svg @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/src/assets/icons/Analytics/leftArrow.svg b/src/assets/icons/Analytics/leftArrow.svg new file mode 100644 index 00000000..5fba1769 --- /dev/null +++ b/src/assets/icons/Analytics/leftArrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/Analytics/next.svg b/src/assets/icons/Analytics/next.svg new file mode 100644 index 00000000..1fd3b611 --- /dev/null +++ b/src/assets/icons/Analytics/next.svg @@ -0,0 +1,23 @@ + + + + + diff --git a/src/assets/icons/Analytics/open.svg b/src/assets/icons/Analytics/open.svg new file mode 100644 index 00000000..72c6afe4 --- /dev/null +++ b/src/assets/icons/Analytics/open.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/Analytics/rightArrow.svg b/src/assets/icons/Analytics/rightArrow.svg new file mode 100644 index 00000000..6858a01a --- /dev/null +++ b/src/assets/icons/Analytics/rightArrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/pages/Analytics/Analytics.tsx b/src/pages/Analytics/Analytics.tsx new file mode 100644 index 00000000..960e0cbf --- /dev/null +++ b/src/pages/Analytics/Analytics.tsx @@ -0,0 +1,181 @@ +import { useState } from "react"; +import { + Box, + Button, + IconButton, + Paper, + Typography, + useMediaQuery, + useTheme, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { LineChart } from "@mui/x-charts"; +import moment from "moment"; + +import HeaderFull from "@ui_kit/Header/HeaderFull"; +import SectionWrapper from "@ui_kit/SectionWrapper"; + +import { General } from "./General"; +import { AnswersStatistics } from "./Answers"; +import { Devices } from "./Devices"; + +import CalendarIcon from "@icons/CalendarIcon"; + +export default function Analytics() { + const [isOpen, setOpen] = useState(false); + const [isOpenEnd, setOpenEnd] = useState(false); + + const theme = useTheme(); + const isTablet = useMediaQuery(theme.breakpoints.down(1000)); + const isMobile = useMediaQuery(theme.breakpoints.down(600)); + + const handleClose = () => { + setOpen(false); + }; + const handleOpen = () => { + setOpen(true); + }; + const onAdornmentClick = () => { + setOpen((old) => !old); + if (isOpenEnd === true) { + handleCloseEnd(); + } + }; + + const handleCloseEnd = () => { + setOpenEnd(false); + }; + const handleOpenEnd = () => { + setOpenEnd(true); + }; + const onAdornmentClickEnd = () => { + setOpenEnd((old) => !old); + if (isOpen === true) { + handleClose(); + } + }; + + const now = moment(); + return ( + <> + + + Аналитика + + + + + Дата начала + + + + + ), + }, + }, + }} + /> + + + + Дата окончания + + + + + ), + }, + }, + }} + /> + + + + + + + + + + + ); +} diff --git a/src/pages/Analytics/Answers/Answers.tsx b/src/pages/Analytics/Answers/Answers.tsx new file mode 100644 index 00000000..d684d508 --- /dev/null +++ b/src/pages/Analytics/Answers/Answers.tsx @@ -0,0 +1,259 @@ +import { useState } from "react"; +import { + Box, + Paper, + Typography, + LinearProgress, + Pagination as MuiPagination, + PaginationItem, + Input, + ButtonBase, + useTheme, + useMediaQuery, +} from "@mui/material"; + +import { ReactComponent as DoubleCheckIcon } from "@icons/Analytics/doubleCheck.svg"; +import { ReactComponent as NextIcon } from "@icons/Analytics/next.svg"; +import { ReactComponent as LeftArrowIcon } from "@icons/Analytics/leftArrow.svg"; +import { ReactComponent as RightArrowIcon } from "@icons/Analytics/rightArrow.svg"; + +import type { PaginationRenderItemParams } from "@mui/material"; + +type AnswerProps = { + title: string; + percent: number; + highlight?: boolean; +}; + +const ANSWERS_MOCK: Record = { + "Добавьте ответ": 67, + "Вопрос пропущен": 7, + Другое: 27, +}; + +const Answer = ({ title, percent, highlight }: AnswerProps) => { + const theme = useTheme(); + + return ( + + + span": { background: highlight ? "#D9C0F9" : "#9A9AAF1A" }, + "&::before": { + content: `"${title}"`, + position: "absolute", + zIndex: 1, + left: "20px", + top: "50%", + transform: "translateY(-50%)", + color: highlight + ? theme.palette.brightPurple.main + : theme.palette.grey3.main, + }, + }} + /> + + {`${percent}%`} + + + + ); +}; + +const Pagination = () => { + const [count, setCount] = useState(50); + const [page, setPage] = useState(1); + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down(855)); + + const getPaginationItem = (props: PaginationRenderItemParams) => { + if (props.type === "start-ellipsis" || props.type === "end-ellipsis") { + return; + } + + if (props.type !== "previous" && props.type !== "next" && props.page) { + if (isMobile) { + const allowedPages = [ + page - 1 < 1 ? page + 2 : page - 1, + page, + page + 1 > count ? page - 2 : page + 1, + ]; + + if (!allowedPages.includes(props.page)) { + return; + } + } + + const allowedPages = [ + page - 2 < 1 ? page + 3 : page - 2, + page - 1 < 1 ? page + 4 : page - 1, + page, + page + 1 > count ? page - 4 : page + 1, + page + 2 > count ? page - 3 : page + 2, + ]; + + if (!allowedPages.includes(props.page)) { + return; + } + } + + return ( + + ); + }; + + return ( + + + setPage(Number(target.value.replace(/\D/, ""))) + } + sx={{ + height: "30px", + width: "65px", + borderRadius: "5px", + padding: "10px", + marginRight: "5px", + boxShadow: "0 0 20px rgba(0, 0, 0, 0.15)", + backgroundColor: theme.palette.background.paper, + }} + /> + setPage(page)} + renderItem={getPaginationItem} + sx={{ + "& .MuiButtonBase-root": { + borderRadius: "5px", + margin: "0 5px", + height: "30px", + background: theme.palette.background.paper, + boxShadow: "0 0 20px rgba(0, 0, 0, 0.15)", + "&.Mui-selected": { + background: theme.palette.background.paper, + color: theme.palette.brightPurple.main, + }, + "&.MuiPaginationItem-previousNext": { + margin: "0 15px", + background: theme.palette.brightPurple.main, + }, + }, + }} + /> + + ); +}; + +export const Answers = () => { + const [answers, setAnswers] = useState>(ANSWERS_MOCK); + const theme = useTheme(); + + return ( + + + + + Заголовок вопроса. Варианты ответов + + + + + + + + + {Object.entries(answers).map(([title, percent], index) => ( + + ))} + + + + ); +}; diff --git a/src/pages/Analytics/Answers/Funnel.tsx b/src/pages/Analytics/Answers/Funnel.tsx new file mode 100644 index 00000000..bd6777d8 --- /dev/null +++ b/src/pages/Analytics/Answers/Funnel.tsx @@ -0,0 +1,140 @@ +import { useEffect, useState } from "react"; +import { + Box, + Paper, + Typography, + LinearProgress, + useTheme, + useMediaQuery, +} from "@mui/material"; +import { enqueueSnackbar } from "notistack"; + +type FunnelItemProps = { + title: string; + percent: number; +}; + +const FUNNEL_MOCK: Record = { + "Стартовая страница": 100, + "Воронка квиза": 69, + Заявки: 56, + Результаты: 56, +}; + +const FunnelItem = ({ title, percent }: FunnelItemProps) => { + const theme = useTheme(); + + return ( + + + {title} + + + + 1 + + + span": { background: "#D9C0F9" }, + }} + /> + + {`${percent}%`} + + + + + ); +}; + +export const Funnel = () => { + const [funnel, setFunnel] = useState>(FUNNEL_MOCK); + const theme = useTheme(); + const isSmallMonitor = useMediaQuery(theme.breakpoints.down(1150)); + const isMobile = useMediaQuery(theme.breakpoints.down(850)); + + useEffect(() => { + // const requestFunnel = async () => { + // const [funnelResponse, funnelError] = await getGeneral("14761"); + // if (funnelError) { + // enqueueSnackbar(funnelError); + // return; + // } + // if (!funnelResponse) { + // enqueueSnackbar("Воронка пуста."); + // return; + // } + // setFunnel(funnelResponse); + // }; + // requestFunnel(); + }, []); + + return ( + + {Object.entries(funnel).map(([title, percent]) => ( + + ))} + + ); +}; diff --git a/src/pages/Analytics/Answers/Results.tsx b/src/pages/Analytics/Answers/Results.tsx new file mode 100644 index 00000000..3c64d1ef --- /dev/null +++ b/src/pages/Analytics/Answers/Results.tsx @@ -0,0 +1,107 @@ +import { useState } from "react"; +import { + Box, + Paper, + Typography, + LinearProgress, + useTheme, +} from "@mui/material"; + +type ResultProps = { + title: string; + percent: number; + highlight?: boolean; +}; + +const RESULTS_MOCK: Record = { + "Заголовок результата": 100, + "Результат пропущен": 7, + Другое: 27, +}; + +const Result = ({ title, percent, highlight }: ResultProps) => { + const theme = useTheme(); + + return ( + + + span": { background: highlight ? "#FDE9E0" : "#9A9AAF1A" }, + "&::before": { + content: `"${title}"`, + position: "absolute", + zIndex: 1, + left: "20px", + top: "50%", + transform: "translateY(-50%)", + color: highlight ? "#FC7230" : theme.palette.grey3.main, + }, + }} + /> + + {`${percent}%`} + + + + ); +}; + +export const Results = () => { + const [results, setResults] = useState>(RESULTS_MOCK); + const theme = useTheme(); + + return ( + + + Статистика по результатам + + + {Object.entries(results).map(([title, percent], index) => ( + + ))} + + + ); +}; diff --git a/src/pages/Analytics/Answers/index.tsx b/src/pages/Analytics/Answers/index.tsx new file mode 100644 index 00000000..d850a2ca --- /dev/null +++ b/src/pages/Analytics/Answers/index.tsx @@ -0,0 +1,66 @@ +import { + Box, + ButtonBase, + Typography, + useMediaQuery, + useTheme, +} from "@mui/material"; + +import { Answers } from "./Answers"; +import { Funnel } from "./Funnel"; +import { Results } from "./Results"; + +import { ReactComponent as OpenIcon } from "@icons/Analytics/open.svg"; + +export const AnswersStatistics = () => { + const theme = useTheme(); + const isSmallMonitor = useMediaQuery(theme.breakpoints.down(1150)); + const isMobile = useMediaQuery(theme.breakpoints.down(850)); + + return ( + + + Статистика по ответам + + + Фильтры + + + + + + + + + + + ); +}; diff --git a/src/pages/Analytics/Devices.tsx b/src/pages/Analytics/Devices.tsx new file mode 100644 index 00000000..bd7e3b42 --- /dev/null +++ b/src/pages/Analytics/Devices.tsx @@ -0,0 +1,156 @@ +import { useEffect, useState } from "react"; +import { Box, Paper, Typography, useMediaQuery, useTheme } from "@mui/material"; +import { PieChart } from "@mui/x-charts"; +import { enqueueSnackbar } from "notistack"; + +import { getDevices } from "@api/statistic"; + +import type { DevicesResponse } from "@api/statistic"; + +type DeviceProps = { + title: string; + devices: Record; +}; + +const COLORS: Record = { + 0: "#7E2AEA", + 1: "#FA7738", + 2: "#62BB1C", + 3: "#0886FB", +}; + +const DEVICES_MOCK: DevicesResponse = { + device: { PC: 75, Mobile: 25 }, + os: { Windows: 44, AndroidOS: 25, "OS X": 19, Linux: 13 }, + browser: { Chrome: 75, Firefox: 25 }, +}; + +const Device = ({ title, devices }: DeviceProps) => { + const theme = useTheme(); + const data = Object.entries(devices).map(([id, value], index) => ({ + id, + value, + color: COLORS[index], + })); + + return ( + + {title} + + + + + + + {data.map(({ id, value, color }) => ( + + + {id} + + {value} % + + ))} + + + ); +}; + +export const Devices = () => { + const [devices, setDevices] = useState(DEVICES_MOCK); + const theme = useTheme(); + const isTablet = useMediaQuery(theme.breakpoints.down(1000)); + const isMobile = useMediaQuery(theme.breakpoints.down(700)); + + useEffect(() => { + const requestDevices = async () => { + const [devicesResponse, devicesError] = await getDevices("14761"); + + if (devicesError) { + enqueueSnackbar(devicesError); + + return; + } + + if (!devicesResponse) { + enqueueSnackbar("Список девайсов пуст."); + + return; + } + + setDevices(devicesResponse); + }; + + // requestDevices(); + }, []); + + return ( + + + Статистика пользователей + + + + + + + + ); +}; diff --git a/src/pages/Analytics/General.tsx b/src/pages/Analytics/General.tsx new file mode 100644 index 00000000..e78a7a9a --- /dev/null +++ b/src/pages/Analytics/General.tsx @@ -0,0 +1,148 @@ +import { useEffect, useState } from "react"; +import { Box, Paper, Typography, useMediaQuery, useTheme } from "@mui/material"; +import { LineChart } from "@mui/x-charts"; +import { enqueueSnackbar } from "notistack"; + +import { getGeneral } from "@api/statistic"; + +import type { GeneralResponse } from "@api/statistic"; + +type GeneralProps = { + title: string; + general: Record; + color: string; + numberType: "sum" | "percent"; +}; + +const COLORS: Record = { + 0: "#61BB1A", + 1: "#7E2AEA", + 2: "#FB5607", + 3: "#0886FB", +}; + +const GENERAL_MOCK: GeneralResponse = { + open: { 100: 20, 50: 10, 60: 5 }, + result: { 100: 90, 10: 3, 50: 48 }, + avtime: { 100: 0, 2000: 550, 60: 0 }, + conversation: { 100: 50, 1000: 50, 10000: 50 }, +}; + +const GeneralItem = ({ title, general, color, numberType }: GeneralProps) => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down(700)); + + const numberValue = + numberType === "sum" + ? Object.values(general).reduce((total, item) => total + item, 0) + : Object.entries(general).reduce( + (total, [key, value]) => total + (value / Number(key)) * 100, + 0, + ) / Object.keys(general).length; + + return ( + + {title} + + {numberType === "sum" ? numberValue : `${numberValue.toFixed()}%`} + + + + ); +}; + +export const General = () => { + const [general, setGeneral] = useState(GENERAL_MOCK); + const theme = useTheme(); + const isTablet = useMediaQuery(theme.breakpoints.down(1000)); + const isMobile = useMediaQuery(theme.breakpoints.down(700)); + + useEffect(() => { + const requestGeneral = async () => { + const [generalResponse, generalError] = await getGeneral("14761"); + + if (generalError) { + enqueueSnackbar(generalError); + + return; + } + + if (!generalResponse) { + enqueueSnackbar("Список девайсов пуст."); + + return; + } + + setGeneral(generalResponse); + }; + + // requestGeneral(); + }, []); + + return ( + + + Ключевые метрики + + + + + + + + + ); +}; diff --git a/src/pages/Tariffs/Tariffs.tsx b/src/pages/Tariffs/Tariffs.tsx index a3ef5bc9..82d6fbb9 100644 --- a/src/pages/Tariffs/Tariffs.tsx +++ b/src/pages/Tariffs/Tariffs.tsx @@ -206,7 +206,7 @@ function TariffPage() { - console.log(cash)}> + ; } -export default function HeaderFull({ isRequest, sx }: Props) { +export default function HeaderFull({ isRequest = false, sx }: HeaderFullProps) { const theme = useTheme(); const navigate = useNavigate(); const isTablet = useMediaQuery(theme.breakpoints.down(1000)); diff --git a/yarn.lock b/yarn.lock index 4a61d1b5..824d7c10 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1112,13 +1112,20 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.3", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.9", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.3", "@babel/runtime@^7.23.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7" integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw== dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.20.1", "@babel/runtime@^7.23.9", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.1.tgz#431f9a794d173b53720e69a6464abc6f0e2a5c57" + integrity sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.22.15", "@babel/template@^7.23.9", "@babel/template@^7.3.3": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.23.9.tgz#f881d0487cba2828d3259dcb9ef5005a9731011a" @@ -1369,6 +1376,13 @@ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== +"@emotion/is-prop-valid@^1.2.0": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz#d4175076679c6a26faa92b03bb786f9e52612337" + integrity sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw== + dependencies: + "@emotion/memoize" "^0.8.1" + "@emotion/is-prop-valid@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" @@ -1854,7 +1868,21 @@ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== -"@mui/base@5.0.0-beta.36", "@mui/base@^5.0.0-beta.22": +"@mui/base@5.0.0-alpha.106": + version "5.0.0-alpha.106" + resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-alpha.106.tgz#23e5f61639b5786318be873d7e6d26db412c5211" + integrity sha512-xJQQtwPCPwr6hGWTBdvDwHYwExn3Bw7nPQkN8Fuz8kHpZqoMVWQvvaFS557AIkkI2AFLV3DxVIMjbCvrIntBWg== + dependencies: + "@babel/runtime" "^7.20.1" + "@emotion/is-prop-valid" "^1.2.0" + "@mui/types" "^7.2.1" + "@mui/utils" "^5.10.14" + "@popperjs/core" "^2.11.6" + clsx "^1.2.1" + prop-types "^15.8.1" + react-is "^18.2.0" + +"@mui/base@^5.0.0-beta.22": version "5.0.0-beta.36" resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.36.tgz#29ca2de9d387f6d3943b6f18a84415c43e5f206c" integrity sha512-6A8fYiXgjqTO6pgj31Hc8wm1M3rFYCxDRh09dBVk0L0W4cb2lnurRJa3cAyic6hHY+we1S58OdGYRbKmOsDpGQ== @@ -1867,10 +1895,10 @@ clsx "^2.1.0" prop-types "^15.8.1" -"@mui/core-downloads-tracker@^5.15.10": - version "5.15.10" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.10.tgz#616bfb54e3860268d56ff59cd187d47044d954f3" - integrity sha512-qPv7B+LeMatYuzRjB3hlZUHqinHx/fX4YFBiaS19oC02A1e9JFuDKDvlyRQQ5oRSbJJt0QlaLTlr0IcauVcJRQ== +"@mui/core-downloads-tracker@^5.10.14": + version "5.15.14" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.14.tgz#f7c57b261904831877220182303761c012d05046" + integrity sha512-on75VMd0XqZfaQW+9pGjSNiqW+ghc5E2ZSLRBXwcXl/C4YzjfyjrLPhrEpKnR9Uym9KXBvxrhoHfPcczYHweyA== "@mui/icons-material@^5.10.14": version "5.15.10" @@ -1879,63 +1907,73 @@ dependencies: "@babel/runtime" "^7.23.9" -"@mui/material@^5.10.14": - version "5.15.10" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.15.10.tgz#6533ba53edbd0790dbc5bb7e9e173f6069ffd7e6" - integrity sha512-YJJGHjwDOucecjDEV5l9ISTCo+l9YeWrho623UajzoHRYxuKUmwrGVYOW4PKwGvCx9SU9oklZnbbi2Clc5XZHw== +"@mui/material@5.10.14": + version "5.10.14" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.10.14.tgz#fcd687c92b22a71dc139376a5bc2d0bc578a172b" + integrity sha512-HWzKVAykePMx54WtxVwZyL1W4k3xlHYIqwMw0CaXAvgB3UE9yjABZuuGr8vG5Z6CSNWamzd+s1x8u7pQPFl9og== dependencies: - "@babel/runtime" "^7.23.9" - "@mui/base" "5.0.0-beta.36" - "@mui/core-downloads-tracker" "^5.15.10" - "@mui/system" "^5.15.9" - "@mui/types" "^7.2.13" - "@mui/utils" "^5.15.9" - "@types/react-transition-group" "^4.4.10" - clsx "^2.1.0" - csstype "^3.1.3" + "@babel/runtime" "^7.20.1" + "@mui/base" "5.0.0-alpha.106" + "@mui/core-downloads-tracker" "^5.10.14" + "@mui/system" "^5.10.14" + "@mui/types" "^7.2.1" + "@mui/utils" "^5.10.14" + "@types/react-transition-group" "^4.4.5" + clsx "^1.2.1" + csstype "^3.1.1" prop-types "^15.8.1" react-is "^18.2.0" react-transition-group "^4.4.5" -"@mui/private-theming@^5.15.9": - version "5.15.9" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.15.9.tgz#3ea3514ed2f6bf68541dbe9206665a82cd89cb01" - integrity sha512-/aMJlDOxOTAXyp4F2rIukW1O0anodAMCkv1DfBh/z9vaKHY3bd5fFf42wmP+0GRmwMinC5aWPpNfHXOED1fEtg== +"@mui/private-theming@^5.15.14": + version "5.15.14" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.15.14.tgz#edd9a82948ed01586a01c842eb89f0e3f68970ee" + integrity sha512-UH0EiZckOWcxiXLX3Jbb0K7rC8mxTr9L9l6QhOZxYc4r8FHUkefltV9VDGLrzCaWh30SQiJvAEd7djX3XXY6Xw== dependencies: "@babel/runtime" "^7.23.9" - "@mui/utils" "^5.15.9" + "@mui/utils" "^5.15.14" prop-types "^15.8.1" -"@mui/styled-engine@^5.15.9": - version "5.15.9" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.15.9.tgz#444605039ec3fe456bdd5d5cb94330183be62b91" - integrity sha512-NRKtYkL5PZDH7dEmaLEIiipd3mxNnQSO+Yo8rFNBNptY8wzQnQ+VjayTq39qH7Sast5cwHKYFusUrQyD+SS4Og== +"@mui/styled-engine@^5.15.14": + version "5.15.14" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.15.14.tgz#168b154c4327fa4ccc1933a498331d53f61c0de2" + integrity sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw== dependencies: "@babel/runtime" "^7.23.9" "@emotion/cache" "^11.11.0" csstype "^3.1.3" prop-types "^15.8.1" -"@mui/system@^5.15.9": - version "5.15.9" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.15.9.tgz#8a34ac0ab133af2550cc7ab980a35174142fd265" - integrity sha512-SxkaaZ8jsnIJ77bBXttfG//LUf6nTfOcaOuIgItqfHv60ZCQy/Hu7moaob35kBb+guxVJnoSZ+7vQJrA/E7pKg== +"@mui/system@^5.10.14": + version "5.15.14" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.15.14.tgz#8a0c6571077eeb6b5f1ff7aa7ff6a3dc4a14200d" + integrity sha512-auXLXzUaCSSOLqJXmsAaq7P96VPRXg2Rrz6OHNV7lr+kB8lobUF+/N84Vd9C4G/wvCXYPs5TYuuGBRhcGbiBGg== dependencies: "@babel/runtime" "^7.23.9" - "@mui/private-theming" "^5.15.9" - "@mui/styled-engine" "^5.15.9" - "@mui/types" "^7.2.13" - "@mui/utils" "^5.15.9" + "@mui/private-theming" "^5.15.14" + "@mui/styled-engine" "^5.15.14" + "@mui/types" "^7.2.14" + "@mui/utils" "^5.15.14" clsx "^2.1.0" csstype "^3.1.3" prop-types "^15.8.1" -"@mui/types@^7.2.13": - version "7.2.13" - resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.13.tgz#d1584912942f9dc042441ecc2d1452be39c666b8" - integrity sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g== +"@mui/types@^7.2.1", "@mui/types@^7.2.13", "@mui/types@^7.2.14": + version "7.2.14" + resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.14.tgz#8a02ac129b70f3d82f2f9b76ded2c8d48e3fc8c9" + integrity sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ== -"@mui/utils@^5.14.16", "@mui/utils@^5.15.9": +"@mui/utils@^5.10.14", "@mui/utils@^5.15.14", "@mui/utils@^5.15.9": + version "5.15.14" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.15.14.tgz#e414d7efd5db00bfdc875273a40c0a89112ade3a" + integrity sha512-0lF/7Hh/ezDv5X7Pry6enMsbYyGKjADzvHyo3Qrc/SSlTsQ1VkbDMbH0m2t3OR5iIVLwMoxwM7yGd+6FCMtTFA== + dependencies: + "@babel/runtime" "^7.23.9" + "@types/prop-types" "^15.7.11" + prop-types "^15.8.1" + react-is "^18.2.0" + +"@mui/utils@^5.14.16": version "5.15.9" resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.15.9.tgz#2bdf925e274d87cbe90c14eb52d0835318205e86" integrity sha512-yDYfr61bCYUz1QtwvpqYy/3687Z8/nS4zv7lv/ih/6ZFGMl1iolEvxRmR84v2lOYxlds+kq1IVYbXxDKh8Z9sg== @@ -1945,6 +1983,21 @@ prop-types "^15.8.1" react-is "^18.2.0" +"@mui/x-charts@^6.19.5": + version "6.19.5" + resolved "https://registry.yarnpkg.com/@mui/x-charts/-/x-charts-6.19.5.tgz#1c427961b87ba12ea3407ce1623e235a090828f4" + integrity sha512-BBRGLup5gpaLkhECv+J2ahFbDDgqK4BgLyLXLHKUASoWSU3YRCyDt9ifBREspEPfTZXgrcqNkybAl5b+l6baFQ== + dependencies: + "@babel/runtime" "^7.23.2" + "@mui/base" "^5.0.0-beta.22" + "@react-spring/rafz" "^9.7.3" + "@react-spring/web" "^9.7.3" + clsx "^2.0.0" + d3-color "^3.1.0" + d3-scale "^4.0.2" + d3-shape "^3.2.0" + prop-types "^15.8.1" + "@mui/x-date-pickers@^6.16.1": version "6.19.4" resolved "https://registry.yarnpkg.com/@mui/x-date-pickers/-/x-date-pickers-6.19.4.tgz#7df5ea081bdf9e2ce75c346bd95af340b1b56e9f" @@ -2006,7 +2059,7 @@ schema-utils "^3.0.0" source-map "^0.7.3" -"@popperjs/core@^2.0.0", "@popperjs/core@^2.11.8": +"@popperjs/core@^2.0.0", "@popperjs/core@^2.11.6", "@popperjs/core@^2.11.8": version "2.11.8" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== @@ -2026,6 +2079,50 @@ resolved "https://registry.yarnpkg.com/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz#d1b4befa423f692fa4abf1c79209702e7d8ae4b4" integrity sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA== +"@react-spring/animated@~9.7.3": + version "9.7.3" + resolved "https://registry.yarnpkg.com/@react-spring/animated/-/animated-9.7.3.tgz#4211b1a6d48da0ff474a125e93c0f460ff816e0f" + integrity sha512-5CWeNJt9pNgyvuSzQH+uy2pvTg8Y4/OisoscZIR8/ZNLIOI+CatFBhGZpDGTF/OzdNFsAoGk3wiUYTwoJ0YIvw== + dependencies: + "@react-spring/shared" "~9.7.3" + "@react-spring/types" "~9.7.3" + +"@react-spring/core@~9.7.3": + version "9.7.3" + resolved "https://registry.yarnpkg.com/@react-spring/core/-/core-9.7.3.tgz#60056bcb397f2c4f371c6c9a5f882db77ae90095" + integrity sha512-IqFdPVf3ZOC1Cx7+M0cXf4odNLxDC+n7IN3MDcVCTIOSBfqEcBebSv+vlY5AhM0zw05PDbjKrNmBpzv/AqpjnQ== + dependencies: + "@react-spring/animated" "~9.7.3" + "@react-spring/shared" "~9.7.3" + "@react-spring/types" "~9.7.3" + +"@react-spring/rafz@^9.7.3": + version "9.7.3" + resolved "https://registry.yarnpkg.com/@react-spring/rafz/-/rafz-9.7.3.tgz#d6a9695c581f58a49e047ff7ed5646e0b681396c" + integrity sha512-9vzW1zJPcC4nS3aCV+GgcsK/WLaB520Iyvm55ARHfM5AuyBqycjvh1wbmWmgCyJuX4VPoWigzemq1CaaeRSHhQ== + +"@react-spring/shared@~9.7.3": + version "9.7.3" + resolved "https://registry.yarnpkg.com/@react-spring/shared/-/shared-9.7.3.tgz#4cf29797847c689912aec4e62e34c99a4d5d9e53" + integrity sha512-NEopD+9S5xYyQ0pGtioacLhL2luflh6HACSSDUZOwLHoxA5eku1UPuqcJqjwSD6luKjjLfiLOspxo43FUHKKSA== + dependencies: + "@react-spring/types" "~9.7.3" + +"@react-spring/types@~9.7.3": + version "9.7.3" + resolved "https://registry.yarnpkg.com/@react-spring/types/-/types-9.7.3.tgz#ea78fd447cbc2612c1f5d55852e3c331e8172a0b" + integrity sha512-Kpx/fQ/ZFX31OtlqVEFfgaD1ACzul4NksrvIgYfIFq9JpDHFwQkMVZ10tbo0FU/grje4rcL4EIrjekl3kYwgWw== + +"@react-spring/web@^9.7.3": + version "9.7.3" + resolved "https://registry.yarnpkg.com/@react-spring/web/-/web-9.7.3.tgz#d9f4e17fec259f1d65495a19502ada4f5b57fa3d" + integrity sha512-BXt6BpS9aJL/QdVqEIX9YoUy8CE6TJrU0mNCqSoxdXlIeNcEBWOfIyE6B14ENNsyQKS3wOWkiJfco0tCr/9tUg== + dependencies: + "@react-spring/animated" "~9.7.3" + "@react-spring/core" "~9.7.3" + "@react-spring/shared" "~9.7.3" + "@react-spring/types" "~9.7.3" + "@remix-run/router@1.15.0": version "1.15.0" resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.15.0.tgz#461a952c2872dd82c8b2e9b74c4dfaff569123e2" @@ -2534,9 +2631,9 @@ integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== "@types/prop-types@*", "@types/prop-types@^15.7.11": - version "15.7.11" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" - integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== + version "15.7.12" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" + integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== "@types/q@^1.5.1": version "1.5.8" @@ -2599,14 +2696,23 @@ dependencies: "@types/react" "*" -"@types/react-transition-group@^4.4.10", "@types/react-transition-group@^4.4.8": +"@types/react-transition-group@^4.4.5", "@types/react-transition-group@^4.4.8": version "4.4.10" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.10.tgz#6ee71127bdab1f18f11ad8fb3322c6da27c327ac" integrity sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q== dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^18.2.55": +"@types/react@*": + version "18.2.70" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.70.tgz#89a37f9e0a6a4931f4259c598f40fd44dd6abf71" + integrity sha512-hjlM2hho2vqklPhopNkXkdkeq6Lv8WSZTpr7956zY+3WS5cfYUewtCzsJLsbW5dEv3lfSeQ4W14ZFeKC437JRQ== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/react@^18.2.55": version "18.2.55" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.55.tgz#38141821b7084404b5013742bc4ae08e44da7a67" integrity sha512-Y2Tz5P4yz23brwm2d7jNon39qoAtMMmalOQv6+fEFt1mT+FcM3D841wDpoUvFXhaYenuROCy3FZYqdTjM7qVyA== @@ -3914,7 +4020,7 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" -clsx@^1.1.0, clsx@^1.1.1: +clsx@^1.1.0, clsx@^1.1.1, clsx@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== @@ -4379,7 +4485,7 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" -csstype@^3.0.2, csstype@^3.1.3: +csstype@^3.0.2, csstype@^3.1.1, csstype@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== @@ -4452,6 +4558,67 @@ cytoscape@^3.26.0: heap "^0.2.6" lodash "^4.17.21" +"d3-array@2 - 3", "d3-array@2.10.0 - 3": + version "3.2.4" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5" + integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== + dependencies: + internmap "1 - 2" + +"d3-color@1 - 3", d3-color@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2" + integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== + +"d3-format@1 - 3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641" + integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== + +"d3-interpolate@1.2.0 - 3": + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d" + integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== + dependencies: + d3-color "1 - 3" + +d3-path@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526" + integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== + +d3-scale@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396" + integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== + dependencies: + d3-array "2.10.0 - 3" + d3-format "1 - 3" + d3-interpolate "1.2.0 - 3" + d3-time "2.1.1 - 3" + d3-time-format "2 - 4" + +d3-shape@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5" + integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== + dependencies: + d3-path "^3.1.0" + +"d3-time-format@2 - 4": + version "4.1.0" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a" + integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== + dependencies: + d3-time "1 - 3" + +"d3-time@1 - 3", "d3-time@2.1.1 - 3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7" + integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== + dependencies: + d3-array "2 - 3" + damerau-levenshtein@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" @@ -6408,6 +6575,11 @@ internal-slot@^1.0.4, internal-slot@^1.0.5, internal-slot@^1.0.7: hasown "^2.0.0" side-channel "^1.0.4" +"internmap@1 - 2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" + integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== + ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -9400,6 +9572,11 @@ react-is@^18.0.0, react-is@^18.2.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== +react-lazily@^0.9.2: + version "0.9.2" + resolved "https://registry.yarnpkg.com/react-lazily/-/react-lazily-0.9.2.tgz#74596dbde43c8e0f607445da5c4839cf6cc48ab5" + integrity sha512-oBVRDQ+SuMPWenBO/0Kq+iZk34lOYJEmjiTto4bYRufndf8pux3E50BT3mJZbsq0vBsAVbX3fpQjlUvsXgDVag== + react-redux@^7.2.0: version "7.2.9" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.9.tgz#09488fbb9416a4efe3735b7235055442b042481d"