Merge branch 'new-page-framework' of https://github.com/csunny/DB-GPT into new-page-framework

This commit is contained in:
changhuiping.chp 2023-06-28 10:47:51 +08:00
commit f854c94aba
5 changed files with 876 additions and 355 deletions

View File

@ -1,65 +1,76 @@
"use client"; 'use client'
import { useSearchParams } from 'next/navigation' import { useSearchParams } from 'next/navigation'
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react'
import { Table, Popover } from 'antd'; import { Table } from '@/lib/mui'
import moment from 'moment'; import { Popover } from 'antd'
const ChunkList = () => { const ChunkList = () => {
const spaceName = useSearchParams().get('spacename'); const spaceName = useSearchParams().get('spacename')
const documentId = useSearchParams().get('documentid'); const documentId = useSearchParams().get('documentid')
const [chunkList, setChunkList] = useState<any>([]); const [chunkList, setChunkList] = useState<any>([])
useEffect(() => { useEffect(() => {
async function fetchChunks() { async function fetchChunks() {
const res = await fetch(`http://localhost:8000/knowledge/${spaceName}/chunk/list`, { const res = await fetch(
method: 'POST', `http://localhost:8000/knowledge/${spaceName}/chunk/list`,
headers: { {
'Content-Type': 'application/json', method: 'POST',
}, headers: {
body: JSON.stringify({ 'Content-Type': 'application/json'
document_id: documentId },
}), body: JSON.stringify({
}); document_id: documentId
const data = await res.json(); })
if (data.success) {
setChunkList(data.data);
}
} }
fetchChunks(); )
}, []); const data = await res.json()
return ( if (data.success) {
<div className='p-4'> setChunkList(data.data)
<Table }
columns={[ }
{ fetchChunks()
title: 'Name', }, [])
dataIndex: 'doc_name', return (
key: 'doc_name', <div className="p-4">
align: 'center', <Table sx={{ '& thead th:nth-child(1)': { width: '40%' } }}>
}, <thead>
{ <tr>
title: 'Content', <th>Name</th>
dataIndex: 'content', <th>Content</th>
key: 'content', <th>Meta Data</th>
align: 'center', </tr>
render: (text: string, label: any) => { </thead>
return <Popover content={text} trigger="hover">{text.length < 10 ? `${text.slice(0, 10)}...` : text}</Popover>; <tbody>
} {chunkList.map((row: any) => (
}, <tr key={row.id}>
{ <td>{row.doc_name}</td>
title: 'Meta Data', <td>
dataIndex: 'meta_info', {
key: 'meta_info', <Popover content={row.content} trigger="hover">
align: 'center', {row.content.length > 10
render: (text: string, label: any) => { ? `${row.content.slice(0, 10)}...`
return <Popover content={JSON.stringify(text || '{}', null, 2)} trigger="hover">{text.length < 10 ? `${text.slice(0, 10)}...` : text}</Popover>; : row.content}
} </Popover>
}, }
]} </td>
dataSource={chunkList} <td>
/> {
</div> <Popover
) content={JSON.stringify(row.meta_info || '{}', null, 2)}
trigger="hover"
>
{row.meta_info.length > 10
? `${row.meta_info.slice(0, 10)}...`
: row.meta_info}
</Popover>
}
</td>
</tr>
))}
</tbody>
</Table>
</div>
)
} }
export default ChunkList; export default ChunkList

View File

@ -1,84 +1,292 @@
"use client"; 'use client'
import Link from 'next/link'
import { useRouter, useSearchParams } from 'next/navigation' import { useRouter, useSearchParams } from 'next/navigation'
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react'
import { Table, Button } from 'antd'; import {
import moment from 'moment'; Button,
Table,
Sheet,
Modal,
Box,
Stack,
Input,
styled
} from '@/lib/mui'
import moment from 'moment'
import { message } from 'antd'
const stepsOfAddingDocument = [
'Choose a Datasource type',
'Setup the Datasource'
]
const documentTypeList = [
{
type: 'text',
title: 'Text',
subTitle: 'Paste some text'
},
{
type: 'webPage',
title: 'Web Page',
subTitle: 'Crawl text from a web page'
},
{
type: 'file',
title: 'File',
subTitle: 'It can be: PDF, CSV, JSON, Text, PowerPoint, Word, Excel'
}
]
const Item = styled(Sheet)(({ theme }) => ({
width: '50%',
backgroundColor:
theme.palette.mode === 'dark' ? theme.palette.background.level1 : '#fff',
...theme.typography.body2,
padding: theme.spacing(1),
textAlign: 'center',
borderRadius: 4,
color: theme.vars.palette.text.secondary
}))
const Documents = () => { const Documents = () => {
const router = useRouter(); const router = useRouter()
const spaceName = useSearchParams().get('name'); const spaceName = useSearchParams().get('name')
const [documents, setDocuments] = useState<any>([]); const [isAddDocumentModalShow, setIsAddDocumentModalShow] =
useEffect(() => { useState<boolean>(false)
async function fetchDocuments() { const [activeStep, setActiveStep] = useState<number>(0)
const res = await fetch(`http://localhost:8000/knowledge/${spaceName}/document/list`, { const [documents, setDocuments] = useState<any>([])
method: 'POST', const [webPageUrl, setWebPageUrl] = useState<string>('')
headers: { const [documentName, setDocumentName] = useState<string>('')
'Content-Type': 'application/json', useEffect(() => {
}, async function fetchDocuments() {
body: JSON.stringify({}), const res = await fetch(
}); `http://localhost:8000/knowledge/${spaceName}/document/list`,
const data = await res.json(); {
if (data.success) { method: 'POST',
setDocuments(data.data); headers: {
} 'Content-Type': 'application/json'
},
body: JSON.stringify({})
} }
fetchDocuments(); )
}, []); const data = await res.json()
return ( if (data.success) {
<div className='p-4'> setDocuments(data.data)
<Table }
columns={[ }
{ fetchDocuments()
title: 'Name', }, [])
dataIndex: 'doc_name', return (
key: 'doc_name', <div className="p-4">
align: 'center', <Sheet
}, sx={{
{ display: 'flex',
title: 'Type', flexDirection: 'row-reverse'
dataIndex: 'doc_type', }}
key: 'doc_type', >
align: 'center', <Button
}, variant="outlined"
{ onClick={() => setIsAddDocumentModalShow(true)}
title: 'Size', >
dataIndex: 'chunk_size', + Add Datasource
key: 'chunk_size', </Button>
align: 'center', </Sheet>
}, <Table sx={{ '& thead th:nth-child(1)': { width: '40%' } }}>
{ <thead>
title: 'Last Synch', <tr>
dataIndex: 'last_sync', <th>Name</th>
key: 'last_sync', <th>Type</th>
align: 'center', <th>Size</th>
render: (text: string) => moment(text).format('YYYY-MM-DD HH:MM:SS') <th>Last Synch</th>
}, <th>Status</th>
{ <th>Operation</th>
title: 'Status', </tr>
dataIndex: 'status', </thead>
key: 'status', <tbody>
align: 'center', {documents.map((row: any) => (
}, <tr key={row.id}>
{ <td>{row.doc_name}</td>
title: 'Operation', <td>{row.doc_type}</td>
dataIndex: 'operation', <td>{row.chunk_size}</td>
key: 'operation', <td>{moment(row.last_sync).format('YYYY-MM-DD HH:MM:SS')}</td>
align: 'center', <td>{row.status}</td>
render: (_: any, label: any) => { <td>
return ( {
<Button onClick={() => { <>
router.push(`/datastores/documents/chunklist?spacename=${spaceName}&documentid=${label.id}`) <Button
}}>Detail of Chunks</Button> variant="outlined"
) onClick={async () => {
const res = await fetch(
`http://localhost:8000/knowledge/${spaceName}/document/sync`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
doc_ids: [row.id]
})
}
)
const data = await res.json()
if (data.success) {
message.success('success')
} else {
message.error(data.err_msg || 'failed')
} }
}, }}
]} >
dataSource={documents} Synch
/> </Button>
</div> <Button
) variant="outlined"
onClick={() => {
router.push(
`/datastores/documents/chunklist?spacename=${spaceName}&documentid=${row.id}`
)
}}
>
Detail of Chunks
</Button>
</>
}
</td>
</tr>
))}
</tbody>
</Table>
<Modal
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
'z-index': 1000
}}
open={isAddDocumentModalShow}
onClose={() => setIsAddDocumentModalShow(false)}
>
<Sheet
variant="outlined"
sx={{
width: 800,
borderRadius: 'md',
p: 3,
boxShadow: 'lg'
}}
>
<Box sx={{ width: '100%' }}>
<Stack spacing={2} direction="row">
{stepsOfAddingDocument.map((item: any, index: number) => (
<Item
key={item}
sx={{ fontWeight: activeStep === index ? 'bold' : '' }}
>
{item}
</Item>
))}
</Stack>
</Box>
{activeStep === 0 ? (
<>
<Box sx={{ margin: '30px auto' }}>
{documentTypeList.map((item: any) => (
<Sheet
key={item.type}
sx={{
boxSizing: 'border-box',
height: '80px',
padding: '12px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
border: '1px solid gray',
borderRadius: '6px',
marginBottom: '20px',
cursor: 'pointer'
}}
onClick={() => {
if (item.type === 'webPage') {
setActiveStep(1)
}
}}
>
<Sheet sx={{ fontSize: '20px', fontWeight: 'bold' }}>
{item.title}
</Sheet>
<Sheet>{item.subTitle}</Sheet>
</Sheet>
))}
</Box>
</>
) : (
<>
<Box sx={{ margin: '30px auto' }}>
Name:
<Input
placeholder="Please input the name"
onChange={(e: any) => setDocumentName(e.target.value)}
sx={{ marginBottom: '20px' }}
/>
Web Page URL:
<Input
placeholder="Please input the Web Page URL"
onChange={(e: any) => setWebPageUrl(e.target.value)}
/>
</Box>
<Button
onClick={async () => {
if (documentName === '') {
message.error('Please input the name')
return
}
if (webPageUrl === '') {
message.error('Please input the Web Page URL')
return
}
const res = await fetch(
`http://localhost:8000/knowledge/${spaceName}/document/add`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
doc_name: documentName,
content: webPageUrl,
doc_type: 'URL'
})
}
)
const data = await res.json()
if (data.success) {
message.success('success')
setIsAddDocumentModalShow(false)
const res = await fetch(
`http://localhost:8000/knowledge/${spaceName}/document/list`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({})
}
)
const data = await res.json()
if (data.success) {
setDocuments(data.data)
}
} else {
message.error(data.err_msg || 'failed')
}
}}
>
Finish
</Button>
</>
)}
</Sheet>
</Modal>
</div>
)
} }
export default Documents; export default Documents

View File

@ -1,252 +1,298 @@
'use client' 'use client'
import { useRouter } from 'next/navigation' import { useRouter } from 'next/navigation'
import type { ProFormInstance } from '@ant-design/pro-components'; import React, { useState, useEffect } from 'react'
import React, { useState, useRef, useEffect } from 'react' import { message } from 'antd'
import { import {
ProCard, Modal,
ProForm, Button,
ProFormCheckbox, Table,
ProFormDatePicker, Sheet,
ProFormDateRangePicker, Stack,
ProFormSelect, Box,
ProFormText, Input,
ProFormTextArea, styled
StepsForm } from '@/lib/mui'
} from '@ant-design/pro-components'
import { Button, Modal, Table, message } from 'antd' const Item = styled(Sheet)(({ theme }) => ({
width: '33%',
backgroundColor:
theme.palette.mode === 'dark' ? theme.palette.background.level1 : '#fff',
...theme.typography.body2,
padding: theme.spacing(1),
textAlign: 'center',
borderRadius: 4,
color: theme.vars.palette.text.secondary
}))
const stepsOfAddingSpace = [
'Knowledge Space Configuration',
'Choose a Datasource type',
'Setup the Datasource'
]
const documentTypeList = [
{
type: 'text',
title: 'Text',
subTitle: 'Paste some text'
},
{
type: 'webPage',
title: 'Web Page',
subTitle: 'Crawl text from a web page'
},
{
type: 'file',
title: 'File',
subTitle: 'It can be: PDF, CSV, JSON, Text, PowerPoint, Word, Excel'
}
]
const Index = () => { const Index = () => {
const router = useRouter(); const router = useRouter()
const formRef = useRef<ProFormInstance>(); const [activeStep, setActiveStep] = useState<number>(0)
const [knowledgeSpaceList, setKnowledgeSpaceList] = useState<any>([]); const [knowledgeSpaceList, setKnowledgeSpaceList] = useState<any>([])
const [isAddKnowledgeSpaceModalShow, setIsAddKnowledgeSpaceModalShow] = const [isAddKnowledgeSpaceModalShow, setIsAddKnowledgeSpaceModalShow] =
useState<boolean>(false); useState<boolean>(false)
const [knowledgeSpaceName, setKnowledgeSpaceName] = useState<string>(''); const [knowledgeSpaceName, setKnowledgeSpaceName] = useState<string>('')
const [webPageUrl, setWebPageUrl] = useState<string>(''); const [webPageUrl, setWebPageUrl] = useState<string>('')
const [documentName, setDocumentName] = useState<string>('')
useEffect(() => { useEffect(() => {
async function fetchData() { async function fetchData() {
const res = await fetch('http://localhost:8000/knowledge/space/list', { const res = await fetch('http://localhost:8000/knowledge/space/list', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json'
}, },
body: JSON.stringify({}), body: JSON.stringify({})
}); })
const data = await res.json(); const data = await res.json()
if (data.success) { if (data.success) {
setKnowledgeSpaceList(data.data); setKnowledgeSpaceList(data.data)
} }
} }
fetchData(); fetchData()
}, []); }, [])
return ( return (
<> <>
<div className="page-header p-4"> <Sheet sx={{
<div className="page-header-title">Knowledge Spaces</div> display: "flex",
<Button onClick={() => setIsAddKnowledgeSpaceModalShow(true)} type='default'> justifyContent: "space-between"
}} className="p-4">
<Sheet sx={{
fontSize: '30px',
fontWeight: 'bold'
}}>Knowledge Spaces</Sheet>
<Button
onClick={() => setIsAddKnowledgeSpaceModalShow(true)}
variant="outlined"
>
+ New Knowledge Space + New Knowledge Space
</Button> </Button>
</div> </Sheet>
<div className="page-body p-4"> <div className="page-body p-4">
<Table <Table sx={{ '& thead th:nth-child(1)': { width: '40%' } }}>
columns={[ <thead>
{ <tr>
title: 'Name', <th>Name</th>
dataIndex: 'name', <th>Provider</th>
key: 'name', <th>Owner</th>
align: 'center', </tr>
render: (text: string) => { </thead>
return <a href='javascript:;' onClick={() => router.push(`/datastores/documents?name=${text}`)}>{text}</a> <tbody>
} {knowledgeSpaceList.map((row: any) => (
}, <tr key={row.id}>
{ <td>
title: 'Provider', {
dataIndex: 'vector_type', <a
key: 'vector_type', href="javascript:;"
align: 'center', onClick={() =>
}, router.push(`/datastores/documents?name=${row.name}`)
{ }
title: 'Owner', >
dataIndex: 'owner', {row.name}
key: 'owner', </a>
align: 'center', }
}, </td>
]} <td>{row.vector_type}</td>
dataSource={knowledgeSpaceList} <td>{row.owner}</td>
/> </tr>
))}
</tbody>
</Table>
</div> </div>
<Modal <Modal
title="Add Knowledge Space" sx={{
footer={null} display: 'flex',
width={900} justifyContent: 'center',
alignItems: 'center',
'z-index': 1000
}}
open={isAddKnowledgeSpaceModalShow} open={isAddKnowledgeSpaceModalShow}
onOk={() => console.log('ok')} onClose={() => setIsAddKnowledgeSpaceModalShow(false)}
onCancel={() => setIsAddKnowledgeSpaceModalShow(false)}
> >
<ProCard> <Sheet
<StepsForm<{ variant="outlined"
name: string sx={{
}> width: 800,
formRef={formRef} borderRadius: 'md',
onFinish={async () => { p: 3,
message.success('success') boxShadow: 'lg'
}} }}
formProps={{ >
validateMessages: { <Box sx={{ width: '100%' }}>
required: 'This is required' <Stack spacing={2} direction="row">
} {stepsOfAddingSpace.map((item: any, index: number) => (
}} <Item
submitter={{ key={item}
render: (props) => { sx={{ fontWeight: activeStep === index ? 'bold' : '' }}
if (props.step === 0) { >
return ( {item}
<Button type="default" onClick={async () => { </Item>
if (knowledgeSpaceName === '') { ))}
props.onSubmit?.() </Stack>
} else { </Box>
const res = await fetch('http://localhost:8000/knowledge/space/add', { {activeStep === 0 ? (
method: 'POST', <>
headers: { <Box sx={{ margin: '30px auto' }}>
'Content-Type': 'application/json', Knowledge Space Name:
}, <Input
body: JSON.stringify({ placeholder="Please input the name"
name: knowledgeSpaceName, onChange={(e: any) => setKnowledgeSpaceName(e.target.value)}
vector_type: "Chroma", />
owner: "keting", </Box>
desc: "test1" <Button
}), variant="outlined"
}); onClick={async () => {
const data = await res.json(); if (knowledgeSpaceName === '') {
if (data.success) { message.error('please input the name')
props.onSubmit?.(); return
message.success('success'); }
const res = await fetch('http://localhost:8000/knowledge/space/list', { const res = await fetch(
method: 'POST', 'http://localhost:8000/knowledge/space/add',
headers: { {
'Content-Type': 'application/json', method: 'POST',
}, headers: {
body: JSON.stringify({}), 'Content-Type': 'application/json'
}); },
const data = await res.json(); body: JSON.stringify({
if (data.success) { name: knowledgeSpaceName,
setKnowledgeSpaceList(data.data); vector_type: 'Chroma',
} owner: 'keting',
} else { desc: 'test1'
message.error(data.err_msg || 'failed'); })
} }
} )
}}> const data = await res.json()
Next {'>'} if (data.success) {
</Button> message.success('success')
); setActiveStep(1)
} else if (props.step === 1) { const res = await fetch(
return ( 'http://localhost:8000/knowledge/space/list',
<Button type="default" onClick={() => props.onSubmit?.()}> {
Web Page {'>'}
</Button>
);
}
return [
<Button key="gotoTwo" onClick={() => props.onPre?.()}>
Previous {'<'}
</Button>,
<Button
type="default"
key="goToTree"
onClick={async () => {
props.onSubmit?.();
const res = await fetch(`http://localhost:8000/knowledge/${knowledgeSpaceName}/document/add`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json'
}, },
body: JSON.stringify({ body: JSON.stringify({})
doc_name: webPageUrl, }
doc_type: 'URL' )
}), const data = await res.json()
}); if (data.success) {
const data = await res.json(); setKnowledgeSpaceList(data.data)
if (data.success) { }
props.onSubmit?.(); } else {
message.success('success'); message.error(data.err_msg || 'failed')
setIsAddKnowledgeSpaceModalShow(false); }
} else { }}
message.error(data.err_msg || 'failed'); >
Next
</Button>
</>
) : activeStep === 1 ? (
<>
<Box sx={{ margin: '30px auto' }}>
{documentTypeList.map((item: any) => (
<Sheet
key={item.type}
sx={{
boxSizing: 'border-box',
height: '80px',
padding: '12px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
border: '1px solid gray',
borderRadius: '6px',
marginBottom: '20px',
cursor: 'pointer'
}}
onClick={() => {
if (item.type === 'webPage') {
setActiveStep(2);
} }
}} }}
> >
Finish <Sheet sx={{ fontSize: '20px', fontWeight: 'bold' }}>{item.title}</Sheet>
</Button>, <Sheet>{item.subTitle}</Sheet>
]; </Sheet>
}, ))}
}} </Box>
> </>
<StepsForm.StepForm<{ ) : (
name: string <>
}> <Box sx={{ margin: '30px auto' }}>
name="base" Name:
title="Knowledge Space Configuration" <Input
onFinish={async () => { placeholder="Please input the name"
console.log(formRef.current?.getFieldsValue()) onChange={(e: any) => setDocumentName(e.target.value)}
return true sx={{ marginBottom: '20px'}}
}} />
> Web Page URL:
<ProFormText <Input
name="name" placeholder="Please input the Web Page URL"
label="Knowledge Space Name" onChange={(e: any) => setWebPageUrl(e.target.value)}
width="lg" />
placeholder="Please input the name" </Box>
rules={[{ required: true }]} <Button
onChange={(e: any) => setKnowledgeSpaceName(e.target.value)} onClick={async () => {
/> if (documentName === '') {
</StepsForm.StepForm> message.error('Please input the name');
<StepsForm.StepForm<{ return;
checkbox: string }
}> if (webPageUrl === '') {
name="checkbox" message.error('Please input the Web Page URL');
title="Choose a Datasource type" return;
onFinish={async () => { }
console.log(formRef.current?.getFieldsValue()) const res = await fetch(
return true `http://localhost:8000/knowledge/${knowledgeSpaceName}/document/add`,
}} {
> method: 'POST',
</StepsForm.StepForm> headers: {
<StepsForm.StepForm 'Content-Type': 'application/json'
name="time" },
title="Setup the Datasource" body: JSON.stringify({
> doc_name: documentName,
<ProFormText content: webPageUrl,
name="webPageUrl" doc_type: 'URL'
label="Web Page URL" })
width="lg" }
placeholder="Please input the Web Page URL" )
rules={[{ required: true }]} const data = await res.json()
onChange={(e: any) => setWebPageUrl(e.target.value)} if (data.success) {
/> message.success('success')
</StepsForm.StepForm> setIsAddKnowledgeSpaceModalShow(false)
</StepsForm> } else {
</ProCard> message.error(data.err_msg || 'failed')
}
}}
>
Finish
</Button>
</>
)}
</Sheet>
</Modal> </Modal>
<style jsx>{`
.page-header {
display: flex;
justify-content: space-between;
.page-header-title {
font-size: 30px;
font-weight: bold
}
}
.datasource-type-wrap {
height: 100px;
line-height: 100px;
border: 1px solid black;
border-radius: 20px;
margin-bottom: 20px;
cursor: pointer;
}
`}</style>
</> </>
) )
} }

View File

@ -17,7 +17,8 @@
"@mui/icons-material": "^5.11.16", "@mui/icons-material": "^5.11.16",
"@mui/joy": "5.0.0-alpha.72", "@mui/joy": "5.0.0-alpha.72",
"@mui/lab": "5.0.0-alpha.124", "@mui/lab": "5.0.0-alpha.124",
"@mui/material": "^5.11.14", "@mui/material": "^5.13.6",
"@mui/styled-engine-sc": "^5.12.0",
"@mui/utils": "^5.11.13", "@mui/utils": "^5.11.13",
"@prisma/client": "^4.12.0", "@prisma/client": "^4.12.0",
"@types/node": "20.3.1", "@types/node": "20.3.1",
@ -42,6 +43,7 @@
"react-hook-form": "^7.43.8", "react-hook-form": "^7.43.8",
"react-markdown": "^8.0.7", "react-markdown": "^8.0.7",
"remark-gfm": "^3.0.1", "remark-gfm": "^3.0.1",
"styled-components": "^5.3.11",
"swr": "^2.1.1", "swr": "^2.1.1",
"tailwindcss": "3.3.2", "tailwindcss": "3.3.2",
"typescript": "5.1.3", "typescript": "5.1.3",
@ -713,6 +715,17 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@babel/helper-annotate-as-pure": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
"integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
"dependencies": {
"@babel/types": "^7.22.5"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-compilation-targets": { "node_modules/@babel/helper-compilation-targets": {
"version": "7.22.5", "version": "7.22.5",
"resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz", "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz",
@ -992,6 +1005,20 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/@babel/plugin-syntax-jsx": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz",
"integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5"
},
"engines": {
"node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@babel/plugin-transform-modules-commonjs": { "node_modules/@babel/plugin-transform-modules-commonjs": {
"version": "7.22.5", "version": "7.22.5",
"resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz",
@ -1279,6 +1306,11 @@
} }
} }
}, },
"node_modules/@emotion/stylis": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
"integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ=="
},
"node_modules/@emotion/unitless": { "node_modules/@emotion/unitless": {
"version": "0.8.1", "version": "0.8.1",
"resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.8.1.tgz", "resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.8.1.tgz",
@ -1645,7 +1677,7 @@
}, },
"node_modules/@mui/material": { "node_modules/@mui/material": {
"version": "5.13.6", "version": "5.13.6",
"resolved": "https://registry.npmmirror.com/@mui/material/-/material-5.13.6.tgz", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.13.6.tgz",
"integrity": "sha512-/c2ZApeQm2sTYdQXjqEnldaBMBcUEiyu2VRS6bS39ZeNaAcCLBQbYocLR46R+f0S5dgpBzB0T4AsOABPOFYZ5Q==", "integrity": "sha512-/c2ZApeQm2sTYdQXjqEnldaBMBcUEiyu2VRS6bS39ZeNaAcCLBQbYocLR46R+f0S5dgpBzB0T4AsOABPOFYZ5Q==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.22.5", "@babel/runtime": "^7.22.5",
@ -1664,6 +1696,10 @@
"engines": { "engines": {
"node": ">=12.0.0" "node": ">=12.0.0"
}, },
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mui"
},
"peerDependencies": { "peerDependencies": {
"@emotion/react": "^11.5.0", "@emotion/react": "^11.5.0",
"@emotion/styled": "^11.3.0", "@emotion/styled": "^11.3.0",
@ -1737,6 +1773,31 @@
} }
} }
}, },
"node_modules/@mui/styled-engine-sc": {
"version": "5.12.0",
"resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-5.12.0.tgz",
"integrity": "sha512-3MgYoY2YG5tx0E5oKqvCv94oL0ABVBr+qpcyvciXW/v0wzPG6bXvuZV80GHYlJfasgnnRa1AbRWf5a9FcX8v6g==",
"dependencies": {
"@babel/runtime": "^7.21.0",
"prop-types": "^15.8.1"
},
"engines": {
"node": ">=12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mui"
},
"peerDependencies": {
"@types/styled-components": "^5.1.14",
"styled-components": "^5.3.1"
},
"peerDependenciesMeta": {
"@types/styled-components": {
"optional": true
}
}
},
"node_modules/@mui/system": { "node_modules/@mui/system": {
"version": "5.13.6", "version": "5.13.6",
"resolved": "https://registry.npmmirror.com/@mui/system/-/system-5.13.6.tgz", "resolved": "https://registry.npmmirror.com/@mui/system/-/system-5.13.6.tgz",
@ -2779,6 +2840,21 @@
"@babel/core": "^7.0.0-0" "@babel/core": "^7.0.0-0"
} }
}, },
"node_modules/babel-plugin-styled-components": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz",
"integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.22.5",
"@babel/helper-module-imports": "^7.22.5",
"@babel/plugin-syntax-jsx": "^7.22.5",
"lodash": "^4.17.21",
"picomatch": "^2.3.1"
},
"peerDependencies": {
"styled-components": ">= 2"
}
},
"node_modules/babel-plugin-transform-replace-object-assign": { "node_modules/babel-plugin-transform-replace-object-assign": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmmirror.com/babel-plugin-transform-replace-object-assign/-/babel-plugin-transform-replace-object-assign-2.0.0.tgz", "resolved": "https://registry.npmmirror.com/babel-plugin-transform-replace-object-assign/-/babel-plugin-transform-replace-object-assign-2.0.0.tgz",
@ -2978,6 +3054,14 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/camelize": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
"integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001507", "version": "1.0.30001507",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001507.tgz", "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001507.tgz",
@ -3196,6 +3280,24 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/css-color-keywords": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
"integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
"engines": {
"node": ">=4"
}
},
"node_modules/css-to-react-native": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
"integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
"dependencies": {
"camelize": "^1.0.0",
"css-color-keywords": "^1.0.0",
"postcss-value-parser": "^4.0.2"
}
},
"node_modules/cssesc": { "node_modules/cssesc": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
@ -7484,6 +7586,59 @@
"inline-style-parser": "0.1.1" "inline-style-parser": "0.1.1"
} }
}, },
"node_modules/styled-components": {
"version": "5.3.11",
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz",
"integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==",
"dependencies": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/traverse": "^7.4.5",
"@emotion/is-prop-valid": "^1.1.0",
"@emotion/stylis": "^0.8.4",
"@emotion/unitless": "^0.7.4",
"babel-plugin-styled-components": ">= 1.12.0",
"css-to-react-native": "^3.0.0",
"hoist-non-react-statics": "^3.0.0",
"shallowequal": "^1.1.0",
"supports-color": "^5.5.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/styled-components"
},
"peerDependencies": {
"react": ">= 16.8.0",
"react-dom": ">= 16.8.0",
"react-is": ">= 16.8.0"
}
},
"node_modules/styled-components/node_modules/@emotion/unitless": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
},
"node_modules/styled-components/node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"engines": {
"node": ">=4"
}
},
"node_modules/styled-components/node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/styled-jsx": { "node_modules/styled-jsx": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmmirror.com/styled-jsx/-/styled-jsx-5.1.1.tgz", "resolved": "https://registry.npmmirror.com/styled-jsx/-/styled-jsx-5.1.1.tgz",
@ -8765,6 +8920,14 @@
"jsesc": "^2.5.1" "jsesc": "^2.5.1"
} }
}, },
"@babel/helper-annotate-as-pure": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
"integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
"requires": {
"@babel/types": "^7.22.5"
}
},
"@babel/helper-compilation-targets": { "@babel/helper-compilation-targets": {
"version": "7.22.5", "version": "7.22.5",
"resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz", "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz",
@ -8975,6 +9138,14 @@
"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.22.5.tgz", "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.22.5.tgz",
"integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==" "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q=="
}, },
"@babel/plugin-syntax-jsx": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz",
"integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==",
"requires": {
"@babel/helper-plugin-utils": "^7.22.5"
}
},
"@babel/plugin-transform-modules-commonjs": { "@babel/plugin-transform-modules-commonjs": {
"version": "7.22.5", "version": "7.22.5",
"resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz",
@ -9199,6 +9370,11 @@
"@emotion/utils": "^1.2.1" "@emotion/utils": "^1.2.1"
} }
}, },
"@emotion/stylis": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
"integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ=="
},
"@emotion/unitless": { "@emotion/unitless": {
"version": "0.8.1", "version": "0.8.1",
"resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.8.1.tgz", "resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.8.1.tgz",
@ -9444,7 +9620,7 @@
}, },
"@mui/material": { "@mui/material": {
"version": "5.13.6", "version": "5.13.6",
"resolved": "https://registry.npmmirror.com/@mui/material/-/material-5.13.6.tgz", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.13.6.tgz",
"integrity": "sha512-/c2ZApeQm2sTYdQXjqEnldaBMBcUEiyu2VRS6bS39ZeNaAcCLBQbYocLR46R+f0S5dgpBzB0T4AsOABPOFYZ5Q==", "integrity": "sha512-/c2ZApeQm2sTYdQXjqEnldaBMBcUEiyu2VRS6bS39ZeNaAcCLBQbYocLR46R+f0S5dgpBzB0T4AsOABPOFYZ5Q==",
"requires": { "requires": {
"@babel/runtime": "^7.22.5", "@babel/runtime": "^7.22.5",
@ -9489,6 +9665,15 @@
"prop-types": "^15.8.1" "prop-types": "^15.8.1"
} }
}, },
"@mui/styled-engine-sc": {
"version": "5.12.0",
"resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-5.12.0.tgz",
"integrity": "sha512-3MgYoY2YG5tx0E5oKqvCv94oL0ABVBr+qpcyvciXW/v0wzPG6bXvuZV80GHYlJfasgnnRa1AbRWf5a9FcX8v6g==",
"requires": {
"@babel/runtime": "^7.21.0",
"prop-types": "^15.8.1"
}
},
"@mui/system": { "@mui/system": {
"version": "5.13.6", "version": "5.13.6",
"resolved": "https://registry.npmmirror.com/@mui/system/-/system-5.13.6.tgz", "resolved": "https://registry.npmmirror.com/@mui/system/-/system-5.13.6.tgz",
@ -10248,6 +10433,18 @@
"@babel/helper-define-polyfill-provider": "^0.4.0" "@babel/helper-define-polyfill-provider": "^0.4.0"
} }
}, },
"babel-plugin-styled-components": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz",
"integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==",
"requires": {
"@babel/helper-annotate-as-pure": "^7.22.5",
"@babel/helper-module-imports": "^7.22.5",
"@babel/plugin-syntax-jsx": "^7.22.5",
"lodash": "^4.17.21",
"picomatch": "^2.3.1"
}
},
"babel-plugin-transform-replace-object-assign": { "babel-plugin-transform-replace-object-assign": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmmirror.com/babel-plugin-transform-replace-object-assign/-/babel-plugin-transform-replace-object-assign-2.0.0.tgz", "resolved": "https://registry.npmmirror.com/babel-plugin-transform-replace-object-assign/-/babel-plugin-transform-replace-object-assign-2.0.0.tgz",
@ -10404,6 +10601,11 @@
"resolved": "https://registry.npmmirror.com/camelcase-css/-/camelcase-css-2.0.1.tgz", "resolved": "https://registry.npmmirror.com/camelcase-css/-/camelcase-css-2.0.1.tgz",
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="
}, },
"camelize": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
"integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ=="
},
"caniuse-lite": { "caniuse-lite": {
"version": "1.0.30001507", "version": "1.0.30001507",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001507.tgz", "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001507.tgz",
@ -10588,6 +10790,21 @@
"which": "^2.0.1" "which": "^2.0.1"
} }
}, },
"css-color-keywords": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
"integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg=="
},
"css-to-react-native": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
"integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
"requires": {
"camelize": "^1.0.0",
"css-color-keywords": "^1.0.0",
"postcss-value-parser": "^4.0.2"
}
},
"cssesc": { "cssesc": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
@ -13973,6 +14190,43 @@
"inline-style-parser": "0.1.1" "inline-style-parser": "0.1.1"
} }
}, },
"styled-components": {
"version": "5.3.11",
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz",
"integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==",
"requires": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/traverse": "^7.4.5",
"@emotion/is-prop-valid": "^1.1.0",
"@emotion/stylis": "^0.8.4",
"@emotion/unitless": "^0.7.4",
"babel-plugin-styled-components": ">= 1.12.0",
"css-to-react-native": "^3.0.0",
"hoist-non-react-statics": "^3.0.0",
"shallowequal": "^1.1.0",
"supports-color": "^5.5.0"
},
"dependencies": {
"@emotion/unitless": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
"styled-jsx": { "styled-jsx": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmmirror.com/styled-jsx/-/styled-jsx-5.1.1.tgz", "resolved": "https://registry.npmmirror.com/styled-jsx/-/styled-jsx-5.1.1.tgz",

View File

@ -18,7 +18,8 @@
"@mui/icons-material": "^5.11.16", "@mui/icons-material": "^5.11.16",
"@mui/joy": "5.0.0-alpha.72", "@mui/joy": "5.0.0-alpha.72",
"@mui/lab": "5.0.0-alpha.124", "@mui/lab": "5.0.0-alpha.124",
"@mui/material": "^5.11.14", "@mui/material": "^5.13.6",
"@mui/styled-engine-sc": "^5.12.0",
"@mui/utils": "^5.11.13", "@mui/utils": "^5.11.13",
"@prisma/client": "^4.12.0", "@prisma/client": "^4.12.0",
"@types/node": "20.3.1", "@types/node": "20.3.1",
@ -43,6 +44,7 @@
"react-hook-form": "^7.43.8", "react-hook-form": "^7.43.8",
"react-markdown": "^8.0.7", "react-markdown": "^8.0.7",
"remark-gfm": "^3.0.1", "remark-gfm": "^3.0.1",
"styled-components": "^5.3.11",
"swr": "^2.1.1", "swr": "^2.1.1",
"tailwindcss": "3.3.2", "tailwindcss": "3.3.2",
"typescript": "5.1.3", "typescript": "5.1.3",