From 963a1c769980425bf49ff1e78392ebf27d537698 Mon Sep 17 00:00:00 2001 From: Yann Stepienik Date: Thu, 27 Apr 2023 19:29:26 +0100 Subject: [PATCH] [skip ci] v0.2.0-unstable temp commit --- .gitignore | 7 +- build.sh | 3 + client/src/assets/images/icons/folder(1).svg | 44 + client/src/assets/images/icons/folder.svg | 0 client/src/components/hostChip.jsx | 41 + client/src/components/routeComponents.jsx | 132 ++ .../components/tableView/prettyTableView.jsx | 84 + client/src/isLoggedIn.jsx | 7 +- client/src/pages/config/routeConfig.jsx | 194 +++ client/src/pages/config/users/configman.jsx | 4 +- .../pages/config/users/containerPicker.jsx | 61 +- client/src/pages/config/users/proxyman.jsx | 73 +- client/src/pages/config/users/restart.jsx | 2 +- client/src/pages/config/users/routeman.jsx | 2 +- .../src/pages/config/users/usermanagement.jsx | 5 +- client/src/pages/dashboard/index.jsx | 11 +- client/src/pages/servapps/servapps.jsx | 53 +- client/src/themes/palette.jsx | 2 +- client/src/themes/theme/index.jsx | 4 +- client/src/utils/routes.jsx | 39 + favicon.ico | Bin 0 -> 5430 bytes go.mod | 5 + go.sum | 72 +- package-lock.json | 1449 ++++++++++++++++- package.json | 3 +- readme.md | 2 + src/config.go | 37 +- src/configapi/get.go | 2 +- src/configapi/set.go | 3 +- src/docker/docker.go | 7 + src/httpServer.go | 2 + src/icons.go | 200 +++ src/status.go | 1 + src/user/token.go | 4 +- src/utils/middleware.go | 1 + src/utils/utils.go | 42 +- 36 files changed, 2461 insertions(+), 137 deletions(-) create mode 100644 client/src/assets/images/icons/folder(1).svg create mode 100644 client/src/assets/images/icons/folder.svg create mode 100644 client/src/components/hostChip.jsx create mode 100644 client/src/components/routeComponents.jsx create mode 100644 client/src/components/tableView/prettyTableView.jsx create mode 100644 client/src/pages/config/routeConfig.jsx create mode 100644 client/src/utils/routes.jsx create mode 100644 favicon.ico create mode 100644 src/icons.go diff --git a/.gitignore b/.gitignore index c340c84..e2c7385 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,9 @@ tests todo.txt LICENCE tokens.json -.vscode \ No newline at end of file +<<<<<<< Updated upstream +.vscode +cosmos_gray.png +======= +cosmos_gray.png +>>>>>>> Stashed changes diff --git a/build.sh b/build.sh index 20ac0d9..bb5a0ac 100644 --- a/build.sh +++ b/build.sh @@ -4,6 +4,9 @@ if [ $? -ne 0 ]; then exit 1 fi cp -r static build/ +mkdir build/images +cp client/src/assets/images/icons/cosmos_gray.png build/cosmos_gray.png +cp client/src/assets/images/icons/cosmos_gray.png cosmos_gray.png echo '{' > build/meta.json cat package.json | grep -E '"version"' >> build/meta.json echo ' "buildDate": "'`date`'",' >> build/meta.json diff --git a/client/src/assets/images/icons/folder(1).svg b/client/src/assets/images/icons/folder(1).svg new file mode 100644 index 0000000..f1f3b8b --- /dev/null +++ b/client/src/assets/images/icons/folder(1).svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/src/assets/images/icons/folder.svg b/client/src/assets/images/icons/folder.svg new file mode 100644 index 0000000..e69de29 diff --git a/client/src/components/hostChip.jsx b/client/src/components/hostChip.jsx new file mode 100644 index 0000000..4a1df6e --- /dev/null +++ b/client/src/components/hostChip.jsx @@ -0,0 +1,41 @@ +import { SettingOutlined } from "@ant-design/icons"; +import { Chip } from "@mui/material"; +import { useEffect, useState } from "react"; +import { getOrigin, getFullOrigin } from "../utils/routes"; +import { useTheme } from '@mui/material/styles'; + +const HostChip = ({route, settings}) => { + const theme = useTheme(); + const isDark = theme.palette.mode === 'dark'; + const [isOnline, setIsOnline] = useState(null); + const url = getOrigin(route) + + useEffect(() => { + fetch(getFullOrigin(route), { + method: 'HEAD', + mode: 'no-cors', + }).then((res) => { + setIsOnline(true); + }).catch((err) => { + setIsOnline(false); + }); + }, [url]); + + return { + if(route.UseHost) + window.open(window.location.origin.split("://")[0] + "://" + route.Host + route.PathPrefix, '_blank'); + else + window.open(window.location.origin + route.PathPrefix, '_blank'); + }} + onDelete={settings ? () => { + window.open('/ui/config-url#'+route.Name, '_blank'); + } : null} + deleteIcon={settings ? : null} + /> +} + +export default HostChip; \ No newline at end of file diff --git a/client/src/components/routeComponents.jsx b/client/src/components/routeComponents.jsx new file mode 100644 index 0000000..0e13fbf --- /dev/null +++ b/client/src/components/routeComponents.jsx @@ -0,0 +1,132 @@ +import { CheckOutlined, ClockCircleOutlined, DashboardOutlined, DeleteOutlined, DownOutlined, LockOutlined, UpOutlined } from "@ant-design/icons"; +import { Card, Chip, Stack, Tooltip } from "@mui/material"; +import { useState } from "react"; +import { useTheme } from '@mui/material/styles'; + +let routeImages = { + "SERVAPP": { + label: "ServApp", + icon: "🐳", + backgroundColor: "#0db7ed", + color: "white", + colorDark: "black", + }, + "STATIC": { + label: "Static", + icon: "📁", + backgroundColor: "#f9d71c", + color: "black", + colorDark: "black", + }, + "REDIRECT": { + label: "Redir", + icon: "🔀", + backgroundColor: "#2c3e50", + color: "white", + colorDark: "white", + }, + "PROXY": { + label: "Proxy", + icon: "🔗", + backgroundColor: "#2ecc71", + color: "white", + colorDark: "black", + }, + "SPA": { + label: "SPA", + icon: "🌐", + backgroundColor: "#e74c3c", + color: "white", + colorDark: "black", + }, +} + +export const RouteMode = ({route}) => { + const theme = useTheme(); + const isDark = theme.palette.mode === 'dark'; + let c = routeImages[route.Mode.toUpperCase()]; + return <> + {c.icon}} + label={c.label} + sx={{ + backgroundColor: c.backgroundColor, + color: isDark ? c.colorDark : c.color, + paddingLeft: "5px", + alignItems: "right", + }} + > + +} + +export const RouteSecurity = ({route}) => { + return
+ +
+ {route.AuthEnabled ? + : + + } +
+
+   + +
+ {route.ThrottlePerMinute ? + : + + } +
+
+   + +
+ {route.Timeout ? + : + + } +
+
+
+} + + +export const RouteActions = ({route, routeKey, up, down, deleteRoute}) => { + const [confirmDelete, setConfirmDelete] = useState(false); + const theme = useTheme(); + const isDark = theme.palette.mode === 'dark'; + + const miniChip = { + width: '30px', + height: '20px', + display: 'inline-block', + textAlign: 'center', + cursor: 'pointer', + color: theme.palette.text.secondary, + fontSize: '12px', + lineHeight: '20px', + padding: '0px', + borderRadius: '0px', + background: isDark ? 'rgba(255, 255, 255, 0.03)' : '', + fontWeight: 'bold', + + '&:hover': { + backgroundColor: 'rgba(0, 0, 0, 0.04)', + } + } + + return <> + + {!confirmDelete && (} onClick={() => setConfirmDelete(true)}/>)} + {confirmDelete && (} color="error" onClick={() => deleteRoute()}/>)} + + + + up()}> + {routeKey} + down()}> + + + + ; +} \ No newline at end of file diff --git a/client/src/components/tableView/prettyTableView.jsx b/client/src/components/tableView/prettyTableView.jsx new file mode 100644 index 0000000..b9924f0 --- /dev/null +++ b/client/src/components/tableView/prettyTableView.jsx @@ -0,0 +1,84 @@ +import * as React from 'react'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TableRow from '@mui/material/TableRow'; +import Paper from '@mui/material/Paper'; +import { Input, InputAdornment, Stack, TextField } from '@mui/material'; +import { SearchOutlined } from '@ant-design/icons'; +import { useTheme } from '@mui/material/styles'; + +const PrettyTableView = ({ getKey, data, columns, onRowClick }) => { + const [search, setSearch] = React.useState(''); + const theme = useTheme(); + const isDark = theme.palette.mode === 'dark'; + + return ( + + + + + } + onChange={(e) => { + setSearch(e.target.value); + }} + /> + + + + + + {columns.map((column) => ( + {column.title} + ))} + + + + {data + .filter((row) => { + if (!search || search.length <= 2) return true; + let found = false; + columns.forEach((column) => { + if (column.search && column.search(row).toLowerCase().includes(search.toLowerCase())) { + found = true; + } + }) + return found; + }) + .map((row, key) => ( + onRowClick && onRowClick(row, key)} + key={getKey(row)} + sx={{ + cursor: 'pointer', + borderLeft: 'transparent solid 5px', + '&:last-child td, &:last-child th': { border: 0 }, + '&:hover': { + backgroundColor: 'rgba(0, 0, 0, 0.04)', + borderColor: 'gray', + }, + }} + > + {columns.map((column) => ( + {column.field(row, key)} + ))} + + ))} + +
+
+
+ ) +} + +export default PrettyTableView; \ No newline at end of file diff --git a/client/src/isLoggedIn.jsx b/client/src/isLoggedIn.jsx index 8593627..5b914d4 100644 --- a/client/src/isLoggedIn.jsx +++ b/client/src/isLoggedIn.jsx @@ -2,16 +2,17 @@ import * as API from './api'; import { useEffect } from 'react'; -const isLoggedIn = () => useEffect(() => { +const IsLoggedIn = () => useEffect(() => { console.log("CHECK LOGIN") API.auth.me().then((data) => { if(data.status != 'OK') { if(data.status == 'NEW_INSTALL') { window.location.href = '/ui/newInstall'; - } else + } else if (data.status == 'error' && data.code == "HTTP004") { window.location.href = '/ui/login'; + } } }); }, []); -export default isLoggedIn; \ No newline at end of file +export default IsLoggedIn; \ No newline at end of file diff --git a/client/src/pages/config/routeConfig.jsx b/client/src/pages/config/routeConfig.jsx new file mode 100644 index 0000000..ac6f5ea --- /dev/null +++ b/client/src/pages/config/routeConfig.jsx @@ -0,0 +1,194 @@ +import * as React from 'react'; +import MainCard from '../../../components/MainCard'; +import { Formik } from 'formik'; +import * as Yup from 'yup'; +import { + Alert, + Grid, + FormHelperText, + Chip, + +} from '@mui/material'; +import { CosmosCheckbox, CosmosCollapse, CosmosFormDivider, CosmosInputText, CosmosSelect } from './formShortcuts'; +import { DownOutlined, UpOutlined, CheckOutlined, DeleteOutlined } from '@ant-design/icons'; +import { CosmosContainerPicker } from './containerPicker'; +import { ValidateRoute } from './users/routeman'; + +const RouteConfig = ({route, key, lockTarget, TargetContainer, setRouteConfig}) => { + return (
+ {route && <> + { + return false; + }} + // validate={(values) => { + // setRouteConfig(values); + // }} + > + {(formik) => ( +
+ + + {formik.errors.submit && ( + + {formik.errors.submit} + + )} + + + + + + + + + + What are you trying to access with this route? + + + + + + + { + (formik.values.Mode === "SERVAPP")? + { + setRouteConfig(formik.values); + }} + /> + : + } + + + + What URL do you want to access your target from? + + + + {formik.values.UseHost && } + + + + {formik.values.UsePathPrefix && } + + {formik.values.UsePathPrefix && } + + + + + Additional security settings. MFA and Captcha are not yet implemented. + + + + + + + + + + + + + +
+ )} +
+ + } +
) +} + +export default RouteConfig; \ No newline at end of file diff --git a/client/src/pages/config/users/configman.jsx b/client/src/pages/config/users/configman.jsx index fdcf273..0f600e7 100644 --- a/client/src/pages/config/users/configman.jsx +++ b/client/src/pages/config/users/configman.jsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import isLoggedIn from '../../../isLoggedIn'; +import IsLoggedIn from '../../../IsLoggedIn'; import * as API from '../../../api'; import MainCard from '../../../components/MainCard'; import { Formik, Field } from 'formik'; @@ -32,7 +32,6 @@ import { CosmosInputText, CosmosSelect } from './formShortcuts'; const ConfigManagement = () => { - isLoggedIn(); const [config, setConfig] = React.useState(null); const [openModal, setOpenModal] = React.useState(false); @@ -47,6 +46,7 @@ const ConfigManagement = () => { }, []); return
+

diff --git a/client/src/pages/config/users/containerPicker.jsx b/client/src/pages/config/users/containerPicker.jsx index 055a38e..44ec7b6 100644 --- a/client/src/pages/config/users/containerPicker.jsx +++ b/client/src/pages/config/users/containerPicker.jsx @@ -39,7 +39,7 @@ export function CosmosContainerPicker({formik, lockTarget, TargetContainer, onTa const [hasPublicPorts, setHasPublicPorts] = React.useState(false); const [isOnBridge, setIsOnBridge] = React.useState(false); const [options, setOptions] = React.useState(null); - const [portsOptions, setPortsOptions] = React.useState([]); + const [portsOptions, setPortsOptions] = React.useState(null); const loading = options === null; const name = "Target" @@ -78,35 +78,37 @@ export function CosmosContainerPicker({formik, lockTarget, TargetContainer, onTa }) setPortsOptions(portsTemp) - targetResult.port = '80' - - if(portsTemp.length > 0) { - // pick best default port - // set default to first port - targetResult.port = portsTemp[0] - // first, check if a manual override exists - let override = Object.keys(defaultport.overrides).find((key) => { - let keyMatch = new RegExp(key, "i"); - return newContainer.Image.match(keyMatch) && portsTemp.includes(defaultport.overrides[key]) - }); - - if(override) { - targetResult.port = defaultport.overrides[override] - } else { - // if not, check the default list of common ports - let priorityList = defaultport.priority; - priorityList.find((_portReg) => { - return portsTemp.find((portb) => { - let portReg = new RegExp(_portReg, "i"); - if(portb.toString().match(portReg)) { - targetResult.port = portb - return true; - } + if(targetResult.port == '') { + targetResult.port = '80' + + if(portsTemp.length > 0) { + // pick best default port + // set default to first port + targetResult.port = portsTemp[0] + // first, check if a manual override exists + let override = Object.keys(defaultport.overrides).find((key) => { + let keyMatch = new RegExp(key, "i"); + return newContainer.Image.match(keyMatch) && portsTemp.includes(defaultport.overrides[key]) + }); + + if(override) { + targetResult.port = defaultport.overrides[override] + } else { + // if not, check the default list of common ports + let priorityList = defaultport.priority; + priorityList.find((_portReg) => { + return portsTemp.find((portb) => { + let portReg = new RegExp(_portReg, "i"); + if(portb.toString().match(portReg)) { + targetResult.port = portb + return true; + } + }) }) - }) + } } } - + formik.setFieldValue(name, getTarget()); if(newContainer.NetworkSettings.Networks["bridge"]) { @@ -151,6 +153,7 @@ export function CosmosContainerPicker({formik, lockTarget, TargetContainer, onTa if (active) { setOptions([...names]); } + if (targetResult.container !== 'null') { postContainerChange(res.data.find((container) => container.Names[0] === targetResult.container)) } @@ -217,7 +220,7 @@ export function CosmosContainerPicker({formik, lockTarget, TargetContainer, onTa )} />} - {(portsOptions.length > 0) ? (<> + {(portsOptions) ? (<> Container Port ) : ''} - {(portsOptions.length > 0) ? (<> + {(portsOptions) ? (<> Container Protocol (use HTTP if unsure) 75) { + return test.substring(0, 75) + '...'; + } + return test; +} const ProxyManagement = () => { - isLoggedIn(); + const theme = useTheme(); + const isDark = theme.palette.mode === 'dark'; const [config, setConfig] = React.useState(null); const [openModal, setOpenModal] = React.useState(false); const [error, setError] = React.useState(null); @@ -118,7 +129,8 @@ const ProxyManagement = () => { } let routes = config && (config.HTTPConfig.ProxyConfig.Routes || []); - return
+ return
+    @@ -145,10 +157,49 @@ const ProxyManagement = () => { {config && <> - {routes && routes.map((route,key) => (<> + + {routes && r.Name + r.Target + r.Mode} + columns={[ + { + title: '', + field: (r) => , + style: { + textAlign: 'center', + }, + }, + { title: 'URL', + search: (r) => r.Name + ' ' + r.Description, + field: (r) => <> +
{r.Name}

+
{r.Description}
+ + }, + // { title: 'Description', field: (r) => shorten(r.Description), style:{fontSize: '90%', opacity: '90%'} }, + { title: 'Origin', search: (r) => r.Host + ' ' + r.PathPrefix, field: (r) => }, + // { title: 'Mode', field: (r) => }, + { title: 'Target', search: (r) => r.Target, field: (r) => <> }, + { title: 'Security', field: (r) => , + style: {minWidth: '70px'} }, + { title: '', field: (r, k) => up(k)} + down={() => down(k)} + deleteRoute={() => deleteRoute(k)} + />, + style: { + textAlign: 'right', + } + }, + ]} + />} + + {/* {routes && routes.map((route,key) => (<> { - routes[key] = newRoute; + routes[key] = sanitizeRoute(newRoute); setNeedSave(true); }} up={() => up(key)} @@ -156,7 +207,7 @@ const ProxyManagement = () => { deleteRoute={() => deleteRoute(key)} />

- ))} + ))} */} {routes && needSave && <>
@@ -207,7 +258,7 @@ const ProxyManagement = () => { variant="contained" color="primary" > - Save + Save Changes diff --git a/client/src/pages/config/users/restart.jsx b/client/src/pages/config/users/restart.jsx index f2395e0..caa3d40 100644 --- a/client/src/pages/config/users/restart.jsx +++ b/client/src/pages/config/users/restart.jsx @@ -20,7 +20,7 @@ import Chip from '@mui/material/Chip'; import IconButton from '@mui/material/IconButton'; import * as API from '../../../api'; import MainCard from '../../../components/MainCard'; -import isLoggedIn from '../../../isLoggedIn'; +import IsLoggedIn from '../../../IsLoggedIn'; import { useEffect, useState } from 'react'; const RestartModal = ({openModal, setOpenModal}) => { diff --git a/client/src/pages/config/users/routeman.jsx b/client/src/pages/config/users/routeman.jsx index ce87a61..046142f 100644 --- a/client/src/pages/config/users/routeman.jsx +++ b/client/src/pages/config/users/routeman.jsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import isLoggedIn from '../../../isLoggedIn'; +import IsLoggedIn from '../../../IsLoggedIn'; import * as API from '../../../api'; import MainCard from '../../../components/MainCard'; import { Formik, Field } from 'formik'; diff --git a/client/src/pages/config/users/usermanagement.jsx b/client/src/pages/config/users/usermanagement.jsx index a2f0352..9c56aff 100644 --- a/client/src/pages/config/users/usermanagement.jsx +++ b/client/src/pages/config/users/usermanagement.jsx @@ -20,7 +20,7 @@ import Chip from '@mui/material/Chip'; import IconButton from '@mui/material/IconButton'; import * as API from '../../../api'; import MainCard from '../../../components/MainCard'; -import isLoggedIn from '../../../isLoggedIn'; +import IsLoggedIn from '../../../IsLoggedIn'; import { useEffect, useState } from 'react'; const UserManagement = () => { @@ -34,8 +34,6 @@ const UserManagement = () => { const [rows, setRows] = useState([]); - isLoggedIn(); - function refresh() { setIsLoading(true); API.users.list() @@ -62,6 +60,7 @@ const UserManagement = () => { return <> {openInviteForm ? setOpenInviteForm(false)}> + Invite User diff --git a/client/src/pages/dashboard/index.jsx b/client/src/pages/dashboard/index.jsx index fb20c17..dcdcc82 100644 --- a/client/src/pages/dashboard/index.jsx +++ b/client/src/pages/dashboard/index.jsx @@ -34,7 +34,7 @@ import avatar1 from '../../assets/images/users/avatar-1.png'; import avatar2 from '../../assets/images/users/avatar-2.png'; import avatar3 from '../../assets/images/users/avatar-3.png'; import avatar4 from '../../assets/images/users/avatar-4.png'; -import isLoggedIn from '../../isLoggedIn'; +import IsLoggedIn from '../../IsLoggedIn'; import * as API from '../../api'; import AnimateButton from '../../components/@extended/AnimateButton'; @@ -78,8 +78,6 @@ const DashboardDefault = () => { const [value, setValue] = useState('today'); const [slot, setSlot] = useState('week'); - isLoggedIn(); - const [coStatus, setCoStatus] = useState(null); const [isCreatingDB, setIsCreatingDB] = useState(false); @@ -102,6 +100,7 @@ const DashboardDefault = () => { return ( <> +
{coStatus && !coStatus.database && ( @@ -117,6 +116,12 @@ const DashboardDefault = () => { )} + {coStatus && coStatus.needsRestart && ( + + You have made changes to the configuration that require a restart to take effect. Please restart Cosmos to apply the changes. + + )} + {coStatus && coStatus.domain && ( You are using localhost or 0.0.0.0 as a hostname in the configuration. It is recommended that you use a domain name instead. diff --git a/client/src/pages/servapps/servapps.jsx b/client/src/pages/servapps/servapps.jsx index 3946dc2..d4e9fd3 100644 --- a/client/src/pages/servapps/servapps.jsx +++ b/client/src/pages/servapps/servapps.jsx @@ -8,9 +8,11 @@ import Paper from '@mui/material/Paper'; import { styled } from '@mui/material/styles'; import * as API from '../../api'; -import isLoggedIn from '../../isLoggedIn'; +import IsLoggedIn from '../../IsLoggedIn'; import RestartModal from '../config/users/restart'; import RouteManagement, { ValidateRoute } from '../config/users/routeman'; +import { sanitizeRoute } from '../../utils/routes'; +import HostChip from '../../components/hostChip'; const Item = styled(Paper)(({ theme }) => ({ backgroundColor: theme.palette.mode === 'dark' ? '#1A2027' : '#fff', @@ -20,11 +22,14 @@ const Item = styled(Paper)(({ theme }) => ({ color: theme.palette.text.secondary, })); -const noOver = {overflowX: 'auto', width: "100%"} +const noOver = { + overflowX: 'auto', + width: "100%", + maxWidth: "800px", + height: "50px" +} const ServeApps = () => { - isLoggedIn(); - const [serveApps, setServeApps] = useState([]); const [isUpdating, setIsUpdating] = useState({}); const [search, setSearch] = useState(""); @@ -71,10 +76,12 @@ const ServeApps = () => { const getContainersRoutes = (containerName) => { return (config && config.HTTPConfig && config.HTTPConfig.ProxyConfig.Routes.filter((route) => { - return route.Mode == "SERVAPP" && ( - route.Target.startsWith(containerName) || - route.Target.split('://')[1].startsWith(containerName) - ) + let reg = new RegExp(`^(([a-z]+):\/\/)?${containerName}(:?[0-9]+)?$`, 'i'); + return route.Mode == "SERVAPP" && reg.test(route.Target) + // ( + // route.Target.startsWith(containerName) || + // route.Target.split('://')[1].startsWith(containerName) + // ) })) || []; } @@ -112,7 +119,12 @@ const ServeApps = () => { }, }; + const getHostnameFromName = (name) => { + return name.replace('/', '').replace(/_/g, '-').replace(/[^a-zA-Z0-9-]/g, '').toLowerCase().replace(/\s/g, '-') + '.' + window.location.origin.split('://')[1] + } + return
+ setOpenModal(false)}> Expose ServApp @@ -134,7 +146,7 @@ const ServeApps = () => { Name: openModal.Names[0].replace('/', ''), Description: "Expose " + openModal.Names[0].replace('/', '') + " to the internet", UseHost: true, - Host: openModal.Names[0].replace('/', '') + '.' + window.location.origin.split('://')[1], + Host: getHostnameFromName(openModal.Names[0]), UsePathPrefix: false, PathPrefix: '', Timeout: 30000, @@ -144,7 +156,7 @@ const ServeApps = () => { AuthEnabled: false, }} setRouteConfig={(_newRoute) => { - setNewRoute(_newRoute); + setNewRoute(sanitizeRoute(_newRoute)); }} up={() => {}} down={() => {}} @@ -237,9 +249,9 @@ const ServeApps = () => { Ports - {app.Ports.map((port) => { + {app.Ports.filter(p => p.IP != '::').map((port) => { return - + })} @@ -281,22 +293,7 @@ const ServeApps = () => { {getContainersRoutes(app.Names[0].replace('/', '')).map((route) => { - return <> { - if(route.UseHost) - window.open(window.location.origin.split("://")[0] + "://" + route.Host + route.PathPrefix, '_blank'); - else - window.open(window.location.origin + route.PathPrefix, '_blank'); - }} - onDelete={() => { - window.open('/ui/config-url#'+route.Name, '_blank'); - }} - deleteIcon={} - /> - + return })} {/* {getContainersRoutes(app.Names[0].replace('/', '')).length == 0 && */} { colors.grey = [...greyPrimary, ...greyAscent, ...greyConstant]; - const paletteColor = ThemeOption(colors); + const paletteColor = ThemeOption(colors, mode === 'dark'); return createTheme(mode === 'dark' ? { palette: { diff --git a/client/src/themes/theme/index.jsx b/client/src/themes/theme/index.jsx index 73f8016..1540de9 100644 --- a/client/src/themes/theme/index.jsx +++ b/client/src/themes/theme/index.jsx @@ -2,7 +2,7 @@ import { purple, pink, deepPurple } from '@mui/material/colors'; -const Theme = (colors) => { +const Theme = (colors, darkMode) => { const { blue, red, gold, cyan, green, grey } = colors; const greyColors = { 0: grey[0], @@ -30,7 +30,7 @@ const Theme = (colors) => { main: purple[400], }, secondary: { - main: deepPurple[100] + main: darkMode ? deepPurple[800] : deepPurple[100] }, error: { lighter: red[0], diff --git a/client/src/utils/routes.jsx b/client/src/utils/routes.jsx new file mode 100644 index 0000000..82e58dc --- /dev/null +++ b/client/src/utils/routes.jsx @@ -0,0 +1,39 @@ +import Folder from '../assets/images/icons/folder(1).svg'; + +export const sanitizeRoute = (route) => { + if (!route.UseHost) { + route.Host = ""; + } + if (!route.UsePathPrefix) { + route.PathPrefix = ""; + } + return route; +} + +const addProtocol = (url) => { + if (url.indexOf("http://") === 0 || url.indexOf("https://") === 0) { + return url; + } + return "https://" + url; +} + +export const getOrigin = (route) => { + return (route.UseHost ? route.Host : '') + (route.UsePathPrefix ? route.PathPrefix : ''); +} + +export const getFullOrigin = (route) => { + return addProtocol(getOrigin(route)); +} + +export const getFaviconURL = (route) => { + const addRemote = (url) => { + return '/cosmos/api/favicon?q=' + encodeURIComponent(url) + } + if(route.Mode == "SERVAP") { + return addRemote(addProtocol(route.Target)) + } else if (route.Mode == "STATIC") { + return Folder; + } else { + return addRemote(addProtocol(getOrigin(route))); + } +} \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..82339b3b1dbbcf4550b737faf99c7774196fb8cb GIT binary patch literal 5430 zcmcgwX>3$g6n=;X+3|<}Oe_lM4}(N0C5Rv{W&J^*wo?RyAcBe}5&;u}0*OVy7L=Ay zXf2DCb|BCKWlMolQL5~P(pm(H?9=IVT4p+(_4u9l<_-5P?F_|ulQZ|;bI*6abC-9Q zk)%%2V^W_!67o1{&f}6aK$4`mIHg_yeFk(dLWd$O6g@IYf<9UzqCvr6a2=!u;tfkR z^2|^uG_Wl^+PcCf8~An;Y_eeRr06G%J;p#^&`W#&+C~cwO(V;@`5-Yh&vvE5}7=D}8hx zzSiZsXwv%)bp1v^?_?0K0r<(~hP$>PS!Oz9AM8gja~C)xcwp8umJ^iSP?sl_;1=C2bSk~ zIqV~QVl4FGK3B%d6U`1WoP*7Cv2eqV&l#JUPn+vD?W*2P%gW}`tm3iqo|;^kKr@RH zY4PD%lwX-eR~DX!e8cgN$vb75Ey(67=P7uRfkXkImj>G|>W zXT}Kf9?R3aA>af^1Lr9{g9Fh;$_Uj zO$l^k#i+>nrk<;6AmH+WGxBYsuGwFCoxNu==CgNCpi{TXRX2vbuCbO1if2-j?re3h zNurQfd;WoQ1CIgX=!LSTaoLI0hQ7}~IF*{c56&3_xvB{G$g^!>r0?n(@2eryDTfPDUI#V#9aW zg7STZ?<{>w_Rz$F;Z%C1NHmG5>^o7Q;pZ4a&N~_`xcMwODJn;w2}JlghJocb$*)|6 zM6;;npzW%G-(M|XWg}Q{^O>a?*k{U>`xbMvSSk&7lL(#*;uuFO`zov&EV%jH)Lg2% zgzt+g|Kh(*E?9z>Xq;lZelGwwpWpu*zwftvA#(Y?#rzGTQa}Ew7yi5P_g5Visdyjc z@z<=s#M9dK*LSCv{F%%UeQ!jK5^1Z6D)T6KJ>Z&m?k z4s&xt950}*S?DE)JO+L>j?`HWTD#FjJNJ5MSBZx*QRcUd+Rk}eMzi`HHqe9156*rH zyYdU2@^}@jH*Irke2V^KDKA~wEO>iR1lLNDo6Cr&JM>i#tdtUu!-(<5xroL;azZ^F zI@+pt$MaqZF3lTHjRpDvXs_3UZruscS4*2{$lJ!Zr#=q0S@2C0F-D)@+om6Pm0Qix z&hJD+4D5^7IInszx)= 0.6" + } + }, "node_modules/acorn": { "version": "8.8.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", @@ -4189,12 +4202,26 @@ "get-intrinsic": "^1.1.3" } }, + "node_modules/assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dependencies": { + "object-assign": "^4.1.1", + "util": "0.10.3" + } + }, "node_modules/ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", "dev": true }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -4309,6 +4336,11 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + }, "node_modules/better-commit": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/better-commit/-/better-commit-3.1.1.tgz", @@ -4355,6 +4387,16 @@ "better-commit": "*" } }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4490,6 +4532,32 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/cheerio": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA==", + "dependencies": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -4525,6 +4593,11 @@ "node": ">=6" } }, + "node_modules/co": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", + "integrity": "sha512-CQsjCRiNObI8AtTsNIBDRMQ4oMR83CzEswHYahClvul7gKk+lDQiOKv+5qh7LQWf5sh6jkZNispz/QlsZxyNgA==" + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -4538,6 +4611,17 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/comma-separated-tokens": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", @@ -4547,6 +4631,11 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -4558,11 +4647,35 @@ "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", "dev": true }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" + }, "node_modules/copy-to-clipboard": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", @@ -4605,6 +4718,11 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, "node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", @@ -4642,6 +4760,25 @@ "node": ">= 8" } }, + "node_modules/css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==", + "dependencies": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "node_modules/css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "engines": { + "node": "*" + } + }, "node_modules/css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", @@ -4739,6 +4876,28 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-0.1.0.tgz", + "integrity": "sha512-tPYr58xmVlUWcL8zPk6ZAxP6XqiYx5IIn395dkeER12JmMy8P6ipGKnUvgD++g8+uCaALfs/CRERixvKBu1pow==" + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/dictionary-en-us": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/dictionary-en-us/-/dictionary-en-us-2.2.1.tgz", @@ -4794,11 +4953,52 @@ "csstype": "^3.0.2" } }, + "node_modules/dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "dependencies": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, "node_modules/electron-to-chromium": { "version": "1.4.333", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.333.tgz", "integrity": "sha512-YyE8+GKyGtPEP1/kpvqsdhD6rA/TP1DUFDN4uiU/YI52NzDxmwHkEb3qjId8hLBa5siJvG0sfC3O66501jMruQ==" }, + "node_modules/emitter-component": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.1.tgz", + "integrity": "sha512-G+mpdiAySMuB7kesVRLuyvYRqDmshB7ReKEVuyBPkzQlmiDiLrt7hHHIy4Aff552bgknVN7B2/d3lzhGO5dvpQ==" + }, "node_modules/emoji-named-characters": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/emoji-named-characters/-/emoji-named-characters-1.0.2.tgz", @@ -4824,6 +5024,27 @@ "node": ">=10.13.0" } }, + "node_modules/enqueue": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/enqueue/-/enqueue-1.0.2.tgz", + "integrity": "sha512-6C3wjFsq5SqRLDAgOBYVouvjlFblsp//cdoIdUDt66jdHii7dp3yJCqiNDcFdRp4vKNXYug+XVTbhxfe5MCtCw==", + "dependencies": { + "sliced": "0.0.5" + } + }, + "node_modules/enstore": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/enstore/-/enstore-1.0.1.tgz", + "integrity": "sha512-qBY73Jkl/W/5QMjmBG4yq+IDpzGmfYtakOF+Ml/XdUWfpkbME0QZbTCp8XqAyTJ8eVdC06XS8B/15b9k0+EnCQ==", + "dependencies": { + "monotonic-timestamp": "0.0.8" + } + }, + "node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -4832,6 +5053,11 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/error-inject": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/error-inject/-/error-inject-1.0.0.tgz", + "integrity": "sha512-JM8N6PytDbmIYm1IhPWlo8vr3NtfjhDY/1MhD/a5b/aad/USE8a0+NsqE9d5n+GVGmuNkPQWm4bFQWv18d8tMg==" + }, "node_modules/es-abstract": { "version": "1.21.2", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", @@ -4983,6 +5209,11 @@ "node": ">=6" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -5687,6 +5918,11 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5760,6 +5996,14 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/fetch-favicon": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/fetch-favicon/-/fetch-favicon-0.0.2.tgz", + "integrity": "sha512-itLeg0WRmgwuoPHKgrRVqroCi16m426qz0eMNvN4eZvcD5EnnfgX5/WHAL7zKWaQ43deoB/tYuLL0tmYaFiu3g==", + "dependencies": { + "x-ray": "^2.2.0" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -5831,6 +6075,19 @@ "is-callable": "^1.1.3" } }, + "node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, "node_modules/format": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", @@ -5839,6 +6096,20 @@ "node": ">=0.4.x" } }, + "node_modules/format-parser": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/format-parser/-/format-parser-0.0.2.tgz", + "integrity": "sha512-5V7k/brHdjzkCxLEbS5giO0tABQsSRRRIZCV5sCNHpg7cBZ9HlhCpe665W8/rNpqEhHaoio2SXN5KUahl2Sjjg==" + }, + "node_modules/formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, "node_modules/formik": { "version": "2.2.9", "resolved": "https://registry.npmjs.org/formik/-/formik-2.2.9.tgz", @@ -6259,6 +6530,54 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/http-context": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-context/-/http-context-1.1.1.tgz", + "integrity": "sha512-uq2wNL4SH787+Sm1NIwFz/mjwBWCBt15l82n8pWXmD/N/iAZnzrBRBdh5+0Svery4DTAGXLSO5wPrdghKnojbA==", + "dependencies": { + "accepts": "^1.2.5", + "assert": "^1.3.0", + "content-disposition": "^0.5.0", + "content-type": "^1.0.1", + "delegates": "^0.1.0", + "destroy": "^1.0.3", + "error-inject": "^1.0.0", + "escape-html": "^1.0.1", + "http-incoming": "^0.12.0", + "http-outgoing": "^0.12.0", + "koa-is-json": "^1.0.0", + "mime-types": "^2.0.10", + "on-finished": "^2.2.0", + "parseurl": "^1.3.0", + "querystring": "^0.2.0", + "statuses": "^1.2.1", + "type-is": "^1.6.1", + "vary": "^1.0.0" + } + }, + "node_modules/http-incoming": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/http-incoming/-/http-incoming-0.12.0.tgz", + "integrity": "sha512-HwkYmUNOm1/V/5xvwli4xyr/iJPY2uTa0qVWJ+QKfBoOcNabmYI/mEFW0rLjvo+A6JGAAKt1ysWqYi0ag9Q/cg==" + }, + "node_modules/http-outgoing": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/http-outgoing/-/http-outgoing-0.12.0.tgz", + "integrity": "sha512-Q2yA/LvokPsgFwbmdytWgoL7K8D+cxDJlOgjE4UrQmYHapNBRnnC+Bz97wcYmKxPRIGgVlTWrYZAPhMC/l9VxA==" + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -6417,6 +6736,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-browser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-browser/-/is-browser-2.0.1.tgz", + "integrity": "sha512-iMZxCYx2zVO3sR40Bp3LKP7nJQ3R2zVuPJJ2p2anmU6Ijl+L50v7c8Y+AVuIFMNkjZgbxgfLBcJgkoLCAOO48w==" + }, "node_modules/is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", @@ -6668,6 +6992,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" + }, "node_modules/is-weakmap": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", @@ -6723,6 +7052,14 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/jest-diff": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", @@ -7201,6 +7538,11 @@ "node": ">=4.0" } }, + "node_modules/koa-is-json": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/koa-is-json/-/koa-is-json-1.0.0.tgz", + "integrity": "sha512-+97CtHAlWDx0ndt0J8y3P12EWLwTLMXIfMnYDev3wOTwH/RpBGMlfn4bDXlMEg1u73K6XRE9BbUp+5ZAYoRYWw==" + }, "node_modules/language-subtag-registry": { "version": "0.3.22", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", @@ -7259,11 +7601,46 @@ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, + "node_modules/lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg==" + }, + "node_modules/lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha512-lxdsn7xxlCymgLYo1gGvVrfHmkjDiyqVv62FAeF2i5ta72BipE1SLxw8hPEPLhD4/247Ijw07UQH7Hq/chT5LA==" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" + }, + "node_modules/lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha512-pXYUy7PR8BCLwX5mgJ/aNtyOvuJTdZAo9EQFUvMIYugqmJxnrYaANvTbgndOzHSCSR0wnlBBfRXJL5SbWxo3FQ==" + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==" + }, + "node_modules/lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==" + }, + "node_modules/lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -7272,14 +7649,33 @@ "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "node_modules/lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==" + }, + "node_modules/lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw==" + }, + "node_modules/lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha512-qkTuvgEzYdyhiJBx42YPzPo71R1aEr0z79kAv7Ixg8wPFEjgRgJdUsGMG3Hf3OYSF/kHI79XhNlt+5Ar6OzwxQ==" }, "node_modules/lodash.shuffle": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.shuffle/-/lodash.shuffle-4.2.0.tgz", "integrity": "sha512-V/rTAABKLFjoecTZjKSv+A1ZomG8hZg8hlgeG6wwQVD9AGv+10zqqSf6mFq2tVA703Zd5R0YhSuSlXA+E/Ei+Q==" }, + "node_modules/lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ==" + }, "node_modules/lodash.throttle": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", @@ -7336,6 +7732,14 @@ "node": ">=12" } }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/memoize-one": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", @@ -7350,6 +7754,14 @@ "node": ">= 8" } }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -7362,6 +7774,36 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -7390,6 +7832,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/monotonic-timestamp": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/monotonic-timestamp/-/monotonic-timestamp-0.0.8.tgz", + "integrity": "sha512-3fQw+dAni/JJ4rkvMY7EZOz+tM+yuhrY3tKLJk74YOp/DQR0Ip+9yiKzZrC40uQ+Kin86s5TOjmL6UmxljOAfA==" + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -7431,6 +7878,14 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -7463,6 +7918,14 @@ "is-buffer": "^2.0.0" } }, + "node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dependencies": { + "boolbase": "~1.0.0" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -7580,6 +8043,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -7697,6 +8171,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -7853,6 +8335,16 @@ "node": ">=6" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/promise-polyfill": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-1.1.6.tgz", + "integrity": "sha512-7rrONfyLkDEc7OJ5QBkqa4KI4EBhCd340xRuIUPGCfu13znS+vx+VDdrT9ODAJHlXm7w4lbxN3DRjyv58EuzDg==" + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -7894,6 +8386,29 @@ "node": ">=6" } }, + "node_modules/qs": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.1.tgz", + "integrity": "sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystring": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", + "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -8190,6 +8705,19 @@ "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -8418,6 +8946,25 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -8440,6 +8987,11 @@ "loose-envify": "^1.1.0" } }, + "node_modules/selectn": { + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/selectn/-/selectn-0.9.6.tgz", + "integrity": "sha512-XOdvku6f41EAVbZGYTTyPp0CHWmUVYNuq81Hgy+4zEBZqFVk55rD1E3t1mqJZF0qZG40+PCJd+DQ8zUFy4v5Jg==" + }, "node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -8516,6 +9068,11 @@ "node": ">=8" } }, + "node_modules/sliced": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz", + "integrity": "sha512-9bYT917D6H3+q8GlQBJmLVz3bc4OeVGfZ2BB12wvLnluTGfG6/8UdOUbKJDW1EEx9SZMDbjnatkau5/XcUeyOw==" + }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -8560,6 +9117,14 @@ "node": ">=8" } }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/stop-iteration-iterator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", @@ -8571,6 +9136,22 @@ "node": ">= 0.4" } }, + "node_modules/stream-to-string": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/stream-to-string/-/stream-to-string-1.2.1.tgz", + "integrity": "sha512-WsvTDNF8UYs369Yko3pcdTducQtYpzEZeOV7cTuReyFvOoA9S/DLJ6sYK+xPafSPHhUMpaxiljKYnT6JSFztIA==", + "dependencies": { + "promise-polyfill": "^1.1.6" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-natural-compare": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", @@ -8690,6 +9271,67 @@ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" }, + "node_modules/superagent": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", + "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", + "deprecated": "Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at .", + "dependencies": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.3.5" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/superagent/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/superagent/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/superagent/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/superagent/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/superagent/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -8957,6 +9599,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/typed-array-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", @@ -9098,6 +9752,24 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", + "dependencies": { + "inherits": "2.0.1" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/util/node_modules/inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==" + }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -9106,6 +9778,14 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/vite": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.0.tgz", @@ -9245,11 +9925,91 @@ "node": ">=0.10.0" } }, + "node_modules/wrap-fn": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/wrap-fn/-/wrap-fn-0.1.5.tgz", + "integrity": "sha512-xDLdGx0M8JQw9QDAC9s5NUxtg9MI09F6Vbxa2LYoSoCvzJnx2n81YMIfykmXEGsUvuLaxnblJTzhSOjUOX37ag==", + "dependencies": { + "co": "3.1.0" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/x-ray": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/x-ray/-/x-ray-2.3.4.tgz", + "integrity": "sha512-QyprpnQb70ySaJ9LttmcS2R0e5d8oMiyDZ3bQ3bH/+dk5yUjt4obB9BUHz8/iGi+e7AZMxZOK60k/7x2/QiEJg==", + "dependencies": { + "batch": "~0.6.0", + "bluebird": "^3.4.7", + "chalk": "~2.4.0", + "cheerio": "~0.22.0", + "debug": "~4.1.0", + "enstore": "~1.0.1", + "is-url": "~1.2.0", + "isobject": "~4.0.0", + "object-assign": "~4.1.0", + "stream-to-string": "^1.1.0", + "x-ray-crawler": "~2.0.1", + "x-ray-parse": "~1.0.1" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/x-ray-crawler": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/x-ray-crawler/-/x-ray-crawler-2.0.5.tgz", + "integrity": "sha512-+VPYebF7WgiqZBLFOOCir1zExBXX1vkQ68o5S4NvyUHnfzm0LINN41l7h2h8CsqCfM1wzn9MgyUkxQPBs9kIfg==", + "dependencies": { + "cheerio": "^0.22.0", + "debug": "^2.1.3", + "delegates": "^0.1.0", + "emitter-component": "^1.1.1", + "enqueue": "^1.0.2", + "http-context": "^1.1.0", + "ms": "^2.0.0", + "selectn": "^0.9.6", + "sliced": "0.0.5", + "superagent": "^3.6.0", + "wrap-fn": "^0.1.4", + "x-ray-parse": "^1.0.0", + "yieldly": "0.0.1" + } + }, + "node_modules/x-ray-crawler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/x-ray-crawler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/x-ray-parse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/x-ray-parse/-/x-ray-parse-1.0.1.tgz", + "integrity": "sha512-ueeSjGQNctJxPLfV9Eyjxs6GSCI77Ai1RBmd4RzXJxFdO9ksgTB3inoMqw/rdNiQh4D4n1BdX403r/VXp9ab+w==", + "dependencies": { + "format-parser": "0.0.2" + } + }, + "node_modules/x-ray/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -9271,6 +10031,14 @@ "node": ">= 6" } }, + "node_modules/yieldly": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/yieldly/-/yieldly-0.0.1.tgz", + "integrity": "sha512-XdKZCVYVrA5UP8PFa8jjNkb0j9/5I3+X0KTVGjVndE+t1n41pdHVeQORzyTgLzg2g/6lAijqvjHR1oVErQ0fDg==", + "dependencies": { + "is-browser": "2.0.1" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -11977,6 +12745,15 @@ "react-refresh": "^0.14.0" } }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, "acorn": { "version": "8.8.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", @@ -12108,12 +12885,26 @@ "get-intrinsic": "^1.1.3" } }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + } + }, "ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", "dev": true }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -12206,6 +12997,11 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + }, "better-commit": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/better-commit/-/better-commit-3.1.1.tgz", @@ -12241,6 +13037,16 @@ "integrity": "sha512-D3jME5zNbAbsILA09wWtkA9j26Uqa4Pbn0dw30uLBLT9b7HnO58jm5eRGLTVyBAy+huNdnDwmiOazli9VyL5fg==", "requires": {} }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -12325,6 +13131,29 @@ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" }, + "cheerio": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA==", + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" + } + }, "ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -12348,6 +13177,11 @@ "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" }, + "co": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", + "integrity": "sha512-CQsjCRiNObI8AtTsNIBDRMQ4oMR83CzEswHYahClvul7gKk+lDQiOKv+5qh7LQWf5sh6jkZNispz/QlsZxyNgA==" + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -12361,11 +13195,24 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, "comma-separated-tokens": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==" }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -12377,11 +13224,29 @@ "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", "dev": true }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" + }, "convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, + "cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" + }, "copy-to-clipboard": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", @@ -12410,6 +13275,11 @@ "integrity": "sha512-4En6zYVi0i0XlXHVz/bi6l1XDjCqkKRq765NXuX+SnaIatlE96Odt5lMLjdxUiNI1v9OXI5DSLWYPlmTfkTktg==", "dev": true }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, "cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", @@ -12441,6 +13311,22 @@ "which": "^2.0.1" } }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" + }, "css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", @@ -12515,6 +13401,21 @@ "object-keys": "^1.1.1" } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "delegates": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-0.1.0.tgz", + "integrity": "sha512-tPYr58xmVlUWcL8zPk6ZAxP6XqiYx5IIn395dkeER12JmMy8P6ipGKnUvgD++g8+uCaALfs/CRERixvKBu1pow==" + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + }, "dictionary-en-us": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/dictionary-en-us/-/dictionary-en-us-2.2.1.tgz", @@ -12557,11 +13458,52 @@ "csstype": "^3.0.2" } }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, "electron-to-chromium": { "version": "1.4.333", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.333.tgz", "integrity": "sha512-YyE8+GKyGtPEP1/kpvqsdhD6rA/TP1DUFDN4uiU/YI52NzDxmwHkEb3qjId8hLBa5siJvG0sfC3O66501jMruQ==" }, + "emitter-component": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.1.tgz", + "integrity": "sha512-G+mpdiAySMuB7kesVRLuyvYRqDmshB7ReKEVuyBPkzQlmiDiLrt7hHHIy4Aff552bgknVN7B2/d3lzhGO5dvpQ==" + }, "emoji-named-characters": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/emoji-named-characters/-/emoji-named-characters-1.0.2.tgz", @@ -12583,6 +13525,27 @@ "tapable": "^2.2.0" } }, + "enqueue": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/enqueue/-/enqueue-1.0.2.tgz", + "integrity": "sha512-6C3wjFsq5SqRLDAgOBYVouvjlFblsp//cdoIdUDt66jdHii7dp3yJCqiNDcFdRp4vKNXYug+XVTbhxfe5MCtCw==", + "requires": { + "sliced": "0.0.5" + } + }, + "enstore": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/enstore/-/enstore-1.0.1.tgz", + "integrity": "sha512-qBY73Jkl/W/5QMjmBG4yq+IDpzGmfYtakOF+Ml/XdUWfpkbME0QZbTCp8XqAyTJ8eVdC06XS8B/15b9k0+EnCQ==", + "requires": { + "monotonic-timestamp": "0.0.8" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -12591,6 +13554,11 @@ "is-arrayish": "^0.2.1" } }, + "error-inject": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/error-inject/-/error-inject-1.0.0.tgz", + "integrity": "sha512-JM8N6PytDbmIYm1IhPWlo8vr3NtfjhDY/1MhD/a5b/aad/USE8a0+NsqE9d5n+GVGmuNkPQWm4bFQWv18d8tMg==" + }, "es-abstract": { "version": "1.21.2", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", @@ -12714,6 +13682,11 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -13221,6 +14194,11 @@ "jest-util": "^29.5.0" } }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -13286,6 +14264,14 @@ "format": "^0.2.0" } }, + "fetch-favicon": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/fetch-favicon/-/fetch-favicon-0.0.2.tgz", + "integrity": "sha512-itLeg0WRmgwuoPHKgrRVqroCi16m426qz0eMNvN4eZvcD5EnnfgX5/WHAL7zKWaQ43deoB/tYuLL0tmYaFiu3g==", + "requires": { + "x-ray": "^2.2.0" + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -13342,11 +14328,31 @@ "is-callable": "^1.1.3" } }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, "format": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==" }, + "format-parser": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/format-parser/-/format-parser-0.0.2.tgz", + "integrity": "sha512-5V7k/brHdjzkCxLEbS5giO0tABQsSRRRIZCV5sCNHpg7cBZ9HlhCpe665W8/rNpqEhHaoio2SXN5KUahl2Sjjg==" + }, + "formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==" + }, "formik": { "version": "2.2.9", "resolved": "https://registry.npmjs.org/formik/-/formik-2.2.9.tgz", @@ -13653,6 +14659,54 @@ } } }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "http-context": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-context/-/http-context-1.1.1.tgz", + "integrity": "sha512-uq2wNL4SH787+Sm1NIwFz/mjwBWCBt15l82n8pWXmD/N/iAZnzrBRBdh5+0Svery4DTAGXLSO5wPrdghKnojbA==", + "requires": { + "accepts": "^1.2.5", + "assert": "^1.3.0", + "content-disposition": "^0.5.0", + "content-type": "^1.0.1", + "delegates": "^0.1.0", + "destroy": "^1.0.3", + "error-inject": "^1.0.0", + "escape-html": "^1.0.1", + "http-incoming": "^0.12.0", + "http-outgoing": "^0.12.0", + "koa-is-json": "^1.0.0", + "mime-types": "^2.0.10", + "on-finished": "^2.2.0", + "parseurl": "^1.3.0", + "querystring": "^0.2.0", + "statuses": "^1.2.1", + "type-is": "^1.6.1", + "vary": "^1.0.0" + } + }, + "http-incoming": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/http-incoming/-/http-incoming-0.12.0.tgz", + "integrity": "sha512-HwkYmUNOm1/V/5xvwli4xyr/iJPY2uTa0qVWJ+QKfBoOcNabmYI/mEFW0rLjvo+A6JGAAKt1ysWqYi0ag9Q/cg==" + }, + "http-outgoing": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/http-outgoing/-/http-outgoing-0.12.0.tgz", + "integrity": "sha512-Q2yA/LvokPsgFwbmdytWgoL7K8D+cxDJlOgjE4UrQmYHapNBRnnC+Bz97wcYmKxPRIGgVlTWrYZAPhMC/l9VxA==" + }, "ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -13763,6 +14817,11 @@ "has-tostringtag": "^1.0.0" } }, + "is-browser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-browser/-/is-browser-2.0.1.tgz", + "integrity": "sha512-iMZxCYx2zVO3sR40Bp3LKP7nJQ3R2zVuPJJ2p2anmU6Ijl+L50v7c8Y+AVuIFMNkjZgbxgfLBcJgkoLCAOO48w==" + }, "is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", @@ -13905,6 +14964,11 @@ "has-tostringtag": "^1.0.0" } }, + "is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" + }, "is-weakmap": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", @@ -13948,6 +15012,11 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==" + }, "jest-diff": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", @@ -14292,6 +15361,11 @@ "object.assign": "^4.1.3" } }, + "koa-is-json": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/koa-is-json/-/koa-is-json-1.0.0.tgz", + "integrity": "sha512-+97CtHAlWDx0ndt0J8y3P12EWLwTLMXIfMnYDev3wOTwH/RpBGMlfn4bDXlMEg1u73K6XRE9BbUp+5ZAYoRYWw==" + }, "language-subtag-registry": { "version": "0.3.22", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", @@ -14341,11 +15415,46 @@ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, + "lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg==" + }, + "lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha512-lxdsn7xxlCymgLYo1gGvVrfHmkjDiyqVv62FAeF2i5ta72BipE1SLxw8hPEPLhD4/247Ijw07UQH7Hq/chT5LA==" + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" + }, + "lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha512-pXYUy7PR8BCLwX5mgJ/aNtyOvuJTdZAo9EQFUvMIYugqmJxnrYaANvTbgndOzHSCSR0wnlBBfRXJL5SbWxo3FQ==" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==" + }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==" + }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -14354,14 +15463,33 @@ "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==" + }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw==" + }, + "lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha512-qkTuvgEzYdyhiJBx42YPzPo71R1aEr0z79kAv7Ixg8wPFEjgRgJdUsGMG3Hf3OYSF/kHI79XhNlt+5Ar6OzwxQ==" }, "lodash.shuffle": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.shuffle/-/lodash.shuffle-4.2.0.tgz", "integrity": "sha512-V/rTAABKLFjoecTZjKSv+A1ZomG8hZg8hlgeG6wwQVD9AGv+10zqqSf6mFq2tVA703Zd5R0YhSuSlXA+E/Ei+Q==" }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ==" + }, "lodash.throttle": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", @@ -14405,6 +15533,11 @@ "@jridgewell/sourcemap-codec": "^1.4.13" } }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + }, "memoize-one": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", @@ -14416,6 +15549,11 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + }, "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -14425,6 +15563,24 @@ "picomatch": "^2.3.1" } }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, "min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -14444,6 +15600,11 @@ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true }, + "monotonic-timestamp": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/monotonic-timestamp/-/monotonic-timestamp-0.0.8.tgz", + "integrity": "sha512-3fQw+dAni/JJ4rkvMY7EZOz+tM+yuhrY3tKLJk74YOp/DQR0Ip+9yiKzZrC40uQ+Kin86s5TOjmL6UmxljOAfA==" + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -14476,6 +15637,11 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -14497,6 +15663,14 @@ "is-buffer": "^2.0.0" } }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "requires": { + "boolbase": "~1.0.0" + } + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -14575,6 +15749,14 @@ "es-abstract": "^1.20.4" } }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -14658,6 +15840,11 @@ "lines-and-columns": "^1.1.6" } }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -14758,6 +15945,16 @@ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==" }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise-polyfill": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-1.1.6.tgz", + "integrity": "sha512-7rrONfyLkDEc7OJ5QBkqa4KI4EBhCd340xRuIUPGCfu13znS+vx+VDdrT9ODAJHlXm7w4lbxN3DRjyv58EuzDg==" + }, "prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -14794,6 +15991,19 @@ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, + "qs": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.1.tgz", + "integrity": "sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "querystring": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", + "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==" + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -14987,6 +16197,16 @@ "memoize-one": ">=3.1.1 <6" } }, + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, "redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -15149,6 +16369,11 @@ "queue-microtask": "^1.2.2" } }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, "safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -15168,6 +16393,11 @@ "loose-envify": "^1.1.0" } }, + "selectn": { + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/selectn/-/selectn-0.9.6.tgz", + "integrity": "sha512-XOdvku6f41EAVbZGYTTyPp0CHWmUVYNuq81Hgy+4zEBZqFVk55rD1E3t1mqJZF0qZG40+PCJd+DQ8zUFy4v5Jg==" + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -15225,6 +16455,11 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, + "sliced": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz", + "integrity": "sha512-9bYT917D6H3+q8GlQBJmLVz3bc4OeVGfZ2BB12wvLnluTGfG6/8UdOUbKJDW1EEx9SZMDbjnatkau5/XcUeyOw==" + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -15255,6 +16490,11 @@ } } }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" + }, "stop-iteration-iterator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", @@ -15263,6 +16503,22 @@ "internal-slot": "^1.0.4" } }, + "stream-to-string": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/stream-to-string/-/stream-to-string-1.2.1.tgz", + "integrity": "sha512-WsvTDNF8UYs369Yko3pcdTducQtYpzEZeOV7cTuReyFvOoA9S/DLJ6sYK+xPafSPHhUMpaxiljKYnT6JSFztIA==", + "requires": { + "promise-polyfill": "^1.1.6" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string-natural-compare": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", @@ -15352,6 +16608,65 @@ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" }, + "superagent": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", + "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", + "requires": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.3.5" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -15559,6 +16874,15 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, "typed-array-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", @@ -15644,11 +16968,36 @@ "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", "requires": {} }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==" + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + }, "vite": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.0.tgz", @@ -15731,11 +17080,91 @@ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, + "wrap-fn": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/wrap-fn/-/wrap-fn-0.1.5.tgz", + "integrity": "sha512-xDLdGx0M8JQw9QDAC9s5NUxtg9MI09F6Vbxa2LYoSoCvzJnx2n81YMIfykmXEGsUvuLaxnblJTzhSOjUOX37ag==", + "requires": { + "co": "3.1.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "x-ray": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/x-ray/-/x-ray-2.3.4.tgz", + "integrity": "sha512-QyprpnQb70ySaJ9LttmcS2R0e5d8oMiyDZ3bQ3bH/+dk5yUjt4obB9BUHz8/iGi+e7AZMxZOK60k/7x2/QiEJg==", + "requires": { + "batch": "~0.6.0", + "bluebird": "^3.4.7", + "chalk": "~2.4.0", + "cheerio": "~0.22.0", + "debug": "~4.1.0", + "enstore": "~1.0.1", + "is-url": "~1.2.0", + "isobject": "~4.0.0", + "object-assign": "~4.1.0", + "stream-to-string": "^1.1.0", + "x-ray-crawler": "~2.0.1", + "x-ray-parse": "~1.0.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "x-ray-crawler": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/x-ray-crawler/-/x-ray-crawler-2.0.5.tgz", + "integrity": "sha512-+VPYebF7WgiqZBLFOOCir1zExBXX1vkQ68o5S4NvyUHnfzm0LINN41l7h2h8CsqCfM1wzn9MgyUkxQPBs9kIfg==", + "requires": { + "cheerio": "^0.22.0", + "debug": "^2.1.3", + "delegates": "^0.1.0", + "emitter-component": "^1.1.1", + "enqueue": "^1.0.2", + "http-context": "^1.1.0", + "ms": "^2.0.0", + "selectn": "^0.9.6", + "sliced": "0.0.5", + "superagent": "^3.6.0", + "wrap-fn": "^0.1.4", + "x-ray-parse": "^1.0.0", + "yieldly": "0.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "x-ray-parse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/x-ray-parse/-/x-ray-parse-1.0.1.tgz", + "integrity": "sha512-ueeSjGQNctJxPLfV9Eyjxs6GSCI77Ai1RBmd4RzXJxFdO9ksgTB3inoMqw/rdNiQh4D4n1BdX403r/VXp9ab+w==", + "requires": { + "format-parser": "0.0.2" + } + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -15751,6 +17180,14 @@ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" }, + "yieldly": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/yieldly/-/yieldly-0.0.1.tgz", + "integrity": "sha512-XdKZCVYVrA5UP8PFa8jjNkb0j9/5I3+X0KTVGjVndE+t1n41pdHVeQORzyTgLzg2g/6lAijqvjHR1oVErQ0fDg==", + "requires": { + "is-browser": "2.0.1" + } + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 1c853b6..8ed499d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cosmos-server", - "version": "0.1.18-unstable4", + "version": "0.2.0-unstable", "description": "", "main": "test-server.js", "bugs": { @@ -22,7 +22,6 @@ "@testing-library/user-event": "^14.4.3", "@vitejs/plugin-react": "^3.1.0", "apexcharts": "^3.35.5", - "better-commit": "^3.1.1", "formik": "^2.2.9", "framer-motion": "^7.3.6", "history": "^5.3.0", diff --git a/readme.md b/readme.md index ffe74de..acd03eb 100644 --- a/readme.md +++ b/readme.md @@ -21,6 +21,8 @@ Cosmos is a self-hosted platform for running server applications securely and wi Whether you have a **server**, a **NAS**, or a **Raspberry Pi** with applications such as **Plex**, **HomeAssistant** or even a blog, Cosmos is the perfect solution to secure them all. Simply install Cosmos on your server and connect to your applications through it to enjoy built-in security and robustness for all your services, right out of the box. + * **Easy to use** 🚀👍 to install and use, with a simple web UI to manage your applications + * **User-friendly** 🧑‍🎨 For both new and experienced users: easily integrates into your existing home server (even with NGinx, Traefik, Portainer, etc...), the already existing applications you have, and the new ones you want to install * **Secure Authentication** 👦👩 Connect to all your applications with the same account, including **strong security** and **multi-factor authentication** * **Latest Encryption Methods** 🔒🔑 To encrypt your data and protect your privacy. Security by design, and not as an afterthought * **Reverse Proxy** 🔄🔗 Reverse Proxy included, with a UI to easily manage your applications and their settings diff --git a/src/config.go b/src/config.go index d9fe765..89fda52 100644 --- a/src/config.go +++ b/src/config.go @@ -1,49 +1,16 @@ package main import ( - "os" - "regexp" "encoding/json" "github.com/azukaar/cosmos-server/src/utils" ) func LoadConfig() utils.Config { - configFile := utils.GetConfigFileName() - utils.Log("Using config file: " + configFile) - if utils.CreateDefaultConfigFileIfNecessary() { - utils.LoadBaseMainConfig(utils.DefaultConfig) - return utils.DefaultConfig - } - - file, err := os.Open(configFile) - if err != nil { - utils.Fatal("Opening Config File: ", err) - } - defer file.Close() - - decoder := json.NewDecoder(file) - config := utils.Config{} - err = decoder.Decode(&config) - - // check file is not empty - if err != nil { - // check error is not empty - if err.Error() == "EOF" { - utils.Fatal("Reading Config File: File is empty.", err) - } - - // get error string - errString := err.Error() - - // replace string in error - m1 := regexp.MustCompile(`json: cannot unmarshal ([A-Za-z\.]+) into Go struct field ([A-Za-z\.]+) of type ([A-Za-z\.]+)`) - errString = m1.ReplaceAllString(errString, "Invalid JSON in config file.\n > Field $2 is wrong.\n > Type is $1 Should be $3") - utils.Fatal("Reading Config File: " + errString, err) - } + config := utils.ReadConfigFromFile() // check if config is valid utils.Log("Validating config file...") - err = utils.Validate.Struct(config) + err := utils.Validate.Struct(config) if err != nil { utils.Fatal("Reading Config File: " + err.Error(), err) } diff --git a/src/configapi/get.go b/src/configapi/get.go index 49935ad..cff6670 100644 --- a/src/configapi/get.go +++ b/src/configapi/get.go @@ -12,7 +12,7 @@ func ConfigApiGet(w http.ResponseWriter, req *http.Request) { } if(req.Method == "GET") { - config := utils.GetBaseMainConfig() + config := utils.ReadConfigFromFile() // delete AuthPrivateKey and TLSKey config.HTTPConfig.AuthPrivateKey = "" diff --git a/src/configapi/set.go b/src/configapi/set.go index 1d47ab5..62bc501 100644 --- a/src/configapi/set.go +++ b/src/configapi/set.go @@ -30,12 +30,13 @@ func ConfigApiSet(w http.ResponseWriter, req *http.Request) { } // restore AuthPrivateKey and TLSKey - config := utils.GetBaseMainConfig() + config := utils.ReadConfigFromFile() request.HTTPConfig.AuthPrivateKey = config.HTTPConfig.AuthPrivateKey request.HTTPConfig.TLSKey = config.HTTPConfig.TLSKey request.NewInstall = config.NewInstall utils.SaveConfigTofile(request) + utils.NeedsRestart = true // if err != nil { // utils.Error("SettingsUpdate: Error saving config to file", err) diff --git a/src/docker/docker.go b/src/docker/docker.go index 9102784..739b708 100644 --- a/src/docker/docker.go +++ b/src/docker/docker.go @@ -139,8 +139,15 @@ func EditContainer(containerID string, newConfig types.ContainerJSON) (string, e newName, ) + // is force secure + isForceSecure := newConfig.Config.Labels["cosmos-force-network-secured"] == "true" + // re-connect to networks for networkName, _ := range oldContainer.NetworkSettings.Networks { + if(isForceSecure && networkName == "bridge") { + utils.Log("EditContainer - Skipping network " + networkName + " (cosmos-force-network-secured is true)") + continue + } errNet := ConnectToNetworkSync(networkName, createResponse.ID) if errNet != nil { utils.Error("EditContainer - Failed to connect to network " + networkName, errNet) diff --git a/src/httpServer.go b/src/httpServer.go index 985070e..85caf73 100644 --- a/src/httpServer.go +++ b/src/httpServer.go @@ -180,6 +180,8 @@ func StartServer() { srapi := router.PathPrefix("/cosmos").Subrouter() srapi.HandleFunc("/api/status", StatusRoute) + srapi.HandleFunc("/api/favicon", GetFavicon) + srapi.HandleFunc("/api/ping", PingURL) srapi.HandleFunc("/api/newInstall", NewInstallRoute) srapi.HandleFunc("/api/login", user.UserLogin) srapi.HandleFunc("/api/logout", user.UserLogout) diff --git a/src/icons.go b/src/icons.go new file mode 100644 index 0000000..831389e --- /dev/null +++ b/src/icons.go @@ -0,0 +1,200 @@ +package main + +import ( + "net/http" + "net/url" + // "fmt" + "os" + "io/ioutil" + "encoding/json" + "strconv" + + "github.com/azukaar/cosmos-server/src/utils" + "go.deanishe.net/favicon" +) + +type CachedImage struct { + ContentType string + ETag string + Body []byte +} + +var cache = make(map[string]CachedImage) + +func sendImage(w http.ResponseWriter, image CachedImage) { + // Copy the response to the output + w.Header().Set("Content-Type", image.ContentType) + w.Header().Set("ETag", image.ETag) + w.Header().Set("Cache-Control", "max-age=86400") + w.WriteHeader(http.StatusOK) + w.Write(image.Body) +} + +func sendFallback(w http.ResponseWriter) { + // Send the fallback image + pwd,_ := os.Getwd() + imgsrc := "cosmos_gray.png" + fallback, err := ioutil.ReadFile(pwd + "/" + imgsrc) + if err != nil { + utils.Error("Favicon: fallback", err) + utils.HTTPError(w, "Favicon", http.StatusInternalServerError, "FA003") + return + } + w.Header().Set("Content-Type", "image/png") + w.Header().Set("Cache-Control", "max-age=5") + w.WriteHeader(http.StatusOK) + w.Write(fallback) +} + + +func GetFavicon(w http.ResponseWriter, req *http.Request) { + if utils.LoggedInOnly(w, req) != nil { + return + } + + // get url from query string + escsiteurl := req.URL.Query().Get("q") + + // URL decode + siteurl, err := url.QueryUnescape(escsiteurl) + if err != nil { + utils.Error("Favicon: URL decode", err) + utils.HTTPError(w, "URL decode", http.StatusInternalServerError, "FA002") + return + } + + + if(req.Method == "GET") { + utils.Log("Fetch favicon for " + siteurl) + + // Check if we have the favicon in cache + if _, ok := cache[siteurl]; ok { + utils.Debug("Favicon in cache") + resp := cache[siteurl] + sendImage(w, resp) + return + } + + icons, err := favicon.Find(siteurl) + utils.Debug("Found Favicon: " + strconv.Itoa(len(icons))) + if err != nil { + utils.Error("FaviconFetch", err) + sendFallback(w) + return + } + + if len(icons) == 0 { + utils.Error("FaviconFetch", err) + sendFallback(w) + return + } + + iconIndex := len(icons)-1 + iconChanged := false + + for i, icon := range icons { + utils.Debug("Favicon Width: " + icon.URL + " " + strconv.Itoa(icon.Width)) + if icon.Width <= 256 { + iconIndex = i + iconChanged = true + break + } + } + if !iconChanged { + iconIndex = 0 + } + icon := icons[iconIndex] + + utils.Log("Favicon: " + icon.URL) + + // Fetch the favicon + resp, err := http.Get(icon.URL) + if err != nil { + utils.Error("FaviconFetch", err) + sendFallback(w) + return + } + + // save the body to a file + // out, err := os.Create("favicon.ico") + // if err != nil { + // utils.Error("FaviconFetch", err) + // utils.HTTPError(w, "Favicon Fetch", http.StatusInternalServerError, "FA001") + // return + // } + // defer out.Close() + // _, err = io.Copy(out, resp.Body) + // if err != nil { + // utils.Error("FaviconFetch", err) + // utils.HTTPError(w, "Favicon Fetch", http.StatusInternalServerError, "FA001") + // return + // } + + // Cache the response + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + utils.Error("FaviconFetch", err) + sendFallback(w) + return + } + + finalImage := CachedImage{ + ContentType: resp.Header.Get("Content-Type"), + ETag: resp.Header.Get("ETag"), + Body: body, + } + + cache[siteurl] = finalImage + + sendImage(w, cache[siteurl]) + } else { + utils.Error("Favicon: Method not allowed" + req.Method, nil) + utils.HTTPError(w, "Method not allowed", http.StatusMethodNotAllowed, "HTTP001") + return + } +} + +func PingURL(w http.ResponseWriter, req *http.Request) { + if utils.LoggedInOnly(w, req) != nil { + return + } + + // get url from query string + escsiteurl := req.URL.Query().Get("q") + + // URL decode + siteurl, err := url.QueryUnescape(escsiteurl) + if err != nil { + utils.Error("Ping: URL decode", err) + utils.HTTPError(w, "Ping URL decode", http.StatusInternalServerError, "FA002") + return + } + + + if(req.Method == "GET") { + utils.Log("Ping for " + siteurl) + + resp, err := http.Get(siteurl) + if err != nil { + utils.Error("Ping", err) + utils.HTTPError(w, "URL decode", http.StatusInternalServerError, "PI0001") + return + } + + if resp.StatusCode >= 500 { + utils.Error("Ping", err) + utils.HTTPError(w, "URL decode", http.StatusInternalServerError, "PI0002") + return + } + + json.NewEncoder(w).Encode(map[string]interface{}{ + "status": "OK", + "data": map[string]interface{}{ + }, + }) + } else { + utils.Error("Favicon: Method not allowed" + req.Method, nil) + utils.HTTPError(w, "Method not allowed", http.StatusMethodNotAllowed, "HTTP001") + return + } +} \ No newline at end of file diff --git a/src/status.go b/src/status.go index de6ce38..f729ad1 100644 --- a/src/status.go +++ b/src/status.go @@ -43,6 +43,7 @@ func StatusRoute(w http.ResponseWriter, req *http.Request) { "letsencrypt": utils.GetMainConfig().HTTPConfig.HTTPSCertificateMode == "LETSENCRYPT" && utils.GetMainConfig().HTTPConfig.SSLEmail == "", "domain": utils.GetMainConfig().HTTPConfig.Hostname == "localhost" || utils.GetMainConfig().HTTPConfig.Hostname == "0.0.0.0", "HTTPSCertificateMode": utils.GetMainConfig().HTTPConfig.HTTPSCertificateMode, + "needsRestart": utils.NeedsRestart, }, }) } else { diff --git a/src/user/token.go b/src/user/token.go index 6c8a2e6..5a24ce9 100644 --- a/src/user/token.go +++ b/src/user/token.go @@ -137,11 +137,11 @@ func logOutUser(w http.ResponseWriter) { } func redirectToReLogin(w http.ResponseWriter, req *http.Request) { - http.Redirect(w, req, "/ui/login?invalid=1&redirect=" + req.URL.Path, http.StatusFound) + http.Redirect(w, req, "/ui/login?invalid=1&redirect=" + req.URL.Path + "&" + req.URL.RawQuery, http.StatusTemporaryRedirect) } func SendUserToken(w http.ResponseWriter, user utils.User) { - expiration := time.Now().Add(2 * 24 * time.Hour) + expiration := time.Now().Add(3 * 24 * time.Hour) token := jwt.New(jwt.SigningMethodEdDSA) claims := token.Claims.(jwt.MapClaims) diff --git a/src/utils/middleware.go b/src/utils/middleware.go index 6ffb15f..bd6d372 100644 --- a/src/utils/middleware.go +++ b/src/utils/middleware.go @@ -61,6 +61,7 @@ func SetSecurityHeaders(next http.Handler) http.Handler { w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains") } + w.Header().Set("X-Content-Type-Options", "nosniff") w.Header().Set("X-Frame-Options", "DENY") w.Header().Set("X-XSS-Protection", "1; mode=block") diff --git a/src/utils/utils.go b/src/utils/utils.go index 9019682..4d45fda 100644 --- a/src/utils/utils.go +++ b/src/utils/utils.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "math/rand" + "regexp" "net/http" "os" "strconv" @@ -16,6 +17,8 @@ var BaseMainConfig Config var MainConfig Config var IsHTTPS = false +var NeedsRestart = false + var DefaultConfig = Config{ LoggingLevel: "INFO", NewInstall: true, @@ -83,7 +86,44 @@ func SetBaseMainConfig(config Config) { SaveConfigTofile(config) } -func LoadBaseMainConfig(config Config) { +func ReadConfigFromFile() Config { + configFile := GetConfigFileName() + Log("Using config file: " + configFile) + if CreateDefaultConfigFileIfNecessary() { + LoadBaseMainConfig(DefaultConfig) + return DefaultConfig + } + + file, err := os.Open(configFile) + if err != nil { + Fatal("Opening Config File: ", err) + } + defer file.Close() + + decoder := json.NewDecoder(file) + config := Config{} + err = decoder.Decode(&config) + + // check file is not empty + if err != nil { + // check error is not empty + if err.Error() == "EOF" { + Fatal("Reading Config File: File is empty.", err) + } + + // get error string + errString := err.Error() + + // replace string in error + m1 := regexp.MustCompile(`json: cannot unmarshal ([A-Za-z\.]+) into Go struct field ([A-Za-z\.]+) of type ([A-Za-z\.]+)`) + errString = m1.ReplaceAllString(errString, "Invalid JSON in config file.\n > Field $2 is wrong.\n > Type is $1 Should be $3") + Fatal("Reading Config File: " + errString, err) + } + + return config +} + +func LoadBaseMainConfig(config Config){ BaseMainConfig = config MainConfig = config