提交 506c37f5 authored 作者: 王鹏飞's avatar 王鹏飞

chore: update pnpm-workspace.yaml to exclude minimum release age for vite@8.2.2

上级 91d8ca2c
......@@ -55,10 +55,10 @@
"@vitejs/plugin-react": "^6.0.5",
"jsdom": "^29.1.1",
"less": "^4.2.0",
"oxfmt": "^0.59.0",
"oxlint": "^1.74.0",
"oxfmt": "^0.64.0",
"oxlint": "^1.79.0",
"typescript": "^7.0.2",
"vite": "^8.2.1",
"vite": "^8.2.2",
"vite-plugin-mkcert": "^2.1.0",
"vitest": "^4.1.10"
}
......
......@@ -70,14 +70,6 @@ dd {
display: inline-block !important;
}
.ant-space-item {
.ant-btn.css-dev-only-do-not-override-1scgnrh {
display: flex;
align-items: center;
justify-content: center;
}
}
.form-devices-inline {
.ant-form-inline {
.ant-form-item {
......
......@@ -2,13 +2,13 @@
.wrap-phone-privew {
.ant-modal {
.ant-modal-close {
.phone-close {
inset-inline-end: 17px;
top: 0px;
top: 0;
right: 0;
}
.ant-modal-content {
.phone-content {
background: url('@/assets/images/phone_6.7.png') no-repeat;
background-size: 100% 100%;
box-shadow: none;
......@@ -16,7 +16,7 @@
border-radius: 48px;
padding: 36px 32px 34px 32px;
}
.priview-modal {
.preview-modal {
padding-top: 40px;
width: 430px;
height: 932px;
......@@ -33,7 +33,7 @@
width: 430px;
border-radius: 30px;
}
.previee-container {
.preview-container {
height: 100%;
overflow: hidden;
position: relative;
......@@ -431,7 +431,7 @@
}
// 画廊展示
.gallery-prview-container {
.gallery-preview-container {
.gallery-img {
max-height: 300px;
height: 300px;
......@@ -680,17 +680,17 @@
}
}
.priview-drawer-container {
.preview-drawer-container {
height: 932px;
top: 42px;
left: 0px;
width: 430px;
border-radius: 15px 0 40px 40px;
overflow: hidden;
.priview-drawer-header {
.preview-drawer-header {
padding: 10px;
}
.priview-drawer-body {
.preview-drawer-body {
padding: 10px;
height: 100%;
overflow-x: hidden;
......
......@@ -45,6 +45,7 @@ export default function DigitalHumanDialog({ editor }) {
footer={null}
width={1600}
className='digital-human-modal'
classNames={{ container: 'digital-human-container', body: 'digital-human-body' }}
centered
destroyOnHidden
>
......
......@@ -74,6 +74,10 @@ export default function DigitalHumanFigureField({ figures, loading, value, onCha
onCancel={() => setOpen(false)}
width={920}
className='digital-human-picker-modal figure-picker-modal'
classNames={{
container: 'digital-human-picker-container',
body: 'digital-human-picker-body figure-picker-body',
}}
>
{loading && figures.length === 0 ? (
<div className='picker-loading'>
......
......@@ -151,6 +151,10 @@ export default function DigitalHumanVoiceSettings({
onCancel={() => setOpen(false)}
width={620}
className='digital-human-picker-modal voice-picker-modal'
classNames={{
container: 'digital-human-picker-container',
body: 'digital-human-picker-body',
}}
>
<div className='picker-tabs' role='tablist' aria-label='声音性别'>
<button
......
......@@ -8,12 +8,12 @@
--dh-canvas: #f8f6f7;
max-width: calc(100vw - 24px);
.ant-modal-content {
.digital-human-container {
overflow: hidden;
border-radius: 10px;
}
.ant-modal-body {
.digital-human-body {
max-height: calc(100vh - 96px);
overflow-y: auto;
overscroll-behavior: contain;
......@@ -988,17 +988,17 @@
}
.digital-human-picker-modal {
.ant-modal-content {
.digital-human-picker-container {
border-radius: 14px;
}
.ant-modal-body {
.digital-human-picker-body {
max-height: 65vh;
overflow-y: auto;
}
}
.figure-picker-modal .ant-modal-body {
.figure-picker-modal .figure-picker-body {
overflow: hidden;
}
......@@ -1178,7 +1178,7 @@
width: calc(100vw - 24px) !important;
max-width: calc(100vw - 24px);
.ant-modal-body {
.digital-human-body {
padding: 12px;
}
}
......
......@@ -19,9 +19,6 @@ const AudioModal = ({ open, onClose, payload = {}, runtime }) => {
const fileAccept = ['.mp3', '.wav', '.ogg']
const [form] = Form.useForm()
const [uploading, setUploading] = useState(false) // 文件上传状态
const [progress, setProgress] = useState(0)
const [file, setFile] = useState({})
const [audioUrl, setAudioUrl] = useState('')
useEffect(() => {
......@@ -44,17 +41,21 @@ const AudioModal = ({ open, onClose, payload = {}, runtime }) => {
message.error('请上传正确格式的音频文件')
return false
}
setProgress(0)
setUploading(false)
setFile(file)
return true
},
customRequest: async () => {
customRequest: async ({ file, onSuccess, onError }) => {
setUploading(true)
try {
const url = await uploadFile(file)
setAudioUrl(url)
form.setFieldsValue({ audioUrl: url })
onSuccess?.({ url })
} catch (error) {
message.error('音频上传失败,请重试')
onError?.(error instanceof Error ? error : new Error('音频上传失败'))
} finally {
setUploading(false)
}
},
}
......@@ -80,7 +81,6 @@ const AudioModal = ({ open, onClose, payload = {}, runtime }) => {
children: [{ text: '' }],
})
setAudioUrl('')
setProgress(0)
setUploading(false)
form.resetFields()
onClose()
......@@ -106,7 +106,7 @@ const AudioModal = ({ open, onClose, payload = {}, runtime }) => {
<div className='editor-content-form'>
<Form layout='vertical' name='validate_other' form={form} onFinish={onFinish}>
<Form.Item label='上传音频' name='audioUrl'>
<Spin spinning={uploading} description={`${progress}%`}>
<Spin spinning={uploading} tip='上传中'>
<div className='editor-dragger'>
<Dragger {...uploadProps} showUploadList={false}>
{!audioUrl && (
......
......@@ -35,8 +35,6 @@ const ImageModal = (props, ref) => {
const [bgColorValue, setBgColorValue] = useState('#000000')
const [textColor, setTextColor] = useState('#ffffff')
const [uploading, setUploading] = useState(false) // 文件上传状态
const [progress, setProgress] = useState(0)
const [file, setFile] = useState({})
const [imgUrl, setImgUrl] = useState('')
const [initValues, setInitValues] = useState({
title: '',
......@@ -108,15 +106,21 @@ const ImageModal = (props, ref) => {
message.error('请上传正确格式的图片')
return false
}
setFile(file)
return true
},
customRequest: async () => {
customRequest: async ({ file, onSuccess, onError }) => {
setUploading(true)
try {
const url = await uploadFile(file)
setImgUrl(url)
form.setFieldsValue({ bgImgUrl: url })
onSuccess?.({ url })
} catch (error) {
message.error('图片上传失败,请重试')
onError?.(error instanceof Error ? error : new Error('图片上传失败'))
} finally {
setUploading(false)
}
},
}
......@@ -144,7 +148,6 @@ const ImageModal = (props, ref) => {
if (parseInt(node.random) === parseInt(nowRandom)) {
SlateTransforms.setNodes(editor, { ...node, ...values }, { at: path })
setImgUrl('')
setProgress(0)
setUploading(false)
form.resetFields()
setTitleVisible(false)
......@@ -179,7 +182,6 @@ const ImageModal = (props, ref) => {
children: [{ text: '' }],
})
setImgUrl('')
setProgress(0)
setUploading(false)
form.resetFields()
setTitleVisible(false)
......@@ -197,7 +199,7 @@ const ImageModal = (props, ref) => {
initialValues={initValues}
>
<Form.Item label='章头背景图片' name='bgImgUrl'>
<Spin spinning={uploading} description={`${progress}%`}>
<Spin spinning={uploading}>
<div className='editor-dragger'>
<Dragger {...uploadProps} showUploadList={false}>
{!imgUrl && (
......
import { useState, useEffect, useImperativeHandle, forwardRef } from 'react'
import { CloudUploadOutlined } from '@ant-design/icons'
import { Form, Input, Spin, Upload, Button } from 'antd'
import { Form, Input, Spin, Upload, Button, message } from 'antd'
import OnlineImageList from '../../shared/online-image/OnlineImageList'
import { uploadFile } from '@/utils/oss'
......@@ -11,7 +11,6 @@ const GalleryFormItem = (props, ref) => {
const { activeKey, form, setPicList, galleryInfo, isOnline = false } = props
const [uploading, setUploading] = useState(false) // 文件上传状态
const [file, setFile] = useState({})
const [imgUrl, setImgUrl] = useState('')
useImperativeHandle(ref, () => {
......@@ -59,11 +58,9 @@ const GalleryFormItem = (props, ref) => {
maxCount: 1,
showUploadList: false,
accept: fileAccept.join(','),
beforeUpload: (file) => {
setFile(file)
},
customRequest: async () => {
customRequest: async ({ file, onSuccess, onError }) => {
setUploading(true)
try {
const url = await uploadFile(file)
const values = {
['content']: {
......@@ -84,7 +81,13 @@ const GalleryFormItem = (props, ref) => {
}
setPicList(newGalleryList)
form.setFieldsValue({ gallery: newGalleryList })
onSuccess?.({ url })
} catch (error) {
message.error('图片上传失败,请重试')
onError?.(error instanceof Error ? error : new Error('图片上传失败'))
} finally {
setUploading(false)
}
},
}
......@@ -169,7 +172,15 @@ const GalleryFormItem = (props, ref) => {
<img src={imgUrl} alt='' />
</div>
<div className='editor-uploader-result-tips'>
<Button size='small' color='primary' variant='outlined' onClick={() => setImgUrl(null)}>
<Button
size='small'
color='primary'
variant='outlined'
onClick={() => {
setImgUrl(null)
form.setFieldValue(['content', activeKey, 'url'], '')
}}
>
替换
</Button>
</div>
......
......@@ -14,6 +14,7 @@ export default function HistoryFeatureDialog({ open, onClose, runtime }) {
mask={{ closable: false }}
width='90%'
onCancel={onClose}
classNames={{ container: 'history-content' }}
wrapClassName='history1'
style={{ padding: 0 }}
>
......
......@@ -10,7 +10,7 @@ const HistoryEditor = (props) => {
const { setHistoryVisible, chapterId, bookId, setContent, saveContent } = props
const [loading, setLoading] = useState(false)
const [delMoadal, setDelModal] = useState(false)
const [delModal, setDelModal] = useState(false)
const [recordContent, setRecordContent] = useState('') // 内容
const [recordList, setRecordList] = useState([]) // 列表
const [recordId, setRecordId] = useState(null) // 当前的记录id
......@@ -134,7 +134,8 @@ const HistoryEditor = (props) => {
mask={false}
centered
className='history2'
open={delMoadal}
classNames={{ container: 'history2-content' }}
open={delModal}
onOk={handleSuccess}
onCancel={() => setDelModal(false)}
footer={(_, { OkBtn, CancelBtn }) => {
......
......@@ -8,7 +8,7 @@
overflow: hidden;
}
.ant-modal,
.ant-modal-content,
.history-content,
.ant-modal-body {
max-height: 90vh;
min-height: 90vh;
......@@ -17,7 +17,7 @@
}
}
.history1 {
.ant-modal-content {
.history-content {
padding: 0;
.history-content-container {
......@@ -297,7 +297,7 @@
}
// 画廊展示
.gallery-prview-container {
.gallery-preview-container {
.gallery-img {
max-height: 300px;
height: 300px;
......@@ -493,7 +493,7 @@
.history2 {
z-index: 1000;
.ant-modal-content {
.history2-content {
padding: 20px;
}
}
......@@ -20,8 +20,6 @@ const ImageModal = (props, ref) => {
const fileAccept = ['.png', '.jpg', '.jpeg', '.svg']
const [form] = Form.useForm()
const [uploading, setUploading] = useState(false) // 文件上传状态
const [progress, setProgress] = useState(0)
const [file, setFile] = useState({})
const [initValues, setInitValues] = useState({ imgUrl: '', imgTitle: '', imgDescript: '' })
const [tempNodeInfo, setTempNodeInfo] = useState(null)
......@@ -32,7 +30,6 @@ const ImageModal = (props, ref) => {
setInitValues({ imgUrl: image.src, imgTitle: image.alt, imgDescript: image.href })
form.setFieldsValue({ imgUrl: image.src, imgTitle: image.alt, imgDescript: image.href })
setTempNodeInfo(imageInfo)
setFile({})
setImageInfo({})
}
}, [imageInfo])
......@@ -48,20 +45,26 @@ const ImageModal = (props, ref) => {
message.error('请上传正确格式的图片')
return false
}
setFile(file)
return true
},
customRequest: async () => {
customRequest: async ({ file, onSuccess, onError }) => {
setUploading(true)
try {
const url = await uploadFile(file)
setImgUrl(url)
form.setFieldsValue({ imgUrl: url })
onSuccess?.({ url })
} catch (error) {
message.error('图片上传失败,请重试')
onError?.(error instanceof Error ? error : new Error('图片上传失败'))
} finally {
setUploading(false)
}
},
}
const clear = () => {
setImgUrl('')
setProgress(0)
setUploading(false)
setTempNodeInfo(null)
setInitValues({ imgUrl: imgUrl, imgTitle: '', imgDescript: '' })
......@@ -158,7 +161,7 @@ const ImageModal = (props, ref) => {
name='imgUrl'
rules={[{ required: true, message: '请上传图片' }]}
>
<Spin spinning={uploading} description={`${progress}%`}>
<Spin spinning={uploading}>
<div className='editor-dragger'>
<Dragger {...uploadProps} showUploadList={false}>
{!imgUrl && (
......@@ -178,7 +181,15 @@ const ImageModal = (props, ref) => {
<img src={imgUrl} alt='' />
</div>
<div className='editor-uploader-result-tips'>
<Button size='small' color='primary' variant='outlined' onClick={() => setImgUrl(null)}>
<Button
size='small'
color='primary'
variant='outlined'
onClick={() => {
setImgUrl(null)
form.setFieldsValue({ imgUrl: '' })
}}
>
替换
</Button>
</div>
......
......@@ -54,6 +54,7 @@ export function PracticeSettingsFeatureDialog({ open, onClose, payload, runtime
header: 'practice-topic-header',
body: 'practice-topic-content',
wrapper: 'practice-topic-modal',
container: 'practice-topic-container',
}}
mask={{ closable: false }}
closeIcon={false}
......
......@@ -5,7 +5,7 @@ import { useEditorStore } from '@/stores/editorStore'
import TopicItem from './topicItem'
import { addChapterTopic, getChapterTopic } from '../../../shared/request'
import { clacTopicText } from '@/utils/common'
import { calcTopicText } from '@/utils/common'
const InsertTopic = (props, ref) => {
const {
......@@ -77,7 +77,7 @@ const InsertTopic = (props, ref) => {
<div className='practice-insert-topic list-topic-box'>
{radioList.length > 0 && (
<div className='list-topic-container'>
<h4>{clacTopicText('radio')}. 单选题</h4>
<h4>{calcTopicText('radio')}. 单选题</h4>
<div>
{radioList.map((item, index) => {
return (
......@@ -108,7 +108,7 @@ const InsertTopic = (props, ref) => {
{checkboxList.length > 0 && (
<div className='list-topic-container'>
<h4>{clacTopicText('checkbox', radioList)}. 多选题</h4>
<h4>{calcTopicText('checkbox', radioList)}. 多选题</h4>
<div>
{checkboxList.map((item, index) => {
return (
......@@ -138,7 +138,7 @@ const InsertTopic = (props, ref) => {
)}
{equalsList.length > 0 && (
<div className='list-topic-container'>
<h4>{clacTopicText('judge', radioList, checkboxList)}. 判断题</h4>
<h4>{calcTopicText('judge', radioList, checkboxList)}. 判断题</h4>
<div>
{equalsList.map((item, index) => {
return (
......@@ -168,7 +168,7 @@ const InsertTopic = (props, ref) => {
)}
{pressList.length > 0 && (
<div className='list-topic-container'>
<h4>{clacTopicText('fill', radioList, checkboxList, equalsList)}. 填空题</h4>
<h4>{calcTopicText('fill', radioList, checkboxList, equalsList)}. 填空题</h4>
<div>
{pressList.map((item, index) => {
return (
......@@ -199,7 +199,7 @@ const InsertTopic = (props, ref) => {
{textareaList.length > 0 && (
<div className='list-topic-container'>
<h4>
{clacTopicText('textarea', radioList, checkboxList, equalsList, pressList)}. 简答题
{calcTopicText('textarea', radioList, checkboxList, equalsList, pressList)}. 简答题
</h4>
<div>
{textareaList.map((item, index) => {
......
......@@ -4,7 +4,7 @@
inset-inline-end: 17px;
top: 16px;
}
.ant-modal-content {
.practice-topic-container {
padding: 15px 18px;
}
.ant-divider {
......
......@@ -13,7 +13,12 @@ export default function PreviewFeatureDialog({ open, onClose, runtime }) {
keyboard={false}
closeIcon={<CloseOutlined style={{ fontSize: 20, color: '#fff' }} />}
mask={{ closable: false }}
classNames={{ body: 'phone-body', wrapper: 'phone-wrapper' }}
classNames={{
container: 'phone-content',
body: 'phone-body',
wrapper: 'phone-wrapper',
close: 'phone-close',
}}
wrapClassName='wrap-phone-privew'
width='494px'
onCancel={onClose}
......
......@@ -9,7 +9,7 @@ import { getChapterTopic, expandReadInfo } from '../../shared/request'
import TopicItem from '../practice/components/topicItem'
import '@/components/editor/preview.less'
import { clacTopicText } from '@/utils/common'
import { calcTopicText } from '@/utils/common'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'
......@@ -46,7 +46,7 @@ const correctList = [
const PreviewScreen = (props, ref) => {
const { editor, bookId, chapterId, gData, nowTitle } = props
const [loading, setLoading] = useState(false) // 展示
const [prviewHtml, setPrviewHtml] = useState('') // 预览html
const [previewHtml, setPrviewHtml] = useState('') // 预览html
const [open, setOpen] = useState(false) // 抽屉
const [toolTip, setTooltip] = useState({})
......@@ -114,12 +114,15 @@ const PreviewScreen = (props, ref) => {
}
const handlerClick = () => {
const eventNamespace = '.editorPreview'
const previewContent = $('.preview-content-html')
const secondaryContent = $('.expand-content, .gallery-preview-container')
const iParentW = $('.preview-content-it').innerWidth()
const iParentH = $('.preview-content-it').innerHeight()
const parentOffset = $('.preview-content-it').offset() // 获取父元素相对于文档的位置
const parentRect = $('.preview-content-it')[0].getBoundingClientRect() // 获取父元素相对于文档的位置
$('.preview-content-html').on('click', (ev) => {
previewContent.off(eventNamespace).on(`click${eventNamespace}`, (ev) => {
ev.stopPropagation()
const target = ev.target
......@@ -326,7 +329,7 @@ const PreviewScreen = (props, ref) => {
setGallery([])
})
$('.expand-content, .gallery-prview-container').on('click', (ev) => {
secondaryContent.off(eventNamespace).on(`click${eventNamespace}`, (ev) => {
const target = ev.target
if (target.nodeName.toLowerCase() === 'img') {
......@@ -338,10 +341,15 @@ const PreviewScreen = (props, ref) => {
setSecondType('扩展图片')
}
})
return () => {
previewContent.off(eventNamespace)
secondaryContent.off(eventNamespace)
}
}
useEffect(() => {
handlerClick()
return handlerClick()
}, [])
const getChapterId = async () => {
......@@ -356,7 +364,7 @@ const PreviewScreen = (props, ref) => {
if (data) {
const content = get(data, 'content', '')
setPrviewHtml(content)
$('#previee-container')
$('#preview-container')
.find('video audio')
.each((index, item) => {
$(item).attr('controls', true).attr('controlslist', 'nodownload')
......@@ -383,7 +391,7 @@ const PreviewScreen = (props, ref) => {
// if (data) {
// const content = get(data, 'content', '');
// setPrviewHtml(content);
// $('#previee-container')
// $('#preview-container')
// .find('video audio')
// .each((index, item) => {
// $(item).attr('controls', true);
......@@ -417,8 +425,8 @@ const PreviewScreen = (props, ref) => {
}
return (
<div className='priview-modal'>
<div className='previee-container' id='previee-container'>
<div className='preview-modal'>
<div className='preview-container' id='preview-container'>
<div className='chapter-head-title'>
<h2>
{opend ? (
......@@ -456,14 +464,14 @@ const PreviewScreen = (props, ref) => {
<Spin spinning={loading} classNames={{ root: 'chapter-loading' }}>
<div
className='preview-content-html'
dangerouslySetInnerHTML={{ __html: prviewHtml }}
dangerouslySetInnerHTML={{ __html: previewHtml }}
></div>
</Spin>
</div>
{isType && (
<div className='preview-content-other'>
{isType === 'gallery' && (
<div className='gallery-prview-container'>
<div className='gallery-preview-container'>
{gallery && gallery.length > 0 ? (
<>
<div className='gallery-img'>
......@@ -491,7 +499,7 @@ const PreviewScreen = (props, ref) => {
<div className='practice-insert-topic'>
{radioList.length > 0 && (
<div className='topic_style'>
<h3>{clacTopicText('radio')}. 单选题</h3>
<h3>{calcTopicText('radio')}. 单选题</h3>
<div className='practice-list'>
{radioList.map((item, index) => {
return (
......@@ -540,7 +548,7 @@ const PreviewScreen = (props, ref) => {
)}
{checkBoxList.length > 0 && (
<div className='topic_style'>
<h3>{clacTopicText('checkbox', radioList)}. 多选题</h3>
<h3>{calcTopicText('checkbox', radioList)}. 多选题</h3>
<div className='practice-list'>
{checkBoxList.map((item, index) => {
return (
......@@ -589,7 +597,7 @@ const PreviewScreen = (props, ref) => {
)}
{judgeList.length > 0 && (
<div className='topic_style'>
<h3>{clacTopicText('judge', radioList, checkBoxList)}. 判断题</h3>
<h3>{calcTopicText('judge', radioList, checkBoxList)}. 判断题</h3>
<div className='practice-list'>
{judgeList.map((item, index) => {
return (
......@@ -638,7 +646,7 @@ const PreviewScreen = (props, ref) => {
)}
{fillList.length > 0 && (
<div className='topic_style'>
<h3>{clacTopicText('fill', radioList, checkBoxList, judgeList)}. 填空题</h3>
<h3>{calcTopicText('fill', radioList, checkBoxList, judgeList)}. 填空题</h3>
<div className='practice-list'>
{fillList.map((item, index) => {
return (
......@@ -688,7 +696,7 @@ const PreviewScreen = (props, ref) => {
{textareaList.length > 0 && (
<div className='topic_style'>
<h3>
{clacTopicText('textarea', radioList, checkBoxList, judgeList, fillList)}.
{calcTopicText('textarea', radioList, checkBoxList, judgeList, fillList)}.
简答题
</h3>
<div className='practice-list'>
......@@ -786,10 +794,10 @@ const PreviewScreen = (props, ref) => {
open={open}
getContainer={false}
placement='left'
classNames={{ header: 'priview-drawer-header', body: 'priview-drawer-body' }}
classNames={{ header: 'preview-drawer-header', body: 'preview-drawer-body' }}
width='200'
title='章节目录'
rootClassName='priview-drawer-container'
rootClassName='preview-drawer-container'
>
<Tree
className='draggable-tree'
......
......@@ -20,9 +20,6 @@ const VideoModal = ({ open, onClose, payload = {}, runtime }) => {
const fileAccept = ['.ogg', '.mp4', '.webm']
const [form] = Form.useForm()
const [uploading, setUploading] = useState(false) // 文件上传状态
const [progress, setProgress] = useState(0)
const [file, setFile] = useState({})
const [videoUrl, setVideoUrl] = useState('')
useEffect(() => {
......@@ -45,16 +42,21 @@ const VideoModal = ({ open, onClose, payload = {}, runtime }) => {
message.error('请上传正确格式的视频')
return false
}
setProgress(0)
setUploading(false)
setFile(file)
return true
},
customRequest: async () => {
customRequest: async ({ file, onSuccess, onError }) => {
setUploading(true)
try {
const url = await uploadFile(file)
setVideoUrl(url)
form.setFieldsValue({ videoUrl: url })
onSuccess?.({ url })
} catch (error) {
message.error('视频上传失败,请重试')
onError?.(error instanceof Error ? error : new Error('视频上传失败'))
} finally {
setUploading(false)
}
},
}
......@@ -81,7 +83,6 @@ const VideoModal = ({ open, onClose, payload = {}, runtime }) => {
})
setVideoUrl('')
setProgress(0)
setUploading(false)
form.resetFields()
onClose()
......@@ -111,7 +112,7 @@ const VideoModal = ({ open, onClose, payload = {}, runtime }) => {
name='videoUrl'
rules={[{ required: true, message: '请上传视频' }]}
>
<Spin spinning={uploading} description={`${progress}%`}>
<Spin spinning={uploading} tip='上传中'>
<div className='editor-dragger'>
<Dragger {...uploadProps} showUploadList={false}>
{!videoUrl && (
......
......@@ -131,11 +131,9 @@ export function usePagedList<Row, Filters, Query>({
}, [initialFilters, initialPage, loadFor, state.pageSize])
const refresh = useCallback(() => {
if (useAppliedFilters) {
setState((current) => ({ ...current, appliedFilters: state.filters }))
}
void loadFor(state.page, state.pageSize, state.filters)
}, [loadFor, state.filters, state.page, state.pageSize, useAppliedFilters])
const filters = useAppliedFilters ? state.appliedFilters : state.filters
void loadFor(state.page, state.pageSize, filters)
}, [loadFor, state.appliedFilters, state.filters, state.page, state.pageSize, useAppliedFilters])
const refreshUnfiltered = useCallback(() => {
void loadFor(state.page, state.pageSize, initialFilters)
......
......@@ -38,7 +38,7 @@
}
.audit-preview-tree,
.previee-container {
.preview-container {
height: 100%;
min-width: 0;
border: 0;
......@@ -94,13 +94,13 @@
}
}
.previee-container {
.preview-container {
display: flex;
flex-direction: column;
border-radius: 0;
}
&.wrap-phone-privew .previee-container .chapter-head-title {
&.wrap-phone-privew .preview-container .chapter-head-title {
flex: 0 0 var(--audit-review-header-height);
height: var(--audit-review-header-height);
line-height: var(--audit-review-header-height);
......@@ -528,7 +528,7 @@
.audit-review-preview {
.audit-preview-tree,
.previee-container {
.preview-container {
height: 360px;
}
}
......
......@@ -15,7 +15,7 @@ import {
convertToAntdTreeData,
findTreeElementByKey,
findFirstNotHasChildren,
clacTopicText,
calcTopicText,
} from '@/utils/common'
import { findReviewCommentRange, useReviewHighlights } from '../../review-comments/highlights'
import { get } from 'lodash-es'
......@@ -86,7 +86,7 @@ const PreviewScreen = (props, ref) => {
} = props
const [gData, setGData] = useState([])
const [loading, setLoading] = useState(false) // 展示
const [prviewHtml, setPrviewHtml] = useState('') // 预览html
const [previewHtml, setPrviewHtml] = useState('') // 预览html
const [open, setOpen] = useState(false) // 抽屉
const [secondType, setSecondType] = useState(false)
const [pageMap, setPageMap] = useState({}) // 叶子节点页码映射
......@@ -118,9 +118,9 @@ const PreviewScreen = (props, ref) => {
const previewContentRef = useRef(null)
const previewText = useMemo(() => {
const element = document.createElement('div')
element.innerHTML = prviewHtml || ''
element.innerHTML = previewHtml || ''
return element.textContent || ''
}, [prviewHtml])
}, [previewHtml])
const getPreviewRoot = useCallback(() => previewContentRef.current || undefined, [])
useReviewHighlights({
......@@ -130,7 +130,7 @@ const PreviewScreen = (props, ref) => {
draftAnchor: draftCommentAnchor,
activeCommentId,
enabled: true,
rootVersion: prviewHtml,
rootVersion: previewHtml,
})
// 递归函数,获取所有节点的key
......@@ -225,7 +225,7 @@ const PreviewScreen = (props, ref) => {
content,
text: contentElement.textContent || '',
})
$('#previee-container')
$('#preview-container')
.find('video audio')
.each((index, item) => {
$(item).attr('controls', true).attr('controlslist', 'nodownload')
......@@ -244,12 +244,15 @@ const PreviewScreen = (props, ref) => {
}
const handlerClick = () => {
const eventNamespace = '.auditPreview'
const previewContent = $('.preview-content-html')
const secondaryContent = $('.expand-content, .gallery-preview-container')
const iParentW = $('.preview-content-it').innerWidth()
const iParentH = $('.preview-content-it').innerHeight()
const parentOffset = $('.preview-content-it').offset() // 获取父元素相对于文档的位置
const parentRect = $('.preview-content-it')[0].getBoundingClientRect() // 获取父元素相对于文档的位置
$('.preview-content-html').on('click', async (ev) => {
previewContent.off(eventNamespace).on(`click${eventNamespace}`, async (ev) => {
ev.stopPropagation()
const target = ev.target
......@@ -455,7 +458,7 @@ const PreviewScreen = (props, ref) => {
setGallery([])
})
$('.expand-content, .gallery-prview-container').on('click', (ev) => {
secondaryContent.off(eventNamespace).on(`click${eventNamespace}`, (ev) => {
const target = ev.target
if (target.nodeName.toLowerCase() === 'img') {
......@@ -467,10 +470,15 @@ const PreviewScreen = (props, ref) => {
setSecondType('扩展图片')
}
})
return () => {
previewContent.off(eventNamespace)
secondaryContent.off(eventNamespace)
}
}
useEffect(() => {
handlerClick()
return handlerClick()
}, [isType])
useEffect(() => {
......@@ -594,7 +602,7 @@ const PreviewScreen = (props, ref) => {
)
return (
<div className={`priview-modal${desktop ? ' desktop-preview' : ''}`}>
<div className={`preview-modal${desktop ? ' desktop-preview' : ''}`}>
{/* <Spin spinning={loading}> */}
{desktop && (
<aside
......@@ -613,7 +621,7 @@ const PreviewScreen = (props, ref) => {
{!treeCollapsed && renderChapterTree()}
</aside>
)}
<div className='previee-container' id='previee-container'>
<div className='preview-container' id='preview-container'>
<div className='chapter-head-title'>
<h2 className='tree'>
{opend ? (
......@@ -658,7 +666,7 @@ const PreviewScreen = (props, ref) => {
<div
ref={previewContentRef}
className='preview-content-html'
dangerouslySetInnerHTML={{ __html: prviewHtml }}
dangerouslySetInnerHTML={{ __html: previewHtml }}
onMouseDown={() => {
onTextSelection?.(null)
}}
......@@ -676,7 +684,7 @@ const PreviewScreen = (props, ref) => {
{isType && (
<div className='preview-content-other'>
{isType === 'gallery' && (
<div className='gallery-prview-container'>
<div className='gallery-preview-container'>
{gallery && gallery.length > 0 ? (
<>
<div className='gallery-img'>
......@@ -704,7 +712,7 @@ const PreviewScreen = (props, ref) => {
<div className='practice-insert-topic'>
{radioList.length > 0 && (
<div className='topic_style'>
<h3>{clacTopicText('radio')}. 单选题</h3>
<h3>{calcTopicText('radio')}. 单选题</h3>
<div className='practice-list'>
{radioList.map((item, index) => {
return (
......@@ -753,7 +761,7 @@ const PreviewScreen = (props, ref) => {
)}
{checkBoxList.length > 0 && (
<div className='topic_style'>
<h3>{clacTopicText('checkbox', radioList)}. 多选题</h3>
<h3>{calcTopicText('checkbox', radioList)}. 多选题</h3>
<div className='practice-list'>
{checkBoxList.map((item, index) => {
return (
......@@ -802,7 +810,7 @@ const PreviewScreen = (props, ref) => {
)}
{judgeList.length > 0 && (
<div className='topic_style'>
<h3>{clacTopicText('judge', radioList, checkBoxList)}. 判断题</h3>
<h3>{calcTopicText('judge', radioList, checkBoxList)}. 判断题</h3>
<div className='practice-list'>
{judgeList.map((item, index) => {
return (
......@@ -851,7 +859,7 @@ const PreviewScreen = (props, ref) => {
)}
{fillList.length > 0 && (
<div className='topic_style'>
<h3>{clacTopicText('fill', radioList, checkBoxList, judgeList)}. 填空题</h3>
<h3>{calcTopicText('fill', radioList, checkBoxList, judgeList)}. 填空题</h3>
<div className='practice-list'>
{fillList.map((item, index) => {
return (
......@@ -901,7 +909,7 @@ const PreviewScreen = (props, ref) => {
{textareaList.length > 0 && (
<div className='topic_style'>
<h3>
{clacTopicText('textarea', radioList, checkBoxList, judgeList, fillList)}.
{calcTopicText('textarea', radioList, checkBoxList, judgeList, fillList)}.
简答题
</h3>
<div className='practice-list'>
......@@ -1007,10 +1015,10 @@ const PreviewScreen = (props, ref) => {
open={open}
getContainer={false}
placement='left'
classNames={{ header: 'priview-drawer-header', body: 'priview-drawer-body' }}
classNames={{ header: 'preview-drawer-header', body: 'preview-drawer-body' }}
size={300}
title='章节目录'
rootClassName='priview-drawer-container'
rootClassName='preview-drawer-container'
>
{renderChapterTree()}
</Drawer>
......
......@@ -586,6 +586,7 @@ const Examine = () => {
onCancel={() => setEditKey(false)}
classNames={{
wrapper: 'chapter-title-modal',
container: 'chapter-title-container',
}}
>
<EditChapterTitle
......
......@@ -123,7 +123,7 @@
inset-inline-end: 17px;
top: 16px;
}
.ant-modal-content {
.chapter-title-container {
padding: 15px 18px;
}
.ant-divider {
......
......@@ -8,7 +8,7 @@ import { getCommentInfo, commentReply, commentDel } from '../api'
const { TextArea } = Input
const DiscussDetail = () => {
const [showReply, setShowReply] = useState(false)
const [delMoadal, setDelModal] = useState(false)
const [delModal, setDelModal] = useState(false)
const [searchParams] = useSearchParams()
const id = Number(searchParams.get('id'))
const name = searchParams.get('book_name') || ''
......@@ -97,7 +97,7 @@ const DiscussDetail = () => {
<Modal
mask={false}
centered
open={delMoadal}
open={delModal}
onOk={handleDel}
onCancel={() => setDelModal(false)}
footer={(_, { OkBtn, CancelBtn }) => {
......
......@@ -37,7 +37,7 @@ const AppVersion = () => {
changePageSize,
} = useAppVersionList()
const [isEdit, setIsEdit] = useState(false)
const [delMoadal, setDelModal] = useState(false)
const [delModal, setDelModal] = useState(false)
const [isadd, setisadd] = useState(true)
const [form] = Form.useForm()
const checkPermission = usePermission()
......@@ -264,7 +264,7 @@ const AppVersion = () => {
<Modal
mask={false}
centered
open={delMoadal}
open={delModal}
onOk={handleDel}
onCancel={() => setDelModal(false)}
footer={(_, { OkBtn, CancelBtn }) => {
......
import { useState, useEffect, useRef } from 'react'
import { Button, Row, Col, Descriptions, Tree, Dropdown, Spin, App } from 'antd'
import {
EllipsisOutlined,
DiffOutlined,
MenuFoldOutlined,
MenuUnfoldOutlined,
} from '@ant-design/icons'
import { Button, Row, Col, Descriptions, Tree, Spin } from 'antd'
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'
import WangEditorCustomer from '@/components/editor/wangeditor-customer'
import { useLocation, useNavigate, useSearchParams } from 'react-router'
import { useEditorStore } from '@/stores/editorStore'
import { useNavigate, useSearchParams } from 'react-router'
import { useUserStore } from '@/stores/userStore'
import { get } from 'lodash-es'
import md5 from 'js-md5'
import {
convertToAntdTreeData,
findTreeElementByKey,
findFirstNotHasChildren,
findParentLevelOne,
findTreeToIndex,
findNodeById,
} from '@/utils/common'
import {
getAllList,
getInfoByChapterId,
sectionEdit,
chapterDel,
dragOrder,
} from '@/modules/books/management/chapters/api.js'
import { getAllList, getInfoByChapterId } from '@/modules/books/management/chapters/api.js'
import './StudentBookView.less'
const Examine = () => {
const { modal } = App.useApp()
const [searchParams] = useSearchParams()
const location = useLocation()
const id = searchParams.get('book_id')
const isAdminOrCreator = get(location, 'state.isAdminOrCreator', false)
const treeChapter = useUserStore((state) => state.treeChapter)
const userInfo = useUserStore((state) => state.userInfo)
const setTreeChapter = useUserStore((state) => state.setTreeChapter)
const setAutosaveTime = useEditorStore((state) => state.setAutosaveTime)
const navigate = useNavigate()
const [gData, setGData] = useState([])
const [chapterId, setChapterId] = useState(0)
const [bookId, setBookId] = useState(0)
// 树节点设置
const [expandedKeys, setExpandedKeys] = useState([])
......@@ -53,21 +30,9 @@ const Examine = () => {
const [nowTitle, setNowTitle] = useState('')
// 编辑操作
const [isCollapse, setisCollapse] = useState(false)
const [editKey, setEditKey] = useState(null)
const [parentId, setParentId] = useState(null)
const [editValue, setEditValue] = useState('')
const [loading, setLoading] = useState(false)
const [contentMd5, setContentMd5] = useState('')
// 设置编者
const [currentChapter, setCurrentChapter] = useState(null)
const [editChapterEditorsIsOpen, setEditChapterEditorsIsOpen] = useState(false)
const onChapterEditorsChange = () => {
setEditChapterEditorsIsOpen(false)
}
// 编辑器内容
const editorRef = useRef()
const saveInterRef = useRef()
const [html, setHtml] = useState('')
const [contentId, setContentId] = useState(false)
......@@ -86,8 +51,6 @@ const Examine = () => {
return
}
const uniqueBookList = [...new Set(data.map((item) => item.book_id))][0]
setBookId(uniqueBookList)
const arr = convertToAntdTreeData(data, 'name')
setGData(arr)
const allKeys = getAllNodeKeys(arr)
......@@ -126,11 +89,6 @@ const Examine = () => {
setLoading(false)
}
const newChapterChange = (id, title) => {
setChapterId(parseInt(id))
setCheckedKeys([parseInt(id)])
setNowTitle(title)
}
// 递归函数,获取所有节点的key
const getAllNodeKeys = (nodes) => {
let keys = []
......@@ -142,18 +100,13 @@ const Examine = () => {
})
return keys
}
const [disabled, setDisabled] = useState(false)
// 获取内容
const getChapterVal = async () => {
setLoading(true)
const data = await getInfoByChapterId({ chapter_id: chapterId })
setDisabled(!data.selected_editor_ids.includes(userInfo.id) && !isAdminOrCreator)
setTreeChapter({ saveBookId: id, saveChapterId: chapterId, ...data })
const { content, id: cId } = data
if (content) {
setContentMd5(md5(content))
}
setHtml(content)
setContentId(cId)
if (editorRef.current && editorRef.current.editor) {
......@@ -165,46 +118,20 @@ const Examine = () => {
const onExpand = (expandedKeys) => {
setExpandedKeys(expandedKeys)
}
const handleSelect = async (checkedKeys, info) => {
const handleSelect = (selectedKeys, info) => {
const { key } = info.node
const childInKey = findTreeElementByKey(gData, 'key', key)
if (childInKey.children && childInKey.children.length > 0) {
clearInterval(saveInterRef.current)
// 进行展开操作
const tempExpandeds = JSON.parse(JSON.stringify(expandedKeys))
let newExpand = ''
if (expandedKeys.includes(key)) {
newExpand = tempExpandeds.filter((item) => parseInt(item) !== parseInt(key))
} else {
newExpand = [...tempExpandeds, key]
}
setExpandedKeys(newExpand)
setCheckedKeys([key])
setExpandedKeys((keys) =>
keys.includes(key) ? keys.filter((item) => item !== key) : [...keys, key],
)
return
} else {
const { key, title } = info.node
if (info.selected === false) {
setLoading(true)
}
setChapterId(key)
setCheckedKeys([key])
setNowTitle(title)
setLoading(false)
} else {
setLoading(true)
clearInterval(saveInterRef.current)
await saveContent()
if (key !== chapterId) {
editorRef.current.editor.clear()
}
setLoading(true)
setChapterId(checkedKeys[0])
setCheckedKeys([checkedKeys[0]])
setNowTitle(info.node.title)
setLoading(false)
}
}
}
useEffect(() => {
......@@ -217,86 +144,6 @@ const Examine = () => {
}
}, [chapterId])
// 保存方法
const saveContent = async () => {
return
if ((contentId, editorRef.current, editorRef.current.editor, !loading)) {
const contentHtml = editorRef.current.editor.getHtml()
const newMd5 = md5(contentHtml)
clearInterval(saveInterRef.current)
const word_count = editorRef.current.editor.getText().length
// 保存
const data = await sectionEdit({
id: contentId,
content: contentHtml,
word_count,
})
if (data) {
if ((data.code && data.code === 3000) || data.code === '3000') {
navigate('/books/management/list')
return
} else {
setContentMd5(newMd5)
setAutosaveTime(Date.now())
}
}
}
}
useEffect(() => {
if (!loading && contentId) {
clearInterval(saveInterRef.current)
} else {
clearInterval(saveInterRef.current)
}
}, [contentId, loading, contentMd5, html])
const addChapterParent = () => {
setEditKey(-1)
setEditValue('')
setParentId(-1)
}
const delChapter = async (node) => {
const childInKey = findParentLevelOne(gData, 'key', node.key)
let current = null
if (childInKey && childInKey.children && childInKey.children.length > 0) {
const index = findTreeToIndex(childInKey.children, 'key', node.key)
if (childInKey.children.length === 1) {
current = childInKey
} else {
// 前面还有
if (index <= childInKey.children.length) {
if (index === 0) {
current = childInKey.children[index + 1]
} else {
current = childInKey.children[index - 1]
}
}
}
} else {
const index = findTreeToIndex(gData, 'key', node.key)
let child = null
if (index === 0) {
child = gData[index + 1]
} else {
child = gData[index - 1]
}
if (child && child.children && child.children.length > 0) {
current = child.children[0]
} else {
current = child
}
}
const data = await chapterDel({ id: node.key })
if (data) {
setTreeChapter({ saveBookId: id, saveChapterId: current ? current.key : null })
await getChapterTreeList()
}
}
useEffect(() => {
if (gData && gData.length > 0 && treeChapter && Object.entries(treeChapter).length > 0) {
if (parseInt(treeChapter.saveBookId) === parseInt(id)) {
......@@ -310,115 +157,6 @@ const Examine = () => {
}
}, [gData, treeChapter])
const chapterMenuItems = [
{ key: '1', label: '展开全部' },
// { key: '2', label: '添加子节' },
// { key: '5', label: '设置编者' },
// { key: '3', label: '编辑' },
// { key: '4', label: '删除' }
]
// if (!isAdminOrCreator) {
// chapterMenuItems = [{ key: '1', label: '展开全部' }]
// }
const handleMenuClick = async (e, node) => {
e.domEvent.stopPropagation()
setCurrentChapter(node)
if (parseInt(e.key) === 1) {
// 展开全部
const ids = findNodeById([node], 'key', node.key)
const expandedKeysTemp = [...expandedKeys, node.key, ...ids]
setExpandedKeys(expandedKeysTemp)
} else if (parseInt(e.key) === 2) {
// 添加子节
setEditKey(-1)
setEditValue('')
setParentId(node.key)
} else if (parseInt(e.key) === 3) {
// 编辑
setEditKey(node.key)
setEditValue(node.title)
setParentId(false)
} else if (parseInt(e.key) === 4) {
await modal.confirm({
title: '删除确认',
content: `确认删除子节【${node.title}】?`,
onOk() {
delChapter(node)
},
})
} else if (e.key == 5) {
setEditChapterEditorsIsOpen(true)
}
}
// 章节名称
const chapterTitleRender = (node) => {
return (
<div className='chapter-tree-item'>
<p className='title'>{node.title}</p>
<Dropdown
trigger={['click']}
menu={{ items: chapterMenuItems, onClick: (e) => handleMenuClick(e, node) }}
>
<EllipsisOutlined onClick={(e) => e.stopPropagation()} />
</Dropdown>
</div>
)
}
const onDrop = async (info) => {
const dropToGap = info.dropToGap // true 为同级或最大级 false 为子级
const nowDropNode = info.dragNode.key
const sideDropNode = info.node.key
let data = null
if (dropToGap) {
// 同级
const dragOverGapBottom = info.node.dragOverGapBottom
const dragOver = info.node.dragOver
const dragOverGapTop = info.node.dragOverGapTop
if (!dragOverGapTop && !dragOver && !dragOverGapBottom) {
// 拖到最底部
// 拖拽到最顶层
data = await dragOrder({
book_id: id,
drag_node: nowDropNode,
position_node: sideDropNode,
drop_type: 'after',
})
} else {
if (dragOverGapTop) {
// 拖拽到最顶层
data = await dragOrder({
book_id: id,
drag_node: nowDropNode,
position_node: sideDropNode,
drop_type: 'before',
})
} else if (dragOverGapBottom) {
data = await dragOrder({
book_id: id,
drag_node: nowDropNode,
position_node: sideDropNode,
drop_type: 'after',
})
}
}
} else {
// 子级
data = await dragOrder({
book_id: id,
drag_node: nowDropNode,
position_node: sideDropNode,
drop_type: 'inner',
})
}
if (data) {
await getChapterTreeList()
}
}
return (
<div
className='examine'
......@@ -445,13 +183,6 @@ const Examine = () => {
>
<Col>章节目录</Col>
<Col>
{isAdminOrCreator && (
<Button
type='text'
icon={<DiffOutlined />}
onClick={addChapterParent}
></Button>
)}
<Button
type='text'
icon={<MenuFoldOutlined />}
......@@ -476,7 +207,6 @@ const Examine = () => {
disabled={loading}
treeData={gData}
onExpand={onExpand}
titleRender={(nodeData) => chapterTitleRender(nodeData)}
/>
)}
</>
......@@ -514,10 +244,9 @@ const Examine = () => {
contentId={contentId}
setHtml={setHtml}
html={html}
saveContent={saveContent}
gData={gData}
nowTitle={nowTitle}
disabled={disabled}
disabled
isView={true}
/>
</Spin>
......
......@@ -86,7 +86,7 @@
inset-inline-end: 17px;
top: 16px;
}
.ant-modal-content {
.chapter-title-container {
padding: 15px 18px;
}
.ant-divider {
......
......@@ -180,7 +180,7 @@ export const hexToRgb = (hex) => {
: null
}
export const clacTopicText = (type, radio, checkbox, judge, fill, textarea) => {
export const calcTopicText = (type, radio, checkbox, judge, fill, textarea) => {
let i = 0
const arr = ['一', '二', '三', '四', '五']
if (type === 'radio') {
......
......@@ -15,12 +15,12 @@ export default defineConfig(() => {
port: 5174,
strictPort: true,
proxy: {
'/api/admin': {
target: 'http://127.0.0.1:7419',
changeOrigin: true,
secure: false,
rewrite: (path) => path.replace(/^\/api\/admin/, ''),
},
// '/api/admin': {
// target: 'http://127.0.0.1:7419',
// changeOrigin: true,
// secure: false,
// rewrite: (path) => path.replace(/^\/api\/admin/, ''),
// },
'/api': 'https://zijingebook.ezijing.com',
},
},
......
......@@ -33,10 +33,10 @@
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.5",
"jsdom": "^29.1.1",
"oxfmt": "^0.59.0",
"oxlint": "^1.74.0",
"oxfmt": "^0.64.0",
"oxlint": "^1.79.0",
"typescript": "^7.0.2",
"vite": "^8.2.1",
"vite": "^8.2.2",
"vite-plugin-mkcert": "^2.1.0",
"vitest": "^4.1.10"
}
......
.mobile-download-modal .ant-modal-content {
.mobile-download-modal .mobile-download-modal__container {
padding: 40px 52px 48px;
border-radius: 24px;
font-family:
......@@ -6,14 +6,14 @@
'Helvetica Neue', Arial, sans-serif;
}
.mobile-download-modal .ant-modal-close {
.mobile-download-modal .mobile-download-modal__close {
top: 22px;
right: 26px;
color: #b8bcc3;
font-size: 28px;
}
.mobile-download-modal .ant-modal-close:hover {
.mobile-download-modal .mobile-download-modal__close:hover {
color: #90959d;
background: transparent;
}
......@@ -125,7 +125,7 @@
.mobile-download-modal {
max-width: calc(100vw - 32px);
}
.mobile-download-modal .ant-modal-content {
.mobile-download-modal .mobile-download-modal__container {
padding: 28px 24px 36px;
}
.mobile-download-modal__content h2.ant-typography {
......
......@@ -38,6 +38,10 @@ export function MobileDownloadModal() {
<Modal
centered
className='mobile-download-modal'
classNames={{
container: 'mobile-download-modal__container',
close: 'mobile-download-modal__close',
}}
closeIcon={<CloseCircleFilled />}
footer={null}
open={open}
......
......@@ -118,7 +118,7 @@ importers:
version: 19.2.3(@types/react@19.2.17)
'@vitejs/plugin-react':
specifier: ^6.0.5
version: 6.0.5(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))
version: 6.0.5(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))
jsdom:
specifier: ^29.1.1
version: 29.1.1
......@@ -126,23 +126,23 @@ importers:
specifier: ^4.2.0
version: 4.6.7
oxfmt:
specifier: ^0.59.0
version: 0.59.0
specifier: ^0.64.0
version: 0.64.0
oxlint:
specifier: ^1.74.0
version: 1.74.0
specifier: ^1.79.0
version: 1.79.0
typescript:
specifier: ^7.0.2
version: 7.0.2
vite:
specifier: ^8.2.1
version: 8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)
specifier: ^8.2.2
version: 8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)
vite-plugin-mkcert:
specifier: ^2.1.0
version: 2.1.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))
version: 2.1.0(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))
vitest:
specifier: ^4.1.10
version: 4.1.10(@types/node@22.20.1)(jsdom@29.1.1)(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))
version: 4.1.10(@types/node@22.20.1)(jsdom@29.1.1)(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))
apps/learning:
dependencies:
......@@ -200,28 +200,28 @@ importers:
version: 19.2.3(@types/react@19.2.17)
'@vitejs/plugin-react':
specifier: ^6.0.5
version: 6.0.5(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))
version: 6.0.5(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))
jsdom:
specifier: ^29.1.1
version: 29.1.1
oxfmt:
specifier: ^0.59.0
version: 0.59.0
specifier: ^0.64.0
version: 0.64.0
oxlint:
specifier: ^1.74.0
version: 1.74.0
specifier: ^1.79.0
version: 1.79.0
typescript:
specifier: ^7.0.2
version: 7.0.2
vite:
specifier: ^8.2.1
version: 8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)
specifier: ^8.2.2
version: 8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)
vite-plugin-mkcert:
specifier: ^2.1.0
version: 2.1.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))
version: 2.1.0(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))
vitest:
specifier: ^4.1.10
version: 4.1.10(@types/node@22.20.1)(jsdom@29.1.1)(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))
version: 4.1.10(@types/node@22.20.1)(jsdom@29.1.1)(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))
packages:
......@@ -538,246 +538,246 @@ packages:
'@oxc-project/types@0.144.0':
resolution: {integrity: sha512-nuhZIOLuI6TFQ32I/WnUx+SCPY7SdSKwgnFHydAuoS1+Z4BRcaP+RRJmGzl9lw+0OFF7UmaESf7KQRXaNLHypg==}
'@oxfmt/binding-android-arm-eabi@0.59.0':
resolution: {integrity: sha512-bNTnfbuG7sAwb2PakMNaDukx5kXeW9duXOBeWtTOiLz3fXz3q2DlWguufPZ+c2IHEVrRXHD+M4aUgEWm841LDA==}
'@oxfmt/binding-android-arm-eabi@0.64.0':
resolution: {integrity: sha512-o6uzh/jTOQeAY5TdkAeXdqv7MBRcPxiRA08zrcBtkKj5cSu/FMu0Hl7Q6Fi1KCKyCWZ6lJVjBzdsJvsKltUsGQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
'@oxfmt/binding-android-arm64@0.59.0':
resolution: {integrity: sha512-R/Sn7z52QtdAKNqQLLY0EK7hVMjXiz3XUlvoCFCm/60jgIzAnQtiqLKBCFaBkimCQL5rs2ezPMcicpjCsrl54Q==}
'@oxfmt/binding-android-arm64@0.64.0':
resolution: {integrity: sha512-jRGSUeeP7p3Gynw2YaCVtjBIA6ZxY6bEB/ES5i54OhqmRTyuVg7ZgstEtzgq6GOAJd+2QZ5pvf+bFfmW5Mp9cw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@oxfmt/binding-darwin-arm64@0.59.0':
resolution: {integrity: sha512-vm/ynUqE4HjC0ZIEjmXv1UJu1/GngccQ+T+TJudTMxUxm6r+GQTg1TO3E5jJfI71pBaXxSzs1+vWHIwuilGHhw==}
'@oxfmt/binding-darwin-arm64@0.64.0':
resolution: {integrity: sha512-JINwtU2lW7nOFSqi+H2qplipNUqah9Gc1jgGmB82kTD4UnZrZIVxCJ9qEmFiKfjNq27gYLFhrUb0to86aCwMjw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@oxfmt/binding-darwin-x64@0.59.0':
resolution: {integrity: sha512-uTtYDpLN/obfKVWGpgEc8BqYlLZBQTPz2uYEvLRy3HPZxjZ34wiFzukUBU2bf64JuCYZI//GTV1EOMmWlPjf/w==}
'@oxfmt/binding-darwin-x64@0.64.0':
resolution: {integrity: sha512-gCmuswrgrOSajV4HCRFkVCGIruPq8bjYuPYgSE2WQB3mD6XrdyZ3JMSRZCkQ8zCxOyGWriBo6QoZ5nmMHQ1BfA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@oxfmt/binding-freebsd-x64@0.59.0':
resolution: {integrity: sha512-e2UnxL/ifStSPy8ffBCDbdy595SYsGy+U1pur4G65TuMmWxAMBzYGG7atZo/3mp515p8rZdsflxVD/E1FAdPLQ==}
'@oxfmt/binding-freebsd-x64@0.64.0':
resolution: {integrity: sha512-Ab8g7a38pT0MMImjh7anRSTve6buWBIlcXIFBYa5xl4s6UxEgKSc2xOOhbGtLwvXnEi2PsEDGoJh3oUU7xkehQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@oxfmt/binding-linux-arm-gnueabihf@0.59.0':
resolution: {integrity: sha512-LtdeZ1l0urxte3VNi3g8cocZwv1xGM1NKHSgF/fJEEVhyQmlgGh7WFWKFd/pNuO7djfvPNtNO1+MS+FEWkgVSA==}
'@oxfmt/binding-linux-arm-gnueabihf@0.64.0':
resolution: {integrity: sha512-BgvS3CoQ+Xy2deoZqEN8JVKabcCZi2RxA3yant8G9OAv9KuPJ9TCjHkqigzdHUVwErZxEP5d2bzLIEyKYyBDLg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxfmt/binding-linux-arm-musleabihf@0.59.0':
resolution: {integrity: sha512-dBTciSsj9GTMl7p+h2gMSI0hoPn2ijfc/dUsbnWsP0RbwgPl2r0C/5zkMb3Pb+gGj17LH7f1o4qLo9aes/pAvA==}
'@oxfmt/binding-linux-arm-musleabihf@0.64.0':
resolution: {integrity: sha512-QXpNxwoMj0YvnceCNZadNSden3bIcnvjn/sDp/rwZhRoZoZYGpHvtPyhGsdJz9uvT9GkaMW7SsLddurU56dt8w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxfmt/binding-linux-arm64-gnu@0.59.0':
resolution: {integrity: sha512-tXVdJ/JINsNWdponPHN0OuKHtC+HdpyoS9sd6IDPNiiEYsRki8b7tefRZ1iMnRkdbyT4SEbguWsr6o+5awvbPQ==}
'@oxfmt/binding-linux-arm64-gnu@0.64.0':
resolution: {integrity: sha512-BBgH3I1ppDsI5pZ4Pdhw0ceYxwVCfbU/bZEBCeZ6caRS9x0ZabErxubP7riGUn11PXZBhe8DYdjkDKP1FlVQ5w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-arm64-musl@0.59.0':
resolution: {integrity: sha512-RRTq38i2zT5fnw6XGHjvT6w2mh6x/G3m6AZcAZ56OTDTT/lsOeYnG3SVjwmH40z5kPqF+lf+o35e6m6PpKy9Dw==}
'@oxfmt/binding-linux-arm64-musl@0.64.0':
resolution: {integrity: sha512-v19HSjC/BGXdt26qEvKZtwAHgGmQ2Agcap2kQP+KIqoRZqivVzYth3ui2dJA1i+6/fjpjga85lIOaJJjQ/bOOw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@oxfmt/binding-linux-ppc64-gnu@0.59.0':
resolution: {integrity: sha512-lD3k7glAJSaXW0D6xzu8VOZbYbosvy+0ktOVkfLEoQF5HJlMSxTQ2KNW0JO+08ccP/1ElOKktVEMI0fqRbVB4w==}
'@oxfmt/binding-linux-ppc64-gnu@0.64.0':
resolution: {integrity: sha512-PElLnOo4xFTBZrxPhgTIj0eHqZXwEBQoNWtb7facUV170T0B0FRET0iNbb3LUeLWTybkUW+vsdyv4ihOdyXGyw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-riscv64-gnu@0.59.0':
resolution: {integrity: sha512-WH5ZP1RbuHKBO/yfPRQKpNO/ijHcEDNbnmC4VPf/Bcd3+mbMAZpRiJWRa1PL5bREdIZZHo343mk3sqlc9x7Usw==}
'@oxfmt/binding-linux-riscv64-gnu@0.64.0':
resolution: {integrity: sha512-Qzsg15n4F5CH+MorcRW4MkAEMiLzXmeG+DiDSbP/bBTqCmWOH3K9DHryNrve+JHlV0txS+B6Z9P5Xz+cmWeL+g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-riscv64-musl@0.59.0':
resolution: {integrity: sha512-743wOiaI9RZY4QVGkWkfGRavD5ZJUJ6gscFjVrVu1dP8AZh9jM+a6v3NhlR+OIzHdS6DhLM96w+gcVskskz7rw==}
'@oxfmt/binding-linux-riscv64-musl@0.64.0':
resolution: {integrity: sha512-/GZ358wnQ/Ez4UVnCcZIi56JkY0sOdZ+B108pqXKqZz3jLS59F4KEAB1Qv3fRlObrFEk+3L2vUQ/xoPx+3vjXw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@oxfmt/binding-linux-s390x-gnu@0.59.0':
resolution: {integrity: sha512-xjRXQsRnrRZCcCkIEnbd2lmsQNobtwwkJxdy2bWXhZ1lIN0ouZwsBXRsoovW3yATuziAYwr9HMiQuR/Cc75NIw==}
'@oxfmt/binding-linux-s390x-gnu@0.64.0':
resolution: {integrity: sha512-/C9We3DXegowfLXtVCYHeNiU9azwCDr5cQkEtCVlc74vyn+lLQSPApJ1CZmxAduqeq/Oi3gQ+IVptyhCaTMtkQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-x64-gnu@0.59.0':
resolution: {integrity: sha512-4hNjqq/Rbr9B+StY9zMMAfm72+mtM4v80xYL5Qkb59Qd72g2vJMI0iFlPj3kf6miMsie/yJ7rt4urJT292HBgA==}
'@oxfmt/binding-linux-x64-gnu@0.64.0':
resolution: {integrity: sha512-91KM2CeRWscIEHlj1NsW2WSnzGeq1Ehq+39bfDowTdkn+fcvK/x4Y1RcyqT7glyBjZio0ldkeCG6Usj3v7ASog==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-x64-musl@0.59.0':
resolution: {integrity: sha512-NH579iN8EVQYsWowUB8B5vFchcylJtwPVJ7NmUAqEQHNLfhPbDT3K56KrECNAkUN4QpF4qiMgN2vsfZwVvjm7g==}
'@oxfmt/binding-linux-x64-musl@0.64.0':
resolution: {integrity: sha512-gw7uEk9I+7zoT1EYLra1eWArIzNcz8e3jkv+Noo2+o2T7wPvsNSQbfoa4DSfZlvn1i6mJ05RiZ4/omaXPDNhQg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@oxfmt/binding-openharmony-arm64@0.59.0':
resolution: {integrity: sha512-mzZy3Z5Aj1D75Aq9FVlmoRQH5ei8Ga4o/NZmlXkKyeZ5EmPrUXRR7c6BMBteV1ZuZ/356UYDuLRLjAMxTDTiBA==}
'@oxfmt/binding-openharmony-arm64@0.64.0':
resolution: {integrity: sha512-HYHFf616FHSPSO07c09mjmXBfQ73wIVM3m0txOiooa5XZkGoxFd6B14PVj0LB0DXIqJ6wAO/dDR/NX/5UUaqnw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@oxfmt/binding-win32-arm64-msvc@0.59.0':
resolution: {integrity: sha512-0CpDJ1gE3jN1Gk6xms1Ie6LPfPcOtY4FAtoOmVLHQoAf8DvO2wd0DW2dIX2f7YTp5dxrr0ND8JeUEjm3DP3k5g==}
'@oxfmt/binding-win32-arm64-msvc@0.64.0':
resolution: {integrity: sha512-uQjFp081IZSWD6VAofX2iO2z01awAdHmfC+NrieWIPKrT2hZKQDyq/U18M7ifC0sm0Wz8aHY/p6+FDYIzs/CrQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@oxfmt/binding-win32-ia32-msvc@0.59.0':
resolution: {integrity: sha512-zwdKBu3pt87uW0bRcywZb0oGMS7C6n87qogwRYFUgmk44T90ZzYlPjtlFYXs/DnBFrgNCvlHwCuWKfVWLeE7kw==}
'@oxfmt/binding-win32-ia32-msvc@0.64.0':
resolution: {integrity: sha512-lNM6byTAQ881jugzFu8juJTbNRgsUTlswMA6pJmwi1XDvmIqnnb49lcUAs5gz94fCJLrVN+/X3s3jOKqx23WIQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ia32]
os: [win32]
'@oxfmt/binding-win32-x64-msvc@0.59.0':
resolution: {integrity: sha512-dUUbZkKgWrmAeI/puzv4bxN8lzcYaFnQVwFTFtwO2Gp8M7lZGSE2qJjC58g518+1bltJ8mizjYwD0BGHym0l/w==}
'@oxfmt/binding-win32-x64-msvc@0.64.0':
resolution: {integrity: sha512-BtmbtL/QjMtF1a6C3CqoDluH2IfB6fJt62E+B9RFfUPtFk4Iz9PFS6+y/SzzOvSxc7aUk2Kphwg7Dh8lMbwu6g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
'@oxlint/binding-android-arm-eabi@1.74.0':
resolution: {integrity: sha512-+gHd12muVI9ZLBaWLPkHt3Fj7jihFjgQ1MGtBaRL8vWrWrI0P7dLUty/cHrHS0oqPYIRgQUJsPu2CExQuMcwNw==}
'@oxlint/binding-android-arm-eabi@1.79.0':
resolution: {integrity: sha512-TebFaaMklO/RXzTv7PucaCq9l3X6D1gA+C8H6K4njtjFOV+zWE9MKLpulcJZN9bzytbUbQIY0mZuz12nQ5Kv4Q==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
'@oxlint/binding-android-arm64@1.74.0':
resolution: {integrity: sha512-xjKdoMB+H+RCOByv/7l7nfIGW9mlOisqYdcyC75UqYuQecLpReAeEYUf2CNeDEI3KtmUgxpRw/+c63y4AeF/Bw==}
'@oxlint/binding-android-arm64@1.79.0':
resolution: {integrity: sha512-KqqnOtAVgNsPPF0YSodkFZA1O80jcKoCZCTu3bgsszxA+MrMP9TLzfXitKjEj1FmrPprKDMdRDMmY3weESO9sg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@oxlint/binding-darwin-arm64@1.74.0':
resolution: {integrity: sha512-iUK7wvc6sejMKsC+Pt67mntoF5weFcyEunhZfLJceU6gL419mexz5wBkSx/EnkFBExMLNtOi9fnDSc5xfK0IzQ==}
'@oxlint/binding-darwin-arm64@1.79.0':
resolution: {integrity: sha512-BVC2nsMzqQzRDPc5RhixkZ+m1p7iH4bxRRvqkbwDXX0PlQKm1BPy8J8cRjnAFafOq2QzI+BfO3vE8w2GZ3CBag==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@oxlint/binding-darwin-x64@1.74.0':
resolution: {integrity: sha512-ggKc/tn5SJ1u2yG2izC6VKODfYKV8MQ2AicJlNzOjuyrC29udvOef6/JzK2r32xqCnBDLFouR1VCkjzEI0/N9Q==}
'@oxlint/binding-darwin-x64@1.79.0':
resolution: {integrity: sha512-p6Lm+snmhGuLKL1+CpCV8L6ijkE/qJzK2H2jG9+eKJT0n31RbY4FLsdhexekgP3bLpw4Kgde+9DZuDZQ4yIInA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@oxlint/binding-freebsd-x64@1.74.0':
resolution: {integrity: sha512-u++dH/43jy9hTLbneaWlS0gla/Bp1JdwJ2zgevCl8nDFUh6qRCGMxcL0f0lb7By3A9p/LfFr+7cG4HU1hG856g==}
'@oxlint/binding-freebsd-x64@1.79.0':
resolution: {integrity: sha512-qDMm0dXZnoHyRqSL4N4xUq82T4sqK5cbKSjvd/dF/YbMUXc2R1wEPf+vmA5S0qUmi0nwXfNbjXBtZaIqzQLIMg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@oxlint/binding-linux-arm-gnueabihf@1.74.0':
resolution: {integrity: sha512-Sj1zmtFDVTPeIbIz4ZfcXAbFHqCmKCXdCUlAJzvTF7I20NTH1RDpoF2PhkqNODutJzVhJYmm3oz0GwgY+tvE2g==}
'@oxlint/binding-linux-arm-gnueabihf@1.79.0':
resolution: {integrity: sha512-2od7s0nuKPzqyUZAWk9KkCyGg7eI9dwFPZg+20lB15fKFkVZ0c9ZFxqPfiBAyDTlTkh9stPI0t+JlPCqMbItVA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxlint/binding-linux-arm-musleabihf@1.74.0':
resolution: {integrity: sha512-//PKyQb/tQXcHArx2f7z+oVI/eMS2Jpv+edNuAtOrgIhWdGcpHxogveAxzmF2rpH1AIHp4Hq04RF/rgJdiICnQ==}
'@oxlint/binding-linux-arm-musleabihf@1.79.0':
resolution: {integrity: sha512-ZOQUjkzDnvlhSE3+tWC3YXx94MMl+sYMlwH+u1+YGApGHOJP/YAc8ZBRFOXZ6eOBmxtXAWuS/fBcdZr8qqNO1A==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxlint/binding-linux-arm64-gnu@1.74.0':
resolution: {integrity: sha512-/k1Me+aX2tjuH10K62mLS0y8cLkJBHX6Ce0xPK+eWeel4bSdEGZ8dv4+hYMzg0GrSmjwy4yAYsDPeEeKBft/2w==}
'@oxlint/binding-linux-arm64-gnu@1.79.0':
resolution: {integrity: sha512-lu158FR4nGqGeRS3BQvtG85wRgU/Fy4MD5Cxp1hzJXizGiLo6u2742wJSCDKh8cFcZntvX7fcxlq4mMmfryH1g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-arm64-musl@1.74.0':
resolution: {integrity: sha512-3tFSjBxc5D8/zvjEuLvOqcA8ZXKD0+6NuaVO/edeamNc49MoAsbfaC9s1UiwODwgF6slGaF8yJA2TPkukd77tg==}
'@oxlint/binding-linux-arm64-musl@1.79.0':
resolution: {integrity: sha512-mbpKQeE2aflTjddaHK7MP8KP/OFbUM++lt5M635ENM8IyIdK0jm2t9pb+2v9mVVIvhF6TqA4l7F79Pll1mi+uw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@oxlint/binding-linux-ppc64-gnu@1.74.0':
resolution: {integrity: sha512-9QggtPkSPXOCTu8Szis7auOK/sC7KdQaN+/TujP7YVVhzCAOhgdRfgv8uEz0r2tk5xdgus5rLYUrCDoZNtiRUw==}
'@oxlint/binding-linux-ppc64-gnu@1.79.0':
resolution: {integrity: sha512-WpGNua7gaxaHnpSDeog2ji8IDHn/QLPl9LPzwkR/FvVv58vT5BcXjRXnU+wbu3N75cpeha8CdC7ho/U2OIsB4g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-riscv64-gnu@1.74.0':
resolution: {integrity: sha512-VM5VPUJ4DJIWiK+AZn8FScUqMr6OFrCAYybMYjEEi7W13ParI64MByiXTkKMqZpBmvQ9zxl9Ebq2VUOiZRJYUg==}
'@oxlint/binding-linux-riscv64-gnu@1.79.0':
resolution: {integrity: sha512-tK1E93A5LVzISg4ngpKJnfTs7EqtIUceGI7MQ4GyDjJiLi8wPCkEyKlj2xkyKWZ1yzkDJyLHTBJ5/iFWRdnJvg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-riscv64-musl@1.74.0':
resolution: {integrity: sha512-SaDY1gh9rOA592J54g+gu5hkOFFQBZsMmIYHs+NRHG+Uq0OxtuuCXMWQ3vu1830Eugv5uMXyjG+bv2Z9y4IXjw==}
'@oxlint/binding-linux-riscv64-musl@1.79.0':
resolution: {integrity: sha512-qhQvUIrngXivA2A9pQ+xPCychztn/5qUv7yS3gDwXv3w7Rag+eTeeXWmRyx+t7XsW5x6LuY/8AsTq36UgFIblg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@oxlint/binding-linux-s390x-gnu@1.74.0':
resolution: {integrity: sha512-ZATQeHZCyr6MbDveg0obD5sxLHFOghtOdC5jwVwYlvFWqtFOxctgFEG6Ef/64hYvZrWyhyCckB10AelqLopeDA==}
'@oxlint/binding-linux-s390x-gnu@1.79.0':
resolution: {integrity: sha512-sv6AaVgU/eE6u+6WFiQVDcPPwTxP6IJMSB9k701W2r/r6Tx465e8vPvVyRxquNH4Vy6KwRNu90mVbxXJN8+5gg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-x64-gnu@1.74.0':
resolution: {integrity: sha512-+aIvJyrdeD7LwCQ2WYLMUWNmnbeDRSPb40aBYtPjD9+PTqUwgJnk+HK5yLfSMeqXrMrDhE9uTmtt2y50tvjhHw==}
'@oxlint/binding-linux-x64-gnu@1.79.0':
resolution: {integrity: sha512-iFZL02deziHslb3jEX9KdqlAkYoo4fGyotchKDzdfK1f5mxlIBeiQeHhvK3iFpuEJSB4ma/qeFn9oxPiwnhUPQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-x64-musl@1.74.0':
resolution: {integrity: sha512-XyktaR8lhK2qWiCK0Tk8oYD+/cgn+oHA6ddRnxSSXUKkkojkV78CmShZUxQF+yrBFs0SuW+JBOPG6hecyc/iZg==}
'@oxlint/binding-linux-x64-musl@1.79.0':
resolution: {integrity: sha512-3DtZR2raqObnh7wXZoFYFd0Fw7skBvcb3f7A+/lkEiDuh8hrE6vv9b/62Qxao1a9/OeHLw/FcXlXzgsW9wTRFg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@oxlint/binding-openharmony-arm64@1.74.0':
resolution: {integrity: sha512-mzbjrPl4neaVUiJ1fUiEUxTGaSZBoiKtaoB6jmIpz9S+VOA2vDYmJpihQ82w6178V5jxziclTg8Cgj5yF6tTDg==}
'@oxlint/binding-openharmony-arm64@1.79.0':
resolution: {integrity: sha512-Oatt4GuA1WJkqzk2ozx4HrWROOi7opV3AKDw/U8qDIqeTqzsjn5K2x3REJMNjU3/KU/Bkq96Zi3CknaiDTaC/Q==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@oxlint/binding-win32-arm64-msvc@1.74.0':
resolution: {integrity: sha512-vUAe9okpS2Oa5+lX67lqHMuNUvfkleRKwrUDJ/WJBsgmddvZ1mrsh2HVmuFDRzqFELhaJhFaCNOuR6a7L3rtIA==}
'@oxlint/binding-win32-arm64-msvc@1.79.0':
resolution: {integrity: sha512-NAgZr9Qp8nIA9rpo0JEvwiabTF/2UVqBNnupBG9X4kxXcQoScJUTi+qHhvabb9s/thgj5wQ4XcIaJvb+ZMgoKw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@oxlint/binding-win32-ia32-msvc@1.74.0':
resolution: {integrity: sha512-yyXXJyYYSXL4I8K8jAWjJs+J3fa9gH2JmEbo4f5adm+1tNC9itseicBNuwK7BDHvqQ5J534s+yDULu89vYL2ZQ==}
'@oxlint/binding-win32-ia32-msvc@1.79.0':
resolution: {integrity: sha512-+KyXjIvcpaXmWW/j9NNY5yWjrIVxaX18VyIheQy3jwc2GSYgpCr7MGI/HxIGQ/shAL5IWEKbhsqoMpAO5Stiog==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ia32]
os: [win32]
'@oxlint/binding-win32-x64-msvc@1.74.0':
resolution: {integrity: sha512-VTC9IYTIMrVUk/i6Ms1ohzzDKZFkWn0KU2OBbPBzgmVZ2V30165T/zK4LztTr0Xgp9fZ1qQZ1rsZAu/rEmySlA==}
'@oxlint/binding-win32-x64-msvc@1.79.0':
resolution: {integrity: sha512-mEelcCMMBS57sIXh2veGMNy+pQwuGtcMxHxGIZWQ5Ba9pJ5jCCUFOZB9E2JhBaxGsURe+WGe0zJp4RVre52gpQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
......@@ -2359,8 +2359,8 @@ packages:
engines: {node: '>=0.10.0'}
hasBin: true
oxfmt@0.59.0:
resolution: {integrity: sha512-Xqk6cPZS1yMvVa7OAuenaDZUsgMDutvvbZ9/L5gSvAfW64+WN4HVhgipLj5rVERbYQt8fLs9TopyZ1rU1XEG/w==}
oxfmt@0.64.0:
resolution: {integrity: sha512-XZ4GFBN/PLbXKq+0zrgpQfPKYuJlUuj+nzZJY7UpIbFMNyefNLCdN9EwViycNqnYcv0wrn0jXcQLlqJp8RCKBg==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
......@@ -2372,12 +2372,12 @@ packages:
vite-plus:
optional: true
oxlint@1.74.0:
resolution: {integrity: sha512-odGl2s2x5IOJoj3A0v1k0PGBXVFBZeZ2+AK/+K2MJur7Ghi3bkyX5NuLUWHKqa4js1wjep3hJeuTQJOlr+4+dA==}
oxlint@1.79.0:
resolution: {integrity: sha512-hVJ9hq9m2unPS+Of4eJJgCPdIeCC+3DHEUX3tkmrPJr3OK2hz7PhXwgC+ZP71ZcYu8cCDEtQrqLxWNvxBppBVg==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
oxlint-tsgolint: '>=0.24.0'
oxlint-tsgolint: '>=7.0.2001'
vite-plus: '*'
peerDependenciesMeta:
oxlint-tsgolint:
......@@ -2794,13 +2794,13 @@ packages:
peerDependencies:
vite: '>=3'
vite@8.2.1:
resolution: {integrity: sha512-EU/eS7BH3XROHh2YnBefjM6DBKA6ZeMZEYQbj7NLWg5wHYlhB8B/Mayd5XsgWq+NFYccDOTemRpdETWR6Ka/lw==}
vite@8.2.2:
resolution: {integrity: sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
'@types/node': ^20.19.0 || >=22.12.0
'@vitejs/devtools': ^0.4.0
'@vitejs/devtools': ^0.4.0 || ^0.5.0
esbuild: ^0.27.0 || ^0.28.0
jiti: '>=1.21.0'
less: ^4.0.0
......@@ -3203,118 +3203,118 @@ snapshots:
'@oxc-project/types@0.144.0': {}
'@oxfmt/binding-android-arm-eabi@0.59.0':
'@oxfmt/binding-android-arm-eabi@0.64.0':
optional: true
'@oxfmt/binding-android-arm64@0.59.0':
'@oxfmt/binding-android-arm64@0.64.0':
optional: true
'@oxfmt/binding-darwin-arm64@0.59.0':
'@oxfmt/binding-darwin-arm64@0.64.0':
optional: true
'@oxfmt/binding-darwin-x64@0.59.0':
'@oxfmt/binding-darwin-x64@0.64.0':
optional: true
'@oxfmt/binding-freebsd-x64@0.59.0':
'@oxfmt/binding-freebsd-x64@0.64.0':
optional: true
'@oxfmt/binding-linux-arm-gnueabihf@0.59.0':
'@oxfmt/binding-linux-arm-gnueabihf@0.64.0':
optional: true
'@oxfmt/binding-linux-arm-musleabihf@0.59.0':
'@oxfmt/binding-linux-arm-musleabihf@0.64.0':
optional: true
'@oxfmt/binding-linux-arm64-gnu@0.59.0':
'@oxfmt/binding-linux-arm64-gnu@0.64.0':
optional: true
'@oxfmt/binding-linux-arm64-musl@0.59.0':
'@oxfmt/binding-linux-arm64-musl@0.64.0':
optional: true
'@oxfmt/binding-linux-ppc64-gnu@0.59.0':
'@oxfmt/binding-linux-ppc64-gnu@0.64.0':
optional: true
'@oxfmt/binding-linux-riscv64-gnu@0.59.0':
'@oxfmt/binding-linux-riscv64-gnu@0.64.0':
optional: true
'@oxfmt/binding-linux-riscv64-musl@0.59.0':
'@oxfmt/binding-linux-riscv64-musl@0.64.0':
optional: true
'@oxfmt/binding-linux-s390x-gnu@0.59.0':
'@oxfmt/binding-linux-s390x-gnu@0.64.0':
optional: true
'@oxfmt/binding-linux-x64-gnu@0.59.0':
'@oxfmt/binding-linux-x64-gnu@0.64.0':
optional: true
'@oxfmt/binding-linux-x64-musl@0.59.0':
'@oxfmt/binding-linux-x64-musl@0.64.0':
optional: true
'@oxfmt/binding-openharmony-arm64@0.59.0':
'@oxfmt/binding-openharmony-arm64@0.64.0':
optional: true
'@oxfmt/binding-win32-arm64-msvc@0.59.0':
'@oxfmt/binding-win32-arm64-msvc@0.64.0':
optional: true
'@oxfmt/binding-win32-ia32-msvc@0.59.0':
'@oxfmt/binding-win32-ia32-msvc@0.64.0':
optional: true
'@oxfmt/binding-win32-x64-msvc@0.59.0':
'@oxfmt/binding-win32-x64-msvc@0.64.0':
optional: true
'@oxlint/binding-android-arm-eabi@1.74.0':
'@oxlint/binding-android-arm-eabi@1.79.0':
optional: true
'@oxlint/binding-android-arm64@1.74.0':
'@oxlint/binding-android-arm64@1.79.0':
optional: true
'@oxlint/binding-darwin-arm64@1.74.0':
'@oxlint/binding-darwin-arm64@1.79.0':
optional: true
'@oxlint/binding-darwin-x64@1.74.0':
'@oxlint/binding-darwin-x64@1.79.0':
optional: true
'@oxlint/binding-freebsd-x64@1.74.0':
'@oxlint/binding-freebsd-x64@1.79.0':
optional: true
'@oxlint/binding-linux-arm-gnueabihf@1.74.0':
'@oxlint/binding-linux-arm-gnueabihf@1.79.0':
optional: true
'@oxlint/binding-linux-arm-musleabihf@1.74.0':
'@oxlint/binding-linux-arm-musleabihf@1.79.0':
optional: true
'@oxlint/binding-linux-arm64-gnu@1.74.0':
'@oxlint/binding-linux-arm64-gnu@1.79.0':
optional: true
'@oxlint/binding-linux-arm64-musl@1.74.0':
'@oxlint/binding-linux-arm64-musl@1.79.0':
optional: true
'@oxlint/binding-linux-ppc64-gnu@1.74.0':
'@oxlint/binding-linux-ppc64-gnu@1.79.0':
optional: true
'@oxlint/binding-linux-riscv64-gnu@1.74.0':
'@oxlint/binding-linux-riscv64-gnu@1.79.0':
optional: true
'@oxlint/binding-linux-riscv64-musl@1.74.0':
'@oxlint/binding-linux-riscv64-musl@1.79.0':
optional: true
'@oxlint/binding-linux-s390x-gnu@1.74.0':
'@oxlint/binding-linux-s390x-gnu@1.79.0':
optional: true
'@oxlint/binding-linux-x64-gnu@1.74.0':
'@oxlint/binding-linux-x64-gnu@1.79.0':
optional: true
'@oxlint/binding-linux-x64-musl@1.74.0':
'@oxlint/binding-linux-x64-musl@1.79.0':
optional: true
'@oxlint/binding-openharmony-arm64@1.74.0':
'@oxlint/binding-openharmony-arm64@1.79.0':
optional: true
'@oxlint/binding-win32-arm64-msvc@1.74.0':
'@oxlint/binding-win32-arm64-msvc@1.79.0':
optional: true
'@oxlint/binding-win32-ia32-msvc@1.74.0':
'@oxlint/binding-win32-ia32-msvc@1.79.0':
optional: true
'@oxlint/binding-win32-x64-msvc@1.74.0':
'@oxlint/binding-win32-x64-msvc@1.79.0':
optional: true
'@rc-component/async-validator@6.0.0':
......@@ -3993,10 +3993,10 @@ snapshots:
'@uppy/utils': 4.1.3
nanoid: 3.3.18
'@vitejs/plugin-react@6.0.5(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))':
'@vitejs/plugin-react@6.0.5(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))':
dependencies:
'@rolldown/pluginutils': 1.0.1
vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)
vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)
'@vitest/expect@4.1.10':
dependencies:
......@@ -4007,13 +4007,13 @@ snapshots:
chai: 6.2.2
tinyrainbow: 3.1.0
'@vitest/mocker@4.1.10(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))':
'@vitest/mocker@4.1.10(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))':
dependencies:
'@vitest/spy': 4.1.10
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)
vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)
'@vitest/pretty-format@4.1.10':
dependencies:
......@@ -4988,51 +4988,51 @@ snapshots:
dependencies:
minimist: 1.2.8
oxfmt@0.59.0:
oxfmt@0.64.0:
dependencies:
tinypool: 2.1.0
optionalDependencies:
'@oxfmt/binding-android-arm-eabi': 0.59.0
'@oxfmt/binding-android-arm64': 0.59.0
'@oxfmt/binding-darwin-arm64': 0.59.0
'@oxfmt/binding-darwin-x64': 0.59.0
'@oxfmt/binding-freebsd-x64': 0.59.0
'@oxfmt/binding-linux-arm-gnueabihf': 0.59.0
'@oxfmt/binding-linux-arm-musleabihf': 0.59.0
'@oxfmt/binding-linux-arm64-gnu': 0.59.0
'@oxfmt/binding-linux-arm64-musl': 0.59.0
'@oxfmt/binding-linux-ppc64-gnu': 0.59.0
'@oxfmt/binding-linux-riscv64-gnu': 0.59.0
'@oxfmt/binding-linux-riscv64-musl': 0.59.0
'@oxfmt/binding-linux-s390x-gnu': 0.59.0
'@oxfmt/binding-linux-x64-gnu': 0.59.0
'@oxfmt/binding-linux-x64-musl': 0.59.0
'@oxfmt/binding-openharmony-arm64': 0.59.0
'@oxfmt/binding-win32-arm64-msvc': 0.59.0
'@oxfmt/binding-win32-ia32-msvc': 0.59.0
'@oxfmt/binding-win32-x64-msvc': 0.59.0
oxlint@1.74.0:
'@oxfmt/binding-android-arm-eabi': 0.64.0
'@oxfmt/binding-android-arm64': 0.64.0
'@oxfmt/binding-darwin-arm64': 0.64.0
'@oxfmt/binding-darwin-x64': 0.64.0
'@oxfmt/binding-freebsd-x64': 0.64.0
'@oxfmt/binding-linux-arm-gnueabihf': 0.64.0
'@oxfmt/binding-linux-arm-musleabihf': 0.64.0
'@oxfmt/binding-linux-arm64-gnu': 0.64.0
'@oxfmt/binding-linux-arm64-musl': 0.64.0
'@oxfmt/binding-linux-ppc64-gnu': 0.64.0
'@oxfmt/binding-linux-riscv64-gnu': 0.64.0
'@oxfmt/binding-linux-riscv64-musl': 0.64.0
'@oxfmt/binding-linux-s390x-gnu': 0.64.0
'@oxfmt/binding-linux-x64-gnu': 0.64.0
'@oxfmt/binding-linux-x64-musl': 0.64.0
'@oxfmt/binding-openharmony-arm64': 0.64.0
'@oxfmt/binding-win32-arm64-msvc': 0.64.0
'@oxfmt/binding-win32-ia32-msvc': 0.64.0
'@oxfmt/binding-win32-x64-msvc': 0.64.0
oxlint@1.79.0:
optionalDependencies:
'@oxlint/binding-android-arm-eabi': 1.74.0
'@oxlint/binding-android-arm64': 1.74.0
'@oxlint/binding-darwin-arm64': 1.74.0
'@oxlint/binding-darwin-x64': 1.74.0
'@oxlint/binding-freebsd-x64': 1.74.0
'@oxlint/binding-linux-arm-gnueabihf': 1.74.0
'@oxlint/binding-linux-arm-musleabihf': 1.74.0
'@oxlint/binding-linux-arm64-gnu': 1.74.0
'@oxlint/binding-linux-arm64-musl': 1.74.0
'@oxlint/binding-linux-ppc64-gnu': 1.74.0
'@oxlint/binding-linux-riscv64-gnu': 1.74.0
'@oxlint/binding-linux-riscv64-musl': 1.74.0
'@oxlint/binding-linux-s390x-gnu': 1.74.0
'@oxlint/binding-linux-x64-gnu': 1.74.0
'@oxlint/binding-linux-x64-musl': 1.74.0
'@oxlint/binding-openharmony-arm64': 1.74.0
'@oxlint/binding-win32-arm64-msvc': 1.74.0
'@oxlint/binding-win32-ia32-msvc': 1.74.0
'@oxlint/binding-win32-x64-msvc': 1.74.0
'@oxlint/binding-android-arm-eabi': 1.79.0
'@oxlint/binding-android-arm64': 1.79.0
'@oxlint/binding-darwin-arm64': 1.79.0
'@oxlint/binding-darwin-x64': 1.79.0
'@oxlint/binding-freebsd-x64': 1.79.0
'@oxlint/binding-linux-arm-gnueabihf': 1.79.0
'@oxlint/binding-linux-arm-musleabihf': 1.79.0
'@oxlint/binding-linux-arm64-gnu': 1.79.0
'@oxlint/binding-linux-arm64-musl': 1.79.0
'@oxlint/binding-linux-ppc64-gnu': 1.79.0
'@oxlint/binding-linux-riscv64-gnu': 1.79.0
'@oxlint/binding-linux-riscv64-musl': 1.79.0
'@oxlint/binding-linux-s390x-gnu': 1.79.0
'@oxlint/binding-linux-x64-gnu': 1.79.0
'@oxlint/binding-linux-x64-musl': 1.79.0
'@oxlint/binding-openharmony-arm64': 1.79.0
'@oxlint/binding-win32-arm64-msvc': 1.79.0
'@oxlint/binding-win32-ia32-msvc': 1.79.0
'@oxlint/binding-win32-x64-msvc': 1.79.0
parse-node-version@1.0.1: {}
......@@ -5454,14 +5454,14 @@ snapshots:
mz: 2.7.0
unescape: 1.0.1
vite-plugin-mkcert@2.1.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)):
vite-plugin-mkcert@2.1.0(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)):
dependencies:
debug: 4.4.3(supports-color@10.2.2)
supports-color: 10.2.2
undici: 8.10.0
vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)
vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)
vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0):
vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0):
dependencies:
lightningcss: 1.33.0
picomatch: 4.0.5
......@@ -5475,10 +5475,10 @@ snapshots:
less: 4.6.7
terser: 5.49.0
vitest@4.1.10(@types/node@22.20.1)(jsdom@29.1.1)(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)):
vitest@4.1.10(@types/node@22.20.1)(jsdom@29.1.1)(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)):
dependencies:
'@vitest/expect': 4.1.10
'@vitest/mocker': 4.1.10(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))
'@vitest/mocker': 4.1.10(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0))
'@vitest/pretty-format': 4.1.10
'@vitest/runner': 4.1.10
'@vitest/snapshot': 4.1.10
......@@ -5495,7 +5495,7 @@ snapshots:
tinyexec: 1.2.4
tinyglobby: 0.2.17
tinyrainbow: 3.1.0
vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)
vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.1)(less@4.6.7)(terser@5.49.0)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 22.20.1
......
......@@ -5,3 +5,6 @@ packages:
allowBuilds:
es5-ext: false
esbuild: true
minimumReleaseAgeExclude:
- vite@8.2.2
Markdown 格式
0% 或
您添加了 0 人 到此讨论。请谨慎行事。
请先完成此评论的编辑!
请 注册 或者 后发表评论