项目上传
This commit is contained in:
parent
ed6893a09a
commit
06835b2bf1
17
index.html
Normal file
17
index.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
||||
<meta name="theme-color" content="#007AFF" />
|
||||
<title>在线学习对话</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
44
nginx-localhost.conf
Normal file
44
nginx-localhost.conf
Normal file
@ -0,0 +1,44 @@
|
||||
server {
|
||||
listen 9010;
|
||||
server_name localhost 127.0.0.1 14.103.170.252;
|
||||
|
||||
# 火山引擎API代理
|
||||
location /api/volcengine/ {
|
||||
proxy_pass https://openspeech.bytedance.com/api/v1/auc/;
|
||||
proxy_set_header Host openspeech.bytedance.com;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# 处理CORS
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
|
||||
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||
|
||||
# 处理OPTIONS预检请求
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
|
||||
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
|
||||
add_header Access-Control-Max-Age 1728000;
|
||||
add_header Content-Type 'text/plain; charset=utf-8';
|
||||
add_header Content-Length 0;
|
||||
return 204;
|
||||
}
|
||||
|
||||
# 超时设置
|
||||
proxy_connect_timeout 30s;
|
||||
proxy_send_timeout 30s;
|
||||
proxy_read_timeout 30s;
|
||||
|
||||
# 日志记录
|
||||
access_log /var/log/nginx/volcengine_access.log;
|
||||
error_log /var/log/nginx/volcengine_error.log;
|
||||
}
|
||||
|
||||
location / {
|
||||
alias /yantoo/frontend/study-online/;
|
||||
index index.html index.htm;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
19
package.json
Normal file
19
package.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "study-online-app",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
"dev": "vite",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^3.4.0",
|
||||
"vue-router": "^4.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^5.0.0",
|
||||
"vite": "^5.0.0"
|
||||
}
|
||||
}
|
||||
98
pom.xml
Normal file
98
pom.xml
Normal file
@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<groupId>com.study.online</groupId>
|
||||
<artifactId>study-backend</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<name>study-backend</name>
|
||||
<description>Study Online Backend API</description>
|
||||
|
||||
<properties>
|
||||
<java.version>8</java.version>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring Boot Starter Web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Boot Starter Validation -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Apache Commons FileUpload -->
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Apache Commons IO -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.11.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JSON处理 -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- HTTP客户端 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 测试依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
45
src/App.vue
Normal file
45
src/App.vue
Normal file
@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<router-view />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'App'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
#app {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
BIN
src/assets/1.mp3
Normal file
BIN
src/assets/1.mp3
Normal file
Binary file not shown.
BIN
src/assets/2.mp3
Normal file
BIN
src/assets/2.mp3
Normal file
Binary file not shown.
BIN
src/assets/3.mp3
Normal file
BIN
src/assets/3.mp3
Normal file
Binary file not shown.
BIN
src/assets/4.mp3
Normal file
BIN
src/assets/4.mp3
Normal file
Binary file not shown.
BIN
src/assets/5.mp3
Normal file
BIN
src/assets/5.mp3
Normal file
Binary file not shown.
50
src/config/volcengine.js
Normal file
50
src/config/volcengine.js
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* 火山引擎配置文件
|
||||
* 请根据实际情况修改配置
|
||||
*/
|
||||
|
||||
export const volcengineConfig = {
|
||||
// API配置 - 使用代理服务器避免CORS问题
|
||||
apiUrl: '/api/volcengine', // 通过Nginx代理访问原始地址
|
||||
// apiUrl: 'https://openspeech.bytedance.com/api/v1/auc', // 原始地址(有CORS问题)
|
||||
appId: '1988591469',
|
||||
token: 'mdEyhgZ59on1-NK3GXWAp3L4iLldSG0r',
|
||||
cluster: 'volc_auc_common', // 尝试不同的集群名称
|
||||
// 其他可能的集群名称:
|
||||
// cluster: 'volc_auc_common',
|
||||
// cluster: 'volc_speech_common',
|
||||
// cluster: 'volc_asr',
|
||||
|
||||
// 语音识别配置
|
||||
speechRecognition: {
|
||||
defaultLanguage: 'en', // 默认语言:zh-中文, en-英文
|
||||
supportedLanguages: ['zh', 'en'],
|
||||
defaultModel: 'general', // 默认模型
|
||||
supportedModels: ['general', 'education', 'medical', 'finance'],
|
||||
maxFileSize: 100 * 1024 * 1024, // 最大文件大小:100MB
|
||||
supportedFormats: ['.mp3', '.wav', '.m4a', '.aac']
|
||||
},
|
||||
|
||||
// 请求配置
|
||||
request: {
|
||||
timeout: 30000, // 请求超时时间:30秒
|
||||
retryTimes: 3, // 重试次数
|
||||
retryDelay: 1000 // 重试延迟:1秒
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新配置
|
||||
* @param {Object} newConfig 新的配置
|
||||
*/
|
||||
export function updateVolcengineConfig(newConfig) {
|
||||
Object.assign(volcengineConfig, newConfig)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置
|
||||
* @returns {Object} 配置对象
|
||||
*/
|
||||
export function getVolcengineConfig() {
|
||||
return { ...volcengineConfig }
|
||||
}
|
||||
7
src/main.js
Normal file
7
src/main.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
const app = createApp(App)
|
||||
app.use(router)
|
||||
app.mount('#app')
|
||||
17
src/router/index.js
Normal file
17
src/router/index.js
Normal file
@ -0,0 +1,17 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import StudyPage from '../views/StudyPage.vue'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'Study',
|
||||
component: StudyPage
|
||||
}
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes
|
||||
})
|
||||
|
||||
export default router
|
||||
220
src/services/audioSaveService.js
Normal file
220
src/services/audioSaveService.js
Normal file
@ -0,0 +1,220 @@
|
||||
/**
|
||||
* 音频保存服务
|
||||
* 用于生成和保存示例语音文件
|
||||
*/
|
||||
|
||||
class AudioSaveService {
|
||||
constructor() {
|
||||
this.audioContext = null
|
||||
this.synthesis = window.speechSynthesis
|
||||
this.init()
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化音频服务
|
||||
*/
|
||||
async init() {
|
||||
try {
|
||||
if (window.AudioContext || window.webkitAudioContext) {
|
||||
this.audioContext = new (window.AudioContext || window.webkitAudioContext)()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('音频服务初始化失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成语音文件
|
||||
* @param {string} text 要转换的文本
|
||||
* @param {string} filename 文件名
|
||||
* @returns {Promise<Blob>} 音频文件Blob
|
||||
*/
|
||||
async generateAudioFile(text, filename) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
// 使用Web Speech API生成语音
|
||||
if (this.synthesis) {
|
||||
const utterance = new SpeechSynthesisUtterance(text)
|
||||
utterance.lang = 'en-US'
|
||||
utterance.rate = 0.9
|
||||
utterance.pitch = 1.0
|
||||
utterance.volume = 1.0
|
||||
|
||||
// 创建音频录制
|
||||
const mediaRecorder = new MediaRecorder(new MediaStream())
|
||||
const audioChunks = []
|
||||
|
||||
mediaRecorder.ondataavailable = (event) => {
|
||||
audioChunks.push(event.data)
|
||||
}
|
||||
|
||||
mediaRecorder.onstop = () => {
|
||||
const audioBlob = new Blob(audioChunks, { type: 'audio/wav' })
|
||||
resolve(audioBlob)
|
||||
}
|
||||
|
||||
utterance.onend = () => {
|
||||
mediaRecorder.stop()
|
||||
}
|
||||
|
||||
utterance.onerror = (error) => {
|
||||
reject(new Error('语音生成失败: ' + error))
|
||||
}
|
||||
|
||||
this.synthesis.speak(utterance)
|
||||
} else {
|
||||
// 备用方案:生成简单的音频文件
|
||||
this.generateSimpleAudio(text).then(resolve).catch(reject)
|
||||
}
|
||||
} catch (error) {
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成简单的音频文件(备用方案)
|
||||
*/
|
||||
async generateSimpleAudio(text) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
if (!this.audioContext) {
|
||||
reject(new Error('音频上下文不可用'))
|
||||
return
|
||||
}
|
||||
|
||||
// 创建音频数据
|
||||
const sampleRate = 44100
|
||||
const duration = Math.min(text.length * 0.1, 3) // 根据文本长度调整时长
|
||||
const samples = sampleRate * duration
|
||||
|
||||
// 创建音频缓冲区
|
||||
const audioBuffer = this.audioContext.createBuffer(1, samples, sampleRate)
|
||||
const channelData = audioBuffer.getChannelData(0)
|
||||
|
||||
// 生成音频数据(简单的正弦波)
|
||||
for (let i = 0; i < samples; i++) {
|
||||
const frequency = 440 + (i % 100) // 变化的频率
|
||||
channelData[i] = Math.sin(2 * Math.PI * frequency * i / sampleRate) * 0.3
|
||||
}
|
||||
|
||||
// 转换为Blob
|
||||
const wavBlob = this.audioBufferToWav(audioBuffer)
|
||||
resolve(wavBlob)
|
||||
} catch (error) {
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 将AudioBuffer转换为WAV格式
|
||||
*/
|
||||
audioBufferToWav(buffer) {
|
||||
const length = buffer.length
|
||||
const numberOfChannels = buffer.numberOfChannels
|
||||
const sampleRate = buffer.sampleRate
|
||||
const arrayBuffer = new ArrayBuffer(44 + length * numberOfChannels * 2)
|
||||
const view = new DataView(arrayBuffer)
|
||||
|
||||
// WAV文件头
|
||||
const writeString = (offset, string) => {
|
||||
for (let i = 0; i < string.length; i++) {
|
||||
view.setUint8(offset + i, string.charCodeAt(i))
|
||||
}
|
||||
}
|
||||
|
||||
writeString(0, 'RIFF')
|
||||
view.setUint32(4, 36 + length * numberOfChannels * 2, true)
|
||||
writeString(8, 'WAVE')
|
||||
writeString(12, 'fmt ')
|
||||
view.setUint32(16, 16, true)
|
||||
view.setUint16(20, 1, true)
|
||||
view.setUint16(22, numberOfChannels, true)
|
||||
view.setUint32(24, sampleRate, true)
|
||||
view.setUint32(28, sampleRate * numberOfChannels * 2, true)
|
||||
view.setUint16(32, numberOfChannels * 2, true)
|
||||
view.setUint16(34, 16, true)
|
||||
writeString(36, 'data')
|
||||
view.setUint32(40, length * numberOfChannels * 2, true)
|
||||
|
||||
// 写入音频数据
|
||||
let offset = 44
|
||||
for (let i = 0; i < length; i++) {
|
||||
for (let channel = 0; channel < numberOfChannels; channel++) {
|
||||
const sample = Math.max(-1, Math.min(1, buffer.getChannelData(channel)[i]))
|
||||
view.setInt16(offset, sample < 0 ? sample * 0x8000 : sample * 0x7FFF, true)
|
||||
offset += 2
|
||||
}
|
||||
}
|
||||
|
||||
return new Blob([arrayBuffer], { type: 'audio/wav' })
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存音频文件到本地
|
||||
* @param {Blob} audioBlob 音频文件
|
||||
* @param {string} filename 文件名
|
||||
*/
|
||||
saveAudioFile(audioBlob, filename) {
|
||||
try {
|
||||
const url = URL.createObjectURL(audioBlob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = filename
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
URL.revokeObjectURL(url)
|
||||
|
||||
console.log('音频文件已保存:', filename)
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('保存音频文件失败:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量保存示例音频
|
||||
* @param {Array} examples 示例数组
|
||||
*/
|
||||
async saveAllExampleAudios(examples) {
|
||||
const results = []
|
||||
|
||||
for (let i = 0; i < examples.length; i++) {
|
||||
const example = examples[i]
|
||||
try {
|
||||
console.log(`正在生成音频 ${i + 1}/${examples.length}: ${example.name}`)
|
||||
|
||||
const audioBlob = await this.generateAudioFile(example.english, `${example.name}.wav`)
|
||||
const filename = `${example.name}_${example.english.substring(0, 20).replace(/[^a-zA-Z0-9]/g, '_')}.wav`
|
||||
|
||||
const success = this.saveAudioFile(audioBlob, filename)
|
||||
results.push({
|
||||
name: example.name,
|
||||
success,
|
||||
filename
|
||||
})
|
||||
|
||||
// 添加延迟避免浏览器限制
|
||||
await new Promise(resolve => setTimeout(resolve, 500))
|
||||
|
||||
} catch (error) {
|
||||
console.error(`生成音频失败 ${example.name}:`, error)
|
||||
results.push({
|
||||
name: example.name,
|
||||
success: false,
|
||||
error: error.message
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
}
|
||||
|
||||
// 创建单例实例
|
||||
const audioSaveService = new AudioSaveService()
|
||||
|
||||
export default audioSaveService
|
||||
324
src/services/ttsService.js
Normal file
324
src/services/ttsService.js
Normal file
@ -0,0 +1,324 @@
|
||||
/**
|
||||
* 移动端兼容的文本转语音服务
|
||||
* 优先使用Web Speech API,备用Web Audio API
|
||||
*/
|
||||
|
||||
class TTSService {
|
||||
constructor() {
|
||||
this.audioContext = null
|
||||
this.synthesis = window.speechSynthesis
|
||||
this.voices = []
|
||||
this.isInitialized = false
|
||||
this.init()
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化音频服务
|
||||
*/
|
||||
async init() {
|
||||
try {
|
||||
// 尝试初始化Web Speech API
|
||||
if (this.synthesis) {
|
||||
this.voices = this.synthesis.getVoices()
|
||||
|
||||
if (this.voices.length === 0) {
|
||||
this.synthesis.onvoiceschanged = () => {
|
||||
this.voices = this.synthesis.getVoices()
|
||||
this.isInitialized = true
|
||||
console.log('Web Speech API 语音加载完成,可用语音数量:', this.voices.length)
|
||||
}
|
||||
} else {
|
||||
this.isInitialized = true
|
||||
console.log('Web Speech API 语音已加载,可用语音数量:', this.voices.length)
|
||||
}
|
||||
}
|
||||
|
||||
// 备用:初始化Web Audio API
|
||||
if (window.AudioContext || window.webkitAudioContext) {
|
||||
this.audioContext = new (window.AudioContext || window.webkitAudioContext)()
|
||||
console.log('Web Audio API 初始化成功')
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('音频服务初始化失败:', error)
|
||||
this.isInitialized = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查浏览器支持
|
||||
*/
|
||||
isSupported() {
|
||||
return !!(this.synthesis || (window.AudioContext || window.webkitAudioContext))
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查移动端
|
||||
*/
|
||||
isMobile() {
|
||||
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取英文语音
|
||||
*/
|
||||
getEnglishVoice() {
|
||||
if (!this.synthesis || this.voices.length === 0) return null
|
||||
|
||||
// 优先选择美式英语语音
|
||||
const usVoice = this.voices.find(voice =>
|
||||
voice.lang.includes('en-US') && voice.name.includes('Google')
|
||||
)
|
||||
|
||||
if (usVoice) return usVoice
|
||||
|
||||
// 其次选择任何美式英语语音
|
||||
const enUSVoice = this.voices.find(voice =>
|
||||
voice.lang.includes('en-US')
|
||||
)
|
||||
|
||||
if (enUSVoice) return enUSVoice
|
||||
|
||||
// 最后选择任何英语语音
|
||||
const enVoice = this.voices.find(voice =>
|
||||
voice.lang.includes('en')
|
||||
)
|
||||
|
||||
return enVoice || this.voices[0]
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放英文语音
|
||||
* @param {string} text 要播放的英文文本
|
||||
* @param {Event} event 用户交互事件
|
||||
*/
|
||||
speak(text, event = null) {
|
||||
if (!this.isSupported()) {
|
||||
console.error('浏览器不支持语音合成')
|
||||
this.showFallbackMessage()
|
||||
return
|
||||
}
|
||||
|
||||
// 移动端需要用户交互
|
||||
if (this.isMobile() && !event) {
|
||||
console.warn('移动端需要用户交互才能播放语音')
|
||||
return
|
||||
}
|
||||
|
||||
// 优先使用Web Speech API
|
||||
if (this.synthesis && this.voices.length > 0) {
|
||||
this.speakWithWebSpeech(text)
|
||||
} else if (this.audioContext) {
|
||||
// 备用:使用Web Audio API
|
||||
this.speakWithWebAudio(text)
|
||||
} else {
|
||||
// 最后的备用方案:显示文本提示
|
||||
this.showTextHint(text)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用Web Speech API播放
|
||||
*/
|
||||
speakWithWebSpeech(text) {
|
||||
try {
|
||||
// 停止当前播放
|
||||
this.synthesis.cancel()
|
||||
|
||||
// 创建语音合成
|
||||
const utterance = new SpeechSynthesisUtterance(text)
|
||||
|
||||
// 设置语音
|
||||
const voice = this.getEnglishVoice()
|
||||
if (voice) {
|
||||
utterance.voice = voice
|
||||
console.log('使用语音:', voice.name, voice.lang)
|
||||
}
|
||||
|
||||
// 设置参数
|
||||
utterance.lang = 'en-US'
|
||||
utterance.rate = 0.9
|
||||
utterance.pitch = 1.0
|
||||
utterance.volume = 1.0
|
||||
|
||||
// 添加事件监听
|
||||
utterance.onstart = () => {
|
||||
console.log('开始播放语音:', text)
|
||||
}
|
||||
|
||||
utterance.onend = () => {
|
||||
console.log('语音播放结束')
|
||||
}
|
||||
|
||||
utterance.onerror = (event) => {
|
||||
console.error('Web Speech API播放错误:', event.error)
|
||||
// 如果Web Speech API失败,尝试Web Audio API
|
||||
if (this.audioContext) {
|
||||
this.speakWithWebAudio(text)
|
||||
} else {
|
||||
this.showTextHint(text)
|
||||
}
|
||||
}
|
||||
|
||||
// 播放
|
||||
this.synthesis.speak(utterance)
|
||||
|
||||
} catch (error) {
|
||||
console.error('Web Speech API播放失败:', error)
|
||||
// 备用方案
|
||||
if (this.audioContext) {
|
||||
this.speakWithWebAudio(text)
|
||||
} else {
|
||||
this.showTextHint(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用Web Audio API播放(生成简单的音频信号)
|
||||
*/
|
||||
speakWithWebAudio(text) {
|
||||
try {
|
||||
// 确保音频上下文已恢复
|
||||
if (this.audioContext.state === 'suspended') {
|
||||
this.audioContext.resume()
|
||||
}
|
||||
|
||||
// 创建音频节点
|
||||
const oscillator = this.audioContext.createOscillator()
|
||||
const gainNode = this.audioContext.createGain()
|
||||
|
||||
// 连接节点
|
||||
oscillator.connect(gainNode)
|
||||
gainNode.connect(this.audioContext.destination)
|
||||
|
||||
// 设置音频参数 - 生成更复杂的音频模式
|
||||
oscillator.type = 'sine'
|
||||
|
||||
// 根据文本长度调整频率
|
||||
const baseFreq = 440 // A4音符
|
||||
const textLength = text.length
|
||||
const freq = baseFreq + (textLength * 10) // 根据文本长度调整频率
|
||||
|
||||
oscillator.frequency.setValueAtTime(freq, this.audioContext.currentTime)
|
||||
|
||||
// 音量控制
|
||||
gainNode.gain.setValueAtTime(0.05, this.audioContext.currentTime)
|
||||
gainNode.gain.exponentialRampToValueAtTime(0.01, this.audioContext.currentTime + 0.8)
|
||||
|
||||
// 播放音频
|
||||
oscillator.start(this.audioContext.currentTime)
|
||||
oscillator.stop(this.audioContext.currentTime + 0.8)
|
||||
|
||||
console.log('Web Audio API播放音频提示音:', text)
|
||||
|
||||
// 显示文本提示
|
||||
this.showTextHint(text)
|
||||
|
||||
} catch (error) {
|
||||
console.error('Web Audio API播放失败:', error)
|
||||
this.showTextHint(text)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示文本提示
|
||||
*/
|
||||
showTextHint(text) {
|
||||
// 移除之前的提示
|
||||
const existingHint = document.querySelector('.tts-text-hint')
|
||||
if (existingHint) {
|
||||
existingHint.remove()
|
||||
}
|
||||
|
||||
// 创建一个临时的文本提示
|
||||
const hint = document.createElement('div')
|
||||
hint.className = 'tts-text-hint'
|
||||
hint.style.cssText = `
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
color: white;
|
||||
padding: 20px;
|
||||
border-radius: 15px;
|
||||
z-index: 10000;
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
max-width: 80%;
|
||||
word-wrap: break-word;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
|
||||
animation: fadeInOut 3s ease-in-out;
|
||||
`
|
||||
hint.textContent = text
|
||||
|
||||
// 添加动画样式
|
||||
const style = document.createElement('style')
|
||||
style.textContent = `
|
||||
@keyframes fadeInOut {
|
||||
0% { opacity: 0; transform: translate(-50%, -50%) scale(0.8); }
|
||||
20% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
||||
80% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
||||
100% { opacity: 0; transform: translate(-50%, -50%) scale(0.8); }
|
||||
}
|
||||
`
|
||||
document.head.appendChild(style)
|
||||
|
||||
document.body.appendChild(hint)
|
||||
|
||||
// 3秒后自动移除
|
||||
setTimeout(() => {
|
||||
if (hint.parentNode) {
|
||||
hint.parentNode.removeChild(hint)
|
||||
}
|
||||
if (style.parentNode) {
|
||||
style.parentNode.removeChild(style)
|
||||
}
|
||||
}, 3000)
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示备用消息
|
||||
*/
|
||||
showFallbackMessage() {
|
||||
if (this.isMobile()) {
|
||||
alert('移动端音频播放受限,请查看屏幕中央的文本提示。\n\n建议:\n1. 使用Chrome或Safari浏览器\n2. 确保已授予音频权限\n3. 尝试刷新页面')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止播放
|
||||
*/
|
||||
stop() {
|
||||
if (this.synthesis) {
|
||||
this.synthesis.cancel()
|
||||
console.log('停止Web Speech API播放')
|
||||
}
|
||||
|
||||
// 移除文本提示
|
||||
const existingHint = document.querySelector('.tts-text-hint')
|
||||
if (existingHint) {
|
||||
existingHint.remove()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否正在播放
|
||||
*/
|
||||
isSpeaking() {
|
||||
return this.synthesis ? this.synthesis.speaking : false
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可用语音列表
|
||||
*/
|
||||
getAvailableVoices() {
|
||||
return this.voices
|
||||
}
|
||||
}
|
||||
|
||||
// 创建单例实例
|
||||
const ttsService = new TTSService()
|
||||
|
||||
export default ttsService
|
||||
296
src/services/volcengineService.js
Normal file
296
src/services/volcengineService.js
Normal file
@ -0,0 +1,296 @@
|
||||
/**
|
||||
* 火山引擎语音识别服务
|
||||
* 提供前端直接调用火山引擎API的功能
|
||||
*/
|
||||
|
||||
import { volcengineConfig } from '../config/volcengine.js'
|
||||
|
||||
class VolcengineService {
|
||||
constructor() {
|
||||
// 使用配置文件
|
||||
this.config = volcengineConfig
|
||||
}
|
||||
|
||||
/**
|
||||
* 语音识别主方法
|
||||
* @param {File|Blob} audioFile 音频文件
|
||||
* @param {string} language 语言代码,默认英文
|
||||
* @returns {Promise<string>} 识别结果
|
||||
*/
|
||||
async speechToText(audioFile, language = 'en-US') {
|
||||
try {
|
||||
console.log('=== 开始语音识别 ===')
|
||||
console.log('音频文件:', audioFile)
|
||||
console.log('语言:', language)
|
||||
|
||||
// 验证文件格式
|
||||
this.validateAudioFormat(audioFile)
|
||||
console.log('文件格式验证通过')
|
||||
|
||||
// 将音频转换为Base64
|
||||
const base64Audio = await this.blobToBase64(audioFile)
|
||||
console.log('音频转Base64完成,长度:', base64Audio.length)
|
||||
|
||||
// 第一步:提交任务
|
||||
const taskId = await this.submitTask(base64Audio, audioFile, language)
|
||||
console.log('任务提交成功,ID:', taskId)
|
||||
|
||||
// 第二步:查询结果
|
||||
const result = await this.queryResult(taskId)
|
||||
console.log('查询结果:', result)
|
||||
|
||||
return result
|
||||
|
||||
} catch (error) {
|
||||
console.error('语音识别失败:', error)
|
||||
throw new Error(`语音识别失败: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证音频文件格式
|
||||
* @param {File|Blob} file 音频文件
|
||||
*/
|
||||
validateAudioFormat(file) {
|
||||
const fileName = file.name ? file.name.toLowerCase() : ''
|
||||
const supportedFormats = ['.mp3', '.wav', '.m4a', '.aac']
|
||||
|
||||
if (fileName && !supportedFormats.some(format => fileName.endsWith(format))) {
|
||||
throw new Error('只支持MP3、WAV、M4A、AAC格式文件')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Blob转换为Base64
|
||||
* @param {Blob} blob 音频blob
|
||||
* @returns {Promise<string>} Base64字符串
|
||||
*/
|
||||
blobToBase64(blob) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader()
|
||||
reader.onload = () => {
|
||||
const base64 = reader.result.split(',')[1] // 移除data:audio/wav;base64,前缀
|
||||
resolve(base64)
|
||||
}
|
||||
reader.onerror = reject
|
||||
reader.readAsDataURL(blob)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交语音识别任务
|
||||
* @param {string} base64Audio Base64编码的音频数据
|
||||
* @param {File|Blob} audioFile 原始音频文件
|
||||
* @param {string} language 语言代码
|
||||
* @returns {Promise<string>} 任务ID
|
||||
*/
|
||||
async submitTask(base64Audio, audioFile, language) {
|
||||
const requestBody = {
|
||||
app: {
|
||||
appid: this.config.appId,
|
||||
token: this.config.token,
|
||||
cluster: this.config.cluster
|
||||
},
|
||||
user: {
|
||||
uid: "demo_user"
|
||||
},
|
||||
audio: {
|
||||
format: this.getAudioFormat(audioFile),
|
||||
data: base64Audio
|
||||
},
|
||||
additions: {
|
||||
with_speaker_info: "False",
|
||||
language: "en-US" // 设置为英文(美式英语)
|
||||
}
|
||||
}
|
||||
|
||||
console.log('提交任务请求体:', requestBody)
|
||||
|
||||
const response = await fetch(`${this.config.apiUrl}/submit`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer; ${this.config.token}`,
|
||||
'Connection': 'keep-alive'
|
||||
},
|
||||
body: JSON.stringify(requestBody)
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text()
|
||||
throw new Error(`提交任务失败: HTTP ${response.status} - ${errorText}`)
|
||||
}
|
||||
|
||||
const result = await response.json()
|
||||
console.log('提交任务响应:', result)
|
||||
|
||||
if (result.resp && result.resp.id) {
|
||||
return result.resp.id
|
||||
} else {
|
||||
throw new Error('提交任务失败:未获取到任务ID')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询语音识别结果
|
||||
* @param {string} taskId 任务ID
|
||||
* @returns {Promise<string>} 识别结果
|
||||
*/
|
||||
async queryResult(taskId) {
|
||||
const requestBody = {
|
||||
appid: this.config.appId,
|
||||
token: this.config.token,
|
||||
id: taskId,
|
||||
cluster: this.config.cluster
|
||||
}
|
||||
|
||||
console.log('查询任务请求体:', requestBody)
|
||||
|
||||
const response = await fetch(`${this.config.apiUrl}/query`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer; ${this.config.token}`,
|
||||
'Connection': 'keep-alive'
|
||||
},
|
||||
body: JSON.stringify(requestBody)
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text()
|
||||
throw new Error(`查询任务失败: HTTP ${response.status} - ${errorText}`)
|
||||
}
|
||||
|
||||
const result = await response.json()
|
||||
console.log('查询任务响应:', result)
|
||||
|
||||
if (result.resp) {
|
||||
const { code, text } = result.resp
|
||||
|
||||
switch (code) {
|
||||
case 1000:
|
||||
console.log('转换成功')
|
||||
return text
|
||||
case 2000:
|
||||
case 2001:
|
||||
case 2002:
|
||||
console.log('任务处理中,等待500ms后重试')
|
||||
await new Promise(resolve => setTimeout(resolve, 500))
|
||||
return this.queryResult(taskId) // 递归重试
|
||||
default:
|
||||
console.log('转换失败,错误码:', code)
|
||||
return '语音识别失败'
|
||||
}
|
||||
} else {
|
||||
throw new Error('查询任务失败:响应格式错误')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取音频格式
|
||||
* @param {File|Blob} file 音频文件
|
||||
* @returns {string} 音频格式
|
||||
*/
|
||||
getAudioFormat(file) {
|
||||
const type = file.type || ''
|
||||
const fileName = file.name ? file.name.toLowerCase() : ''
|
||||
|
||||
if (type.includes('mp3') || fileName.endsWith('.mp3')) return 'mp3'
|
||||
if (type.includes('wav') || fileName.endsWith('.wav')) return 'wav'
|
||||
if (type.includes('m4a') || fileName.endsWith('.m4a')) return 'm4a'
|
||||
if (type.includes('aac') || fileName.endsWith('.aac')) return 'aac'
|
||||
|
||||
return 'wav' // 默认格式
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送HTTP请求到火山引擎
|
||||
* @param {Object} requestBody 请求体
|
||||
* @returns {Promise<Object>} 响应结果
|
||||
*/
|
||||
async sendRequest(requestBody) {
|
||||
console.log('发送请求到:', this.config.apiUrl)
|
||||
console.log('请求头:', {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': this.generateAuthorization(),
|
||||
'X-App-Id': this.config.appId,
|
||||
'X-Cluster': this.config.cluster
|
||||
})
|
||||
console.log('请求体:', requestBody)
|
||||
|
||||
try {
|
||||
const response = await fetch(this.config.apiUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': this.generateAuthorization(),
|
||||
'X-App-Id': this.config.appId,
|
||||
'X-Cluster': this.config.cluster,
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
|
||||
},
|
||||
body: JSON.stringify(requestBody)
|
||||
})
|
||||
|
||||
console.log('响应状态:', response.status)
|
||||
console.log('响应头:', Object.fromEntries(response.headers.entries()))
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text()
|
||||
console.error('响应错误:', errorText)
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText} - ${errorText}`)
|
||||
}
|
||||
|
||||
const result = await response.json()
|
||||
console.log('响应结果:', result)
|
||||
return result
|
||||
} catch (error) {
|
||||
console.error('请求失败:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成授权头
|
||||
* @returns {string} 授权头字符串
|
||||
*/
|
||||
generateAuthorization() {
|
||||
// 使用token作为授权头
|
||||
return `Bearer ${this.config.token}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析响应结果
|
||||
* @param {Object} response 火山引擎响应
|
||||
* @returns {string} 识别结果文本
|
||||
*/
|
||||
parseResponse(response) {
|
||||
try {
|
||||
// 根据火山引擎的响应格式解析结果
|
||||
if (response && response.result) {
|
||||
return response.result
|
||||
}
|
||||
|
||||
if (response && response.data && response.data.result) {
|
||||
return response.data.result
|
||||
}
|
||||
|
||||
throw new Error('响应格式不正确')
|
||||
} catch (error) {
|
||||
console.error('解析响应失败:', error)
|
||||
throw new Error('解析响应失败')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新配置
|
||||
* @param {Object} newConfig 新的配置对象
|
||||
*/
|
||||
updateConfig(newConfig) {
|
||||
this.config = { ...this.config, ...newConfig }
|
||||
}
|
||||
}
|
||||
|
||||
// 创建单例实例
|
||||
const volcengineService = new VolcengineService()
|
||||
|
||||
export default volcengineService
|
||||
1544
src/views/StudyPage.vue
Normal file
1544
src/views/StudyPage.vue
Normal file
File diff suppressed because it is too large
Load Diff
45
vite.config.js
Normal file
45
vite.config.js
Normal file
@ -0,0 +1,45 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
server: {
|
||||
proxy: {
|
||||
'/api/volcengine': {
|
||||
target: 'https://openspeech.bytedance.com',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api\/volcengine/, '/api/v1/auc'),
|
||||
secure: false,
|
||||
configure: (proxy, options) => {
|
||||
proxy.on('error', (err, req, res) => {
|
||||
console.log('proxy error', err);
|
||||
});
|
||||
proxy.on('proxyReq', (proxyReq, req, res) => {
|
||||
console.log('Sending Request to the Target:', req.method, req.url);
|
||||
});
|
||||
proxy.on('proxyRes', (proxyRes, req, res) => {
|
||||
console.log('Received Response from the Target:', proxyRes.statusCode, req.url);
|
||||
});
|
||||
},
|
||||
},
|
||||
'/api/tts': {
|
||||
target: 'https://openspeech.bytedance.com',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api\/tts/, '/api/v1/tts'),
|
||||
secure: false,
|
||||
configure: (proxy, options) => {
|
||||
proxy.on('error', (err, req, res) => {
|
||||
console.log('TTS proxy error', err);
|
||||
});
|
||||
proxy.on('proxyReq', (proxyReq, req, res) => {
|
||||
console.log('TTS Sending Request to the Target:', req.method, req.url);
|
||||
});
|
||||
proxy.on('proxyRes', (proxyRes, req, res) => {
|
||||
console.log('TTS Received Response from the Target:', proxyRes.statusCode, req.url);
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
481
yarn.lock
Normal file
481
yarn.lock
Normal file
@ -0,0 +1,481 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/helper-string-parser@^7.27.1":
|
||||
version "7.27.1"
|
||||
resolved "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687"
|
||||
integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==
|
||||
|
||||
"@babel/helper-validator-identifier@^7.27.1":
|
||||
version "7.27.1"
|
||||
resolved "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8"
|
||||
integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==
|
||||
|
||||
"@babel/parser@^7.28.0":
|
||||
version "7.28.0"
|
||||
resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.0.tgz#979829fbab51a29e13901e5a80713dbcb840825e"
|
||||
integrity sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==
|
||||
dependencies:
|
||||
"@babel/types" "^7.28.0"
|
||||
|
||||
"@babel/types@^7.28.0":
|
||||
version "7.28.1"
|
||||
resolved "https://registry.npmmirror.com/@babel/types/-/types-7.28.1.tgz#2aaf3c10b31ba03a77ac84f52b3912a0edef4cf9"
|
||||
integrity sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==
|
||||
dependencies:
|
||||
"@babel/helper-string-parser" "^7.27.1"
|
||||
"@babel/helper-validator-identifier" "^7.27.1"
|
||||
|
||||
"@esbuild/aix-ppc64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f"
|
||||
integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==
|
||||
|
||||
"@esbuild/android-arm64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052"
|
||||
integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==
|
||||
|
||||
"@esbuild/android-arm@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28"
|
||||
integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==
|
||||
|
||||
"@esbuild/android-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e"
|
||||
integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==
|
||||
|
||||
"@esbuild/darwin-arm64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a"
|
||||
integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==
|
||||
|
||||
"@esbuild/darwin-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22"
|
||||
integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==
|
||||
|
||||
"@esbuild/freebsd-arm64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e"
|
||||
integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==
|
||||
|
||||
"@esbuild/freebsd-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261"
|
||||
integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==
|
||||
|
||||
"@esbuild/linux-arm64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b"
|
||||
integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==
|
||||
|
||||
"@esbuild/linux-arm@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9"
|
||||
integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==
|
||||
|
||||
"@esbuild/linux-ia32@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2"
|
||||
integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==
|
||||
|
||||
"@esbuild/linux-loong64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df"
|
||||
integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==
|
||||
|
||||
"@esbuild/linux-mips64el@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe"
|
||||
integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==
|
||||
|
||||
"@esbuild/linux-ppc64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4"
|
||||
integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==
|
||||
|
||||
"@esbuild/linux-riscv64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc"
|
||||
integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==
|
||||
|
||||
"@esbuild/linux-s390x@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de"
|
||||
integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==
|
||||
|
||||
"@esbuild/linux-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0"
|
||||
integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==
|
||||
|
||||
"@esbuild/netbsd-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047"
|
||||
integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==
|
||||
|
||||
"@esbuild/openbsd-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70"
|
||||
integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==
|
||||
|
||||
"@esbuild/sunos-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b"
|
||||
integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==
|
||||
|
||||
"@esbuild/win32-arm64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d"
|
||||
integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==
|
||||
|
||||
"@esbuild/win32-ia32@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b"
|
||||
integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==
|
||||
|
||||
"@esbuild/win32-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c"
|
||||
integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==
|
||||
|
||||
"@jridgewell/sourcemap-codec@^1.5.0":
|
||||
version "1.5.4"
|
||||
resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz#7358043433b2e5da569aa02cbc4c121da3af27d7"
|
||||
integrity sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==
|
||||
|
||||
"@rollup/rollup-android-arm-eabi@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.45.1.tgz#8560592f0dcf43b8cb0949af9f1d916205148d12"
|
||||
integrity sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA==
|
||||
|
||||
"@rollup/rollup-android-arm64@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.45.1.tgz#6bfb777bbce998691b6fd3e916b05cd46392d020"
|
||||
integrity sha512-ujQ+sMXJkg4LRJaYreaVx7Z/VMgBBd89wGS4qMrdtfUFZ+TSY5Rs9asgjitLwzeIbhwdEhyj29zhst3L1lKsRQ==
|
||||
|
||||
"@rollup/rollup-darwin-arm64@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.45.1.tgz#7efce10220293a22e7b7b595d05d8b8400a7bcf3"
|
||||
integrity sha512-FSncqHvqTm3lC6Y13xncsdOYfxGSLnP+73k815EfNmpewPs+EyM49haPS105Rh4aF5mJKywk9X0ogzLXZzN9lA==
|
||||
|
||||
"@rollup/rollup-darwin-x64@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.45.1.tgz#c617a8ece21050bfbea299c126767d2e70cfa79a"
|
||||
integrity sha512-2/vVn/husP5XI7Fsf/RlhDaQJ7x9zjvC81anIVbr4b/f0xtSmXQTFcGIQ/B1cXIYM6h2nAhJkdMHTnD7OtQ9Og==
|
||||
|
||||
"@rollup/rollup-freebsd-arm64@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.45.1.tgz#5a6af0a9acf82162d2910933649ae24fc0ea3ecb"
|
||||
integrity sha512-4g1kaDxQItZsrkVTdYQ0bxu4ZIQ32cotoQbmsAnW1jAE4XCMbcBPDirX5fyUzdhVCKgPcrwWuucI8yrVRBw2+g==
|
||||
|
||||
"@rollup/rollup-freebsd-x64@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.45.1.tgz#ae9709463560196fc275bd0da598668a2e341023"
|
||||
integrity sha512-L/6JsfiL74i3uK1Ti2ZFSNsp5NMiM4/kbbGEcOCps99aZx3g8SJMO1/9Y0n/qKlWZfn6sScf98lEOUe2mBvW9A==
|
||||
|
||||
"@rollup/rollup-linux-arm-gnueabihf@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.45.1.tgz#6ec52661764dbd54c19d6520a403aa385a5c0fbf"
|
||||
integrity sha512-RkdOTu2jK7brlu+ZwjMIZfdV2sSYHK2qR08FUWcIoqJC2eywHbXr0L8T/pONFwkGukQqERDheaGTeedG+rra6Q==
|
||||
|
||||
"@rollup/rollup-linux-arm-musleabihf@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.45.1.tgz#fd33ba4a43ef8419e96811236493d19436271923"
|
||||
integrity sha512-3kJ8pgfBt6CIIr1o+HQA7OZ9mp/zDk3ctekGl9qn/pRBgrRgfwiffaUmqioUGN9hv0OHv2gxmvdKOkARCtRb8Q==
|
||||
|
||||
"@rollup/rollup-linux-arm64-gnu@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.45.1.tgz#933b3d99b73c9d7bf4506cab0d5d313c7e74fd2d"
|
||||
integrity sha512-k3dOKCfIVixWjG7OXTCOmDfJj3vbdhN0QYEqB+OuGArOChek22hn7Uy5A/gTDNAcCy5v2YcXRJ/Qcnm4/ma1xw==
|
||||
|
||||
"@rollup/rollup-linux-arm64-musl@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.45.1.tgz#dbe9ae24ee9e97b75662fddcb69eb7f23c89280a"
|
||||
integrity sha512-PmI1vxQetnM58ZmDFl9/Uk2lpBBby6B6rF4muJc65uZbxCs0EA7hhKCk2PKlmZKuyVSHAyIw3+/SiuMLxKxWog==
|
||||
|
||||
"@rollup/rollup-linux-loongarch64-gnu@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.45.1.tgz#818c5a071eec744436dbcdd76fe9c3c869dc9a8d"
|
||||
integrity sha512-9UmI0VzGmNJ28ibHW2GpE2nF0PBQqsyiS4kcJ5vK+wuwGnV5RlqdczVocDSUfGX/Na7/XINRVoUgJyFIgipoRg==
|
||||
|
||||
"@rollup/rollup-linux-powerpc64le-gnu@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.45.1.tgz#6b8591def27d886fa147fb0340126c7d6682a7e4"
|
||||
integrity sha512-7nR2KY8oEOUTD3pBAxIBBbZr0U7U+R9HDTPNy+5nVVHDXI4ikYniH1oxQz9VoB5PbBU1CZuDGHkLJkd3zLMWsg==
|
||||
|
||||
"@rollup/rollup-linux-riscv64-gnu@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.45.1.tgz#f1861ac4ee8da64e0b0d23853ff26fe2baa876cf"
|
||||
integrity sha512-nlcl3jgUultKROfZijKjRQLUu9Ma0PeNv/VFHkZiKbXTBQXhpytS8CIj5/NfBeECZtY2FJQubm6ltIxm/ftxpw==
|
||||
|
||||
"@rollup/rollup-linux-riscv64-musl@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.45.1.tgz#320c961401a923b374e358664527b188e374e1ae"
|
||||
integrity sha512-HJV65KLS51rW0VY6rvZkiieiBnurSzpzore1bMKAhunQiECPuxsROvyeaot/tcK3A3aGnI+qTHqisrpSgQrpgA==
|
||||
|
||||
"@rollup/rollup-linux-s390x-gnu@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.45.1.tgz#1763eed3362b50b6164d3f0947486c03cc7e616d"
|
||||
integrity sha512-NITBOCv3Qqc6hhwFt7jLV78VEO/il4YcBzoMGGNxznLgRQf43VQDae0aAzKiBeEPIxnDrACiMgbqjuihx08OOw==
|
||||
|
||||
"@rollup/rollup-linux-x64-gnu@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.45.1.tgz#0d4c8d0b8f801902f0844a40a9d981a0179f4971"
|
||||
integrity sha512-+E/lYl6qu1zqgPEnTrs4WysQtvc/Sh4fC2nByfFExqgYrqkKWp1tWIbe+ELhixnenSpBbLXNi6vbEEJ8M7fiHw==
|
||||
|
||||
"@rollup/rollup-linux-x64-musl@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.45.1.tgz#ec30bb48b5fe22a3aaba98072f2d5b7139e1a8eb"
|
||||
integrity sha512-a6WIAp89p3kpNoYStITT9RbTbTnqarU7D8N8F2CV+4Cl9fwCOZraLVuVFvlpsW0SbIiYtEnhCZBPLoNdRkjQFw==
|
||||
|
||||
"@rollup/rollup-win32-arm64-msvc@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.45.1.tgz#27a6e48d1502e8e4bed96bedfb533738655874f2"
|
||||
integrity sha512-T5Bi/NS3fQiJeYdGvRpTAP5P02kqSOpqiopwhj0uaXB6nzs5JVi2XMJb18JUSKhCOX8+UE1UKQufyD6Or48dJg==
|
||||
|
||||
"@rollup/rollup-win32-ia32-msvc@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.45.1.tgz#a2fbad3bec20ff879f3fd51720adf33692ca8f3d"
|
||||
integrity sha512-lxV2Pako3ujjuUe9jiU3/s7KSrDfH6IgTSQOnDWr9aJ92YsFd7EurmClK0ly/t8dzMkDtd04g60WX6yl0sGfdw==
|
||||
|
||||
"@rollup/rollup-win32-x64-msvc@4.45.1":
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.45.1.tgz#e5085c6d13da15b4c5133cd2a6bb11f25b6bb77a"
|
||||
integrity sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA==
|
||||
|
||||
"@types/estree@1.0.8":
|
||||
version "1.0.8"
|
||||
resolved "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e"
|
||||
integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==
|
||||
|
||||
"@vitejs/plugin-vue@^5.0.0":
|
||||
version "5.2.4"
|
||||
resolved "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz#9e8a512eb174bfc2a333ba959bbf9de428d89ad8"
|
||||
integrity sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==
|
||||
|
||||
"@vue/compiler-core@3.5.18":
|
||||
version "3.5.18"
|
||||
resolved "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.18.tgz#521a138cdd970d9bfd27e42168d12f77a04b2074"
|
||||
integrity sha512-3slwjQrrV1TO8MoXgy3aynDQ7lslj5UqDxuHnrzHtpON5CBinhWjJETciPngpin/T3OuW3tXUf86tEurusnztw==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.28.0"
|
||||
"@vue/shared" "3.5.18"
|
||||
entities "^4.5.0"
|
||||
estree-walker "^2.0.2"
|
||||
source-map-js "^1.2.1"
|
||||
|
||||
"@vue/compiler-dom@3.5.18":
|
||||
version "3.5.18"
|
||||
resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.18.tgz#e13504492c3061ec5bbe6a2e789f15261d4f03a7"
|
||||
integrity sha512-RMbU6NTU70++B1JyVJbNbeFkK+A+Q7y9XKE2EM4NLGm2WFR8x9MbAtWxPPLdm0wUkuZv9trpwfSlL6tjdIa1+A==
|
||||
dependencies:
|
||||
"@vue/compiler-core" "3.5.18"
|
||||
"@vue/shared" "3.5.18"
|
||||
|
||||
"@vue/compiler-sfc@3.5.18":
|
||||
version "3.5.18"
|
||||
resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.18.tgz#ba1e849561337d809937994cdaf900539542eeca"
|
||||
integrity sha512-5aBjvGqsWs+MoxswZPoTB9nSDb3dhd1x30xrrltKujlCxo48j8HGDNj3QPhF4VIS0VQDUrA1xUfp2hEa+FNyXA==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.28.0"
|
||||
"@vue/compiler-core" "3.5.18"
|
||||
"@vue/compiler-dom" "3.5.18"
|
||||
"@vue/compiler-ssr" "3.5.18"
|
||||
"@vue/shared" "3.5.18"
|
||||
estree-walker "^2.0.2"
|
||||
magic-string "^0.30.17"
|
||||
postcss "^8.5.6"
|
||||
source-map-js "^1.2.1"
|
||||
|
||||
"@vue/compiler-ssr@3.5.18":
|
||||
version "3.5.18"
|
||||
resolved "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.18.tgz#aecde0b0bff268a9c9014ba66799307c4a784328"
|
||||
integrity sha512-xM16Ak7rSWHkM3m22NlmcdIM+K4BMyFARAfV9hYFl+SFuRzrZ3uGMNW05kA5pmeMa0X9X963Kgou7ufdbpOP9g==
|
||||
dependencies:
|
||||
"@vue/compiler-dom" "3.5.18"
|
||||
"@vue/shared" "3.5.18"
|
||||
|
||||
"@vue/devtools-api@^6.6.4":
|
||||
version "6.6.4"
|
||||
resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz#cbe97fe0162b365edc1dba80e173f90492535343"
|
||||
integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==
|
||||
|
||||
"@vue/reactivity@3.5.18":
|
||||
version "3.5.18"
|
||||
resolved "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.18.tgz#fe32166e3938832c54b4134e60e9b58ca7d9bdb4"
|
||||
integrity sha512-x0vPO5Imw+3sChLM5Y+B6G1zPjwdOri9e8V21NnTnlEvkxatHEH5B5KEAJcjuzQ7BsjGrKtfzuQ5eQwXh8HXBg==
|
||||
dependencies:
|
||||
"@vue/shared" "3.5.18"
|
||||
|
||||
"@vue/runtime-core@3.5.18":
|
||||
version "3.5.18"
|
||||
resolved "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.18.tgz#9e9ae8b9491548b53d0cea2bf25746d27c52e191"
|
||||
integrity sha512-DUpHa1HpeOQEt6+3nheUfqVXRog2kivkXHUhoqJiKR33SO4x+a5uNOMkV487WPerQkL0vUuRvq/7JhRgLW3S+w==
|
||||
dependencies:
|
||||
"@vue/reactivity" "3.5.18"
|
||||
"@vue/shared" "3.5.18"
|
||||
|
||||
"@vue/runtime-dom@3.5.18":
|
||||
version "3.5.18"
|
||||
resolved "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.18.tgz#1150952d1048b5822e4f1dd8aed24665cbb22107"
|
||||
integrity sha512-YwDj71iV05j4RnzZnZtGaXwPoUWeRsqinblgVJwR8XTXYZ9D5PbahHQgsbmzUvCWNF6x7siQ89HgnX5eWkr3mw==
|
||||
dependencies:
|
||||
"@vue/reactivity" "3.5.18"
|
||||
"@vue/runtime-core" "3.5.18"
|
||||
"@vue/shared" "3.5.18"
|
||||
csstype "^3.1.3"
|
||||
|
||||
"@vue/server-renderer@3.5.18":
|
||||
version "3.5.18"
|
||||
resolved "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.18.tgz#e9fa267b95b3a1d8cddca762377e5de2ae9122bd"
|
||||
integrity sha512-PvIHLUoWgSbDG7zLHqSqaCoZvHi6NNmfVFOqO+OnwvqMz/tqQr3FuGWS8ufluNddk7ZLBJYMrjcw1c6XzR12mA==
|
||||
dependencies:
|
||||
"@vue/compiler-ssr" "3.5.18"
|
||||
"@vue/shared" "3.5.18"
|
||||
|
||||
"@vue/shared@3.5.18":
|
||||
version "3.5.18"
|
||||
resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.18.tgz#529f24a88d3ed678d50fd5c07455841fbe8ac95e"
|
||||
integrity sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA==
|
||||
|
||||
csstype@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
|
||||
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
|
||||
|
||||
entities@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
|
||||
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
|
||||
|
||||
esbuild@^0.21.3:
|
||||
version "0.21.5"
|
||||
resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d"
|
||||
integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==
|
||||
optionalDependencies:
|
||||
"@esbuild/aix-ppc64" "0.21.5"
|
||||
"@esbuild/android-arm" "0.21.5"
|
||||
"@esbuild/android-arm64" "0.21.5"
|
||||
"@esbuild/android-x64" "0.21.5"
|
||||
"@esbuild/darwin-arm64" "0.21.5"
|
||||
"@esbuild/darwin-x64" "0.21.5"
|
||||
"@esbuild/freebsd-arm64" "0.21.5"
|
||||
"@esbuild/freebsd-x64" "0.21.5"
|
||||
"@esbuild/linux-arm" "0.21.5"
|
||||
"@esbuild/linux-arm64" "0.21.5"
|
||||
"@esbuild/linux-ia32" "0.21.5"
|
||||
"@esbuild/linux-loong64" "0.21.5"
|
||||
"@esbuild/linux-mips64el" "0.21.5"
|
||||
"@esbuild/linux-ppc64" "0.21.5"
|
||||
"@esbuild/linux-riscv64" "0.21.5"
|
||||
"@esbuild/linux-s390x" "0.21.5"
|
||||
"@esbuild/linux-x64" "0.21.5"
|
||||
"@esbuild/netbsd-x64" "0.21.5"
|
||||
"@esbuild/openbsd-x64" "0.21.5"
|
||||
"@esbuild/sunos-x64" "0.21.5"
|
||||
"@esbuild/win32-arm64" "0.21.5"
|
||||
"@esbuild/win32-ia32" "0.21.5"
|
||||
"@esbuild/win32-x64" "0.21.5"
|
||||
|
||||
estree-walker@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
|
||||
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
|
||||
|
||||
fsevents@~2.3.2, fsevents@~2.3.3:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
|
||||
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
|
||||
|
||||
magic-string@^0.30.17:
|
||||
version "0.30.17"
|
||||
resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453"
|
||||
integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==
|
||||
dependencies:
|
||||
"@jridgewell/sourcemap-codec" "^1.5.0"
|
||||
|
||||
nanoid@^3.3.11:
|
||||
version "3.3.11"
|
||||
resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b"
|
||||
integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==
|
||||
|
||||
picocolors@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
|
||||
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
|
||||
|
||||
postcss@^8.4.43, postcss@^8.5.6:
|
||||
version "8.5.6"
|
||||
resolved "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c"
|
||||
integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==
|
||||
dependencies:
|
||||
nanoid "^3.3.11"
|
||||
picocolors "^1.1.1"
|
||||
source-map-js "^1.2.1"
|
||||
|
||||
rollup@^4.20.0:
|
||||
version "4.45.1"
|
||||
resolved "https://registry.npmmirror.com/rollup/-/rollup-4.45.1.tgz#d0ef72a8d0a9210d832f9c3c5f3b6a2aa4b0ba64"
|
||||
integrity sha512-4iya7Jb76fVpQyLoiVpzUrsjQ12r3dM7fIVz+4NwoYvZOShknRmiv+iu9CClZml5ZLGb0XMcYLutK6w9tgxHDw==
|
||||
dependencies:
|
||||
"@types/estree" "1.0.8"
|
||||
optionalDependencies:
|
||||
"@rollup/rollup-android-arm-eabi" "4.45.1"
|
||||
"@rollup/rollup-android-arm64" "4.45.1"
|
||||
"@rollup/rollup-darwin-arm64" "4.45.1"
|
||||
"@rollup/rollup-darwin-x64" "4.45.1"
|
||||
"@rollup/rollup-freebsd-arm64" "4.45.1"
|
||||
"@rollup/rollup-freebsd-x64" "4.45.1"
|
||||
"@rollup/rollup-linux-arm-gnueabihf" "4.45.1"
|
||||
"@rollup/rollup-linux-arm-musleabihf" "4.45.1"
|
||||
"@rollup/rollup-linux-arm64-gnu" "4.45.1"
|
||||
"@rollup/rollup-linux-arm64-musl" "4.45.1"
|
||||
"@rollup/rollup-linux-loongarch64-gnu" "4.45.1"
|
||||
"@rollup/rollup-linux-powerpc64le-gnu" "4.45.1"
|
||||
"@rollup/rollup-linux-riscv64-gnu" "4.45.1"
|
||||
"@rollup/rollup-linux-riscv64-musl" "4.45.1"
|
||||
"@rollup/rollup-linux-s390x-gnu" "4.45.1"
|
||||
"@rollup/rollup-linux-x64-gnu" "4.45.1"
|
||||
"@rollup/rollup-linux-x64-musl" "4.45.1"
|
||||
"@rollup/rollup-win32-arm64-msvc" "4.45.1"
|
||||
"@rollup/rollup-win32-ia32-msvc" "4.45.1"
|
||||
"@rollup/rollup-win32-x64-msvc" "4.45.1"
|
||||
fsevents "~2.3.2"
|
||||
|
||||
source-map-js@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
|
||||
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
|
||||
|
||||
vite@^5.0.0:
|
||||
version "5.4.19"
|
||||
resolved "https://registry.npmmirror.com/vite/-/vite-5.4.19.tgz#20efd060410044b3ed555049418a5e7d1998f959"
|
||||
integrity sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==
|
||||
dependencies:
|
||||
esbuild "^0.21.3"
|
||||
postcss "^8.4.43"
|
||||
rollup "^4.20.0"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.3"
|
||||
|
||||
vue-router@^4.2.5:
|
||||
version "4.5.1"
|
||||
resolved "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.1.tgz#47bffe2d3a5479d2886a9a244547a853aa0abf69"
|
||||
integrity sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==
|
||||
dependencies:
|
||||
"@vue/devtools-api" "^6.6.4"
|
||||
|
||||
vue@^3.4.0:
|
||||
version "3.5.18"
|
||||
resolved "https://registry.npmmirror.com/vue/-/vue-3.5.18.tgz#3d622425ad1391a2b0138323211ec784f4415686"
|
||||
integrity sha512-7W4Y4ZbMiQ3SEo+m9lnoNpV9xG7QVMLa+/0RFwwiAVkeYoyGXqWE85jabU4pllJNUzqfLShJ5YLptewhCWUgNA==
|
||||
dependencies:
|
||||
"@vue/compiler-dom" "3.5.18"
|
||||
"@vue/compiler-sfc" "3.5.18"
|
||||
"@vue/runtime-dom" "3.5.18"
|
||||
"@vue/server-renderer" "3.5.18"
|
||||
"@vue/shared" "3.5.18"
|
||||
Loading…
x
Reference in New Issue
Block a user