修改了会议详情

main
mula.liu 2025-08-05 10:58:13 +08:00
parent b7ee731ced
commit 7f5d16e9fc
12 changed files with 2274 additions and 100 deletions

1047
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -10,12 +10,16 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@uiw/react-md-editor": "^4.0.8",
"axios": "^1.6.2", "axios": "^1.6.2",
"lucide-react": "^0.294.0", "lucide-react": "^0.294.0",
"react": "^19.1.0", "react": "^19.1.0",
"react-dom": "^19.1.0", "react-dom": "^19.1.0",
"react-markdown": "^10.1.0", "react-markdown": "^10.1.0",
"react-router-dom": "^7.7.1" "react-router-dom": "^7.7.1",
"rehype-raw": "^7.0.0",
"rehype-sanitize": "^6.0.0",
"remark-gfm": "^4.0.1"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.30.1", "@eslint/js": "^9.30.1",

View File

@ -58,7 +58,7 @@ function App() {
user ? <Dashboard user={user} onLogout={handleLogout} /> : <Navigate to="/" /> user ? <Dashboard user={user} onLogout={handleLogout} /> : <Navigate to="/" />
} /> } />
<Route path="/meetings/:meeting_id" element={ <Route path="/meetings/:meeting_id" element={
user ? <MeetingDetails /> : <Navigate to="/" /> user ? <MeetingDetails user={user} /> : <Navigate to="/" />
} /> } />
<Route path="/meetings/create" element={ <Route path="/meetings/create" element={
user ? <CreateMeeting user={user} /> : <Navigate to="/" /> user ? <CreateMeeting user={user} /> : <Navigate to="/" />

View File

@ -383,7 +383,7 @@
/* Markdown content styling */ /* Markdown content styling */
.markdown-content { .markdown-content {
font-size: 0.85rem; font-size: 0.85rem;
line-height: 1.6; line-height: 1.5;
} }
.markdown-content h1, .markdown-content h1,
@ -392,11 +392,20 @@
.markdown-content h4, .markdown-content h4,
.markdown-content h5, .markdown-content h5,
.markdown-content h6 { .markdown-content h6 {
margin: 0.5rem 0 0.25rem 0; margin: 0.4rem 0 0.2rem 0;
font-weight: 600; font-weight: 600;
color: #334155; color: #334155;
} }
.markdown-content h1:first-child,
.markdown-content h2:first-child,
.markdown-content h3:first-child,
.markdown-content h4:first-child,
.markdown-content h5:first-child,
.markdown-content h6:first-child {
margin-top: 0;
}
.markdown-content h1 { font-size: 1rem; } .markdown-content h1 { font-size: 1rem; }
.markdown-content h2 { font-size: 0.95rem; } .markdown-content h2 { font-size: 0.95rem; }
.markdown-content h3 { font-size: 0.9rem; } .markdown-content h3 { font-size: 0.9rem; }
@ -405,17 +414,29 @@
.markdown-content h6 { font-size: 0.85rem; } .markdown-content h6 { font-size: 0.85rem; }
.markdown-content p { .markdown-content p {
margin: 0.25rem 0; margin: 0.1rem 0;
}
.markdown-content p:first-child {
margin-top: 0;
}
.markdown-content p:last-child {
margin-bottom: 0;
} }
.markdown-content ul, .markdown-content ul,
.markdown-content ol { .markdown-content ol {
margin: 0.25rem 0; margin: 0.2rem 0;
padding-left: 1.2rem; padding-left: 1.2rem;
} }
.markdown-content li { .markdown-content li {
margin: 0.1rem 0; margin: 0.05rem 0;
}
.markdown-content li p {
margin: 0.05rem 0;
} }
.markdown-content strong { .markdown-content strong {
@ -443,6 +464,33 @@
color: #64748b; color: #64748b;
} }
.markdown-content table {
width: 100%;
border-collapse: collapse;
margin: 0.5rem 0;
font-size: 0.8rem;
}
.markdown-content th,
.markdown-content td {
border: 1px solid #e2e8f0;
padding: 0.4rem;
text-align: left;
}
.markdown-content th {
background: #f8fafc;
font-weight: 600;
color: #334155;
}
.markdown-content hr {
border: none;
height: 1px;
background: #e2e8f0;
margin: 1rem 0;
}
/* Meeting Footer */ /* Meeting Footer */
.meeting-footer { .meeting-footer {
display: flex; display: flex;

View File

@ -2,6 +2,9 @@ import React, { useState } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Clock, Users, FileText, Calendar, User, Edit, Trash2, MoreVertical } from 'lucide-react'; import { Clock, Users, FileText, Calendar, User, Edit, Trash2, MoreVertical } from 'lucide-react';
import ReactMarkdown from 'react-markdown'; import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import rehypeRaw from 'rehype-raw';
import rehypeSanitize from 'rehype-sanitize';
import './MeetingTimeline.css'; import './MeetingTimeline.css';
const MeetingTimeline = ({ meetingsByDate, currentUser, onDeleteMeeting }) => { const MeetingTimeline = ({ meetingsByDate, currentUser, onDeleteMeeting }) => {
@ -103,7 +106,7 @@ const MeetingTimeline = ({ meetingsByDate, currentUser, onDeleteMeeting }) => {
</div> </div>
<div className="meetings-for-date"> <div className="meetings-for-date">
{meetingsByDate[date].map(meeting => { {meetingsByDate[date].map(meeting => {
const isCreator = meeting.creator_id === currentUser.user_id; const isCreator = String(meeting.creator_id) === String(currentUser.user_id);
const cardClass = isCreator ? 'created-by-me' : 'attended-by-me'; const cardClass = isCreator ? 'created-by-me' : 'attended-by-me';
return ( return (
@ -179,7 +182,10 @@ const MeetingTimeline = ({ meetingsByDate, currentUser, onDeleteMeeting }) => {
</div> </div>
<div className="summary-content"> <div className="summary-content">
<div className="markdown-content"> <div className="markdown-content">
<ReactMarkdown> <ReactMarkdown
remarkPlugins={[remarkGfm]}
rehypePlugins={[rehypeRaw, rehypeSanitize]}
>
{truncateSummary(meeting.summary)} {truncateSummary(meeting.summary)}
</ReactMarkdown> </ReactMarkdown>
</div> </div>

View File

@ -119,29 +119,22 @@
} }
.remove-attendee { .remove-attendee {
background: rgba(255, 255, 255, 0.2); background: none;
border: none; border: none;
border-radius: 50%; cursor: pointer;
width: 22px; color: rgba(255, 255, 255, 0.7);
height: 22px; transition: all 0.2s ease;
min-width: 22px; margin-left: 0.5rem;
min-height: 22px; padding: 2px;
display: inline-flex; border-radius: 2px;
display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
cursor: pointer;
color: white;
transition: background 0.3s ease;
margin-left: 0.5rem;
flex-shrink: 0;
font-size: 16px;
font-weight: bold;
line-height: 1;
font-family: Arial, sans-serif;
} }
.remove-attendee:hover { .remove-attendee:hover {
background: rgba(255, 255, 255, 0.3); color: #ffffff;
transform: scale(1.2);
} }
.user-search-container { .user-search-container {

View File

@ -202,7 +202,7 @@ const CreateMeeting = ({ user }) => {
className="remove-attendee" className="remove-attendee"
title="移除参会人" title="移除参会人"
> >
× <X size={14} />
</button> </button>
</div> </div>
))} ))}

View File

@ -178,29 +178,22 @@
} }
.remove-attendee { .remove-attendee {
background: rgba(255, 255, 255, 0.2); background: none;
border: none; border: none;
border-radius: 50%; cursor: pointer;
width: 22px; color: rgba(255, 255, 255, 0.7);
height: 22px; transition: all 0.2s ease;
min-width: 22px; margin-left: 0.5rem;
min-height: 22px; padding: 2px;
display: inline-flex; border-radius: 2px;
display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
cursor: pointer;
color: white;
transition: background 0.3s ease;
margin-left: 0.5rem;
flex-shrink: 0;
font-size: 16px;
font-weight: bold;
line-height: 1;
font-family: Arial, sans-serif;
} }
.remove-attendee:hover { .remove-attendee:hover {
background: rgba(255, 255, 255, 0.3); color: #ffffff;
transform: scale(1.2);
} }
.user-search-container { .user-search-container {
@ -352,6 +345,138 @@
cursor: not-allowed; cursor: not-allowed;
} }
/* Error Message */
.error-message {
background: #fef2f2;
color: #ef4444;
padding: 0.75rem 1rem;
border-radius: 6px;
border: 1px solid #fecaca;
font-size: 0.9rem;
margin: 1rem 0;
}
/* File Upload Styles */
.file-upload-container {
position: relative;
}
.file-input {
display: none;
}
.file-upload-label {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
padding: 2rem;
border: 2px dashed #d1d5db;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
text-align: center;
background: #fafafa;
}
.file-upload-label:hover {
border-color: #667eea;
background: #f8fafc;
}
.file-upload-label span {
font-weight: 500;
color: #334155;
}
.file-upload-label small {
color: #64748b;
font-size: 0.85rem;
}
.selected-file {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem 1rem;
background: #f0f9ff;
border: 1px solid #bae6fd;
border-radius: 6px;
margin-top: 1rem;
}
.remove-file {
background: none;
border: none;
color: #64748b;
cursor: pointer;
padding: 0.25rem;
border-radius: 4px;
transition: color 0.3s ease;
}
.remove-file:hover {
color: #ef4444;
}
.upload-btn {
display: flex;
align-items: center;
gap: 0.5rem;
margin-top: 1rem;
padding: 0.75rem 1.5rem;
background: #667eea;
color: white;
border: none;
border-radius: 8px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
width: 100%;
justify-content: center;
}
.upload-btn:hover:not(:disabled) {
background: #5a67d8;
transform: translateY(-1px);
}
.upload-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
/* Markdown Editor */
.markdown-editor-container {
margin-top: 0.5rem;
}
.markdown-editor-container .w-md-editor {
background-color: white;
}
.markdown-editor-container .w-md-editor-text-input,
.markdown-editor-container .w-md-editor-text-textarea,
.markdown-editor-container .w-md-editor-text {
font-size: 0.9rem !important;
line-height: 1.6 !important;
}
.markdown-editor-container .w-md-editor-toolbar {
background-color: #f8fafc;
border-bottom: 1px solid #e2e8f0;
}
.markdown-editor-container .w-md-editor-toolbar button {
color: #64748b;
}
.markdown-editor-container .w-md-editor-toolbar button:hover {
background-color: #e2e8f0;
color: #334155;
}
/* Responsive Design */ /* Responsive Design */
@media (max-width: 768px) { @media (max-width: 768px) {
.edit-meeting-page { .edit-meeting-page {

View File

@ -1,7 +1,9 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Link, useNavigate, useParams } from 'react-router-dom'; import { Link, useNavigate, useParams } from 'react-router-dom';
import axios from 'axios'; import axios from 'axios';
import { ArrowLeft, Users, Calendar, FileText, X, User, Save, Zap } from 'lucide-react'; import { ArrowLeft, Users, Calendar, FileText, X, User, Save, Upload, Plus } from 'lucide-react';
import MDEditor from '@uiw/react-md-editor';
import '@uiw/react-md-editor/markdown-editor.css';
import { buildApiUrl, API_ENDPOINTS } from '../config/api'; import { buildApiUrl, API_ENDPOINTS } from '../config/api';
import './EditMeeting.css'; import './EditMeeting.css';
@ -17,9 +19,10 @@ const EditMeeting = ({ user }) => {
const [availableUsers, setAvailableUsers] = useState([]); const [availableUsers, setAvailableUsers] = useState([]);
const [userSearch, setUserSearch] = useState(''); const [userSearch, setUserSearch] = useState('');
const [showUserDropdown, setShowUserDropdown] = useState(false); const [showUserDropdown, setShowUserDropdown] = useState(false);
const [audioFile, setAudioFile] = useState(null);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [isSaving, setIsSaving] = useState(false); const [isSaving, setIsSaving] = useState(false);
const [isRegenerating, setIsRegenerating] = useState(false); const [isUploading, setIsUploading] = useState(false);
const [error, setError] = useState(''); const [error, setError] = useState('');
const [meeting, setMeeting] = useState(null); const [meeting, setMeeting] = useState(null);
@ -90,6 +93,28 @@ const EditMeeting = ({ user }) => {
})); }));
}; };
const handleFileChange = (e) => {
const file = e.target.files[0];
if (file) {
// Check file type - include both MIME types and extensions
const allowedMimeTypes = ['audio/mp3', 'audio/wav', 'audio/m4a', 'audio/mpeg', 'audio/mp4', 'audio/x-m4a'];
const fileExtension = file.name.toLowerCase().split('.').pop();
const allowedExtensions = ['mp3', 'wav', 'm4a', 'mpeg'];
if (!allowedMimeTypes.includes(file.type) && !allowedExtensions.includes(fileExtension)) {
setError('请上传支持的音频格式 (MP3, WAV, M4A)');
return;
}
// Check file size (max 100MB)
if (file.size > 100 * 1024 * 1024) {
setError('音频文件大小不能超过100MB');
return;
}
setAudioFile(file);
setError('');
}
};
const handleSubmit = async (e) => { const handleSubmit = async (e) => {
e.preventDefault(); e.preventDefault();
if (!formData.title.trim()) { if (!formData.title.trim()) {
@ -117,20 +142,44 @@ const EditMeeting = ({ user }) => {
} }
}; };
const handleRegenerateSummary = async () => { const handleUploadAudio = async () => {
setIsRegenerating(true); if (!audioFile) {
setError('请先选择音频文件');
return;
}
setIsUploading(true);
setError(''); setError('');
try { try {
const response = await axios.post(buildApiUrl(API_ENDPOINTS.MEETINGS.REGENERATE_SUMMARY(meeting_id))); // Upload new audio file
const formDataUpload = new FormData();
formDataUpload.append('audio_file', audioFile);
formDataUpload.append('meeting_id', meeting_id);
const response = await axios.post(buildApiUrl(API_ENDPOINTS.MEETINGS.UPLOAD_AUDIO), formDataUpload, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
// Update summary with new AI analysis result
if (response.data.summary) {
setFormData(prev => ({ setFormData(prev => ({
...prev, ...prev,
summary: response.data.summary summary: response.data.summary
})); }));
}
setAudioFile(null);
// Reset file input
const fileInput = document.getElementById('audio-file');
if (fileInput) fileInput.value = '';
} catch (err) { } catch (err) {
setError('重新生成摘要失败,请重试'); setError('上传音频文件失败,请重试');
} finally { } finally {
setIsRegenerating(false); setIsUploading(false);
} }
}; };
@ -225,7 +274,7 @@ const EditMeeting = ({ user }) => {
className="remove-attendee" className="remove-attendee"
title="移除参会人" title="移除参会人"
> >
× <X size={14} />
</button> </button>
</div> </div>
))} ))}
@ -271,33 +320,70 @@ const EditMeeting = ({ user }) => {
</div> </div>
</div> </div>
<div className="form-group">
<label>
<Upload size={18} />
重新上传录音
</label>
<div className="file-upload-container">
<input
type="file"
id="audio-file"
accept="audio/*"
onChange={handleFileChange}
className="file-input"
/>
<label htmlFor="audio-file" className="file-upload-label">
<Plus size={20} />
<span>选择新的音频文件</span>
<small>支持 MP3, WAV, M4A 格式最大100MB</small>
</label>
{audioFile && (
<div className="selected-file">
<span>已选择: {audioFile.name}</span>
<button
type="button"
onClick={() => setAudioFile(null)}
className="remove-file"
>
<X size={16} />
</button>
</div>
)}
{audioFile && (
<button
type="button"
onClick={handleUploadAudio}
className="upload-btn"
disabled={isUploading}
>
<Upload size={16} />
{isUploading ? '上传并分析中...' : '上传并重新分析'}
</button>
)}
</div>
</div>
<div className="form-group"> <div className="form-group">
<div className="summary-header"> <div className="summary-header">
<label htmlFor="summary"> <label htmlFor="summary">
<FileText size={18} /> <FileText size={18} />
会议摘要 会议摘要
</label> </label>
<button
type="button"
onClick={handleRegenerateSummary}
className="regenerate-btn"
disabled={isRegenerating}
>
<Zap size={16} />
{isRegenerating ? 'AI生成中...' : '重新AI解析'}
</button>
</div> </div>
<textarea <div className="markdown-editor-container">
id="summary" <MDEditor
name="summary"
value={formData.summary} value={formData.summary}
onChange={handleInputChange} onChange={(value) => setFormData(prev => ({ ...prev, summary: value || '' }))}
placeholder="会议摘要将显示在这里... 支持Markdown格式" data-color-mode="light"
rows="12" height={400}
className="summary-textarea" preview="edit"
hideToolbar={false}
toolbarBottom={false}
/> />
</div>
<div className="markdown-hint"> <div className="markdown-hint">
<small>支持Markdown格式**粗体** *斜体* # 标题 - 列表</small> <small>使用Markdown格式编写会议摘要支持**粗体***斜体*# 标题- 列表等格式</small>
</div> </div>
</div> </div>

View File

@ -7,6 +7,9 @@
.details-header { .details-header {
max-width: 1400px; max-width: 1400px;
margin: 0 auto 1.5rem auto; margin: 0 auto 1.5rem auto;
display: flex;
justify-content: space-between;
align-items: center;
} }
.details-layout { .details-layout {
@ -104,7 +107,7 @@
/* Markdown content styling */ /* Markdown content styling */
.markdown-content { .markdown-content {
font-size: 1rem; font-size: 1rem;
line-height: 1.7; line-height: 1.6;
} }
.markdown-content h1, .markdown-content h1,
@ -113,11 +116,20 @@
.markdown-content h4, .markdown-content h4,
.markdown-content h5, .markdown-content h5,
.markdown-content h6 { .markdown-content h6 {
margin: 1rem 0 0.5rem 0; margin: 0.8rem 0 0.4rem 0;
font-weight: 600; font-weight: 600;
color: #1e293b; color: #1e293b;
} }
.markdown-content h1:first-child,
.markdown-content h2:first-child,
.markdown-content h3:first-child,
.markdown-content h4:first-child,
.markdown-content h5:first-child,
.markdown-content h6:first-child {
margin-top: 0;
}
.markdown-content h1 { font-size: 1.5rem; } .markdown-content h1 { font-size: 1.5rem; }
.markdown-content h2 { font-size: 1.25rem; } .markdown-content h2 { font-size: 1.25rem; }
.markdown-content h3 { font-size: 1.1rem; } .markdown-content h3 { font-size: 1.1rem; }
@ -126,17 +138,29 @@
.markdown-content h6 { font-size: 1rem; } .markdown-content h6 { font-size: 1rem; }
.markdown-content p { .markdown-content p {
margin: 0.75rem 0; margin: 0.3rem 0;
}
.markdown-content p:first-child {
margin-top: 0;
}
.markdown-content p:last-child {
margin-bottom: 0;
} }
.markdown-content ul, .markdown-content ul,
.markdown-content ol { .markdown-content ol {
margin: 0.75rem 0; margin: 0.4rem 0;
padding-left: 1.5rem; padding-left: 1.5rem;
} }
.markdown-content li { .markdown-content li {
margin: 0.25rem 0; margin: 0.1rem 0;
}
.markdown-content li p {
margin: 0.1rem 0;
} }
.markdown-content strong { .markdown-content strong {
@ -481,6 +505,127 @@
margin: 0; margin: 0;
color: rgba(255, 255, 255, 0.8); color: rgba(255, 255, 255, 0.8);
} }
/* Meeting Actions */
.meeting-actions {
display: flex;
gap: 0.75rem;
align-items: center;
}
.action-btn {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 1rem;
border-radius: 8px;
font-size: 0.9rem;
font-weight: 500;
text-decoration: none;
border: none;
cursor: pointer;
transition: all 0.3s ease;
min-width: 100px;
justify-content: center;
}
.edit-btn {
background: #667eea;
color: white;
box-shadow: 0 2px 4px rgba(102, 126, 234, 0.2);
}
.edit-btn:hover {
background: #5a67d8;
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(102, 126, 234, 0.3);
color: white;
}
.delete-btn {
background: #ef4444;
color: white;
box-shadow: 0 2px 4px rgba(239, 68, 68, 0.2);
}
.delete-btn:hover {
background: #dc2626;
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(239, 68, 68, 0.3);
}
/* Delete Modal */
.delete-modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.delete-modal {
background: white;
border-radius: 12px;
padding: 2rem;
max-width: 400px;
width: 90%;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}
.delete-modal h3 {
margin: 0 0 1rem 0;
color: #1e293b;
font-size: 1.25rem;
}
.delete-modal p {
margin: 0 0 2rem 0;
color: #64748b;
line-height: 1.6;
}
.modal-actions {
display: flex;
gap: 1rem;
justify-content: flex-end;
}
.btn-cancel, .btn-delete {
padding: 0.5rem 1rem;
border-radius: 6px;
font-size: 0.9rem;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
border: none;
}
.btn-cancel {
background: #f1f5f9;
color: #475569;
}
.btn-cancel:hover {
background: #e2e8f0;
}
.btn-delete {
background: #ef4444;
color: white;
}
.btn-delete:hover {
background: #dc2626;
}
/* Responsive Design */
@media (max-width: 1200px) { @media (max-width: 1200px) {
.details-layout { .details-layout {
grid-template-columns: 1fr; grid-template-columns: 1fr;
@ -497,6 +642,27 @@
padding: 1rem; padding: 1rem;
} }
.details-header {
flex-direction: column;
gap: 1rem;
align-items: stretch;
}
.meeting-actions {
justify-content: center;
gap: 0.5rem;
}
.action-btn {
padding: 0.4rem 0.8rem;
font-size: 0.8rem;
min-width: 80px;
}
.action-btn span {
display: none;
}
.player-controls { .player-controls {
flex-wrap: wrap; flex-wrap: wrap;
gap: 0.75rem; gap: 0.75rem;

View File

@ -1,13 +1,17 @@
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import { useParams, Link } from 'react-router-dom'; import { useParams, Link, useNavigate } from 'react-router-dom';
import axios from 'axios'; import axios from 'axios';
import { ArrowLeft, Clock, Users, FileText, User, Calendar, Play, Pause, Volume2, MessageCircle } from 'lucide-react'; import { ArrowLeft, Clock, Users, FileText, User, Calendar, Play, Pause, Volume2, MessageCircle, Edit, Trash2 } from 'lucide-react';
import ReactMarkdown from 'react-markdown'; import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import rehypeRaw from 'rehype-raw';
import rehypeSanitize from 'rehype-sanitize';
import { buildApiUrl, API_ENDPOINTS, API_BASE_URL } from '../config/api'; import { buildApiUrl, API_ENDPOINTS, API_BASE_URL } from '../config/api';
import './MeetingDetails.css'; import './MeetingDetails.css';
const MeetingDetails = () => { const MeetingDetails = ({ user }) => {
const { meeting_id } = useParams(); const { meeting_id } = useParams();
const navigate = useNavigate();
const [meeting, setMeeting] = useState(null); const [meeting, setMeeting] = useState(null);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [error, setError] = useState(''); const [error, setError] = useState('');
@ -19,6 +23,7 @@ const MeetingDetails = () => {
const [showTranscript, setShowTranscript] = useState(true); const [showTranscript, setShowTranscript] = useState(true);
const [audioUrl, setAudioUrl] = useState(null); const [audioUrl, setAudioUrl] = useState(null);
const [audioFileName, setAudioFileName] = useState(null); const [audioFileName, setAudioFileName] = useState(null);
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
const audioRef = useRef(null); const audioRef = useRef(null);
useEffect(() => { useEffect(() => {
@ -147,6 +152,18 @@ const MeetingDetails = () => {
} }
}; };
const handleDeleteMeeting = async () => {
try {
await axios.delete(buildApiUrl(API_ENDPOINTS.MEETINGS.DELETE(meeting_id)));
navigate('/dashboard');
} catch (err) {
console.error('Error deleting meeting:', err);
setError('删除会议失败,请重试');
}
};
const isCreator = meeting && user && String(meeting.creator_id) === String(user.user_id);
if (loading) { if (loading) {
return <div className="loading-container"><div className="loading-spinner"></div><p>加载中...</p></div>; return <div className="loading-container"><div className="loading-spinner"></div><p>加载中...</p></div>;
} }
@ -168,6 +185,21 @@ const MeetingDetails = () => {
<span>返回首页</span> <span>返回首页</span>
</span> </span>
</Link> </Link>
{isCreator && (
<div className="meeting-actions">
<Link to={`/meetings/edit/${meeting_id}`} className="action-btn edit-btn">
<Edit size={16} />
<span>编辑会议</span>
</Link>
<button
className="action-btn delete-btn"
onClick={() => setShowDeleteConfirm(true)}
>
<Trash2 size={16} />
<span>删除会议</span>
</button>
</div>
)}
</div> </div>
<div className="details-layout"> <div className="details-layout">
@ -199,6 +231,18 @@ const MeetingDetails = () => {
</div> </div>
</header> </header>
<section className="card-section">
<h2><Users size={20} /> 参会人员</h2>
<div className="attendees-list">
{meeting.attendees.map((attendee, index) => (
<div key={index} className="attendee-chip">
<User size={16} />
<span>{typeof attendee === 'string' ? attendee : attendee.caption}</span>
</div>
))}
</div>
</section>
{/* Audio Player Section */} {/* Audio Player Section */}
<section className="card-section audio-section"> <section className="card-section audio-section">
<h2><Volume2 size={20} /> 会议录音</h2> <h2><Volume2 size={20} /> 会议录音</h2>
@ -272,24 +316,15 @@ const MeetingDetails = () => {
<h2><FileText size={20} /> 会议摘要</h2> <h2><FileText size={20} /> 会议摘要</h2>
<div className="summary-content"> <div className="summary-content">
<div className="markdown-content"> <div className="markdown-content">
<ReactMarkdown> <ReactMarkdown
remarkPlugins={[remarkGfm]}
rehypePlugins={[rehypeRaw, rehypeSanitize]}
>
{meeting.summary || '暂无摘要信息。'} {meeting.summary || '暂无摘要信息。'}
</ReactMarkdown> </ReactMarkdown>
</div> </div>
</div> </div>
</section> </section>
<section className="card-section">
<h2><Users size={20} /> 参会人员</h2>
<div className="attendees-list">
{meeting.attendees.map((attendee, index) => (
<div key={index} className="attendee-chip">
<User size={16} />
<span>{typeof attendee === 'string' ? attendee : attendee.caption}</span>
</div>
))}
</div>
</section>
</div> </div>
</div> </div>
@ -326,6 +361,30 @@ const MeetingDetails = () => {
)} )}
</div> </div>
</div> </div>
{/* Delete Confirmation Modal */}
{showDeleteConfirm && (
<div className="delete-modal-overlay" onClick={() => setShowDeleteConfirm(false)}>
<div className="delete-modal" onClick={(e) => e.stopPropagation()}>
<h3>确认删除</h3>
<p>确定要删除会议 "{meeting.title}" 此操作无法撤销</p>
<div className="modal-actions">
<button
className="btn-cancel"
onClick={() => setShowDeleteConfirm(false)}
>
取消
</button>
<button
className="btn-delete"
onClick={handleDeleteMeeting}
>
确定删除
</button>
</div>
</div>
</div>
)}
</div> </div>
); );
}; };

648
yarn.lock
View File

@ -138,6 +138,11 @@
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.27.1" "@babel/helper-plugin-utils" "^7.27.1"
"@babel/runtime@^7.14.6", "@babel/runtime@^7.17.2":
version "7.28.2"
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.28.2.tgz"
integrity sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==
"@babel/template@^7.27.2": "@babel/template@^7.27.2":
version "7.27.2" version "7.27.2"
resolved "https://registry.npmmirror.com/@babel/template/-/template-7.27.2.tgz" resolved "https://registry.npmmirror.com/@babel/template/-/template-7.27.2.tgz"
@ -355,6 +360,13 @@
resolved "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz" resolved "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz"
integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==
"@types/hast@^2.0.0":
version "2.3.10"
resolved "https://registry.npmmirror.com/@types/hast/-/hast-2.3.10.tgz"
integrity sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==
dependencies:
"@types/unist" "^2"
"@types/hast@^3.0.0": "@types/hast@^3.0.0":
version "3.0.4" version "3.0.4"
resolved "https://registry.npmmirror.com/@types/hast/-/hast-3.0.4.tgz" resolved "https://registry.npmmirror.com/@types/hast/-/hast-3.0.4.tgz"
@ -379,6 +391,11 @@
resolved "https://registry.npmmirror.com/@types/ms/-/ms-2.1.0.tgz" resolved "https://registry.npmmirror.com/@types/ms/-/ms-2.1.0.tgz"
integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==
"@types/prismjs@^1.0.0":
version "1.26.5"
resolved "https://registry.npmmirror.com/@types/prismjs/-/prismjs-1.26.5.tgz"
integrity sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==
"@types/react-dom@^19.1.6": "@types/react-dom@^19.1.6":
version "19.1.6" version "19.1.6"
resolved "https://registry.npmmirror.com/@types/react-dom/-/react-dom-19.1.6.tgz" resolved "https://registry.npmmirror.com/@types/react-dom/-/react-dom-19.1.6.tgz"
@ -396,11 +413,50 @@
resolved "https://registry.npmmirror.com/@types/unist/-/unist-3.0.3.tgz" resolved "https://registry.npmmirror.com/@types/unist/-/unist-3.0.3.tgz"
integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q== integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==
"@types/unist@^2":
version "2.0.11"
resolved "https://registry.npmmirror.com/@types/unist/-/unist-2.0.11.tgz"
integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==
"@types/unist@^2.0.0": "@types/unist@^2.0.0":
version "2.0.11" version "2.0.11"
resolved "https://registry.npmmirror.com/@types/unist/-/unist-2.0.11.tgz" resolved "https://registry.npmmirror.com/@types/unist/-/unist-2.0.11.tgz"
integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA== integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==
"@uiw/copy-to-clipboard@~1.0.12":
version "1.0.17"
resolved "https://registry.npmmirror.com/@uiw/copy-to-clipboard/-/copy-to-clipboard-1.0.17.tgz"
integrity sha512-O2GUHV90Iw2VrSLVLK0OmNIMdZ5fgEg4NhvtwINsX+eZ/Wf6DWD0TdsK9xwV7dNRnK/UI2mQtl0a2/kRgm1m1A==
"@uiw/react-markdown-preview@^5.0.6":
version "5.1.5"
resolved "https://registry.npmmirror.com/@uiw/react-markdown-preview/-/react-markdown-preview-5.1.5.tgz"
integrity sha512-DNOqx1a6gJR7Btt57zpGEKTfHRlb7rWbtctMRO2f82wWcuoJsxPBrM+JWebDdOD0LfD8oe2CQvW2ICQJKHQhZg==
dependencies:
"@babel/runtime" "^7.17.2"
"@uiw/copy-to-clipboard" "~1.0.12"
react-markdown "~9.0.1"
rehype-attr "~3.0.1"
rehype-autolink-headings "~7.1.0"
rehype-ignore "^2.0.0"
rehype-prism-plus "2.0.0"
rehype-raw "^7.0.0"
rehype-rewrite "~4.0.0"
rehype-slug "~6.0.0"
remark-gfm "~4.0.0"
remark-github-blockquote-alert "^1.0.0"
unist-util-visit "^5.0.0"
"@uiw/react-md-editor@^4.0.8":
version "4.0.8"
resolved "https://registry.npmmirror.com/@uiw/react-md-editor/-/react-md-editor-4.0.8.tgz"
integrity sha512-S3mOzZeGmJNhzdXJxRTCwsFMDp8nBWeQUf59cK3L6QHzDUHnRoHpcmWpfVRyKGKSg8zaI2+meU5cYWf8kYn3mQ==
dependencies:
"@babel/runtime" "^7.14.6"
"@uiw/react-markdown-preview" "^5.0.6"
rehype "~13.0.0"
rehype-prism-plus "~2.0.0"
"@ungap/structured-clone@^1.0.0": "@ungap/structured-clone@^1.0.0":
version "1.3.0" version "1.3.0"
resolved "https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz" resolved "https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz"
@ -474,6 +530,16 @@ balanced-match@^1.0.0:
resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz" resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
bcp-47-match@^2.0.0:
version "2.0.3"
resolved "https://registry.npmmirror.com/bcp-47-match/-/bcp-47-match-2.0.3.tgz"
integrity sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==
boolbase@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz"
integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
brace-expansion@^1.1.7: brace-expansion@^1.1.7:
version "1.1.12" version "1.1.12"
resolved "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz" resolved "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz"
@ -591,6 +657,11 @@ cross-spawn@^7.0.6:
shebang-command "^2.0.0" shebang-command "^2.0.0"
which "^2.0.1" which "^2.0.1"
css-selector-parser@^3.0.0:
version "3.1.3"
resolved "https://registry.npmmirror.com/css-selector-parser/-/css-selector-parser-3.1.3.tgz"
integrity sha512-gJMigczVZqYAk0hPVzx/M4Hm1D9QOtqkdQk9005TNzDIUGzo5cnHEDiKUT7jGPximL/oYb+LIitcHFQ4aKupxg==
csstype@^3.0.2: csstype@^3.0.2:
version "3.1.3" version "3.1.3"
resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz" resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz"
@ -632,6 +703,11 @@ devlop@^1.0.0, devlop@^1.1.0:
dependencies: dependencies:
dequal "^2.0.0" dequal "^2.0.0"
direction@^2.0.0:
version "2.0.1"
resolved "https://registry.npmmirror.com/direction/-/direction-2.0.1.tgz"
integrity sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==
dunder-proto@^1.0.1: dunder-proto@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz" resolved "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz"
@ -646,6 +722,11 @@ electron-to-chromium@^1.5.173:
resolved "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.192.tgz" resolved "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.192.tgz"
integrity sha512-rP8Ez0w7UNw/9j5eSXCe10o1g/8B1P5SM90PCCMVkIRQn2R0LEHWz4Eh9RnxkniuDe1W0cTSOB3MLlkTGDcuCg== integrity sha512-rP8Ez0w7UNw/9j5eSXCe10o1g/8B1P5SM90PCCMVkIRQn2R0LEHWz4Eh9RnxkniuDe1W0cTSOB3MLlkTGDcuCg==
entities@^6.0.0:
version "6.0.1"
resolved "https://registry.npmmirror.com/entities/-/entities-6.0.1.tgz"
integrity sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==
es-define-property@^1.0.1: es-define-property@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz" resolved "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz"
@ -715,6 +796,11 @@ escape-string-regexp@^4.0.0:
resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
escape-string-regexp@^5.0.0:
version "5.0.0"
resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz"
integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==
eslint-plugin-react-hooks@^5.2.0: eslint-plugin-react-hooks@^5.2.0:
version "5.2.0" version "5.2.0"
resolved "https://registry.npmmirror.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz" resolved "https://registry.npmmirror.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz"
@ -930,6 +1016,11 @@ get-proto@^1.0.1:
dunder-proto "^1.0.1" dunder-proto "^1.0.1"
es-object-atoms "^1.0.0" es-object-atoms "^1.0.0"
github-slugger@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/github-slugger/-/github-slugger-2.0.0.tgz"
integrity sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==
glob-parent@^6.0.2: glob-parent@^6.0.2:
version "6.0.2" version "6.0.2"
resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz" resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz"
@ -976,6 +1067,133 @@ hasown@^2.0.2:
dependencies: dependencies:
function-bind "^1.1.2" function-bind "^1.1.2"
hast-util-from-html@^2.0.0:
version "2.0.3"
resolved "https://registry.npmmirror.com/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz"
integrity sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==
dependencies:
"@types/hast" "^3.0.0"
devlop "^1.1.0"
hast-util-from-parse5 "^8.0.0"
parse5 "^7.0.0"
vfile "^6.0.0"
vfile-message "^4.0.0"
hast-util-from-parse5@^8.0.0:
version "8.0.3"
resolved "https://registry.npmmirror.com/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz"
integrity sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==
dependencies:
"@types/hast" "^3.0.0"
"@types/unist" "^3.0.0"
devlop "^1.0.0"
hastscript "^9.0.0"
property-information "^7.0.0"
vfile "^6.0.0"
vfile-location "^5.0.0"
web-namespaces "^2.0.0"
hast-util-has-property@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/hast-util-has-property/-/hast-util-has-property-3.0.0.tgz"
integrity sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==
dependencies:
"@types/hast" "^3.0.0"
hast-util-heading-rank@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz"
integrity sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==
dependencies:
"@types/hast" "^3.0.0"
hast-util-is-element@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz"
integrity sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==
dependencies:
"@types/hast" "^3.0.0"
hast-util-parse-selector@^3.0.0:
version "3.1.1"
resolved "https://registry.npmmirror.com/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz"
integrity sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==
dependencies:
"@types/hast" "^2.0.0"
hast-util-parse-selector@^4.0.0:
version "4.0.0"
resolved "https://registry.npmmirror.com/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz"
integrity sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==
dependencies:
"@types/hast" "^3.0.0"
hast-util-raw@^9.0.0:
version "9.1.0"
resolved "https://registry.npmmirror.com/hast-util-raw/-/hast-util-raw-9.1.0.tgz"
integrity sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==
dependencies:
"@types/hast" "^3.0.0"
"@types/unist" "^3.0.0"
"@ungap/structured-clone" "^1.0.0"
hast-util-from-parse5 "^8.0.0"
hast-util-to-parse5 "^8.0.0"
html-void-elements "^3.0.0"
mdast-util-to-hast "^13.0.0"
parse5 "^7.0.0"
unist-util-position "^5.0.0"
unist-util-visit "^5.0.0"
vfile "^6.0.0"
web-namespaces "^2.0.0"
zwitch "^2.0.0"
hast-util-sanitize@^5.0.0:
version "5.0.2"
resolved "https://registry.npmmirror.com/hast-util-sanitize/-/hast-util-sanitize-5.0.2.tgz"
integrity sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==
dependencies:
"@types/hast" "^3.0.0"
"@ungap/structured-clone" "^1.0.0"
unist-util-position "^5.0.0"
hast-util-select@^6.0.0:
version "6.0.4"
resolved "https://registry.npmmirror.com/hast-util-select/-/hast-util-select-6.0.4.tgz"
integrity sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==
dependencies:
"@types/hast" "^3.0.0"
"@types/unist" "^3.0.0"
bcp-47-match "^2.0.0"
comma-separated-tokens "^2.0.0"
css-selector-parser "^3.0.0"
devlop "^1.0.0"
direction "^2.0.0"
hast-util-has-property "^3.0.0"
hast-util-to-string "^3.0.0"
hast-util-whitespace "^3.0.0"
nth-check "^2.0.0"
property-information "^7.0.0"
space-separated-tokens "^2.0.0"
unist-util-visit "^5.0.0"
zwitch "^2.0.0"
hast-util-to-html@^9.0.0:
version "9.0.5"
resolved "https://registry.npmmirror.com/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz"
integrity sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==
dependencies:
"@types/hast" "^3.0.0"
"@types/unist" "^3.0.0"
ccount "^2.0.0"
comma-separated-tokens "^2.0.0"
hast-util-whitespace "^3.0.0"
html-void-elements "^3.0.0"
mdast-util-to-hast "^13.0.0"
property-information "^7.0.0"
space-separated-tokens "^2.0.0"
stringify-entities "^4.0.0"
zwitch "^2.0.4"
hast-util-to-jsx-runtime@^2.0.0: hast-util-to-jsx-runtime@^2.0.0:
version "2.3.6" version "2.3.6"
resolved "https://registry.npmmirror.com/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz" resolved "https://registry.npmmirror.com/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz"
@ -997,6 +1215,26 @@ hast-util-to-jsx-runtime@^2.0.0:
unist-util-position "^5.0.0" unist-util-position "^5.0.0"
vfile-message "^4.0.0" vfile-message "^4.0.0"
hast-util-to-parse5@^8.0.0:
version "8.0.0"
resolved "https://registry.npmmirror.com/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz"
integrity sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==
dependencies:
"@types/hast" "^3.0.0"
comma-separated-tokens "^2.0.0"
devlop "^1.0.0"
property-information "^6.0.0"
space-separated-tokens "^2.0.0"
web-namespaces "^2.0.0"
zwitch "^2.0.0"
hast-util-to-string@^3.0.0:
version "3.0.1"
resolved "https://registry.npmmirror.com/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz"
integrity sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==
dependencies:
"@types/hast" "^3.0.0"
hast-util-whitespace@^3.0.0: hast-util-whitespace@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.npmmirror.com/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz" resolved "https://registry.npmmirror.com/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz"
@ -1004,11 +1242,38 @@ hast-util-whitespace@^3.0.0:
dependencies: dependencies:
"@types/hast" "^3.0.0" "@types/hast" "^3.0.0"
hastscript@^7.0.0:
version "7.2.0"
resolved "https://registry.npmmirror.com/hastscript/-/hastscript-7.2.0.tgz"
integrity sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==
dependencies:
"@types/hast" "^2.0.0"
comma-separated-tokens "^2.0.0"
hast-util-parse-selector "^3.0.0"
property-information "^6.0.0"
space-separated-tokens "^2.0.0"
hastscript@^9.0.0:
version "9.0.1"
resolved "https://registry.npmmirror.com/hastscript/-/hastscript-9.0.1.tgz"
integrity sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==
dependencies:
"@types/hast" "^3.0.0"
comma-separated-tokens "^2.0.0"
hast-util-parse-selector "^4.0.0"
property-information "^7.0.0"
space-separated-tokens "^2.0.0"
html-url-attributes@^3.0.0: html-url-attributes@^3.0.0:
version "3.0.1" version "3.0.1"
resolved "https://registry.npmmirror.com/html-url-attributes/-/html-url-attributes-3.0.1.tgz" resolved "https://registry.npmmirror.com/html-url-attributes/-/html-url-attributes-3.0.1.tgz"
integrity sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ== integrity sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==
html-void-elements@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/html-void-elements/-/html-void-elements-3.0.0.tgz"
integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==
ignore@^5.2.0: ignore@^5.2.0:
version "5.3.2" version "5.3.2"
resolved "https://registry.npmmirror.com/ignore/-/ignore-5.3.2.tgz" resolved "https://registry.npmmirror.com/ignore/-/ignore-5.3.2.tgz"
@ -1158,11 +1423,26 @@ lucide-react@^0.294.0:
resolved "https://registry.npmmirror.com/lucide-react/-/lucide-react-0.294.0.tgz" resolved "https://registry.npmmirror.com/lucide-react/-/lucide-react-0.294.0.tgz"
integrity sha512-V7o0/VECSGbLHn3/1O67FUgBwWB+hmzshrgDVRJQhMh8uj5D3HBuIvhuAmQTtlupILSplwIZg5FTc4tTKMA2SA== integrity sha512-V7o0/VECSGbLHn3/1O67FUgBwWB+hmzshrgDVRJQhMh8uj5D3HBuIvhuAmQTtlupILSplwIZg5FTc4tTKMA2SA==
markdown-table@^3.0.0:
version "3.0.4"
resolved "https://registry.npmmirror.com/markdown-table/-/markdown-table-3.0.4.tgz"
integrity sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==
math-intrinsics@^1.1.0: math-intrinsics@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz" resolved "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz"
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
mdast-util-find-and-replace@^3.0.0:
version "3.0.2"
resolved "https://registry.npmmirror.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz"
integrity sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==
dependencies:
"@types/mdast" "^4.0.0"
escape-string-regexp "^5.0.0"
unist-util-is "^6.0.0"
unist-util-visit-parents "^6.0.0"
mdast-util-from-markdown@^2.0.0: mdast-util-from-markdown@^2.0.0:
version "2.0.2" version "2.0.2"
resolved "https://registry.npmmirror.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz" resolved "https://registry.npmmirror.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz"
@ -1181,6 +1461,71 @@ mdast-util-from-markdown@^2.0.0:
micromark-util-types "^2.0.0" micromark-util-types "^2.0.0"
unist-util-stringify-position "^4.0.0" unist-util-stringify-position "^4.0.0"
mdast-util-gfm-autolink-literal@^2.0.0:
version "2.0.1"
resolved "https://registry.npmmirror.com/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz"
integrity sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==
dependencies:
"@types/mdast" "^4.0.0"
ccount "^2.0.0"
devlop "^1.0.0"
mdast-util-find-and-replace "^3.0.0"
micromark-util-character "^2.0.0"
mdast-util-gfm-footnote@^2.0.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz"
integrity sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==
dependencies:
"@types/mdast" "^4.0.0"
devlop "^1.1.0"
mdast-util-from-markdown "^2.0.0"
mdast-util-to-markdown "^2.0.0"
micromark-util-normalize-identifier "^2.0.0"
mdast-util-gfm-strikethrough@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz"
integrity sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==
dependencies:
"@types/mdast" "^4.0.0"
mdast-util-from-markdown "^2.0.0"
mdast-util-to-markdown "^2.0.0"
mdast-util-gfm-table@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz"
integrity sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==
dependencies:
"@types/mdast" "^4.0.0"
devlop "^1.0.0"
markdown-table "^3.0.0"
mdast-util-from-markdown "^2.0.0"
mdast-util-to-markdown "^2.0.0"
mdast-util-gfm-task-list-item@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz"
integrity sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==
dependencies:
"@types/mdast" "^4.0.0"
devlop "^1.0.0"
mdast-util-from-markdown "^2.0.0"
mdast-util-to-markdown "^2.0.0"
mdast-util-gfm@^3.0.0:
version "3.1.0"
resolved "https://registry.npmmirror.com/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz"
integrity sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==
dependencies:
mdast-util-from-markdown "^2.0.0"
mdast-util-gfm-autolink-literal "^2.0.0"
mdast-util-gfm-footnote "^2.0.0"
mdast-util-gfm-strikethrough "^2.0.0"
mdast-util-gfm-table "^2.0.0"
mdast-util-gfm-task-list-item "^2.0.0"
mdast-util-to-markdown "^2.0.0"
mdast-util-mdx-expression@^2.0.0: mdast-util-mdx-expression@^2.0.0:
version "2.0.1" version "2.0.1"
resolved "https://registry.npmmirror.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz" resolved "https://registry.npmmirror.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz"
@ -1290,6 +1635,85 @@ micromark-core-commonmark@^2.0.0:
micromark-util-symbol "^2.0.0" micromark-util-symbol "^2.0.0"
micromark-util-types "^2.0.0" micromark-util-types "^2.0.0"
micromark-extension-gfm-autolink-literal@^2.0.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz"
integrity sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==
dependencies:
micromark-util-character "^2.0.0"
micromark-util-sanitize-uri "^2.0.0"
micromark-util-symbol "^2.0.0"
micromark-util-types "^2.0.0"
micromark-extension-gfm-footnote@^2.0.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz"
integrity sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==
dependencies:
devlop "^1.0.0"
micromark-core-commonmark "^2.0.0"
micromark-factory-space "^2.0.0"
micromark-util-character "^2.0.0"
micromark-util-normalize-identifier "^2.0.0"
micromark-util-sanitize-uri "^2.0.0"
micromark-util-symbol "^2.0.0"
micromark-util-types "^2.0.0"
micromark-extension-gfm-strikethrough@^2.0.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz"
integrity sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==
dependencies:
devlop "^1.0.0"
micromark-util-chunked "^2.0.0"
micromark-util-classify-character "^2.0.0"
micromark-util-resolve-all "^2.0.0"
micromark-util-symbol "^2.0.0"
micromark-util-types "^2.0.0"
micromark-extension-gfm-table@^2.0.0:
version "2.1.1"
resolved "https://registry.npmmirror.com/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz"
integrity sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==
dependencies:
devlop "^1.0.0"
micromark-factory-space "^2.0.0"
micromark-util-character "^2.0.0"
micromark-util-symbol "^2.0.0"
micromark-util-types "^2.0.0"
micromark-extension-gfm-tagfilter@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz"
integrity sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==
dependencies:
micromark-util-types "^2.0.0"
micromark-extension-gfm-task-list-item@^2.0.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz"
integrity sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==
dependencies:
devlop "^1.0.0"
micromark-factory-space "^2.0.0"
micromark-util-character "^2.0.0"
micromark-util-symbol "^2.0.0"
micromark-util-types "^2.0.0"
micromark-extension-gfm@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz"
integrity sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==
dependencies:
micromark-extension-gfm-autolink-literal "^2.0.0"
micromark-extension-gfm-footnote "^2.0.0"
micromark-extension-gfm-strikethrough "^2.0.0"
micromark-extension-gfm-table "^2.0.0"
micromark-extension-gfm-tagfilter "^2.0.0"
micromark-extension-gfm-task-list-item "^2.0.0"
micromark-util-combine-extensions "^2.0.0"
micromark-util-types "^2.0.0"
micromark-factory-destination@^2.0.0: micromark-factory-destination@^2.0.0:
version "2.0.1" version "2.0.1"
resolved "https://registry.npmmirror.com/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz" resolved "https://registry.npmmirror.com/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz"
@ -1501,6 +1925,13 @@ node-releases@^2.0.19:
resolved "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.19.tgz" resolved "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.19.tgz"
integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==
nth-check@^2.0.0:
version "2.1.1"
resolved "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz"
integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==
dependencies:
boolbase "^1.0.0"
optionator@^0.9.3: optionator@^0.9.3:
version "0.9.4" version "0.9.4"
resolved "https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz" resolved "https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz"
@ -1547,6 +1978,18 @@ parse-entities@^4.0.0:
is-decimal "^2.0.0" is-decimal "^2.0.0"
is-hexadecimal "^2.0.0" is-hexadecimal "^2.0.0"
parse-numeric-range@^1.3.0:
version "1.3.0"
resolved "https://registry.npmmirror.com/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz"
integrity sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==
parse5@^7.0.0:
version "7.3.0"
resolved "https://registry.npmmirror.com/parse5/-/parse5-7.3.0.tgz"
integrity sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==
dependencies:
entities "^6.0.0"
path-exists@^4.0.0: path-exists@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz" resolved "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz"
@ -1581,6 +2024,11 @@ prelude-ls@^1.2.1:
resolved "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz" resolved "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz"
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
property-information@^6.0.0:
version "6.5.0"
resolved "https://registry.npmmirror.com/property-information/-/property-information-6.5.0.tgz"
integrity sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==
property-information@^7.0.0: property-information@^7.0.0:
version "7.1.0" version "7.1.0"
resolved "https://registry.npmmirror.com/property-information/-/property-information-7.1.0.tgz" resolved "https://registry.npmmirror.com/property-information/-/property-information-7.1.0.tgz"
@ -1620,6 +2068,22 @@ react-markdown@^10.1.0:
unist-util-visit "^5.0.0" unist-util-visit "^5.0.0"
vfile "^6.0.0" vfile "^6.0.0"
react-markdown@~9.0.1:
version "9.0.3"
resolved "https://registry.npmmirror.com/react-markdown/-/react-markdown-9.0.3.tgz"
integrity sha512-Yk7Z94dbgYTOrdk41Z74GoKA7rThnsbbqBTRYuxoe08qvfQ9tJVhmAKw6BJS/ZORG7kTy/s1QvYzSuaoBA1qfw==
dependencies:
"@types/hast" "^3.0.0"
devlop "^1.0.0"
hast-util-to-jsx-runtime "^2.0.0"
html-url-attributes "^3.0.0"
mdast-util-to-hast "^13.0.0"
remark-parse "^11.0.0"
remark-rehype "^11.0.0"
unified "^11.0.0"
unist-util-visit "^5.0.0"
vfile "^6.0.0"
react-refresh@^0.17.0: react-refresh@^0.17.0:
version "0.17.0" version "0.17.0"
resolved "https://registry.npmmirror.com/react-refresh/-/react-refresh-0.17.0.tgz" resolved "https://registry.npmmirror.com/react-refresh/-/react-refresh-0.17.0.tgz"
@ -1645,6 +2109,153 @@ react@^19.1.0:
resolved "https://registry.npmmirror.com/react/-/react-19.1.1.tgz" resolved "https://registry.npmmirror.com/react/-/react-19.1.1.tgz"
integrity sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ== integrity sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==
refractor@^4.8.0:
version "4.9.0"
resolved "https://registry.npmmirror.com/refractor/-/refractor-4.9.0.tgz"
integrity sha512-nEG1SPXFoGGx+dcjftjv8cAjEusIh6ED1xhf5DG3C0x/k+rmZ2duKnc3QLpt6qeHv5fPb8uwN3VWN2BT7fr3Og==
dependencies:
"@types/hast" "^2.0.0"
"@types/prismjs" "^1.0.0"
hastscript "^7.0.0"
parse-entities "^4.0.0"
rehype-attr@~3.0.1:
version "3.0.3"
resolved "https://registry.npmmirror.com/rehype-attr/-/rehype-attr-3.0.3.tgz"
integrity sha512-Up50Xfra8tyxnkJdCzLBIBtxOcB2M1xdeKe1324U06RAvSjYm7ULSeoM+b/nYPQPVd7jsXJ9+39IG1WAJPXONw==
dependencies:
unified "~11.0.0"
unist-util-visit "~5.0.0"
rehype-autolink-headings@~7.1.0:
version "7.1.0"
resolved "https://registry.npmmirror.com/rehype-autolink-headings/-/rehype-autolink-headings-7.1.0.tgz"
integrity sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==
dependencies:
"@types/hast" "^3.0.0"
"@ungap/structured-clone" "^1.0.0"
hast-util-heading-rank "^3.0.0"
hast-util-is-element "^3.0.0"
unified "^11.0.0"
unist-util-visit "^5.0.0"
rehype-ignore@^2.0.0:
version "2.0.2"
resolved "https://registry.npmmirror.com/rehype-ignore/-/rehype-ignore-2.0.2.tgz"
integrity sha512-BpAT/3lU9DMJ2siYVD/dSR0A/zQgD6Fb+fxkJd4j+wDVy6TYbYpK+FZqu8eM9EuNKGvi4BJR7XTZ/+zF02Dq8w==
dependencies:
hast-util-select "^6.0.0"
unified "^11.0.0"
unist-util-visit "^5.0.0"
rehype-parse@^9.0.0:
version "9.0.1"
resolved "https://registry.npmmirror.com/rehype-parse/-/rehype-parse-9.0.1.tgz"
integrity sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==
dependencies:
"@types/hast" "^3.0.0"
hast-util-from-html "^2.0.0"
unified "^11.0.0"
rehype-prism-plus@~2.0.0:
version "2.0.1"
resolved "https://registry.npmmirror.com/rehype-prism-plus/-/rehype-prism-plus-2.0.1.tgz"
integrity sha512-Wglct0OW12tksTUseAPyWPo3srjBOY7xKlql/DPKi7HbsdZTyaLCAoO58QBKSczFQxElTsQlOY3JDOFzB/K++Q==
dependencies:
hast-util-to-string "^3.0.0"
parse-numeric-range "^1.3.0"
refractor "^4.8.0"
rehype-parse "^9.0.0"
unist-util-filter "^5.0.0"
unist-util-visit "^5.0.0"
rehype-prism-plus@2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/rehype-prism-plus/-/rehype-prism-plus-2.0.0.tgz"
integrity sha512-FeM/9V2N7EvDZVdR2dqhAzlw5YI49m9Tgn7ZrYJeYHIahM6gcXpH0K1y2gNnKanZCydOMluJvX2cB9z3lhY8XQ==
dependencies:
hast-util-to-string "^3.0.0"
parse-numeric-range "^1.3.0"
refractor "^4.8.0"
rehype-parse "^9.0.0"
unist-util-filter "^5.0.0"
unist-util-visit "^5.0.0"
rehype-raw@^7.0.0:
version "7.0.0"
resolved "https://registry.npmmirror.com/rehype-raw/-/rehype-raw-7.0.0.tgz"
integrity sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==
dependencies:
"@types/hast" "^3.0.0"
hast-util-raw "^9.0.0"
vfile "^6.0.0"
rehype-rewrite@~4.0.0:
version "4.0.2"
resolved "https://registry.npmmirror.com/rehype-rewrite/-/rehype-rewrite-4.0.2.tgz"
integrity sha512-rjLJ3z6fIV11phwCqHp/KRo8xuUCO8o9bFJCNw5o6O2wlLk6g8r323aRswdGBQwfXPFYeSuZdAjp4tzo6RGqEg==
dependencies:
hast-util-select "^6.0.0"
unified "^11.0.3"
unist-util-visit "^5.0.0"
rehype-sanitize@^6.0.0:
version "6.0.0"
resolved "https://registry.npmmirror.com/rehype-sanitize/-/rehype-sanitize-6.0.0.tgz"
integrity sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==
dependencies:
"@types/hast" "^3.0.0"
hast-util-sanitize "^5.0.0"
rehype-slug@~6.0.0:
version "6.0.0"
resolved "https://registry.npmmirror.com/rehype-slug/-/rehype-slug-6.0.0.tgz"
integrity sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==
dependencies:
"@types/hast" "^3.0.0"
github-slugger "^2.0.0"
hast-util-heading-rank "^3.0.0"
hast-util-to-string "^3.0.0"
unist-util-visit "^5.0.0"
rehype-stringify@^10.0.0:
version "10.0.1"
resolved "https://registry.npmmirror.com/rehype-stringify/-/rehype-stringify-10.0.1.tgz"
integrity sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==
dependencies:
"@types/hast" "^3.0.0"
hast-util-to-html "^9.0.0"
unified "^11.0.0"
rehype@~13.0.0:
version "13.0.2"
resolved "https://registry.npmmirror.com/rehype/-/rehype-13.0.2.tgz"
integrity sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==
dependencies:
"@types/hast" "^3.0.0"
rehype-parse "^9.0.0"
rehype-stringify "^10.0.0"
unified "^11.0.0"
remark-gfm@^4.0.1, remark-gfm@~4.0.0:
version "4.0.1"
resolved "https://registry.npmmirror.com/remark-gfm/-/remark-gfm-4.0.1.tgz"
integrity sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==
dependencies:
"@types/mdast" "^4.0.0"
mdast-util-gfm "^3.0.0"
micromark-extension-gfm "^3.0.0"
remark-parse "^11.0.0"
remark-stringify "^11.0.0"
unified "^11.0.0"
remark-github-blockquote-alert@^1.0.0:
version "1.3.1"
resolved "https://registry.npmmirror.com/remark-github-blockquote-alert/-/remark-github-blockquote-alert-1.3.1.tgz"
integrity sha512-OPNnimcKeozWN1w8KVQEuHOxgN3L4rah8geMOLhA5vN9wITqU4FWD+G26tkEsCGHiOVDbISx+Se5rGZ+D1p0Jg==
dependencies:
unist-util-visit "^5.0.0"
remark-parse@^11.0.0: remark-parse@^11.0.0:
version "11.0.0" version "11.0.0"
resolved "https://registry.npmmirror.com/remark-parse/-/remark-parse-11.0.0.tgz" resolved "https://registry.npmmirror.com/remark-parse/-/remark-parse-11.0.0.tgz"
@ -1666,6 +2277,15 @@ remark-rehype@^11.0.0:
unified "^11.0.0" unified "^11.0.0"
vfile "^6.0.0" vfile "^6.0.0"
remark-stringify@^11.0.0:
version "11.0.0"
resolved "https://registry.npmmirror.com/remark-stringify/-/remark-stringify-11.0.0.tgz"
integrity sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==
dependencies:
"@types/mdast" "^4.0.0"
mdast-util-to-markdown "^2.0.0"
unified "^11.0.0"
resolve-from@^4.0.0: resolve-from@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz" resolved "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz"
@ -1796,7 +2416,7 @@ type-check@^0.4.0, type-check@~0.4.0:
dependencies: dependencies:
prelude-ls "^1.2.1" prelude-ls "^1.2.1"
unified@^11.0.0: unified@^11.0.0, unified@^11.0.3, unified@~11.0.0:
version "11.0.5" version "11.0.5"
resolved "https://registry.npmmirror.com/unified/-/unified-11.0.5.tgz" resolved "https://registry.npmmirror.com/unified/-/unified-11.0.5.tgz"
integrity sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA== integrity sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==
@ -1809,6 +2429,15 @@ unified@^11.0.0:
trough "^2.0.0" trough "^2.0.0"
vfile "^6.0.0" vfile "^6.0.0"
unist-util-filter@^5.0.0:
version "5.0.1"
resolved "https://registry.npmmirror.com/unist-util-filter/-/unist-util-filter-5.0.1.tgz"
integrity sha512-pHx7D4Zt6+TsfwylH9+lYhBhzyhEnCXs/lbq/Hstxno5z4gVdyc2WEW0asfjGKPyG4pEKrnBv5hdkO6+aRnQJw==
dependencies:
"@types/unist" "^3.0.0"
unist-util-is "^6.0.0"
unist-util-visit-parents "^6.0.0"
unist-util-is@^6.0.0: unist-util-is@^6.0.0:
version "6.0.0" version "6.0.0"
resolved "https://registry.npmmirror.com/unist-util-is/-/unist-util-is-6.0.0.tgz" resolved "https://registry.npmmirror.com/unist-util-is/-/unist-util-is-6.0.0.tgz"
@ -1838,7 +2467,7 @@ unist-util-visit-parents@^6.0.0:
"@types/unist" "^3.0.0" "@types/unist" "^3.0.0"
unist-util-is "^6.0.0" unist-util-is "^6.0.0"
unist-util-visit@^5.0.0: unist-util-visit@^5.0.0, unist-util-visit@~5.0.0:
version "5.0.0" version "5.0.0"
resolved "https://registry.npmmirror.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz" resolved "https://registry.npmmirror.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz"
integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==
@ -1862,6 +2491,14 @@ uri-js@^4.2.2:
dependencies: dependencies:
punycode "^2.1.0" punycode "^2.1.0"
vfile-location@^5.0.0:
version "5.0.3"
resolved "https://registry.npmmirror.com/vfile-location/-/vfile-location-5.0.3.tgz"
integrity sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==
dependencies:
"@types/unist" "^3.0.0"
vfile "^6.0.0"
vfile-message@^4.0.0: vfile-message@^4.0.0:
version "4.0.3" version "4.0.3"
resolved "https://registry.npmmirror.com/vfile-message/-/vfile-message-4.0.3.tgz" resolved "https://registry.npmmirror.com/vfile-message/-/vfile-message-4.0.3.tgz"
@ -1892,6 +2529,11 @@ vite@^7.0.4:
optionalDependencies: optionalDependencies:
fsevents "~2.3.3" fsevents "~2.3.3"
web-namespaces@^2.0.0:
version "2.0.1"
resolved "https://registry.npmmirror.com/web-namespaces/-/web-namespaces-2.0.1.tgz"
integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==
which@^2.0.1: which@^2.0.1:
version "2.0.2" version "2.0.2"
resolved "https://registry.npmmirror.com/which/-/which-2.0.2.tgz" resolved "https://registry.npmmirror.com/which/-/which-2.0.2.tgz"
@ -1914,7 +2556,7 @@ yocto-queue@^0.1.0:
resolved "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz" resolved "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
zwitch@^2.0.0: zwitch@^2.0.0, zwitch@^2.0.4:
version "2.0.4" version "2.0.4"
resolved "https://registry.npmmirror.com/zwitch/-/zwitch-2.0.4.tgz" resolved "https://registry.npmmirror.com/zwitch/-/zwitch-2.0.4.tgz"
integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==