mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-19 06:30:10 +08:00
chore: remove qrcode dependency
This commit is contained in:
parent
fc92f356ed
commit
e711824701
@ -98,10 +98,8 @@
|
||||
"node-stream-zip": "^1.15.0",
|
||||
"officeparser": "^4.2.0",
|
||||
"os-proxy-config": "^1.1.2",
|
||||
"qrcode.react": "^4.2.0",
|
||||
"selection-hook": "^1.0.12",
|
||||
"sharp": "^0.34.3",
|
||||
"socket.io": "^4.8.1",
|
||||
"swagger-jsdoc": "^6.2.8",
|
||||
"swagger-ui-express": "^5.0.1",
|
||||
"tesseract.js": "patch:tesseract.js@npm%3A6.0.1#~/.yarn/patches/tesseract.js-npm-6.0.1-2562a7e46d.patch",
|
||||
|
||||
@ -382,13 +382,6 @@ export enum IpcChannel {
|
||||
ClaudeCodePlugin_ReadContent = 'claudeCodePlugin:read-content',
|
||||
ClaudeCodePlugin_WriteContent = 'claudeCodePlugin:write-content',
|
||||
|
||||
// WebSocket
|
||||
WebSocket_Start = 'webSocket:start',
|
||||
WebSocket_Stop = 'webSocket:stop',
|
||||
WebSocket_Status = 'webSocket:status',
|
||||
WebSocket_SendFile = 'webSocket:send-file',
|
||||
WebSocket_GetAllCandidates = 'webSocket:get-all-candidates',
|
||||
|
||||
// Local Transfer
|
||||
LocalTransfer_ListServices = 'local-transfer:list',
|
||||
LocalTransfer_StartScan = 'local-transfer:start-scan',
|
||||
|
||||
@ -76,7 +76,6 @@ import {
|
||||
import storeSyncService from './services/StoreSyncService'
|
||||
import { themeService } from './services/ThemeService'
|
||||
import VertexAIService from './services/VertexAIService'
|
||||
import WebSocketService from './services/WebSocketService'
|
||||
import { setOpenLinkExternal } from './services/WebviewService'
|
||||
import { windowService } from './services/WindowService'
|
||||
import { calculateDirectorySize, getResourcePath } from './utils'
|
||||
@ -1102,13 +1101,6 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
|
||||
}
|
||||
})
|
||||
|
||||
// WebSocket
|
||||
ipcMain.handle(IpcChannel.WebSocket_Start, WebSocketService.start)
|
||||
ipcMain.handle(IpcChannel.WebSocket_Stop, WebSocketService.stop)
|
||||
ipcMain.handle(IpcChannel.WebSocket_Status, WebSocketService.getStatus)
|
||||
ipcMain.handle(IpcChannel.WebSocket_SendFile, WebSocketService.sendFile)
|
||||
ipcMain.handle(IpcChannel.WebSocket_GetAllCandidates, WebSocketService.getAllCandidates)
|
||||
|
||||
ipcMain.handle(IpcChannel.LocalTransfer_ListServices, () => localTransferService.getState())
|
||||
ipcMain.handle(IpcChannel.LocalTransfer_StartScan, () => localTransferService.startDiscovery({ resetList: true }))
|
||||
ipcMain.handle(IpcChannel.LocalTransfer_StopScan, () => localTransferService.stopDiscovery())
|
||||
|
||||
@ -1,359 +0,0 @@
|
||||
import { loggerService } from '@logger'
|
||||
import type { WebSocketCandidatesResponse, WebSocketStatusResponse } from '@shared/config/types'
|
||||
import * as fs from 'fs'
|
||||
import { networkInterfaces } from 'os'
|
||||
import * as path from 'path'
|
||||
import type { Socket } from 'socket.io'
|
||||
import { Server } from 'socket.io'
|
||||
|
||||
import { windowService } from './WindowService'
|
||||
|
||||
const logger = loggerService.withContext('WebSocketService')
|
||||
|
||||
class WebSocketService {
|
||||
private io: Server | null = null
|
||||
private isStarted = false
|
||||
private port = 7017
|
||||
private connectedClients = new Set<string>()
|
||||
|
||||
private getLocalIpAddress(): string | undefined {
|
||||
const interfaces = networkInterfaces()
|
||||
|
||||
// 按优先级排序的网络接口名称模式
|
||||
const interfacePriority = [
|
||||
// macOS: 以太网/Wi-Fi 优先
|
||||
/^en[0-9]+$/, // en0, en1 (以太网/Wi-Fi)
|
||||
/^(en|eth)[0-9]+$/, // 以太网接口
|
||||
/^wlan[0-9]+$/, // 无线接口
|
||||
// Windows: 以太网/Wi-Fi 优先
|
||||
/^(Ethernet|Wi-Fi|Local Area Connection)/,
|
||||
/^(Wi-Fi|无线网络连接)/,
|
||||
// Linux: 以太网/Wi-Fi 优先
|
||||
/^(eth|enp|wlp|wlan)[0-9]+/,
|
||||
// 虚拟化接口(低优先级)
|
||||
/^bridge[0-9]+$/, // Docker bridge
|
||||
/^veth[0-9]+$/, // Docker veth
|
||||
/^docker[0-9]+/, // Docker interfaces
|
||||
/^br-[0-9a-f]+/, // Docker bridge
|
||||
/^vmnet[0-9]+$/, // VMware
|
||||
/^vboxnet[0-9]+$/, // VirtualBox
|
||||
// VPN 隧道接口(低优先级)
|
||||
/^utun[0-9]+$/, // macOS VPN
|
||||
/^tun[0-9]+$/, // Linux/Unix VPN
|
||||
/^tap[0-9]+$/, // TAP interfaces
|
||||
/^tailscale[0-9]*$/, // Tailscale VPN
|
||||
/^wg[0-9]+$/ // WireGuard VPN
|
||||
]
|
||||
|
||||
const candidates: Array<{ interface: string; address: string; priority: number }> = []
|
||||
|
||||
for (const [name, ifaces] of Object.entries(interfaces)) {
|
||||
for (const iface of ifaces || []) {
|
||||
if (iface.family === 'IPv4' && !iface.internal) {
|
||||
// 计算接口优先级
|
||||
let priority = 999 // 默认最低优先级
|
||||
for (let i = 0; i < interfacePriority.length; i++) {
|
||||
if (interfacePriority[i].test(name)) {
|
||||
priority = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
candidates.push({
|
||||
interface: name,
|
||||
address: iface.address,
|
||||
priority
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (candidates.length === 0) {
|
||||
logger.warn('无法获取局域网 IP,使用默认 IP: 127.0.0.1')
|
||||
return '127.0.0.1'
|
||||
}
|
||||
|
||||
// 按优先级排序,选择优先级最高的
|
||||
candidates.sort((a, b) => a.priority - b.priority)
|
||||
const best = candidates[0]
|
||||
|
||||
logger.info(`获取局域网 IP: ${best.address} (interface: ${best.interface})`)
|
||||
return best.address
|
||||
}
|
||||
|
||||
public start = async (): Promise<{ success: boolean; port?: number; error?: string }> => {
|
||||
if (this.isStarted && this.io) {
|
||||
return { success: true, port: this.port }
|
||||
}
|
||||
|
||||
try {
|
||||
this.io = new Server(this.port, {
|
||||
cors: {
|
||||
origin: '*',
|
||||
methods: ['GET', 'POST']
|
||||
},
|
||||
transports: ['websocket', 'polling'],
|
||||
allowEIO3: true,
|
||||
pingTimeout: 60000,
|
||||
pingInterval: 25000
|
||||
})
|
||||
|
||||
this.io.on('connection', (socket: Socket) => {
|
||||
this.connectedClients.add(socket.id)
|
||||
|
||||
const mainWindow = windowService.getMainWindow()
|
||||
if (!mainWindow) {
|
||||
logger.error('Main window is null, cannot send connection event')
|
||||
} else {
|
||||
mainWindow.webContents.send('websocket-client-connected', {
|
||||
connected: true,
|
||||
clientId: socket.id
|
||||
})
|
||||
logger.info(`Connection event sent to renderer, total clients: ${this.connectedClients.size}`)
|
||||
}
|
||||
|
||||
socket.on('message', (data) => {
|
||||
logger.info('Received message from mobile:', data)
|
||||
mainWindow?.webContents.send('websocket-message-received', data)
|
||||
socket.emit('message_received', { success: true })
|
||||
})
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
logger.info(`Client disconnected: ${socket.id}`)
|
||||
this.connectedClients.delete(socket.id)
|
||||
|
||||
if (this.connectedClients.size === 0) {
|
||||
mainWindow?.webContents.send('websocket-client-connected', {
|
||||
connected: false,
|
||||
clientId: socket.id
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// Engine 层面的事件监听
|
||||
this.io.engine.on('connection_error', (err) => {
|
||||
logger.error('Engine connection error:', err)
|
||||
})
|
||||
|
||||
this.io.engine.on('connection', (rawSocket) => {
|
||||
const remoteAddr = rawSocket.request.connection.remoteAddress
|
||||
logger.info(`[Engine] Raw connection from: ${remoteAddr}`)
|
||||
logger.info(`[Engine] Transport: ${rawSocket.transport.name}`)
|
||||
|
||||
rawSocket.on('packet', (packet: { type: string; data?: any }) => {
|
||||
logger.info(
|
||||
`[Engine] ← Packet from ${remoteAddr}: type="${packet.type}"`,
|
||||
packet.data ? { data: packet.data } : {}
|
||||
)
|
||||
})
|
||||
|
||||
rawSocket.on('packetCreate', (packet: { type: string; data?: any }) => {
|
||||
logger.info(`[Engine] → Packet to ${remoteAddr}: type="${packet.type}"`)
|
||||
})
|
||||
|
||||
rawSocket.on('close', (reason: string) => {
|
||||
logger.warn(`[Engine] Connection closed from ${remoteAddr}, reason: ${reason}`)
|
||||
})
|
||||
|
||||
rawSocket.on('error', (error: Error) => {
|
||||
logger.error(`[Engine] Connection error from ${remoteAddr}:`, error)
|
||||
})
|
||||
})
|
||||
|
||||
// Socket.IO 握手失败监听
|
||||
this.io.on('connection_error', (err) => {
|
||||
logger.error('[Socket.IO] Connection error during handshake:', err)
|
||||
})
|
||||
|
||||
this.isStarted = true
|
||||
logger.info(`WebSocket server started on port ${this.port}`)
|
||||
|
||||
return { success: true, port: this.port }
|
||||
} catch (error) {
|
||||
logger.error('Failed to start WebSocket server:', error as Error)
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Unknown error'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public stop = async (): Promise<{ success: boolean }> => {
|
||||
if (!this.isStarted || !this.io) {
|
||||
return { success: true }
|
||||
}
|
||||
|
||||
try {
|
||||
await new Promise<void>((resolve) => {
|
||||
this.io!.close(() => {
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
||||
this.io = null
|
||||
this.isStarted = false
|
||||
this.connectedClients.clear()
|
||||
logger.info('WebSocket server stopped')
|
||||
|
||||
return { success: true }
|
||||
} catch (error) {
|
||||
logger.error('Failed to stop WebSocket server:', error as Error)
|
||||
return { success: false }
|
||||
}
|
||||
}
|
||||
|
||||
public getStatus = async (): Promise<WebSocketStatusResponse> => {
|
||||
return {
|
||||
isRunning: this.isStarted,
|
||||
port: this.isStarted ? this.port : undefined,
|
||||
ip: this.isStarted ? this.getLocalIpAddress() : undefined,
|
||||
clientConnected: this.connectedClients.size > 0
|
||||
}
|
||||
}
|
||||
|
||||
public getAllCandidates = async (): Promise<WebSocketCandidatesResponse[]> => {
|
||||
const interfaces = networkInterfaces()
|
||||
|
||||
// 按优先级排序的网络接口名称模式
|
||||
const interfacePriority = [
|
||||
// macOS: 以太网/Wi-Fi 优先
|
||||
/^en[0-9]+$/, // en0, en1 (以太网/Wi-Fi)
|
||||
/^(en|eth)[0-9]+$/, // 以太网接口
|
||||
/^wlan[0-9]+$/, // 无线接口
|
||||
// Windows: 以太网/Wi-Fi 优先
|
||||
/^(Ethernet|Wi-Fi|Local Area Connection)/,
|
||||
/^(Wi-Fi|无线网络连接)/,
|
||||
// Linux: 以太网/Wi-Fi 优先
|
||||
/^(eth|enp|wlp|wlan)[0-9]+/,
|
||||
// 虚拟化接口(低优先级)
|
||||
/^bridge[0-9]+$/, // Docker bridge
|
||||
/^veth[0-9]+$/, // Docker veth
|
||||
/^docker[0-9]+/, // Docker interfaces
|
||||
/^br-[0-9a-f]+/, // Docker bridge
|
||||
/^vmnet[0-9]+$/, // VMware
|
||||
/^vboxnet[0-9]+$/, // VirtualBox
|
||||
// VPN 隧道接口(低优先级)
|
||||
/^utun[0-9]+$/, // macOS VPN
|
||||
/^tun[0-9]+$/, // Linux/Unix VPN
|
||||
/^tap[0-9]+$/, // TAP interfaces
|
||||
/^tailscale[0-9]*$/, // Tailscale VPN
|
||||
/^wg[0-9]+$/ // WireGuard VPN
|
||||
]
|
||||
|
||||
const candidates: Array<{ host: string; interface: string; priority: number }> = []
|
||||
|
||||
for (const [name, ifaces] of Object.entries(interfaces)) {
|
||||
for (const iface of ifaces || []) {
|
||||
if (iface.family === 'IPv4' && !iface.internal) {
|
||||
// 计算接口优先级
|
||||
let priority = 999 // 默认最低优先级
|
||||
for (let i = 0; i < interfacePriority.length; i++) {
|
||||
if (interfacePriority[i].test(name)) {
|
||||
priority = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
candidates.push({
|
||||
host: iface.address,
|
||||
interface: name,
|
||||
priority
|
||||
})
|
||||
|
||||
logger.debug(`Found interface: ${name} -> ${iface.address} (priority: ${priority})`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 按优先级排序返回
|
||||
candidates.sort((a, b) => a.priority - b.priority)
|
||||
logger.info(
|
||||
`Found ${candidates.length} IP candidates: ${candidates.map((c) => `${c.host}(${c.interface})`).join(', ')}`
|
||||
)
|
||||
return candidates
|
||||
}
|
||||
|
||||
public sendFile = async (
|
||||
_: Electron.IpcMainInvokeEvent,
|
||||
filePath: string
|
||||
): Promise<{ success: boolean; error?: string }> => {
|
||||
if (!this.isStarted || !this.io) {
|
||||
const errorMsg = 'WebSocket server is not running.'
|
||||
logger.error(errorMsg)
|
||||
return { success: false, error: errorMsg }
|
||||
}
|
||||
|
||||
if (this.connectedClients.size === 0) {
|
||||
const errorMsg = 'No client connected.'
|
||||
logger.error(errorMsg)
|
||||
return { success: false, error: errorMsg }
|
||||
}
|
||||
|
||||
const mainWindow = windowService.getMainWindow()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const stats = fs.statSync(filePath)
|
||||
const totalSize = stats.size
|
||||
const filename = path.basename(filePath)
|
||||
const stream = fs.createReadStream(filePath)
|
||||
let bytesSent = 0
|
||||
const startTime = Date.now()
|
||||
|
||||
logger.info(`Starting file transfer: ${filename} (${this.formatFileSize(totalSize)})`)
|
||||
|
||||
// 向客户端发送文件开始的信号,包含文件名和总大小
|
||||
this.io!.emit('zip-file-start', { filename, totalSize })
|
||||
|
||||
stream.on('data', (chunk) => {
|
||||
bytesSent += chunk.length
|
||||
const progress = (bytesSent / totalSize) * 100
|
||||
|
||||
// 向客户端发送文件块
|
||||
this.io!.emit('zip-file-chunk', chunk)
|
||||
|
||||
// 向渲染进程发送进度更新
|
||||
mainWindow?.webContents.send('file-send-progress', { progress })
|
||||
|
||||
// 每10%记录一次进度
|
||||
if (Math.floor(progress) % 10 === 0) {
|
||||
const elapsed = (Date.now() - startTime) / 1000
|
||||
const speed = elapsed > 0 ? bytesSent / elapsed : 0
|
||||
logger.info(`Transfer progress: ${Math.floor(progress)}% (${this.formatFileSize(speed)}/s)`)
|
||||
}
|
||||
})
|
||||
|
||||
stream.on('end', () => {
|
||||
const totalTime = (Date.now() - startTime) / 1000
|
||||
const avgSpeed = totalTime > 0 ? totalSize / totalTime : 0
|
||||
logger.info(
|
||||
`File transfer completed: ${filename} in ${totalTime.toFixed(1)}s (${this.formatFileSize(avgSpeed)}/s)`
|
||||
)
|
||||
|
||||
// 确保发送100%的进度
|
||||
mainWindow?.webContents.send('file-send-progress', { progress: 100 })
|
||||
// 向客户端发送文件结束的信号
|
||||
this.io!.emit('zip-file-end')
|
||||
resolve({ success: true })
|
||||
})
|
||||
|
||||
stream.on('error', (error) => {
|
||||
logger.error(`File transfer failed: ${filename}`, error)
|
||||
reject({
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Unknown error'
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
private formatFileSize(bytes: number): string {
|
||||
if (bytes === 0) return '0 B'
|
||||
const k = 1024
|
||||
const sizes = ['B', 'KB', 'MB', 'GB']
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
|
||||
}
|
||||
}
|
||||
|
||||
export default new WebSocketService()
|
||||
@ -626,13 +626,6 @@ const api = {
|
||||
sendFile: (filePath: string): Promise<LanFileCompleteMessage> =>
|
||||
ipcRenderer.invoke(IpcChannel.LocalTransfer_SendFile, { filePath }),
|
||||
cancelTransfer: (): Promise<void> => ipcRenderer.invoke(IpcChannel.LocalTransfer_CancelTransfer)
|
||||
},
|
||||
webSocket: {
|
||||
start: () => ipcRenderer.invoke(IpcChannel.WebSocket_Start),
|
||||
stop: () => ipcRenderer.invoke(IpcChannel.WebSocket_Stop),
|
||||
status: () => ipcRenderer.invoke(IpcChannel.WebSocket_Status),
|
||||
sendFile: (filePath: string) => ipcRenderer.invoke(IpcChannel.WebSocket_SendFile, filePath),
|
||||
getAllCandidates: () => ipcRenderer.invoke(IpcChannel.WebSocket_GetAllCandidates)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3218,12 +3218,9 @@
|
||||
},
|
||||
"content": "Export some data, including chat logs and settings. Please note that the backup process may take some time. Thank you for your patience.",
|
||||
"lan": {
|
||||
"auto_close_tip": "Auto-closing in {{seconds}} seconds...",
|
||||
"confirm_close_message": "File transfer is in progress. Closing will interrupt the transfer. Are you sure you want to force close?",
|
||||
"confirm_close_title": "Confirm Close",
|
||||
"connected": "Connected",
|
||||
"connection_failed": "Connection failed",
|
||||
"content": "Please ensure your computer and phone are on the same network for LAN transfer. Open the Cherry Studio App to scan this QR code.",
|
||||
"content": "Please ensure your computer and phone are on the same network for LAN transfer.",
|
||||
"device_list_title": "Local network devices",
|
||||
"discovered_devices": "Discovered devices",
|
||||
"error": {
|
||||
@ -3241,8 +3238,6 @@
|
||||
"progress": "Sending... {{progress}}%",
|
||||
"success": "File sent successfully"
|
||||
},
|
||||
"force_close": "Force Close",
|
||||
"generating_qr": "Generating QR code...",
|
||||
"handshake": {
|
||||
"button": "Handshake",
|
||||
"failed": "Handshake failed: {{message}}",
|
||||
@ -3255,14 +3250,10 @@
|
||||
"ip_addresses": "IP addresses",
|
||||
"last_seen": "Last seen at {{time}}",
|
||||
"metadata": "Metadata",
|
||||
"noZipSelected": "No compressed file selected",
|
||||
"no_connection_warning": "Please open LAN Transfer on Cherry Studio mobile",
|
||||
"no_devices": "No LAN peers found yet",
|
||||
"scan_devices": "Scan devices",
|
||||
"scan_qr": "Please scan QR code with your phone",
|
||||
"scanning_hint": "Scanning your local network for Cherry Studio peers...",
|
||||
"selectZip": "Select a compressed file",
|
||||
"sendZip": "Begin data recovery",
|
||||
"send_file": "Send File",
|
||||
"status": {
|
||||
"completed": "Transfer completed",
|
||||
@ -3272,8 +3263,7 @@
|
||||
"error": "Connection error",
|
||||
"initializing": "Initializing connection...",
|
||||
"preparing": "Preparing transfer...",
|
||||
"sending": "Transferring {{progress}}%",
|
||||
"waiting_qr_scan": "Please scan QR code to connect"
|
||||
"sending": "Transferring {{progress}}%"
|
||||
},
|
||||
"status_badge_idle": "Idle",
|
||||
"status_badge_scanning": "Scanning",
|
||||
|
||||
@ -3218,12 +3218,9 @@
|
||||
},
|
||||
"content": "导出部分数据,包括聊天记录、设置。请注意,备份过程可能需要一些时间,感谢您的耐心等待。",
|
||||
"lan": {
|
||||
"auto_close_tip": "{{seconds}} 秒后自动关闭...",
|
||||
"confirm_close_message": "文件正在传输中,关闭将中断传输。确定要强制关闭吗?",
|
||||
"confirm_close_title": "确认关闭",
|
||||
"connected": "连接成功",
|
||||
"connection_failed": "连接失败",
|
||||
"content": "请确保电脑和手机处于同一网络以使用局域网传输。请打开 Cherry Studio App 扫描此二维码。",
|
||||
"content": "请确保电脑和手机处于同一网络以使用局域网传输。",
|
||||
"device_list_title": "局域网设备列表",
|
||||
"discovered_devices": "已发现的设备",
|
||||
"error": {
|
||||
@ -3241,8 +3238,6 @@
|
||||
"progress": "发送中... {{progress}}%",
|
||||
"success": "文件发送成功"
|
||||
},
|
||||
"force_close": "强制关闭",
|
||||
"generating_qr": "正在生成二维码...",
|
||||
"handshake": {
|
||||
"button": "握手测试",
|
||||
"failed": "握手失败:{{message}}",
|
||||
@ -3255,14 +3250,10 @@
|
||||
"ip_addresses": "IP 地址",
|
||||
"last_seen": "最后活动:{{time}}",
|
||||
"metadata": "元数据",
|
||||
"noZipSelected": "未选择压缩文件",
|
||||
"no_connection_warning": "请在 Cherry Studio 移动端打开局域网传输",
|
||||
"no_devices": "尚未发现局域网设备",
|
||||
"scan_devices": "扫描设备",
|
||||
"scan_qr": "请使用手机扫码连接",
|
||||
"scanning_hint": "正在扫描局域网中的 Cherry Studio 设备...",
|
||||
"selectZip": "选择压缩文件",
|
||||
"sendZip": "开始恢复数据",
|
||||
"send_file": "发送文件",
|
||||
"status": {
|
||||
"completed": "传输完成",
|
||||
@ -3272,8 +3263,7 @@
|
||||
"error": "连接出错",
|
||||
"initializing": "正在初始化连接...",
|
||||
"preparing": "准备传输中...",
|
||||
"sending": "传输中 {{progress}}%",
|
||||
"waiting_qr_scan": "请扫描二维码连接"
|
||||
"sending": "传输中 {{progress}}%"
|
||||
},
|
||||
"status_badge_idle": "空闲",
|
||||
"status_badge_scanning": "扫描中",
|
||||
|
||||
@ -3218,12 +3218,9 @@
|
||||
},
|
||||
"content": "匯出部分資料,包括聊天記錄與設定。請注意,備份過程可能需要一些時間,感謝耐心等候。",
|
||||
"lan": {
|
||||
"auto_close_tip": "將於 {{seconds}} 秒後自動關閉...",
|
||||
"confirm_close_message": "檔案傳輸正在進行中。關閉將會中斷傳輸。您確定要強制關閉嗎?",
|
||||
"confirm_close_title": "確認關閉",
|
||||
"connected": "已連線",
|
||||
"connection_failed": "連線失敗",
|
||||
"content": "請確保電腦和手機處於同一網路以使用區域網路傳輸。請開啟 Cherry Studio App 掃描此 QR 碼。",
|
||||
"content": "請確保電腦和手機處於同一網路以使用區域網路傳輸。",
|
||||
"device_list_title": "區域網路裝置",
|
||||
"discovered_devices": "已發現的裝置",
|
||||
"error": {
|
||||
@ -3241,8 +3238,6 @@
|
||||
"progress": "傳送中... {{progress}}%",
|
||||
"success": "檔案傳送成功"
|
||||
},
|
||||
"force_close": "強制關閉",
|
||||
"generating_qr": "正在產生 QR 碼...",
|
||||
"handshake": {
|
||||
"button": "握手",
|
||||
"failed": "握手失敗:{{message}}",
|
||||
@ -3255,14 +3250,10 @@
|
||||
"ip_addresses": "IP 位址",
|
||||
"last_seen": "上次看到:{{time}}",
|
||||
"metadata": "中繼資料",
|
||||
"noZipSelected": "未選取壓縮檔案",
|
||||
"no_connection_warning": "請在 Cherry Studio 行動裝置開啟區域網路傳輸",
|
||||
"no_devices": "尚未找到區域網路節點",
|
||||
"scan_devices": "掃描裝置",
|
||||
"scan_qr": "請使用手機掃描 QR 碼",
|
||||
"scanning_hint": "正在掃描區域網路中的 Cherry Studio 裝置...",
|
||||
"selectZip": "選擇壓縮檔案",
|
||||
"sendZip": "開始還原資料",
|
||||
"send_file": "傳送檔案",
|
||||
"status": {
|
||||
"completed": "傳輸完成",
|
||||
@ -3272,8 +3263,7 @@
|
||||
"error": "連線錯誤",
|
||||
"initializing": "正在初始化連線...",
|
||||
"preparing": "正在準備傳輸...",
|
||||
"sending": "傳輸中 {{progress}}%",
|
||||
"waiting_qr_scan": "請掃描 QR 碼以連線"
|
||||
"sending": "傳輸中 {{progress}}%"
|
||||
},
|
||||
"status_badge_idle": "閒置",
|
||||
"status_badge_scanning": "掃描中",
|
||||
|
||||
@ -3218,9 +3218,6 @@
|
||||
},
|
||||
"content": "Exportieren Sie einige Daten, einschließlich Chat-Protokollen und Einstellungen. Bitte beachten Sie, dass der Sicherungsvorgang einige Zeit in Anspruch nehmen kann. Vielen Dank für Ihre Geduld.",
|
||||
"lan": {
|
||||
"auto_close_tip": "Automatisches Schließen in {{seconds}} Sekunden...",
|
||||
"confirm_close_message": "Dateiübertragung läuft. Beim Schließen wird die Übertragung unterbrochen. Möchten Sie wirklich das Schließen erzwingen?",
|
||||
"confirm_close_title": "Schließen bestätigen",
|
||||
"connected": "Verbunden",
|
||||
"connection_failed": "Verbindung fehlgeschlagen",
|
||||
"content": "Bitte stelle sicher, dass sich dein Computer und dein Telefon im selben Netzwerk befinden, um eine LAN-Übertragung durchzuführen. Öffne die Cherry Studio App, um diesen QR-Code zu scannen.",
|
||||
@ -3241,8 +3238,6 @@
|
||||
"progress": "[to be translated]:Sending... {{progress}}%",
|
||||
"success": "[to be translated]:File sent successfully"
|
||||
},
|
||||
"force_close": "Erzwungenes Schließen",
|
||||
"generating_qr": "QR-Code wird generiert...",
|
||||
"handshake": {
|
||||
"button": "[to be translated]:Handshake",
|
||||
"failed": "[to be translated]:Handshake failed: {{message}}",
|
||||
@ -3255,14 +3250,10 @@
|
||||
"ip_addresses": "[to be translated]:IP addresses",
|
||||
"last_seen": "[to be translated]:Last seen at {{time}}",
|
||||
"metadata": "[to be translated]:Metadata",
|
||||
"noZipSelected": "Keine komprimierte Datei ausgewählt",
|
||||
"no_connection_warning": "[to be translated]:Please open LAN Transfer on Cherry Studio mobile",
|
||||
"no_devices": "[to be translated]:No LAN peers found yet",
|
||||
"scan_devices": "[to be translated]:Scan devices",
|
||||
"scan_qr": "Bitte scannen Sie den QR-Code mit Ihrem Telefon.",
|
||||
"scanning_hint": "[to be translated]:Scanning your local network for Cherry Studio peers...",
|
||||
"selectZip": "Wählen Sie eine komprimierte Datei",
|
||||
"sendZip": "Datenwiederherstellung beginnen",
|
||||
"send_file": "[to be translated]:Send File",
|
||||
"status": {
|
||||
"completed": "Übertragung abgeschlossen",
|
||||
@ -3272,8 +3263,7 @@
|
||||
"error": "Verbindungsfehler",
|
||||
"initializing": "Verbindung wird initialisiert...",
|
||||
"preparing": "Übertragung wird vorbereitet...",
|
||||
"sending": "Übertrage {{progress}}%",
|
||||
"waiting_qr_scan": "Bitte QR-Code scannen, um zu verbinden"
|
||||
"sending": "Übertrage {{progress}}%"
|
||||
},
|
||||
"status_badge_idle": "[to be translated]:Idle",
|
||||
"status_badge_scanning": "[to be translated]:Scanning",
|
||||
|
||||
@ -3218,9 +3218,6 @@
|
||||
},
|
||||
"content": "Εξαγωγή μέρους των δεδομένων, συμπεριλαμβανομένων των ιστορικών συνομιλιών και των ρυθμίσεων. Σημειώστε ότι η διαδικασία δημιουργίας αντιγράφων ασφαλείας ενδέχεται να διαρκέσει κάποιο χρονικό διάστημα, ευχαριστούμε για την υπομονή σας.",
|
||||
"lan": {
|
||||
"auto_close_tip": "Αυτόματο κλείσιμο σε {{seconds}} δευτερόλεπτα...",
|
||||
"confirm_close_message": "Η μεταφορά αρχείων είναι σε εξέλιξη. Το κλείσιμο θα διακόψει τη μεταφορά. Είστε σίγουροι ότι θέλετε να κλείσετε βίαια;",
|
||||
"confirm_close_title": "Επιβεβαίωση Κλεισίματος",
|
||||
"connected": "Συνδεδεμένος",
|
||||
"connection_failed": "Η σύνδεση απέτυχε",
|
||||
"content": "Βεβαιωθείτε ότι ο υπολογιστής και το κινητό βρίσκονται στο ίδιο δίκτυο για να χρησιμοποιήσετε τη μεταφορά LAN. Ανοίξτε την εφαρμογή Cherry Studio και σαρώστε αυτόν τον κωδικό QR.",
|
||||
@ -3241,8 +3238,6 @@
|
||||
"progress": "[to be translated]:Sending... {{progress}}%",
|
||||
"success": "[to be translated]:File sent successfully"
|
||||
},
|
||||
"force_close": "Κλείσιμο με βία",
|
||||
"generating_qr": "Δημιουργία κώδικα QR...",
|
||||
"handshake": {
|
||||
"button": "[to be translated]:Handshake",
|
||||
"failed": "[to be translated]:Handshake failed: {{message}}",
|
||||
@ -3255,14 +3250,10 @@
|
||||
"ip_addresses": "[to be translated]:IP addresses",
|
||||
"last_seen": "[to be translated]:Last seen at {{time}}",
|
||||
"metadata": "[to be translated]:Metadata",
|
||||
"noZipSelected": "Δεν επιλέχθηκε συμπιεσμένο αρχείο",
|
||||
"no_connection_warning": "[to be translated]:Please open LAN Transfer on Cherry Studio mobile",
|
||||
"no_devices": "[to be translated]:No LAN peers found yet",
|
||||
"scan_devices": "[to be translated]:Scan devices",
|
||||
"scan_qr": "Παρακαλώ σαρώστε τον κωδικό QR με το τηλέφωνό σας",
|
||||
"scanning_hint": "[to be translated]:Scanning your local network for Cherry Studio peers...",
|
||||
"selectZip": "Επιλέξτε συμπιεσμένο αρχείο",
|
||||
"sendZip": "Έναρξη ανάκτησης δεδομένων",
|
||||
"send_file": "[to be translated]:Send File",
|
||||
"status": {
|
||||
"completed": "Η μεταφορά ολοκληρώθηκε",
|
||||
@ -3272,8 +3263,7 @@
|
||||
"error": "Σφάλμα σύνδεσης",
|
||||
"initializing": "Αρχικοποίηση σύνδεσης...",
|
||||
"preparing": "Προετοιμασία μεταφοράς...",
|
||||
"sending": "Μεταφορά {{progress}}%",
|
||||
"waiting_qr_scan": "Παρακαλώ σαρώστε τον κωδικό QR για σύνδεση"
|
||||
"sending": "Μεταφορά {{progress}}%"
|
||||
},
|
||||
"status_badge_idle": "[to be translated]:Idle",
|
||||
"status_badge_scanning": "[to be translated]:Scanning",
|
||||
|
||||
@ -3218,9 +3218,6 @@
|
||||
},
|
||||
"content": "Exportar parte de los datos, incluidos los registros de chat y la configuración. Tenga en cuenta que el proceso de copia de seguridad puede tardar un tiempo; gracias por su paciencia.",
|
||||
"lan": {
|
||||
"auto_close_tip": "Cierre automático en {{seconds}} segundos...",
|
||||
"confirm_close_message": "La transferencia de archivos está en progreso. Cerrar interrumpirá la transferencia. ¿Estás seguro de que quieres forzar el cierre?",
|
||||
"confirm_close_title": "Confirmar Cierre",
|
||||
"connected": "Conectado",
|
||||
"connection_failed": "Conexión fallida",
|
||||
"content": "Asegúrate de que el ordenador y el móvil estén en la misma red para usar la transferencia por LAN. Abre la aplicación Cherry Studio y escanea este código QR.",
|
||||
@ -3241,8 +3238,6 @@
|
||||
"progress": "[to be translated]:Sending... {{progress}}%",
|
||||
"success": "[to be translated]:File sent successfully"
|
||||
},
|
||||
"force_close": "Cerrar forzosamente",
|
||||
"generating_qr": "Generando código QR...",
|
||||
"handshake": {
|
||||
"button": "[to be translated]:Handshake",
|
||||
"failed": "[to be translated]:Handshake failed: {{message}}",
|
||||
@ -3255,14 +3250,10 @@
|
||||
"ip_addresses": "[to be translated]:IP addresses",
|
||||
"last_seen": "[to be translated]:Last seen at {{time}}",
|
||||
"metadata": "[to be translated]:Metadata",
|
||||
"noZipSelected": "No se ha seleccionado ningún archivo comprimido",
|
||||
"no_connection_warning": "[to be translated]:Please open LAN Transfer on Cherry Studio mobile",
|
||||
"no_devices": "[to be translated]:No LAN peers found yet",
|
||||
"scan_devices": "[to be translated]:Scan devices",
|
||||
"scan_qr": "Por favor, escanea el código QR con tu teléfono",
|
||||
"scanning_hint": "[to be translated]:Scanning your local network for Cherry Studio peers...",
|
||||
"selectZip": "Seleccionar archivo comprimido",
|
||||
"sendZip": "Comenzar la recuperación de datos",
|
||||
"send_file": "[to be translated]:Send File",
|
||||
"status": {
|
||||
"completed": "Transferencia completada",
|
||||
@ -3272,8 +3263,7 @@
|
||||
"error": "Error de conexión",
|
||||
"initializing": "Inicializando conexión...",
|
||||
"preparing": "Preparando transferencia...",
|
||||
"sending": "Transfiriendo {{progress}}%",
|
||||
"waiting_qr_scan": "Por favor, escanea el código QR para conectarte"
|
||||
"sending": "Transfiriendo {{progress}}%"
|
||||
},
|
||||
"status_badge_idle": "[to be translated]:Idle",
|
||||
"status_badge_scanning": "[to be translated]:Scanning",
|
||||
|
||||
@ -3218,9 +3218,6 @@
|
||||
},
|
||||
"content": "Exporter une partie des données, incluant les historiques de discussion et les paramètres. Veuillez noter que le processus de sauvegarde peut prendre un certain temps ; merci pour votre patience.",
|
||||
"lan": {
|
||||
"auto_close_tip": "Fermeture automatique dans {{seconds}} secondes...",
|
||||
"confirm_close_message": "Le transfert de fichier est en cours. Fermer interrompra le transfert. Êtes-vous sûr de vouloir forcer la fermeture ?",
|
||||
"confirm_close_title": "Confirmer la fermeture",
|
||||
"connected": "Connecté",
|
||||
"connection_failed": "Échec de la connexion",
|
||||
"content": "Assurez-vous que l'ordinateur et le téléphone sont connectés au même réseau pour utiliser le transfert en réseau local. Ouvrez l'application Cherry Studio et scannez ce code QR.",
|
||||
@ -3241,8 +3238,6 @@
|
||||
"progress": "[to be translated]:Sending... {{progress}}%",
|
||||
"success": "[to be translated]:File sent successfully"
|
||||
},
|
||||
"force_close": "Fermer de force",
|
||||
"generating_qr": "Génération du code QR...",
|
||||
"handshake": {
|
||||
"button": "[to be translated]:Handshake",
|
||||
"failed": "[to be translated]:Handshake failed: {{message}}",
|
||||
@ -3255,14 +3250,10 @@
|
||||
"ip_addresses": "[to be translated]:IP addresses",
|
||||
"last_seen": "[to be translated]:Last seen at {{time}}",
|
||||
"metadata": "[to be translated]:Metadata",
|
||||
"noZipSelected": "Aucun fichier compressé sélectionné",
|
||||
"no_connection_warning": "[to be translated]:Please open LAN Transfer on Cherry Studio mobile",
|
||||
"no_devices": "[to be translated]:No LAN peers found yet",
|
||||
"scan_devices": "[to be translated]:Scan devices",
|
||||
"scan_qr": "Veuillez scanner le code QR avec votre téléphone",
|
||||
"scanning_hint": "[to be translated]:Scanning your local network for Cherry Studio peers...",
|
||||
"selectZip": "Sélectionner le fichier compressé",
|
||||
"sendZip": "Commencer la restauration des données",
|
||||
"send_file": "[to be translated]:Send File",
|
||||
"status": {
|
||||
"completed": "Transfert terminé",
|
||||
@ -3272,8 +3263,7 @@
|
||||
"error": "Erreur de connexion",
|
||||
"initializing": "Initialisation de la connexion...",
|
||||
"preparing": "Préparation du transfert...",
|
||||
"sending": "Transfert {{progress}} %",
|
||||
"waiting_qr_scan": "Veuillez scanner le code QR pour vous connecter"
|
||||
"sending": "Transfert {{progress}} %"
|
||||
},
|
||||
"status_badge_idle": "[to be translated]:Idle",
|
||||
"status_badge_scanning": "[to be translated]:Scanning",
|
||||
|
||||
@ -3218,9 +3218,6 @@
|
||||
},
|
||||
"content": "一部のデータ、チャット履歴や設定をエクスポートします。バックアップには時間がかかる場合がありますので、しばらくお待ちください。",
|
||||
"lan": {
|
||||
"auto_close_tip": "{{seconds}}秒後に自動的に閉じます...",
|
||||
"confirm_close_message": "ファイル転送が進行中です。閉じると転送が中断されます。強制終了してもよろしいですか?",
|
||||
"confirm_close_title": "閉じることを確認",
|
||||
"connected": "接続済み",
|
||||
"connection_failed": "接続に失敗しました",
|
||||
"content": "コンピューターとスマートフォンが同じネットワークに接続されていることを確認し、ローカルエリアネットワーク転送を使用してください。Cherry Studioアプリを開き、このQRコードをスキャンしてください。",
|
||||
@ -3241,8 +3238,6 @@
|
||||
"progress": "[to be translated]:Sending... {{progress}}%",
|
||||
"success": "[to be translated]:File sent successfully"
|
||||
},
|
||||
"force_close": "強制終了",
|
||||
"generating_qr": "QRコードを生成中...",
|
||||
"handshake": {
|
||||
"button": "[to be translated]:Handshake",
|
||||
"failed": "[to be translated]:Handshake failed: {{message}}",
|
||||
@ -3255,14 +3250,10 @@
|
||||
"ip_addresses": "[to be translated]:IP addresses",
|
||||
"last_seen": "[to be translated]:Last seen at {{time}}",
|
||||
"metadata": "[to be translated]:Metadata",
|
||||
"noZipSelected": "圧縮ファイルが選択されていません",
|
||||
"no_connection_warning": "[to be translated]:Please open LAN Transfer on Cherry Studio mobile",
|
||||
"no_devices": "[to be translated]:No LAN peers found yet",
|
||||
"scan_devices": "[to be translated]:Scan devices",
|
||||
"scan_qr": "携帯電話でQRコードをスキャンしてください",
|
||||
"scanning_hint": "[to be translated]:Scanning your local network for Cherry Studio peers...",
|
||||
"selectZip": "圧縮ファイルを選択",
|
||||
"sendZip": "データの復元を開始します",
|
||||
"send_file": "[to be translated]:Send File",
|
||||
"status": {
|
||||
"completed": "転送完了",
|
||||
@ -3272,8 +3263,7 @@
|
||||
"error": "接続エラー",
|
||||
"initializing": "接続を初期化中...",
|
||||
"preparing": "転送準備中...",
|
||||
"sending": "転送中 {{progress}}%",
|
||||
"waiting_qr_scan": "QRコードをスキャンして接続してください"
|
||||
"sending": "転送中 {{progress}}%"
|
||||
},
|
||||
"status_badge_idle": "[to be translated]:Idle",
|
||||
"status_badge_scanning": "[to be translated]:Scanning",
|
||||
|
||||
@ -3218,9 +3218,6 @@
|
||||
},
|
||||
"content": "Exportar parte dos dados, incluindo registros de conversas e configurações. Observe que o processo de backup pode demorar um pouco; agradecemos sua paciência.",
|
||||
"lan": {
|
||||
"auto_close_tip": "Fechando automaticamente em {{seconds}} segundos...",
|
||||
"confirm_close_message": "Transferência de arquivo em andamento. Fechar irá interromper a transferência. Tem certeza de que deseja forçar o fechamento?",
|
||||
"confirm_close_title": "Confirmar Fechamento",
|
||||
"connected": "Conectado",
|
||||
"connection_failed": "Falha na conexão",
|
||||
"content": "Certifique-se de que o computador e o telefone estejam na mesma rede para usar a transferência via LAN. Abra o aplicativo Cherry Studio e escaneie este código QR.",
|
||||
@ -3241,8 +3238,6 @@
|
||||
"progress": "[to be translated]:Sending... {{progress}}%",
|
||||
"success": "[to be translated]:File sent successfully"
|
||||
},
|
||||
"force_close": "Forçar Fechamento",
|
||||
"generating_qr": "Gerando código QR...",
|
||||
"handshake": {
|
||||
"button": "[to be translated]:Handshake",
|
||||
"failed": "[to be translated]:Handshake failed: {{message}}",
|
||||
@ -3255,14 +3250,10 @@
|
||||
"ip_addresses": "[to be translated]:IP addresses",
|
||||
"last_seen": "[to be translated]:Last seen at {{time}}",
|
||||
"metadata": "[to be translated]:Metadata",
|
||||
"noZipSelected": "Nenhum arquivo de compressão selecionado",
|
||||
"no_connection_warning": "[to be translated]:Please open LAN Transfer on Cherry Studio mobile",
|
||||
"no_devices": "[to be translated]:No LAN peers found yet",
|
||||
"scan_devices": "[to be translated]:Scan devices",
|
||||
"scan_qr": "Por favor, escaneie o código QR com o seu telefone",
|
||||
"scanning_hint": "[to be translated]:Scanning your local network for Cherry Studio peers...",
|
||||
"selectZip": "Selecionar arquivo compactado",
|
||||
"sendZip": "Iniciar recuperação de dados",
|
||||
"send_file": "[to be translated]:Send File",
|
||||
"status": {
|
||||
"completed": "Transferência concluída",
|
||||
@ -3272,8 +3263,7 @@
|
||||
"error": "Erro de conexão",
|
||||
"initializing": "Inicializando conexão...",
|
||||
"preparing": "Preparando transferência...",
|
||||
"sending": "Transferindo {{progress}}%",
|
||||
"waiting_qr_scan": "Por favor, escaneie o código QR para conectar"
|
||||
"sending": "Transferindo {{progress}}%"
|
||||
},
|
||||
"status_badge_idle": "[to be translated]:Idle",
|
||||
"status_badge_scanning": "[to be translated]:Scanning",
|
||||
|
||||
@ -3218,9 +3218,6 @@
|
||||
},
|
||||
"content": "Экспорт части данных, включая историю чатов и настройки. Обратите внимание, процесс резервного копирования может занять некоторое время, благодарим за ваше терпение.",
|
||||
"lan": {
|
||||
"auto_close_tip": "Автоматическое закрытие через {{seconds}} секунд...",
|
||||
"confirm_close_message": "Передача файла в процессе. Закрытие прервет передачу. Вы уверены, что хотите принудительно закрыть?",
|
||||
"confirm_close_title": "Подтвердить закрытие",
|
||||
"connected": "Подключено",
|
||||
"connection_failed": "Соединение не удалось",
|
||||
"content": "Убедитесь, что компьютер и телефон подключены к одной сети, чтобы использовать локальную передачу. Откройте приложение Cherry Studio и отсканируйте этот QR-код.",
|
||||
@ -3241,8 +3238,6 @@
|
||||
"progress": "[to be translated]:Sending... {{progress}}%",
|
||||
"success": "[to be translated]:File sent successfully"
|
||||
},
|
||||
"force_close": "Принудительное закрытие",
|
||||
"generating_qr": "Генерация QR-кода...",
|
||||
"handshake": {
|
||||
"button": "[to be translated]:Handshake",
|
||||
"failed": "[to be translated]:Handshake failed: {{message}}",
|
||||
@ -3255,14 +3250,10 @@
|
||||
"ip_addresses": "[to be translated]:IP addresses",
|
||||
"last_seen": "[to be translated]:Last seen at {{time}}",
|
||||
"metadata": "[to be translated]:Metadata",
|
||||
"noZipSelected": "Архив не выбран",
|
||||
"no_connection_warning": "[to be translated]:Please open LAN Transfer on Cherry Studio mobile",
|
||||
"no_devices": "[to be translated]:No LAN peers found yet",
|
||||
"scan_devices": "[to be translated]:Scan devices",
|
||||
"scan_qr": "Пожалуйста, отсканируйте QR-код с помощью вашего телефона",
|
||||
"scanning_hint": "[to be translated]:Scanning your local network for Cherry Studio peers...",
|
||||
"selectZip": "Выберите архив",
|
||||
"sendZip": "Начать восстановление данных",
|
||||
"send_file": "[to be translated]:Send File",
|
||||
"status": {
|
||||
"completed": "Перевод завершён",
|
||||
@ -3272,8 +3263,7 @@
|
||||
"error": "Ошибка подключения",
|
||||
"initializing": "Инициализация соединения...",
|
||||
"preparing": "Подготовка передачи...",
|
||||
"sending": "Передача {{progress}}%",
|
||||
"waiting_qr_scan": "Пожалуйста, отсканируйте QR-код для подключения"
|
||||
"sending": "Передача {{progress}}%"
|
||||
},
|
||||
"status_badge_idle": "[to be translated]:Idle",
|
||||
"status_badge_scanning": "[to be translated]:Scanning",
|
||||
|
||||
152
yarn.lock
152
yarn.lock
@ -7250,13 +7250,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@socket.io/component-emitter@npm:~3.1.0":
|
||||
version: 3.1.2
|
||||
resolution: "@socket.io/component-emitter@npm:3.1.2"
|
||||
checksum: 10c0/c4242bad66f67e6f7b712733d25b43cbb9e19a595c8701c3ad99cbeb5901555f78b095e24852f862fffb43e96f1d8552e62def885ca82ae1bb05da3668fd87d7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@standard-schema/spec@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "@standard-schema/spec@npm:1.0.0"
|
||||
@ -8274,7 +8267,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/cors@npm:^2.8.12, @types/cors@npm:^2.8.19":
|
||||
"@types/cors@npm:^2.8.19":
|
||||
version: 2.8.19
|
||||
resolution: "@types/cors@npm:2.8.19"
|
||||
dependencies:
|
||||
@ -8831,15 +8824,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:>=10.0.0":
|
||||
version: 24.3.1
|
||||
resolution: "@types/node@npm:24.3.1"
|
||||
dependencies:
|
||||
undici-types: "npm:~7.10.0"
|
||||
checksum: 10c0/99b86fc32294fcd61136ca1f771026443a1e370e9f284f75e243b29299dd878e18c193deba1ce29a374932db4e30eb80826e1049b9aad02d36f5c30b94b6f928
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:^18.11.18":
|
||||
version: 18.19.86
|
||||
resolution: "@types/node@npm:18.19.86"
|
||||
@ -10286,7 +10270,6 @@ __metadata:
|
||||
pdf-lib: "npm:^1.17.1"
|
||||
pdf-parse: "npm:^1.1.1"
|
||||
proxy-agent: "npm:^6.5.0"
|
||||
qrcode.react: "npm:^4.2.0"
|
||||
react: "npm:^19.2.0"
|
||||
react-dom: "npm:^19.2.0"
|
||||
react-error-boundary: "npm:^6.0.0"
|
||||
@ -10318,7 +10301,6 @@ __metadata:
|
||||
selection-hook: "npm:^1.0.12"
|
||||
sharp: "npm:^0.34.3"
|
||||
shiki: "npm:^3.12.0"
|
||||
socket.io: "npm:^4.8.1"
|
||||
strict-url-sanitise: "npm:^0.0.1"
|
||||
string-width: "npm:^7.2.0"
|
||||
striptags: "npm:^3.2.0"
|
||||
@ -10381,16 +10363,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"accepts@npm:~1.3.4":
|
||||
version: 1.3.8
|
||||
resolution: "accepts@npm:1.3.8"
|
||||
dependencies:
|
||||
mime-types: "npm:~2.1.34"
|
||||
negotiator: "npm:0.6.3"
|
||||
checksum: 10c0/3a35c5f5586cfb9a21163ca47a5f77ac34fa8ceb5d17d2fa2c0d81f41cbd7f8c6fa52c77e2c039acc0f4d09e71abdc51144246900f6bef5e3c4b333f77d89362
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"acorn-jsx@npm:^5.3.2":
|
||||
version: 5.3.2
|
||||
resolution: "acorn-jsx@npm:5.3.2"
|
||||
@ -11029,13 +11001,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"base64id@npm:2.0.0, base64id@npm:~2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "base64id@npm:2.0.0"
|
||||
checksum: 10c0/6919efd237ed44b9988cbfc33eca6f173a10e810ce50292b271a1a421aac7748ef232a64d1e6032b08f19aae48dce6ee8f66c5ae2c9e5066c82b884861d4d453
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"basic-ftp@npm:^5.0.2":
|
||||
version: 5.0.5
|
||||
resolution: "basic-ftp@npm:5.0.5"
|
||||
@ -12272,7 +12237,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cookie@npm:^0.7.1, cookie@npm:~0.7.2":
|
||||
"cookie@npm:^0.7.1":
|
||||
version: 0.7.2
|
||||
resolution: "cookie@npm:0.7.2"
|
||||
checksum: 10c0/9596e8ccdbf1a3a88ae02cf5ee80c1c50959423e1022e4e60b91dd87c622af1da309253d8abdb258fb5e3eacb4f08e579dc58b4897b8087574eee0fd35dfa5d2
|
||||
@ -12309,7 +12274,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cors@npm:^2.8.5, cors@npm:~2.8.5":
|
||||
"cors@npm:^2.8.5":
|
||||
version: 2.8.5
|
||||
resolution: "cors@npm:2.8.5"
|
||||
dependencies:
|
||||
@ -12979,18 +12944,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"debug@npm:~4.3.1, debug@npm:~4.3.2, debug@npm:~4.3.4":
|
||||
version: 4.3.7
|
||||
resolution: "debug@npm:4.3.7"
|
||||
dependencies:
|
||||
ms: "npm:^2.1.3"
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
checksum: 10c0/1471db19c3b06d485a622d62f65947a19a23fbd0dd73f7fd3eafb697eec5360cde447fb075919987899b1a2096e85d35d4eb5a4de09a57600ac9cf7e6c8e768b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"decamelize@npm:1.2.0":
|
||||
version: 1.2.0
|
||||
resolution: "decamelize@npm:1.2.0"
|
||||
@ -13956,30 +13909,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"engine.io-parser@npm:~5.2.1":
|
||||
version: 5.2.3
|
||||
resolution: "engine.io-parser@npm:5.2.3"
|
||||
checksum: 10c0/ed4900d8dbef470ab3839ccf3bfa79ee518ea8277c7f1f2759e8c22a48f64e687ea5e474291394d0c94f84054749fd93f3ef0acb51fa2f5f234cc9d9d8e7c536
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"engine.io@npm:~6.6.0":
|
||||
version: 6.6.4
|
||||
resolution: "engine.io@npm:6.6.4"
|
||||
dependencies:
|
||||
"@types/cors": "npm:^2.8.12"
|
||||
"@types/node": "npm:>=10.0.0"
|
||||
accepts: "npm:~1.3.4"
|
||||
base64id: "npm:2.0.0"
|
||||
cookie: "npm:~0.7.2"
|
||||
cors: "npm:~2.8.5"
|
||||
debug: "npm:~4.3.1"
|
||||
engine.io-parser: "npm:~5.2.1"
|
||||
ws: "npm:~8.17.1"
|
||||
checksum: 10c0/845761163f8ea7962c049df653b75dafb6b3693ad6f59809d4474751d7b0392cbf3dc2730b8a902ff93677a91fd28711d34ab29efd348a8a4b49c6b0724021ab
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"enhanced-resolve@npm:^5.18.3":
|
||||
version: 5.18.3
|
||||
resolution: "enhanced-resolve@npm:5.18.3"
|
||||
@ -19158,7 +19087,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mime-types@npm:^2.1.12, mime-types@npm:^2.1.35, mime-types@npm:~2.1.34":
|
||||
"mime-types@npm:^2.1.12, mime-types@npm:^2.1.35":
|
||||
version: 2.1.35
|
||||
resolution: "mime-types@npm:2.1.35"
|
||||
dependencies:
|
||||
@ -19657,13 +19586,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"negotiator@npm:0.6.3":
|
||||
version: 0.6.3
|
||||
resolution: "negotiator@npm:0.6.3"
|
||||
checksum: 10c0/3ec9fd413e7bf071c937ae60d572bc67155262068ed522cf4b3be5edbe6ddf67d095ec03a3a14ebf8fc8e95f8e1d61be4869db0dbb0de696f6b837358bd43fc2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"negotiator@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "negotiator@npm:1.0.0"
|
||||
@ -21353,15 +21275,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"qrcode.react@npm:^4.2.0":
|
||||
version: 4.2.0
|
||||
resolution: "qrcode.react@npm:4.2.0"
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
checksum: 10c0/68c691d130e5fda2f57cee505ed7aea840e7d02033100687b764601f9595e1116e34c13876628a93e1a5c2b85e4efc27d30b2fda72e2050c02f3e1c4e998d248
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"qs@npm:^6.14.0":
|
||||
version: 6.14.0
|
||||
resolution: "qs@npm:6.14.0"
|
||||
@ -23638,41 +23551,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"socket.io-adapter@npm:~2.5.2":
|
||||
version: 2.5.5
|
||||
resolution: "socket.io-adapter@npm:2.5.5"
|
||||
dependencies:
|
||||
debug: "npm:~4.3.4"
|
||||
ws: "npm:~8.17.1"
|
||||
checksum: 10c0/04a5a2a9c4399d1b6597c2afc4492ab1e73430cc124ab02b09e948eabf341180b3866e2b61b5084cb899beb68a4db7c328c29bda5efb9207671b5cb0bc6de44e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"socket.io-parser@npm:~4.2.4":
|
||||
version: 4.2.4
|
||||
resolution: "socket.io-parser@npm:4.2.4"
|
||||
dependencies:
|
||||
"@socket.io/component-emitter": "npm:~3.1.0"
|
||||
debug: "npm:~4.3.1"
|
||||
checksum: 10c0/9383b30358fde4a801ea4ec5e6860915c0389a091321f1c1f41506618b5cf7cd685d0a31c587467a0c4ee99ef98c2b99fb87911f9dfb329716c43b587f29ca48
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"socket.io@npm:^4.8.1":
|
||||
version: 4.8.1
|
||||
resolution: "socket.io@npm:4.8.1"
|
||||
dependencies:
|
||||
accepts: "npm:~1.3.4"
|
||||
base64id: "npm:~2.0.0"
|
||||
cors: "npm:~2.8.5"
|
||||
debug: "npm:~4.3.2"
|
||||
engine.io: "npm:~6.6.0"
|
||||
socket.io-adapter: "npm:~2.5.2"
|
||||
socket.io-parser: "npm:~4.2.4"
|
||||
checksum: 10c0/acf931a2bb235be96433b71da3d8addc63eeeaa8acabd33dc8d64e12287390a45f1e9f389a73cf7dc336961cd491679741b7a016048325c596835abbcc017ca9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"socks-proxy-agent@npm:^8.0.3, socks-proxy-agent@npm:^8.0.5":
|
||||
version: 8.0.5
|
||||
resolution: "socks-proxy-agent@npm:8.0.5"
|
||||
@ -25169,13 +25047,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"undici-types@npm:~7.10.0":
|
||||
version: 7.10.0
|
||||
resolution: "undici-types@npm:7.10.0"
|
||||
checksum: 10c0/8b00ce50e235fe3cc601307f148b5e8fb427092ee3b23e8118ec0a5d7f68eca8cee468c8fc9f15cbb2cf2a3797945ebceb1cbd9732306a1d00e0a9b6afa0f635
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"undici@npm:6.21.2":
|
||||
version: 6.21.2
|
||||
resolution: "undici@npm:6.21.2"
|
||||
@ -26203,21 +26074,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ws@npm:~8.17.1":
|
||||
version: 8.17.1
|
||||
resolution: "ws@npm:8.17.1"
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: ">=5.0.2"
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
checksum: 10c0/f4a49064afae4500be772abdc2211c8518f39e1c959640457dcee15d4488628620625c783902a52af2dd02f68558da2868fd06e6fd0e67ebcd09e6881b1b5bfe
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"xlsx@https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz":
|
||||
version: 0.20.2
|
||||
resolution: "xlsx@https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user