- 初始化
@@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"recommendations": ["tauri-apps.tauri-vscode", "rust-lang.rust-analyzer"]
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Tauri + React
|
||||||
|
|
||||||
|
This template should help get you started developing with Tauri and React in Vite.
|
||||||
|
|
||||||
|
## Recommended IDE Setup
|
||||||
|
|
||||||
|
- [VS Code](https://code.visualstudio.com/) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<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" />
|
||||||
|
<title>Tauri + React</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.jsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "dpm",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.1.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"tauri": "tauri"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"react": "^19.1.0",
|
||||||
|
"react-dom": "^19.1.0",
|
||||||
|
"@tauri-apps/api": "^2",
|
||||||
|
"@tauri-apps/plugin-opener": "^2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vitejs/plugin-react": "^4.6.0",
|
||||||
|
"vite": "^7.0.4",
|
||||||
|
"@tauri-apps/cli": "^2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<svg width="206" height="231" viewBox="0 0 206 231" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M143.143 84C143.143 96.1503 133.293 106 121.143 106C108.992 106 99.1426 96.1503 99.1426 84C99.1426 71.8497 108.992 62 121.143 62C133.293 62 143.143 71.8497 143.143 84Z" fill="#FFC131"/>
|
||||||
|
<ellipse cx="84.1426" cy="147" rx="22" ry="22" transform="rotate(180 84.1426 147)" fill="#24C8DB"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M166.738 154.548C157.86 160.286 148.023 164.269 137.757 166.341C139.858 160.282 141 153.774 141 147C141 144.543 140.85 142.121 140.558 139.743C144.975 138.204 149.215 136.139 153.183 133.575C162.73 127.404 170.292 118.608 174.961 108.244C179.63 97.8797 181.207 86.3876 179.502 75.1487C177.798 63.9098 172.884 53.4021 165.352 44.8883C157.82 36.3744 147.99 30.2165 137.042 27.1546C126.095 24.0926 114.496 24.2568 103.64 27.6274C92.7839 30.998 83.1319 37.4317 75.8437 46.1553C74.9102 47.2727 74.0206 48.4216 73.176 49.5993C61.9292 50.8488 51.0363 54.0318 40.9629 58.9556C44.2417 48.4586 49.5653 38.6591 56.679 30.1442C67.0505 17.7298 80.7861 8.57426 96.2354 3.77762C111.685 -1.01901 128.19 -1.25267 143.769 3.10474C159.348 7.46215 173.337 16.2252 184.056 28.3411C194.775 40.457 201.767 55.4101 204.193 71.404C206.619 87.3978 204.374 103.752 197.73 118.501C191.086 133.25 180.324 145.767 166.738 154.548ZM41.9631 74.275L62.5557 76.8042C63.0459 72.813 63.9401 68.9018 65.2138 65.1274C57.0465 67.0016 49.2088 70.087 41.9631 74.275Z" fill="#FFC131"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M38.4045 76.4519C47.3493 70.6709 57.2677 66.6712 67.6171 64.6132C65.2774 70.9669 64 77.8343 64 85.0001C64 87.1434 64.1143 89.26 64.3371 91.3442C60.0093 92.8732 55.8533 94.9092 51.9599 97.4256C42.4128 103.596 34.8505 112.392 30.1816 122.756C25.5126 133.12 23.9357 144.612 25.6403 155.851C27.3449 167.09 32.2584 177.598 39.7906 186.112C47.3227 194.626 57.153 200.784 68.1003 203.846C79.0476 206.907 90.6462 206.743 101.502 203.373C112.359 200.002 122.011 193.568 129.299 184.845C130.237 183.722 131.131 182.567 131.979 181.383C143.235 180.114 154.132 176.91 164.205 171.962C160.929 182.49 155.596 192.319 148.464 200.856C138.092 213.27 124.357 222.426 108.907 227.222C93.458 232.019 76.9524 232.253 61.3736 227.895C45.7948 223.538 31.8055 214.775 21.0867 202.659C10.3679 190.543 3.37557 175.59 0.949823 159.596C-1.47592 143.602 0.768139 127.248 7.41237 112.499C14.0566 97.7497 24.8183 85.2327 38.4045 76.4519ZM163.062 156.711L163.062 156.711C162.954 156.773 162.846 156.835 162.738 156.897C162.846 156.835 162.954 156.773 163.062 156.711Z" fill="#24C8DB"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,7 @@
|
|||||||
|
# Generated by Cargo
|
||||||
|
# will have compiled files and executables
|
||||||
|
/target/
|
||||||
|
|
||||||
|
# Generated by Tauri
|
||||||
|
# will have schema files for capabilities auto-completion
|
||||||
|
/gen/schemas
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
[package]
|
||||||
|
name = "dpm"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "A Tauri App"
|
||||||
|
authors = ["you"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
# The `_lib` suffix may seem redundant but it is necessary
|
||||||
|
# to make the lib name unique and wouldn't conflict with the bin name.
|
||||||
|
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
|
||||||
|
name = "dpm_lib"
|
||||||
|
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
tauri-build = { version = "2", features = [] }
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tauri = { version = "2", features = [] }
|
||||||
|
tauri-plugin-opener = "2"
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
serde_json = "1"
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
tauri_build::build()
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../gen/schemas/desktop-schema.json",
|
||||||
|
"identifier": "default",
|
||||||
|
"description": "Capability for the main window",
|
||||||
|
"windows": ["main"],
|
||||||
|
"permissions": [
|
||||||
|
"core:default",
|
||||||
|
"opener:default"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 974 B |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 903 B |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1 @@
|
|||||||
|
{"settings": {"1": {"username": "admin", "password": "123456", "volume": 60, "auto_play": true, "play_mode": "sequential", "image_duration": 8, "control_action": "play"}}, "playlist": {"1": {"path": "\u540d\u7247.png"}, "2": {"path": "02.mp4"}}, "url_media": {"1": {"url": "https://video-qn.ibaotu.com/20/08/52/29f888piCpMR.mp4", "name": "29f888piCpMR.mp4", "type": "video", "added_at": "2026-05-12T20:36:28.512177"}}}
|
||||||
@@ -0,0 +1,352 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
import asyncio, json
|
||||||
|
from fastapi import FastAPI, HTTPException, UploadFile, File, Form, Request
|
||||||
|
from fastapi.responses import HTMLResponse, JSONResponse, StreamingResponse
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from tinydb import TinyDB, Query
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
|
app = FastAPI(title="大屏媒体轮播系统")
|
||||||
|
|
||||||
|
# ===================== 模板加载 =====================
|
||||||
|
TEMPLATE_DIR = Path(__file__).parent / "templates"
|
||||||
|
|
||||||
|
def _load_template(name: str) -> str:
|
||||||
|
return (TEMPLATE_DIR / name).read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
SCREEN_HTML = _load_template("screen.html")
|
||||||
|
ADMIN_HTML = _load_template("admin.html")
|
||||||
|
|
||||||
|
# ===================== SSE 事件管理器 =====================
|
||||||
|
class EventManager:
|
||||||
|
def __init__(self):
|
||||||
|
self._queues: list[asyncio.Queue] = []
|
||||||
|
|
||||||
|
def subscribe(self, q: asyncio.Queue):
|
||||||
|
self._queues.append(q)
|
||||||
|
|
||||||
|
def unsubscribe(self, q: asyncio.Queue):
|
||||||
|
try:
|
||||||
|
self._queues.remove(q)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def broadcast(self, event: dict):
|
||||||
|
data = json.dumps(event)
|
||||||
|
dead = []
|
||||||
|
for q in self._queues:
|
||||||
|
try:
|
||||||
|
q.put_nowait(data)
|
||||||
|
except asyncio.QueueFull:
|
||||||
|
dead.append(q)
|
||||||
|
for q in dead:
|
||||||
|
self.unsubscribe(q)
|
||||||
|
|
||||||
|
events = EventManager()
|
||||||
|
|
||||||
|
# ===================== 播放状态(内存) =====================
|
||||||
|
playback_state: dict = {
|
||||||
|
"status": "idle", # playing | paused | idle
|
||||||
|
"index": 0,
|
||||||
|
"name": "",
|
||||||
|
"type": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
# CORS
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"],
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# ===================== 配置 =====================
|
||||||
|
MEDIA_DIR = Path.home() / "Downloads" / "Media"
|
||||||
|
MEDIA_DIR.mkdir(exist_ok=True, parents=True)
|
||||||
|
DB = TinyDB("db.json")
|
||||||
|
FILES_TABLE = DB.table("files")
|
||||||
|
PLAYLIST_TABLE = DB.table("playlist")
|
||||||
|
SETTINGS_TABLE = DB.table("settings")
|
||||||
|
URL_MEDIA_TABLE = DB.table("url_media")
|
||||||
|
User = Query()
|
||||||
|
FileQuery = Query()
|
||||||
|
UrlMediaQuery = Query()
|
||||||
|
|
||||||
|
ALLOWED_EXTENSIONS = {".mp4", ".mkv", ".avi", ".jpg", ".jpeg", ".png"}
|
||||||
|
|
||||||
|
# ===================== 初始化 =====================
|
||||||
|
DEFAULT_SETTINGS = {
|
||||||
|
"username": "admin",
|
||||||
|
"password": "123456",
|
||||||
|
"volume": 80,
|
||||||
|
"auto_play": True,
|
||||||
|
"play_mode": "sequential",
|
||||||
|
"image_duration": 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
if not SETTINGS_TABLE.search(User.username == "admin"):
|
||||||
|
SETTINGS_TABLE.insert(DEFAULT_SETTINGS)
|
||||||
|
else:
|
||||||
|
# 补齐缺失的默认字段
|
||||||
|
current = SETTINGS_TABLE.get(User.username == "admin")
|
||||||
|
updated = False
|
||||||
|
for key, val in DEFAULT_SETTINGS.items():
|
||||||
|
if key not in current:
|
||||||
|
current[key] = val
|
||||||
|
updated = True
|
||||||
|
if updated:
|
||||||
|
SETTINGS_TABLE.update(current, User.username == "admin")
|
||||||
|
|
||||||
|
# ===================== 前端页面 =====================
|
||||||
|
@app.get("/", response_class=HTMLResponse)
|
||||||
|
async def screen_page():
|
||||||
|
return SCREEN_HTML
|
||||||
|
|
||||||
|
@app.get("/admin", response_class=HTMLResponse)
|
||||||
|
async def admin_page():
|
||||||
|
return ADMIN_HTML
|
||||||
|
|
||||||
|
# ===================== 文件访问 =====================
|
||||||
|
from fastapi.responses import FileResponse
|
||||||
|
@app.get("/file/{path:path}")
|
||||||
|
async def get_file(path: str):
|
||||||
|
target = MEDIA_DIR / path
|
||||||
|
if not target.exists() or not target.is_file():
|
||||||
|
raise HTTPException(404)
|
||||||
|
return FileResponse(target)
|
||||||
|
|
||||||
|
# ===================== API =====================
|
||||||
|
@app.post("/api/login")
|
||||||
|
async def login(username: str = Form(...), password: str = Form(...)):
|
||||||
|
admin = SETTINGS_TABLE.get(User.username == "admin")
|
||||||
|
if admin and admin["password"] == password:
|
||||||
|
return {"success": True}
|
||||||
|
return {"success": False}
|
||||||
|
|
||||||
|
@app.get("/api/settings")
|
||||||
|
async def get_settings():
|
||||||
|
s = SETTINGS_TABLE.get(User.username == "admin")
|
||||||
|
return {k: s[k] for k in DEFAULT_SETTINGS if k in s}
|
||||||
|
|
||||||
|
@app.post("/api/settings")
|
||||||
|
async def update_settings(data: dict):
|
||||||
|
"""统一设置更新,支持 volume/play_mode/image_duration"""
|
||||||
|
allowed = {"volume", "play_mode", "image_duration"}
|
||||||
|
update = {k: v for k, v in data.items() if k in allowed}
|
||||||
|
if update:
|
||||||
|
SETTINGS_TABLE.update(update, User.username == "admin")
|
||||||
|
events.broadcast({"action": "settings_changed", **update})
|
||||||
|
return {"ok": True}
|
||||||
|
|
||||||
|
@app.get("/media")
|
||||||
|
async def get_media_files():
|
||||||
|
files = []
|
||||||
|
# 本地文件
|
||||||
|
for p in MEDIA_DIR.rglob("*"):
|
||||||
|
if not p.is_file(): continue
|
||||||
|
ext = p.suffix.lower()
|
||||||
|
if ext not in ALLOWED_EXTENSIONS: continue
|
||||||
|
rel = str(p.relative_to(MEDIA_DIR))
|
||||||
|
t = "video" if ext in [".mp4",".mkv",".avi"] else "image"
|
||||||
|
files.append({
|
||||||
|
"name": p.name,
|
||||||
|
"relative_path": rel,
|
||||||
|
"type": t,
|
||||||
|
"url": f"/file/{rel}",
|
||||||
|
"source": "local",
|
||||||
|
})
|
||||||
|
# URL 媒体(持久化在 url_media 表中)
|
||||||
|
for item in URL_MEDIA_TABLE.all():
|
||||||
|
files.append({
|
||||||
|
"name": item["name"],
|
||||||
|
"relative_path": item["url"],
|
||||||
|
"type": item["type"],
|
||||||
|
"url": item["url"],
|
||||||
|
"source": "url",
|
||||||
|
})
|
||||||
|
return {"files": files}
|
||||||
|
|
||||||
|
@app.post("/upload")
|
||||||
|
async def upload(file: UploadFile = File(...)):
|
||||||
|
ext = Path(file.filename).suffix.lower()
|
||||||
|
if ext not in ALLOWED_EXTENSIONS:
|
||||||
|
raise HTTPException(400)
|
||||||
|
ts = datetime.now().strftime("%Y%m%d%H%M%S")
|
||||||
|
name = f"{Path(file.filename).stem}_{ts}{ext}"
|
||||||
|
path = MEDIA_DIR / name
|
||||||
|
with open(path, "wb") as f:
|
||||||
|
f.write(await file.read())
|
||||||
|
return {"ok": True}
|
||||||
|
|
||||||
|
@app.post("/api/delete")
|
||||||
|
async def delete_file(data: dict):
|
||||||
|
path = data["path"]
|
||||||
|
if path.startswith(("http://", "https://")):
|
||||||
|
# 删除 URL 媒体及其播放列表引用
|
||||||
|
URL_MEDIA_TABLE.remove(UrlMediaQuery.url == path)
|
||||||
|
else:
|
||||||
|
p = MEDIA_DIR / path
|
||||||
|
if p.exists() and p.is_file():
|
||||||
|
p.unlink()
|
||||||
|
PLAYLIST_TABLE.remove(FileQuery.path == path)
|
||||||
|
events.broadcast({"action": "playlist_changed"})
|
||||||
|
return {"ok": True}
|
||||||
|
|
||||||
|
@app.get("/api/playlist")
|
||||||
|
async def get_playlist():
|
||||||
|
items = PLAYLIST_TABLE.all()
|
||||||
|
admin = SETTINGS_TABLE.get(User.username == "admin")
|
||||||
|
files = []
|
||||||
|
for item in items:
|
||||||
|
if item.get("source") == "url":
|
||||||
|
ext = Path(item["path"]).suffix.lower()
|
||||||
|
files.append({
|
||||||
|
"name": item.get("name", item["path"]),
|
||||||
|
"relative_path": item["path"],
|
||||||
|
"type": "video" if ext in [".mp4",".mkv",".avi"] else "image",
|
||||||
|
"source": "url",
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
p = MEDIA_DIR / item["path"]
|
||||||
|
if p.exists():
|
||||||
|
ext = p.suffix.lower()
|
||||||
|
files.append({
|
||||||
|
"name": p.name,
|
||||||
|
"relative_path": item["path"],
|
||||||
|
"type": "video" if ext in [".mp4",".mkv",".avi"] else "image",
|
||||||
|
"source": "local",
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
"files": files,
|
||||||
|
"volume": admin["volume"],
|
||||||
|
"play_mode": admin.get("play_mode", "sequential"),
|
||||||
|
"image_duration": admin.get("image_duration", 5),
|
||||||
|
}
|
||||||
|
|
||||||
|
@app.post("/api/playlist/add")
|
||||||
|
async def add_playlist(data: dict):
|
||||||
|
path = data["path"]
|
||||||
|
if not PLAYLIST_TABLE.contains(FileQuery.path == path):
|
||||||
|
item: dict = {"path": path}
|
||||||
|
if path.startswith(("http://", "https://")):
|
||||||
|
item["source"] = "url"
|
||||||
|
# 从 URL 媒体库中获取名称
|
||||||
|
um = URL_MEDIA_TABLE.get(UrlMediaQuery.url == path)
|
||||||
|
if um:
|
||||||
|
item["name"] = um["name"]
|
||||||
|
PLAYLIST_TABLE.insert(item)
|
||||||
|
events.broadcast({"action": "playlist_changed"})
|
||||||
|
return {"ok": True}
|
||||||
|
|
||||||
|
@app.post("/api/playlist/remove")
|
||||||
|
async def remove_playlist(data: dict):
|
||||||
|
PLAYLIST_TABLE.remove(FileQuery.path == data["path"])
|
||||||
|
events.broadcast({"action": "playlist_changed"})
|
||||||
|
return {"ok": True}
|
||||||
|
|
||||||
|
@app.post("/api/media/add-url")
|
||||||
|
async def add_url_media(data: dict):
|
||||||
|
"""添加 URL 到媒体库(持久化),不自动加入播放列表"""
|
||||||
|
url = data.get("url", "").strip()
|
||||||
|
if not url:
|
||||||
|
raise HTTPException(400, "url 不能为空")
|
||||||
|
if URL_MEDIA_TABLE.contains(UrlMediaQuery.url == url):
|
||||||
|
return {"ok": True, "duplicate": True}
|
||||||
|
ext = Path(url.split("?")[0]).suffix.lower()
|
||||||
|
name = data.get("name", "").strip() or url.rsplit("/", 1)[-1].split("?")[0]
|
||||||
|
URL_MEDIA_TABLE.insert({
|
||||||
|
"url": url,
|
||||||
|
"name": name,
|
||||||
|
"type": "video" if ext in [".mp4",".mkv",".avi"] else "image",
|
||||||
|
"added_at": datetime.now().isoformat(),
|
||||||
|
})
|
||||||
|
return {"ok": True}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/files")
|
||||||
|
async def list_files_with_url():
|
||||||
|
"""输出媒体文件夹中所有文件的 URL"""
|
||||||
|
files = []
|
||||||
|
for p in sorted(MEDIA_DIR.rglob("*")):
|
||||||
|
if not p.is_file(): continue
|
||||||
|
ext = p.suffix.lower()
|
||||||
|
if ext not in ALLOWED_EXTENSIONS: continue
|
||||||
|
rel = str(p.relative_to(MEDIA_DIR))
|
||||||
|
t = "video" if ext in [".mp4",".mkv",".avi"] else "image"
|
||||||
|
files.append({
|
||||||
|
"name": p.name,
|
||||||
|
"type": t,
|
||||||
|
"url": f"/file/{rel}",
|
||||||
|
})
|
||||||
|
return {"files": files}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/events")
|
||||||
|
async def sse_events(request: Request):
|
||||||
|
"""SSE 端点,向后端推送实时播放控制指令"""
|
||||||
|
q: asyncio.Queue = asyncio.Queue(maxsize=32)
|
||||||
|
events.subscribe(q)
|
||||||
|
async def generate():
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
if await request.is_disconnected():
|
||||||
|
break
|
||||||
|
try:
|
||||||
|
data = await asyncio.wait_for(q.get(), timeout=15)
|
||||||
|
yield f"data: {data}\n\n"
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
yield ": keepalive\n\n"
|
||||||
|
finally:
|
||||||
|
events.unsubscribe(q)
|
||||||
|
return StreamingResponse(generate(), media_type="text/event-stream")
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/control")
|
||||||
|
async def playback_control(data: dict):
|
||||||
|
"""后端控制播放:{action: 'play'|'pause'|'next'|'prev'}"""
|
||||||
|
action = data.get("action", "")
|
||||||
|
if action not in ("play", "pause", "next", "prev"):
|
||||||
|
raise HTTPException(400, "action 必须是 play/pause/next/prev")
|
||||||
|
SETTINGS_TABLE.update({"control_action": action}, User.username == "admin")
|
||||||
|
events.broadcast({"action": action})
|
||||||
|
# 更新本地状态(乐观)
|
||||||
|
if action == "play":
|
||||||
|
playback_state["status"] = "playing"
|
||||||
|
elif action == "pause":
|
||||||
|
playback_state["status"] = "paused"
|
||||||
|
events.broadcast({"action": "state_update", "state": playback_state})
|
||||||
|
return {"ok": True, "action": action}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/state")
|
||||||
|
async def get_state():
|
||||||
|
"""获取当前播放状态"""
|
||||||
|
return {"state": playback_state}
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/state")
|
||||||
|
async def update_state(data: dict):
|
||||||
|
"""前端上报播放状态变更"""
|
||||||
|
state = data.get("state", {})
|
||||||
|
if "status" in state:
|
||||||
|
playback_state["status"] = state["status"]
|
||||||
|
if "index" in state:
|
||||||
|
playback_state["index"] = state["index"]
|
||||||
|
if "name" in state:
|
||||||
|
playback_state["name"] = state["name"]
|
||||||
|
if "type" in state:
|
||||||
|
playback_state["type"] = state["type"]
|
||||||
|
events.broadcast({"action": "state_update", "state": playback_state})
|
||||||
|
return {"ok": True}
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import uvicorn
|
||||||
|
uvicorn.run(
|
||||||
|
"main:app",
|
||||||
|
host="0.0.0.0",
|
||||||
|
port=8000,
|
||||||
|
reload=True
|
||||||
|
)
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
||||||
|
#[tauri::command]
|
||||||
|
fn greet(name: &str) -> String {
|
||||||
|
format!("Hello, {}! You've been greeted from Rust!", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
|
pub fn run() {
|
||||||
|
tauri::Builder::default()
|
||||||
|
.plugin(tauri_plugin_opener::init())
|
||||||
|
.invoke_handler(tauri::generate_handler![greet])
|
||||||
|
.run(tauri::generate_context!())
|
||||||
|
.expect("error while running tauri application");
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||||
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
dpm_lib::run()
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
|
"productName": "dpm",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"identifier": "com.pine.dpm",
|
||||||
|
"build": {
|
||||||
|
"beforeDevCommand": "yarn dev",
|
||||||
|
"devUrl": "http://localhost:1420",
|
||||||
|
"beforeBuildCommand": "yarn build",
|
||||||
|
"frontendDist": "../dist"
|
||||||
|
},
|
||||||
|
"app": {
|
||||||
|
"windows": [
|
||||||
|
{
|
||||||
|
"title": "dpm",
|
||||||
|
"width": 800,
|
||||||
|
"height": 600
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"security": {
|
||||||
|
"csp": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bundle": {
|
||||||
|
"active": true,
|
||||||
|
"targets": "all",
|
||||||
|
"icon": [
|
||||||
|
"icons/32x32.png",
|
||||||
|
"icons/128x128.png",
|
||||||
|
"icons/128x128@2x.png",
|
||||||
|
"icons/icon.icns",
|
||||||
|
"icons/icon.ico"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
.logo.vite:hover {
|
||||||
|
filter: drop-shadow(0 0 2em #747bff);
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo.react:hover {
|
||||||
|
filter: drop-shadow(0 0 2em #61dafb);
|
||||||
|
}
|
||||||
|
:root {
|
||||||
|
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
color: #0f0f0f;
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
|
||||||
|
font-synthesis: none;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
margin: 0;
|
||||||
|
padding-top: 10vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
height: 6em;
|
||||||
|
padding: 1.5em;
|
||||||
|
will-change: filter;
|
||||||
|
transition: 0.75s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo.tauri:hover {
|
||||||
|
filter: drop-shadow(0 0 2em #24c8db);
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #646cff;
|
||||||
|
text-decoration: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: #535bf2;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
button {
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
padding: 0.6em 1.2em;
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: 500;
|
||||||
|
font-family: inherit;
|
||||||
|
color: #0f0f0f;
|
||||||
|
background-color: #ffffff;
|
||||||
|
transition: border-color 0.25s;
|
||||||
|
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
border-color: #396cd8;
|
||||||
|
}
|
||||||
|
button:active {
|
||||||
|
border-color: #396cd8;
|
||||||
|
background-color: #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
button {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#greet-input {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
color: #f6f6f6;
|
||||||
|
background-color: #2f2f2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: #24c8db;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
button {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #0f0f0f98;
|
||||||
|
}
|
||||||
|
button:active {
|
||||||
|
background-color: #0f0f0f69;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import reactLogo from "./assets/react.svg";
|
||||||
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
|
import "./App.css";
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
const [greetMsg, setGreetMsg] = useState("");
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
|
||||||
|
async function greet() {
|
||||||
|
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
||||||
|
setGreetMsg(await invoke("greet", { name }));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main className="container">
|
||||||
|
<h1>Welcome to Tauri + React</h1>
|
||||||
|
|
||||||
|
<div className="row">
|
||||||
|
<a href="https://vite.dev" target="_blank">
|
||||||
|
<img src="/vite.svg" className="logo vite" alt="Vite logo" />
|
||||||
|
</a>
|
||||||
|
<a href="https://tauri.app" target="_blank">
|
||||||
|
<img src="/tauri.svg" className="logo tauri" alt="Tauri logo" />
|
||||||
|
</a>
|
||||||
|
<a href="https://react.dev" target="_blank">
|
||||||
|
<img src={reactLogo} className="logo react" alt="React logo" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<p>Click on the Tauri, Vite, and React logos to learn more.</p>
|
||||||
|
|
||||||
|
<form
|
||||||
|
className="row"
|
||||||
|
onSubmit={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
greet();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
id="greet-input"
|
||||||
|
onChange={(e) => setName(e.currentTarget.value)}
|
||||||
|
placeholder="Enter a name..."
|
||||||
|
/>
|
||||||
|
<button type="submit">Greet</button>
|
||||||
|
</form>
|
||||||
|
<p>{greetMsg}</p>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,9 @@
|
|||||||
|
import React from "react";
|
||||||
|
import ReactDOM from "react-dom/client";
|
||||||
|
import App from "./App";
|
||||||
|
|
||||||
|
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>,
|
||||||
|
);
|
||||||
@@ -0,0 +1,830 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>昆明市大学生创业园-大屏媒体轮播</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--space-deep: #060d1a;
|
||||||
|
--space-mid: #0b1530;
|
||||||
|
--surface-glass: rgba(255,255,255,0.04);
|
||||||
|
--surface-glass-warm: rgba(255,248,240,0.05);
|
||||||
|
--text-dim: rgba(255,255,255,0.38);
|
||||||
|
--text-soft: rgba(255,255,255,0.55);
|
||||||
|
--text-bright: rgba(255,255,255,0.88);
|
||||||
|
--accent-cyan: #06b6d4;
|
||||||
|
--accent-warm: #f59e0b;
|
||||||
|
--accent-rose: #f472b6;
|
||||||
|
--glow-cyan: rgba(6, 182, 212, 0.25);
|
||||||
|
--glow-warm: rgba(245, 158, 11, 0.2);
|
||||||
|
--glow-rose: rgba(244, 114, 182, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: var(--space-deep);
|
||||||
|
color: #fff;
|
||||||
|
font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", sans-serif;
|
||||||
|
overflow: hidden;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============ Spatial Depth Layers ============ */
|
||||||
|
|
||||||
|
/* Layer 0 — Deep space background with warm nebula */
|
||||||
|
body::before {
|
||||||
|
content: '';
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 0;
|
||||||
|
background:
|
||||||
|
/* Warm nebula — upper right */
|
||||||
|
radial-gradient(ellipse 60% 50% at 75% 25%, rgba(245, 158, 11, 0.07) 0%, transparent 60%),
|
||||||
|
/* Cyan nebula — upper left */
|
||||||
|
radial-gradient(ellipse 50% 45% at 20% 20%, rgba(6, 182, 212, 0.05) 0%, transparent 55%),
|
||||||
|
/* Rose accent — lower left */
|
||||||
|
radial-gradient(ellipse 40% 35% at 15% 85%, rgba(244, 114, 182, 0.04) 0%, transparent 50%),
|
||||||
|
/* Deep center vanish */
|
||||||
|
radial-gradient(ellipse 80% 80% at 50% 50%, rgba(6, 13, 26, 0) 0%, var(--space-deep) 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Layer 1 — Perspective grid (vanishing point at center) */
|
||||||
|
.perspective-grid {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0.06;
|
||||||
|
background-image:
|
||||||
|
/* Horizontal lines — perspective spacing */
|
||||||
|
repeating-linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
transparent,
|
||||||
|
transparent calc(2px + 0.5vh),
|
||||||
|
rgba(255,255,255,0.3) calc(2px + 0.5vh),
|
||||||
|
rgba(255,255,255,0.3) calc(2.5px + 0.5vh)
|
||||||
|
),
|
||||||
|
/* Vertical lines — perspective spacing */
|
||||||
|
repeating-linear-gradient(
|
||||||
|
to right,
|
||||||
|
transparent,
|
||||||
|
transparent calc(2px + 0.5vw),
|
||||||
|
rgba(255,255,255,0.3) calc(2px + 0.5vw),
|
||||||
|
rgba(255,255,255,0.3) calc(2.5px + 0.5vw)
|
||||||
|
);
|
||||||
|
mask-image: radial-gradient(ellipse 60% 80% at 50% 50%, transparent 0%, rgba(0,0,0,0.4) 40%, rgba(0,0,0,0.15) 70%, transparent 100%);
|
||||||
|
-webkit-mask-image: radial-gradient(ellipse 60% 80% at 50% 50%, transparent 0%, rgba(0,0,0,0.4) 40%, rgba(0,0,0,0.15) 70%, transparent 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Layer 2 — Floating ambient orbs */
|
||||||
|
.ambient-orb {
|
||||||
|
position: fixed;
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 2;
|
||||||
|
filter: blur(80px);
|
||||||
|
animation: orbDrift 12s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
.ambient-orb.orb-1 {
|
||||||
|
width: 400px; height: 400px;
|
||||||
|
top: -100px; right: -80px;
|
||||||
|
background: rgba(6, 182, 212, 0.06);
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
.ambient-orb.orb-2 {
|
||||||
|
width: 350px; height: 350px;
|
||||||
|
bottom: -120px; left: -60px;
|
||||||
|
background: rgba(245, 158, 11, 0.05);
|
||||||
|
animation-delay: -4s;
|
||||||
|
}
|
||||||
|
.ambient-orb.orb-3 {
|
||||||
|
width: 250px; height: 250px;
|
||||||
|
top: 50%; left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background: rgba(244, 114, 182, 0.03);
|
||||||
|
animation-delay: -8s;
|
||||||
|
}
|
||||||
|
@keyframes orbDrift {
|
||||||
|
0%, 100% { transform: translate(0, 0) scale(1); }
|
||||||
|
25% { transform: translate(30px, -20px) scale(1.08); }
|
||||||
|
50% { transform: translate(-15px, 25px) scale(0.94); }
|
||||||
|
75% { transform: translate(-25px, -10px) scale(1.04); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Layer 3 — Atmospheric vignette (warm) */
|
||||||
|
body::after {
|
||||||
|
content: '';
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 50;
|
||||||
|
background:
|
||||||
|
radial-gradient(ellipse at 50% 50%, transparent 55%, rgba(6, 13, 26, 0.55) 90%, rgba(4, 8, 16, 0.8) 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============ Media Elements ============ */
|
||||||
|
#player {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
object-fit: contain;
|
||||||
|
background: transparent;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#imgPlayer {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
object-fit: contain;
|
||||||
|
background: transparent;
|
||||||
|
z-index: 3;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============ Loader — 3D Depth ============ */
|
||||||
|
.loader {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 100;
|
||||||
|
background: var(--space-deep);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 48px;
|
||||||
|
transition: opacity 0.8s cubic-bezier(0.4, 0, 0.2, 1), visibility 0.8s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
.loader.hidden {
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Brand mark — isometric cube illusion */
|
||||||
|
.loader-brand {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
.loader-brand .mark {
|
||||||
|
width: 56px;
|
||||||
|
height: 56px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
/* Isometric top face */
|
||||||
|
.loader-brand .mark::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 6px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%) rotate(45deg);
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
background: rgba(255,255,255,0.06);
|
||||||
|
border: 1px solid rgba(255,255,255,0.12);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
/* Isometric left face */
|
||||||
|
.loader-brand .mark::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 18px;
|
||||||
|
left: 4px;
|
||||||
|
width: 24px;
|
||||||
|
height: 28px;
|
||||||
|
background: rgba(255,255,255,0.03);
|
||||||
|
border: 1px solid rgba(255,255,255,0.08);
|
||||||
|
border-radius: 3px;
|
||||||
|
transform: skewY(25deg);
|
||||||
|
}
|
||||||
|
/* Isometric right face */
|
||||||
|
.loader-brand .mark .iso-right {
|
||||||
|
position: absolute;
|
||||||
|
top: 18px;
|
||||||
|
right: 4px;
|
||||||
|
width: 24px;
|
||||||
|
height: 28px;
|
||||||
|
background: rgba(6, 182, 212, 0.08);
|
||||||
|
border: 1px solid rgba(6, 182, 212, 0.15);
|
||||||
|
border-radius: 3px;
|
||||||
|
transform: skewY(-25deg);
|
||||||
|
}
|
||||||
|
/* Center glow dot */
|
||||||
|
.loader-brand .mark .iso-dot {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
background: var(--accent-cyan);
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: 0 0 16px var(--glow-cyan), 0 0 32px rgba(6, 182, 212, 0.15);
|
||||||
|
animation: isoPulse 2.4s ease-in-out infinite;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
@keyframes isoPulse {
|
||||||
|
0%, 100% { opacity: 0.5; box-shadow: 0 0 12px var(--glow-cyan); }
|
||||||
|
50% { opacity: 1; box-shadow: 0 0 24px var(--glow-cyan), 0 0 48px rgba(6, 182, 212, 0.2); }
|
||||||
|
}
|
||||||
|
.loader-brand .label {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
letter-spacing: 0.4em;
|
||||||
|
color: rgba(255,255,255,0.35);
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3D Ring spinner with depth */
|
||||||
|
.loader-ring {
|
||||||
|
position: relative;
|
||||||
|
width: 72px;
|
||||||
|
height: 72px;
|
||||||
|
perspective: 200px;
|
||||||
|
}
|
||||||
|
.loader-ring .ring {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1.5px solid transparent;
|
||||||
|
}
|
||||||
|
.loader-ring .ring:nth-child(1) {
|
||||||
|
inset: 0;
|
||||||
|
border-top-color: rgba(6, 182, 212, 0.5);
|
||||||
|
border-right-color: rgba(6, 182, 212, 0.2);
|
||||||
|
animation: spin3d 1.4s linear infinite;
|
||||||
|
box-shadow: 0 0 20px rgba(6, 182, 212, 0.1);
|
||||||
|
}
|
||||||
|
.loader-ring .ring:nth-child(2) {
|
||||||
|
inset: 8px;
|
||||||
|
border-bottom-color: rgba(245, 158, 11, 0.35);
|
||||||
|
border-left-color: rgba(245, 158, 11, 0.12);
|
||||||
|
animation: spin3d 2s linear infinite reverse;
|
||||||
|
transform: rotateX(30deg);
|
||||||
|
}
|
||||||
|
.loader-ring .ring:nth-child(3) {
|
||||||
|
inset: 16px;
|
||||||
|
border-top-color: rgba(244, 114, 182, 0.25);
|
||||||
|
border-right-color: rgba(244, 114, 182, 0.08);
|
||||||
|
animation: spin3d 2.6s linear infinite;
|
||||||
|
transform: rotateX(-25deg);
|
||||||
|
}
|
||||||
|
@keyframes spin3d {
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader-hint {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text-dim);
|
||||||
|
letter-spacing: 0.15em;
|
||||||
|
}
|
||||||
|
.loader-hint a {
|
||||||
|
color: rgba(255,255,255,0.6);
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: 1px solid rgba(255,255,255,0.15);
|
||||||
|
padding-bottom: 2px;
|
||||||
|
transition: color 0.3s, border-color 0.3s;
|
||||||
|
}
|
||||||
|
.loader-hint a:hover {
|
||||||
|
color: rgba(255,255,255,0.9);
|
||||||
|
border-color: rgba(255,255,255,0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============ Sound Hint — Glass Depth ============ */
|
||||||
|
#soundHint {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 48px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
z-index: 100;
|
||||||
|
background: rgba(255,255,255,0.05);
|
||||||
|
backdrop-filter: blur(24px) saturate(180%);
|
||||||
|
-webkit-backdrop-filter: blur(24px) saturate(180%);
|
||||||
|
border: 1px solid rgba(255,255,255,0.1);
|
||||||
|
border-bottom: 1px solid rgba(255,255,255,0.04);
|
||||||
|
color: rgba(255,255,255,0.8);
|
||||||
|
padding: 14px 32px;
|
||||||
|
border-radius: 40px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 450;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
cursor: pointer;
|
||||||
|
display: none;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
box-shadow:
|
||||||
|
0 4px 24px rgba(0,0,0,0.3),
|
||||||
|
0 0 0 1px rgba(255,255,255,0.03) inset,
|
||||||
|
0 1px 0 rgba(255,255,255,0.04) inset;
|
||||||
|
animation: hintFloat 4s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
#soundHint:hover {
|
||||||
|
background: rgba(255,255,255,0.08);
|
||||||
|
border-color: rgba(255,255,255,0.18);
|
||||||
|
box-shadow:
|
||||||
|
0 8px 32px rgba(0,0,0,0.4),
|
||||||
|
0 0 0 1px rgba(255,255,255,0.05) inset,
|
||||||
|
0 1px 0 rgba(255,255,255,0.06) inset,
|
||||||
|
0 0 40px rgba(6, 182, 212, 0.08);
|
||||||
|
transform: translateX(-50%) translateY(-2px);
|
||||||
|
}
|
||||||
|
@keyframes hintFloat {
|
||||||
|
0%, 100% {
|
||||||
|
box-shadow: 0 4px 24px rgba(0,0,0,0.3), 0 0 0 0 rgba(6, 182, 212, 0);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
box-shadow: 0 4px 24px rgba(0,0,0,0.3), 0 0 32px 2px rgba(6, 182, 212, 0.06);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============ Status Elements ============ */
|
||||||
|
|
||||||
|
/* Corner info — glass panel */
|
||||||
|
.corner-info {
|
||||||
|
position: fixed;
|
||||||
|
top: 28px;
|
||||||
|
left: 28px;
|
||||||
|
z-index: 100;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
background: rgba(255,255,255,0.03);
|
||||||
|
backdrop-filter: blur(16px);
|
||||||
|
-webkit-backdrop-filter: blur(16px);
|
||||||
|
border: 1px solid rgba(255,255,255,0.06);
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.6s ease;
|
||||||
|
box-shadow:
|
||||||
|
0 2px 12px rgba(0,0,0,0.2),
|
||||||
|
0 0 0 1px rgba(255,255,255,0.02) inset;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.corner-info.visible {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.corner-info .ci-dot {
|
||||||
|
width: 7px;
|
||||||
|
height: 7px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--accent-cyan);
|
||||||
|
box-shadow: 0 0 10px var(--glow-cyan);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.corner-info .ci-text {
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--text-soft);
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
white-space: nowrap;
|
||||||
|
max-width: 300px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connection indicator — layered dot */
|
||||||
|
.conn-indicator {
|
||||||
|
position: fixed;
|
||||||
|
top: 28px;
|
||||||
|
right: 28px;
|
||||||
|
z-index: 100;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.6s ease;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.conn-indicator.visible {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.conn-rings {
|
||||||
|
position: relative;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
.conn-rings .cr-inner {
|
||||||
|
position: absolute;
|
||||||
|
inset: 1px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(52, 211, 153, 0.6);
|
||||||
|
box-shadow: 0 0 6px rgba(52, 211, 153, 0.3);
|
||||||
|
transition: all 0.6s ease;
|
||||||
|
}
|
||||||
|
.conn-rings .cr-outer {
|
||||||
|
position: absolute;
|
||||||
|
inset: -3px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1px solid rgba(52, 211, 153, 0.2);
|
||||||
|
animation: connPulse 2.5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
@keyframes connPulse {
|
||||||
|
0%, 100% { transform: scale(1); opacity: 0.3; }
|
||||||
|
50% { transform: scale(1.6); opacity: 0; }
|
||||||
|
}
|
||||||
|
.conn-label {
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--text-dim);
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bottom status bar — glass */
|
||||||
|
.status-bar {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 28px;
|
||||||
|
right: 28px;
|
||||||
|
z-index: 100;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
background: rgba(255,255,255,0.03);
|
||||||
|
backdrop-filter: blur(16px);
|
||||||
|
-webkit-backdrop-filter: blur(16px);
|
||||||
|
border: 1px solid rgba(255,255,255,0.05);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 6px 14px;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.6s ease;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.15);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.status-bar.visible {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.status-bar .sb-dot {
|
||||||
|
width: 5px;
|
||||||
|
height: 5px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--accent-warm);
|
||||||
|
box-shadow: 0 0 8px var(--glow-warm);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.status-bar .sb-dot.idle {
|
||||||
|
background: rgba(255,255,255,0.25);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.status-bar .sb-text {
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--text-dim);
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
font-family: "SF Mono", "JetBrains Mono", "Consolas", monospace;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Perspective Grid -->
|
||||||
|
<div class="perspective-grid"></div>
|
||||||
|
|
||||||
|
<!-- Ambient Orbs -->
|
||||||
|
<div class="ambient-orb orb-1"></div>
|
||||||
|
<div class="ambient-orb orb-2"></div>
|
||||||
|
<div class="ambient-orb orb-3"></div>
|
||||||
|
|
||||||
|
<!-- Loader -->
|
||||||
|
<div class="loader" id="loader">
|
||||||
|
<div class="loader-brand">
|
||||||
|
<div class="mark">
|
||||||
|
<div class="iso-right"></div>
|
||||||
|
<div class="iso-dot"></div>
|
||||||
|
</div>
|
||||||
|
<div class="label">PineSound</div>
|
||||||
|
</div>
|
||||||
|
<div class="loader-ring">
|
||||||
|
<div class="ring"></div>
|
||||||
|
<div class="ring"></div>
|
||||||
|
<div class="ring"></div>
|
||||||
|
</div>
|
||||||
|
<div class="loader-hint" id="loaderText">加载播放列表中...</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Media Players -->
|
||||||
|
<video id="player" autoplay playsinline controlsList="nodownload"></video>
|
||||||
|
<img id="imgPlayer" alt="">
|
||||||
|
|
||||||
|
<!-- Corner Info — Now Playing -->
|
||||||
|
<div class="corner-info" id="cornerInfo">
|
||||||
|
<div class="ci-dot"></div>
|
||||||
|
<span class="ci-text" id="ciText">就绪</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Connection Indicator -->
|
||||||
|
<div class="conn-indicator" id="connIndicator">
|
||||||
|
<div class="conn-rings">
|
||||||
|
<div class="cr-inner"></div>
|
||||||
|
<div class="cr-outer"></div>
|
||||||
|
</div>
|
||||||
|
<span class="conn-label">Live</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Bottom Status -->
|
||||||
|
<div class="status-bar" id="statusBar">
|
||||||
|
<div class="sb-dot" id="sbDot"></div>
|
||||||
|
<span class="sb-text" id="sbText">0 / 0</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sound Hint -->
|
||||||
|
<div id="soundHint" onclick="enableSound()">点击启用声音</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const video = document.getElementById('player')
|
||||||
|
const img = document.getElementById('imgPlayer')
|
||||||
|
const loader = document.getElementById('loader')
|
||||||
|
const loaderText = document.getElementById('loaderText')
|
||||||
|
const soundHint = document.getElementById('soundHint')
|
||||||
|
const cornerInfo = document.getElementById('cornerInfo')
|
||||||
|
const ciText = document.getElementById('ciText')
|
||||||
|
const connIndicator = document.getElementById('connIndicator')
|
||||||
|
const statusBar = document.getElementById('statusBar')
|
||||||
|
const sbDot = document.getElementById('sbDot')
|
||||||
|
const sbText = document.getElementById('sbText')
|
||||||
|
let list = []
|
||||||
|
let index = 0
|
||||||
|
let volume = 0.8
|
||||||
|
let playMode = 'sequential'
|
||||||
|
let imageDuration = 5
|
||||||
|
let timer = null
|
||||||
|
let soundBlocked = false
|
||||||
|
let paused = false
|
||||||
|
|
||||||
|
function getUrl(item) {
|
||||||
|
return item.source === 'url' ? item.relative_path : '/file/' + item.relative_path
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadPlaylist() {
|
||||||
|
const res = await fetch('/api/playlist')
|
||||||
|
const data = await res.json()
|
||||||
|
list = data.files
|
||||||
|
volume = (data.volume || 80) / 100
|
||||||
|
playMode = data.play_mode || 'sequential'
|
||||||
|
imageDuration = data.image_duration || 5
|
||||||
|
video.volume = volume
|
||||||
|
if(list.length === 0){
|
||||||
|
loaderText.innerHTML = '播放列表为空,<a href="/admin">前往管理后台添加</a>'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
loader.classList.add('hidden')
|
||||||
|
showUI()
|
||||||
|
connectSSE()
|
||||||
|
tryPlayWithSound(() => play())
|
||||||
|
}
|
||||||
|
|
||||||
|
function showUI() {
|
||||||
|
cornerInfo.classList.add('visible')
|
||||||
|
connIndicator.classList.add('visible')
|
||||||
|
statusBar.classList.add('visible')
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateStatusUI() {
|
||||||
|
const item = list.length > 0 ? list[index] : null
|
||||||
|
if (item) {
|
||||||
|
ciText.textContent = item.name
|
||||||
|
}
|
||||||
|
sbText.textContent = (index + 1) + ' / ' + list.length
|
||||||
|
if (paused) {
|
||||||
|
sbDot.className = 'sb-dot idle'
|
||||||
|
} else {
|
||||||
|
sbDot.className = 'sb-dot'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function tryPlayWithSound(fn) {
|
||||||
|
video.muted = false
|
||||||
|
const testPlay = video.play()
|
||||||
|
if(testPlay !== undefined){
|
||||||
|
testPlay.then(() => {
|
||||||
|
soundBlocked = false
|
||||||
|
soundHint.style.display = 'none'
|
||||||
|
video.pause()
|
||||||
|
fn()
|
||||||
|
}).catch(() => {
|
||||||
|
soundBlocked = true
|
||||||
|
video.muted = true
|
||||||
|
soundHint.style.display = 'block'
|
||||||
|
fn()
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
fn()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function connectSSE() {
|
||||||
|
const es = new EventSource('/api/events')
|
||||||
|
es.onmessage = function(e) {
|
||||||
|
const msg = JSON.parse(e.data)
|
||||||
|
switch(msg.action) {
|
||||||
|
case 'pause':
|
||||||
|
handlePause()
|
||||||
|
break
|
||||||
|
case 'play':
|
||||||
|
handlePlay()
|
||||||
|
break
|
||||||
|
case 'next':
|
||||||
|
paused = false
|
||||||
|
skip(1)
|
||||||
|
break
|
||||||
|
case 'prev':
|
||||||
|
paused = false
|
||||||
|
skip(-1)
|
||||||
|
break
|
||||||
|
case 'playlist_changed':
|
||||||
|
reloadPlaylist()
|
||||||
|
break
|
||||||
|
case 'settings_changed':
|
||||||
|
applySettings(msg)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlePause() {
|
||||||
|
paused = true
|
||||||
|
clearTimeout(timer)
|
||||||
|
video.pause()
|
||||||
|
updateStatusUI()
|
||||||
|
reportState('paused')
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlePlay() {
|
||||||
|
paused = false
|
||||||
|
updateStatusUI()
|
||||||
|
if(video.style.display !== 'none'){
|
||||||
|
if(soundBlocked){
|
||||||
|
video.muted = false
|
||||||
|
video.play().then(() => {
|
||||||
|
soundBlocked = false
|
||||||
|
soundHint.style.display = 'none'
|
||||||
|
reportState('playing')
|
||||||
|
}).catch(() => {
|
||||||
|
video.muted = true
|
||||||
|
video.play().catch(() => {})
|
||||||
|
reportState('playing')
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
video.play().then(() => {
|
||||||
|
reportState('playing')
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
timer = setTimeout(next, imageDuration * 1000)
|
||||||
|
reportState('playing')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function reloadPlaylist() {
|
||||||
|
const res = await fetch('/api/playlist')
|
||||||
|
const data = await res.json()
|
||||||
|
const newList = data.files
|
||||||
|
const currentItem = list.length > 0 ? list[index] : null
|
||||||
|
list = newList
|
||||||
|
if(list.length === 0){
|
||||||
|
video.pause()
|
||||||
|
video.style.display = 'none'
|
||||||
|
img.style.display = 'none'
|
||||||
|
loader.classList.remove('hidden')
|
||||||
|
loaderText.innerHTML = '播放列表已清空,<a href="/admin">前往管理后台添加</a>'
|
||||||
|
cornerInfo.classList.remove('visible')
|
||||||
|
connIndicator.classList.remove('visible')
|
||||||
|
statusBar.classList.remove('visible')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
loader.classList.add('hidden')
|
||||||
|
showUI()
|
||||||
|
let newIndex = -1
|
||||||
|
if(currentItem){
|
||||||
|
newIndex = list.findIndex(item => item.relative_path === currentItem.relative_path)
|
||||||
|
}
|
||||||
|
if(newIndex >= 0){
|
||||||
|
index = newIndex
|
||||||
|
}else{
|
||||||
|
index = Math.min(index, list.length - 1)
|
||||||
|
play()
|
||||||
|
}
|
||||||
|
updateStatusUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
function applySettings(msg) {
|
||||||
|
if(msg.volume !== undefined) {
|
||||||
|
volume = msg.volume / 100
|
||||||
|
video.volume = volume
|
||||||
|
if(soundBlocked){
|
||||||
|
video.muted = false
|
||||||
|
video.play().then(() => {
|
||||||
|
soundBlocked = false
|
||||||
|
soundHint.style.display = 'none'
|
||||||
|
}).catch(() => {
|
||||||
|
video.muted = true
|
||||||
|
video.play().catch(() => {})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(msg.play_mode !== undefined) {
|
||||||
|
playMode = msg.play_mode
|
||||||
|
}
|
||||||
|
if(msg.image_duration !== undefined) {
|
||||||
|
imageDuration = msg.image_duration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function reportState(status) {
|
||||||
|
const item = list.length > 0 ? list[index] : null
|
||||||
|
fetch('/api/state', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {'Content-Type': 'application/json'},
|
||||||
|
body: JSON.stringify({
|
||||||
|
state: {
|
||||||
|
status: status,
|
||||||
|
index: index,
|
||||||
|
name: item ? item.name : '',
|
||||||
|
type: item ? item.type : ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
|
function skip(delta) {
|
||||||
|
clearTimeout(timer)
|
||||||
|
if(playMode === 'random'){
|
||||||
|
index = Math.floor(Math.random() * list.length)
|
||||||
|
}else{
|
||||||
|
index = (index + delta + list.length) % list.length
|
||||||
|
}
|
||||||
|
play()
|
||||||
|
}
|
||||||
|
|
||||||
|
function play() {
|
||||||
|
clearTimeout(timer)
|
||||||
|
if(paused) return
|
||||||
|
const item = list[index]
|
||||||
|
const url = getUrl(item)
|
||||||
|
updateStatusUI()
|
||||||
|
if(item.type === 'video'){
|
||||||
|
img.style.display = 'none'
|
||||||
|
video.style.display = 'block'
|
||||||
|
video.src = url
|
||||||
|
video.load()
|
||||||
|
video.muted = soundBlocked
|
||||||
|
const p = video.play()
|
||||||
|
if(p !== undefined){
|
||||||
|
p.then(() => {
|
||||||
|
reportState('playing')
|
||||||
|
}).catch(e => {
|
||||||
|
soundBlocked = true
|
||||||
|
video.muted = true
|
||||||
|
video.play().catch(() => {})
|
||||||
|
soundHint.style.display = 'block'
|
||||||
|
reportState('playing')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
video.style.display = 'none'
|
||||||
|
img.style.display = 'block'
|
||||||
|
img.src = url
|
||||||
|
reportState('playing')
|
||||||
|
timer = setTimeout(next, imageDuration * 1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
if(paused) return
|
||||||
|
clearTimeout(timer)
|
||||||
|
if(playMode === 'random'){
|
||||||
|
index = Math.floor(Math.random() * list.length)
|
||||||
|
}else{
|
||||||
|
index = (index + 1) % list.length
|
||||||
|
}
|
||||||
|
play()
|
||||||
|
}
|
||||||
|
|
||||||
|
function enableSound() {
|
||||||
|
video.muted = false
|
||||||
|
video.play().then(() => {
|
||||||
|
soundBlocked = false
|
||||||
|
soundHint.style.display = 'none'
|
||||||
|
}).catch(() => {
|
||||||
|
video.muted = true
|
||||||
|
video.play().catch(() => {})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('click', () => {
|
||||||
|
if(soundBlocked){
|
||||||
|
enableSound()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
video.onended = next
|
||||||
|
window.addEventListener('load', loadPlaylist)
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { defineConfig } from "vite";
|
||||||
|
import react from "@vitejs/plugin-react";
|
||||||
|
|
||||||
|
const host = process.env.TAURI_DEV_HOST;
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
|
export default defineConfig(async () => ({
|
||||||
|
plugins: [react()],
|
||||||
|
|
||||||
|
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
|
||||||
|
//
|
||||||
|
// 1. prevent Vite from obscuring rust errors
|
||||||
|
clearScreen: false,
|
||||||
|
// 2. tauri expects a fixed port, fail if that port is not available
|
||||||
|
server: {
|
||||||
|
port: 1420,
|
||||||
|
strictPort: true,
|
||||||
|
host: host || "127.0.0.1",
|
||||||
|
hmr: host
|
||||||
|
? {
|
||||||
|
protocol: "ws",
|
||||||
|
host,
|
||||||
|
port: 1421,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
watch: {
|
||||||
|
// 3. tell Vite to ignore watching `src-tauri`
|
||||||
|
ignored: ["**/src-tauri/**"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}));
|
||||||
@@ -0,0 +1,836 @@
|
|||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0":
|
||||||
|
version "7.29.0"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c"
|
||||||
|
integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-validator-identifier" "^7.28.5"
|
||||||
|
js-tokens "^4.0.0"
|
||||||
|
picocolors "^1.1.1"
|
||||||
|
|
||||||
|
"@babel/compat-data@^7.28.6":
|
||||||
|
version "7.29.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.29.3.tgz#e3f5347f0589596c91d227ccb6a541d37fb1307b"
|
||||||
|
integrity sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==
|
||||||
|
|
||||||
|
"@babel/core@^7.28.0":
|
||||||
|
version "7.29.0"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/core/-/core-7.29.0.tgz#5286ad785df7f79d656e88ce86e650d16ca5f322"
|
||||||
|
integrity sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame" "^7.29.0"
|
||||||
|
"@babel/generator" "^7.29.0"
|
||||||
|
"@babel/helper-compilation-targets" "^7.28.6"
|
||||||
|
"@babel/helper-module-transforms" "^7.28.6"
|
||||||
|
"@babel/helpers" "^7.28.6"
|
||||||
|
"@babel/parser" "^7.29.0"
|
||||||
|
"@babel/template" "^7.28.6"
|
||||||
|
"@babel/traverse" "^7.29.0"
|
||||||
|
"@babel/types" "^7.29.0"
|
||||||
|
"@jridgewell/remapping" "^2.3.5"
|
||||||
|
convert-source-map "^2.0.0"
|
||||||
|
debug "^4.1.0"
|
||||||
|
gensync "^1.0.0-beta.2"
|
||||||
|
json5 "^2.2.3"
|
||||||
|
semver "^6.3.1"
|
||||||
|
|
||||||
|
"@babel/generator@^7.29.0":
|
||||||
|
version "7.29.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/generator/-/generator-7.29.1.tgz#d09876290111abbb00ef962a7b83a5307fba0d50"
|
||||||
|
integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/parser" "^7.29.0"
|
||||||
|
"@babel/types" "^7.29.0"
|
||||||
|
"@jridgewell/gen-mapping" "^0.3.12"
|
||||||
|
"@jridgewell/trace-mapping" "^0.3.28"
|
||||||
|
jsesc "^3.0.2"
|
||||||
|
|
||||||
|
"@babel/helper-compilation-targets@^7.28.6":
|
||||||
|
version "7.28.6"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz#32c4a3f41f12ed1532179b108a4d746e105c2b25"
|
||||||
|
integrity sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/compat-data" "^7.28.6"
|
||||||
|
"@babel/helper-validator-option" "^7.27.1"
|
||||||
|
browserslist "^4.24.0"
|
||||||
|
lru-cache "^5.1.1"
|
||||||
|
semver "^6.3.1"
|
||||||
|
|
||||||
|
"@babel/helper-globals@^7.28.0":
|
||||||
|
version "7.28.0"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674"
|
||||||
|
integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==
|
||||||
|
|
||||||
|
"@babel/helper-module-imports@^7.28.6":
|
||||||
|
version "7.28.6"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz#60632cbd6ffb70b22823187201116762a03e2d5c"
|
||||||
|
integrity sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/traverse" "^7.28.6"
|
||||||
|
"@babel/types" "^7.28.6"
|
||||||
|
|
||||||
|
"@babel/helper-module-transforms@^7.28.6":
|
||||||
|
version "7.28.6"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz#9312d9d9e56edc35aeb6e95c25d4106b50b9eb1e"
|
||||||
|
integrity sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-module-imports" "^7.28.6"
|
||||||
|
"@babel/helper-validator-identifier" "^7.28.5"
|
||||||
|
"@babel/traverse" "^7.28.6"
|
||||||
|
|
||||||
|
"@babel/helper-plugin-utils@^7.27.1":
|
||||||
|
version "7.28.6"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz#6f13ea251b68c8532e985fd532f28741a8af9ac8"
|
||||||
|
integrity sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==
|
||||||
|
|
||||||
|
"@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.28.5":
|
||||||
|
version "7.28.5"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4"
|
||||||
|
integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==
|
||||||
|
|
||||||
|
"@babel/helper-validator-option@^7.27.1":
|
||||||
|
version "7.27.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f"
|
||||||
|
integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==
|
||||||
|
|
||||||
|
"@babel/helpers@^7.28.6":
|
||||||
|
version "7.29.2"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.29.2.tgz#9cfbccb02b8e229892c0b07038052cc1a8709c49"
|
||||||
|
integrity sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/template" "^7.28.6"
|
||||||
|
"@babel/types" "^7.29.0"
|
||||||
|
|
||||||
|
"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0":
|
||||||
|
version "7.29.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.29.3.tgz#116f70a77958307fceac27747573032f8a62f88e"
|
||||||
|
integrity sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/types" "^7.29.0"
|
||||||
|
|
||||||
|
"@babel/plugin-transform-react-jsx-self@^7.27.1":
|
||||||
|
version "7.27.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz#af678d8506acf52c577cac73ff7fe6615c85fc92"
|
||||||
|
integrity sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-plugin-utils" "^7.27.1"
|
||||||
|
|
||||||
|
"@babel/plugin-transform-react-jsx-source@^7.27.1":
|
||||||
|
version "7.27.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz#dcfe2c24094bb757bf73960374e7c55e434f19f0"
|
||||||
|
integrity sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-plugin-utils" "^7.27.1"
|
||||||
|
|
||||||
|
"@babel/template@^7.28.6":
|
||||||
|
version "7.28.6"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/template/-/template-7.28.6.tgz#0e7e56ecedb78aeef66ce7972b082fce76a23e57"
|
||||||
|
integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame" "^7.28.6"
|
||||||
|
"@babel/parser" "^7.28.6"
|
||||||
|
"@babel/types" "^7.28.6"
|
||||||
|
|
||||||
|
"@babel/traverse@^7.28.6", "@babel/traverse@^7.29.0":
|
||||||
|
version "7.29.0"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a"
|
||||||
|
integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame" "^7.29.0"
|
||||||
|
"@babel/generator" "^7.29.0"
|
||||||
|
"@babel/helper-globals" "^7.28.0"
|
||||||
|
"@babel/parser" "^7.29.0"
|
||||||
|
"@babel/template" "^7.28.6"
|
||||||
|
"@babel/types" "^7.29.0"
|
||||||
|
debug "^4.3.1"
|
||||||
|
|
||||||
|
"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.28.2", "@babel/types@^7.28.6", "@babel/types@^7.29.0":
|
||||||
|
version "7.29.0"
|
||||||
|
resolved "https://registry.npmmirror.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7"
|
||||||
|
integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-string-parser" "^7.27.1"
|
||||||
|
"@babel/helper-validator-identifier" "^7.28.5"
|
||||||
|
|
||||||
|
"@esbuild/aix-ppc64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz#82b74f92aa78d720b714162939fb248c90addf53"
|
||||||
|
integrity sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==
|
||||||
|
|
||||||
|
"@esbuild/android-arm64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz#f78cb8a3121fc205a53285adb24972db385d185d"
|
||||||
|
integrity sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==
|
||||||
|
|
||||||
|
"@esbuild/android-arm@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.27.7.tgz#593e10a1450bbfcac6cb321f61f468453bac209d"
|
||||||
|
integrity sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==
|
||||||
|
|
||||||
|
"@esbuild/android-x64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.27.7.tgz#453143d073326033d2d22caf9e48de4bae274b07"
|
||||||
|
integrity sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==
|
||||||
|
|
||||||
|
"@esbuild/darwin-arm64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz#6f23000fb9b40b7e04b7d0606c0693bd0632f322"
|
||||||
|
integrity sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==
|
||||||
|
|
||||||
|
"@esbuild/darwin-x64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz#27393dd18bb1263c663979c5f1576e00c2d024be"
|
||||||
|
integrity sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==
|
||||||
|
|
||||||
|
"@esbuild/freebsd-arm64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz#22e4638fa502d1c0027077324c97640e3adf3a62"
|
||||||
|
integrity sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==
|
||||||
|
|
||||||
|
"@esbuild/freebsd-x64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz#9224b8e4fea924ce2194e3efc3e9aebf822192d6"
|
||||||
|
integrity sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==
|
||||||
|
|
||||||
|
"@esbuild/linux-arm64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz#4f5d1c27527d817b35684ae21419e57c2bda0966"
|
||||||
|
integrity sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==
|
||||||
|
|
||||||
|
"@esbuild/linux-arm@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz#b9e9d070c8c1c0449cf12b20eac37d70a4595921"
|
||||||
|
integrity sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==
|
||||||
|
|
||||||
|
"@esbuild/linux-ia32@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz#3f80fb696aa96051a94047f35c85b08b21c36f9e"
|
||||||
|
integrity sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==
|
||||||
|
|
||||||
|
"@esbuild/linux-loong64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz#9be1f2c28210b13ebb4156221bba356fe1675205"
|
||||||
|
integrity sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==
|
||||||
|
|
||||||
|
"@esbuild/linux-mips64el@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz#4ab5ee67a3dfcbcb5e8fd7883dae6e735b1163b8"
|
||||||
|
integrity sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==
|
||||||
|
|
||||||
|
"@esbuild/linux-ppc64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz#dac78c689f6499459c4321e5c15032c12307e7ea"
|
||||||
|
integrity sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==
|
||||||
|
|
||||||
|
"@esbuild/linux-riscv64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz#050f7d3b355c3a98308e935bc4d6325da91b0027"
|
||||||
|
integrity sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==
|
||||||
|
|
||||||
|
"@esbuild/linux-s390x@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz#d61f715ce61d43fe5844ad0d8f463f88cbe4fef6"
|
||||||
|
integrity sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==
|
||||||
|
|
||||||
|
"@esbuild/linux-x64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz#ca8e1aa478fc8209257bf3ac8f79c4dc2982f32a"
|
||||||
|
integrity sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==
|
||||||
|
|
||||||
|
"@esbuild/netbsd-arm64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz#1650f2c1b948deeb3ef948f2fc30614723c09690"
|
||||||
|
integrity sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==
|
||||||
|
|
||||||
|
"@esbuild/netbsd-x64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz#65772ab342c4b3319bf0705a211050aac1b6e320"
|
||||||
|
integrity sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==
|
||||||
|
|
||||||
|
"@esbuild/openbsd-arm64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz#37ed7cfa66549d7955852fce37d0c3de4e715ea1"
|
||||||
|
integrity sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==
|
||||||
|
|
||||||
|
"@esbuild/openbsd-x64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz#01bf3d385855ef50cb33db7c4b52f957c34cd179"
|
||||||
|
integrity sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==
|
||||||
|
|
||||||
|
"@esbuild/openharmony-arm64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz#6c1f94b34086599aabda4eac8f638294b9877410"
|
||||||
|
integrity sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==
|
||||||
|
|
||||||
|
"@esbuild/sunos-x64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz#4b0dd17ae0a6941d2d0fd35a906392517071a90d"
|
||||||
|
integrity sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==
|
||||||
|
|
||||||
|
"@esbuild/win32-arm64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz#34193ab5565d6ff68ca928ac04be75102ccb2e77"
|
||||||
|
integrity sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==
|
||||||
|
|
||||||
|
"@esbuild/win32-ia32@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz#eb67f0e4482515d8c1894ede631c327a4da9fc4d"
|
||||||
|
integrity sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==
|
||||||
|
|
||||||
|
"@esbuild/win32-x64@0.27.7":
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz#8fe30b3088b89b4873c3a6cc87597ae3920c0a8b"
|
||||||
|
integrity sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==
|
||||||
|
|
||||||
|
"@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.5":
|
||||||
|
version "0.3.13"
|
||||||
|
resolved "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f"
|
||||||
|
integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==
|
||||||
|
dependencies:
|
||||||
|
"@jridgewell/sourcemap-codec" "^1.5.0"
|
||||||
|
"@jridgewell/trace-mapping" "^0.3.24"
|
||||||
|
|
||||||
|
"@jridgewell/remapping@^2.3.5":
|
||||||
|
version "2.3.5"
|
||||||
|
resolved "https://registry.npmmirror.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1"
|
||||||
|
integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==
|
||||||
|
dependencies:
|
||||||
|
"@jridgewell/gen-mapping" "^0.3.5"
|
||||||
|
"@jridgewell/trace-mapping" "^0.3.24"
|
||||||
|
|
||||||
|
"@jridgewell/resolve-uri@^3.1.0":
|
||||||
|
version "3.1.2"
|
||||||
|
resolved "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
|
||||||
|
integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
|
||||||
|
|
||||||
|
"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0":
|
||||||
|
version "1.5.5"
|
||||||
|
resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba"
|
||||||
|
integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
|
||||||
|
|
||||||
|
"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.28":
|
||||||
|
version "0.3.31"
|
||||||
|
resolved "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0"
|
||||||
|
integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==
|
||||||
|
dependencies:
|
||||||
|
"@jridgewell/resolve-uri" "^3.1.0"
|
||||||
|
"@jridgewell/sourcemap-codec" "^1.4.14"
|
||||||
|
|
||||||
|
"@rolldown/pluginutils@1.0.0-beta.27":
|
||||||
|
version "1.0.0-beta.27"
|
||||||
|
resolved "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz#47d2bf4cef6d470b22f5831b420f8964e0bf755f"
|
||||||
|
integrity sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==
|
||||||
|
|
||||||
|
"@rollup/rollup-android-arm-eabi@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.3.tgz#31503ca40424374cd6c5198031cf4d5a73de9727"
|
||||||
|
integrity sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw==
|
||||||
|
|
||||||
|
"@rollup/rollup-android-arm64@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.3.tgz#7cbc30c88507013d0f982cfeb8884337ba1e0bb2"
|
||||||
|
integrity sha512-xw3xtkDApIOGayehp2+Rz4zimfkaX65r4t47iy+ymQB2G4iJCBBfj0ogVg5jpvjpn8UWn/+q9tprxleYeNp3Hw==
|
||||||
|
|
||||||
|
"@rollup/rollup-darwin-arm64@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.3.tgz#bc341a93bb2111326a2865f55d1d23baedecf40c"
|
||||||
|
integrity sha512-vo6Y5Qfpx7/5EaamIwi0WqW2+zfiusVihKatLvtN1VFVy3D13uERk/6gZLU1UiHRL6fDXqj/ELIeVRGnvcTE1g==
|
||||||
|
|
||||||
|
"@rollup/rollup-darwin-x64@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.3.tgz#dfa0236581c55ecc0bcaeb2ea1f2e800c58dc3e2"
|
||||||
|
integrity sha512-D+0QGcZhBzTN82weOnsSlY7V7+RMmPuF1CkbxyMAGE8+ZHeUjyb76ZiWmBlCu//AQQONvxcqRbwZTajZKqjuOw==
|
||||||
|
|
||||||
|
"@rollup/rollup-freebsd-arm64@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.3.tgz#4c5977413b87808a13b5edd524e46fafddb85b52"
|
||||||
|
integrity sha512-6HnvHCT7fDyj6R0Ph7A6x8dQS/S38MClRWeDLqc0MdfWkxjiu1HSDYrdPhqSILzjTIC/pnXbbJbo+ft+gy/9hQ==
|
||||||
|
|
||||||
|
"@rollup/rollup-freebsd-x64@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.3.tgz#5cb2cee62ffee3ada4a0b44353e96cf98cfc7c3c"
|
||||||
|
integrity sha512-KHLgC3WKlUYW3ShFKnnosZDOJ0xjg9zp7au3sIm2bs/tGBeC2ipmvRh/N7JKi0t9Ue20C0dpEshi8WUubg+cnA==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm-gnueabihf@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.3.tgz#04700cad36dd43ae81044fe7ee73e925845c4b85"
|
||||||
|
integrity sha512-DV6fJoxEYWJOvaZIsok7KrYl0tPvga5OZ2yvKHNNYyk/2roMLqQAbGhr78EQ5YhHpnhLKJD3S1WFusAkmUuV5g==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm-musleabihf@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.3.tgz#548ebf3997b3a6dcc7cdd7da813ff0c46000ac0a"
|
||||||
|
integrity sha512-mQKoJAzvuOs6F+TZybQO4GOTSMUu7v0WdxEk24krQ/uUxXoPTtHjuaUuPmFhtBcM4K0ons8nrE3JyhTuCFtT/w==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm64-gnu@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.3.tgz#0264608f504b33725639ebe93be02c40e71a35c1"
|
||||||
|
integrity sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm64-musl@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.3.tgz#147cf4889502cd3b331a800b8ca6741f87873079"
|
||||||
|
integrity sha512-4YTNHKqGng5+yiZt3mg77nmyuCfmNfX4fPmyUapBcIk+BdwSwmCWGXOUxhXbBEkFHtoN5boLj/5NON+u5QC9tg==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-loong64-gnu@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.3.tgz#0c27c6b5258dcb3d0290e3bd04ba6277c9d7e541"
|
||||||
|
integrity sha512-SU3kNlhkpI4UqlUc2VXPGK9o886ZsSeGfMAX2ba2b8DKmMXq4AL7KUrkSWVbb7koVqx41Yczx6dx5PNargIrEA==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-loong64-musl@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.3.tgz#f0f18075ea0bfa2c992f8e3933b39b6ef91f7799"
|
||||||
|
integrity sha512-6lDLl5h4TXpB1mTf2rQWnAk/LcXrx9vBfu/DT5TIPhvMhRWaZ5MxkIc8u4lJAmBo6klTe1ywXIUHFjylW505sg==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-ppc64-gnu@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.3.tgz#149bb5cb8893589ffaa1924b4eac4282e9fa4c69"
|
||||||
|
integrity sha512-BMo8bOw8evlup/8G+cj5xWtPyp93xPdyoSN16Zy90Q2QZ0ZYRhCt6ZJSwbrRzG9HApFabjwj2p25TUPDWrhzqQ==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-ppc64-musl@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.3.tgz#200a063e298b05f996917d2aa53de749d54c0ca0"
|
||||||
|
integrity sha512-E0L8X1dZN1/Rph+5VPF6Xj2G7JJvMACVXtamTJIDrVI44Y3K+G8gQaMEAavbqCGTa16InptiVrX6eM6pmJ+7qA==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-riscv64-gnu@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.3.tgz#6d6d6eb996197ba86f95f9a6c442bc862f0756d4"
|
||||||
|
integrity sha512-oZJ/WHaVfHUiRAtmTAeo3DcevNsVvH8mbvodjZy7D5QKvCefO371SiKRpxoDcCxB3PTRTLayWBkvmDQKTcX/sw==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-riscv64-musl@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.3.tgz#9deb86001785cfcbc761457f50cd7c112fda0df9"
|
||||||
|
integrity sha512-Dhbyh7j9FybM3YaTgaHmVALwA8AkUwTPccyCQ79TG9AJUsMQqgN1DDEZNr4+QUfwiWvLDumW5vdwzoeUF+TNxQ==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-s390x-gnu@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.3.tgz#d8228720c6e42da190d96c31a3495d70cf8284b9"
|
||||||
|
integrity sha512-cJd1X5XhHHlltkaypz1UcWLA8AcoIi1aWhsvaWDskD1oz2eKCypnqvTQ8ykMNI0RSmm7NkTdSqSSD7zM0xa6Ig==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-gnu@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.3.tgz#df6bb38617a66a842bd2aeac9560cd729d084258"
|
||||||
|
integrity sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA==
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-musl@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.3.tgz#75e3e72849266b4fdd65f2da6c62423051e35636"
|
||||||
|
integrity sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA==
|
||||||
|
|
||||||
|
"@rollup/rollup-openbsd-x64@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.3.tgz#e1080f0efb8b15cda39b3e62de5fb806079ab6e9"
|
||||||
|
integrity sha512-QaWcIgRxqEdQdhJqW4DJctsH6HCmo5vHxY0krHSX4jMtOqfzC+dqDGuHM87bu4H8JBeibWx7jFz+h6/4C8wA5Q==
|
||||||
|
|
||||||
|
"@rollup/rollup-openharmony-arm64@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.3.tgz#1fbda2d95c29dbfceb62785431754cd5aab86c72"
|
||||||
|
integrity sha512-AaXwSvUi3QIPtroAUw1t5yHGIyqKEXwH54WUocFolZhpGDruJcs8c+xPNDRn4XiQsS7MEwnYsHW2l0MBLDMkWg==
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-arm64-msvc@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.3.tgz#deab3470815f97996f1d0d3608549cf1b7e4ffc2"
|
||||||
|
integrity sha512-65LAKM/bAWDqKNEelHlcHvm2V+Vfb8C6INFxQXRHCvaVN1rJfwr4NvdP4FyzUaLqWfaCGaadf6UbTm8xJeYfEg==
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-ia32-msvc@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.3.tgz#817acae2ed4572960b59235ff2322381b6d82f26"
|
||||||
|
integrity sha512-EEM2gyhBF5MFnI6vMKdX1LAosE627RGBzIoGMdLloPZkXrUN0Ckqgr2Qi8+J3zip/8NVVro3/FjB+tjhZUgUHA==
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-x64-gnu@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.3.tgz#48129be99b0250d76b9c6d0ac983bef563a1c48a"
|
||||||
|
integrity sha512-E5Eb5H/DpxaoXH++Qkv28RcUJboMopmdDUALBczvHMf7hNIxaDZqwY5lK12UK1BHacSmvupoEWGu+n993Z0y1A==
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-x64-msvc@4.60.3":
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.3.tgz#cc6f094a3ffe5556bb4a831ee6fb572b8cd81a75"
|
||||||
|
integrity sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA==
|
||||||
|
|
||||||
|
"@tauri-apps/api@^2", "@tauri-apps/api@^2.11.0":
|
||||||
|
version "2.11.0"
|
||||||
|
resolved "https://registry.npmmirror.com/@tauri-apps/api/-/api-2.11.0.tgz#00fb69996010178a5153798d4a84f6fe3a1e1182"
|
||||||
|
integrity sha512-7CinYODhky9lmO23xHnUFv0Xt43fbtWMyxZcLcRBlFkcgXKuEirBvHpmtJ89YMhyeGcq20Wuc47Fa4XjyniywA==
|
||||||
|
|
||||||
|
"@tauri-apps/cli-darwin-arm64@2.11.1":
|
||||||
|
version "2.11.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.11.1.tgz#4fc2e2165cde2d71bb9a56beacb75542ceb7dc0e"
|
||||||
|
integrity sha512-6eEKMBXsQPCuM1EmvrjT2+aBuxWQuFdKdW8pzNuNQtpq45nEEpBlD5gr8pUeAyOU1DQKlkFaEc/MPBxb/Pfjtg==
|
||||||
|
|
||||||
|
"@tauri-apps/cli-darwin-x64@2.11.1":
|
||||||
|
version "2.11.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.11.1.tgz#dfea5d1448bd7f4dae5c6483c6f21ab6df53e9c7"
|
||||||
|
integrity sha512-LQUO7exfRWjWALNhetph5guWpMeHphRpokOLk0OIbTTExaNwJNFu3I4vb+CCM/4G/QGoZe/5XikZOJdNEFP1ig==
|
||||||
|
|
||||||
|
"@tauri-apps/cli-linux-arm-gnueabihf@2.11.1":
|
||||||
|
version "2.11.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.11.1.tgz#fd054d074fe1dc7a24e589957e11e8bb1f3bfe90"
|
||||||
|
integrity sha512-5i/awiBCRRhOUG8yjn0fMHXIWD5Ez8eEk5LtvOxyQrKuJkRaZDvnbIjZbE183blAwkoA4xN3aO/prJiqscl02Q==
|
||||||
|
|
||||||
|
"@tauri-apps/cli-linux-arm64-gnu@2.11.1":
|
||||||
|
version "2.11.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.11.1.tgz#13d068385371de50cc876713ded71975a268a3be"
|
||||||
|
integrity sha512-9LrwDw3S9Fygtw/Q6WDhOP+3svJRGAsejeE+GKrc0eO1ThMVhwi2LL6hw4dlKw93IfS7VY1G19sWGxJ/NcU4nA==
|
||||||
|
|
||||||
|
"@tauri-apps/cli-linux-arm64-musl@2.11.1":
|
||||||
|
version "2.11.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.11.1.tgz#a3ff5b2abffd4ef0ba0169ecfceecf71b14e2312"
|
||||||
|
integrity sha512-mNA5dbbqPqDUdTIwdUYYuhO2GvIe9UnB2r0VU2njxBOS3Opbx4gKNC5yP0Iu4rYmEmqdlwry9VzGZQ3wq9dyFg==
|
||||||
|
|
||||||
|
"@tauri-apps/cli-linux-riscv64-gnu@2.11.1":
|
||||||
|
version "2.11.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.11.1.tgz#708711c15705dca13f51fb1ee45a16a6fccac809"
|
||||||
|
integrity sha512-fZj3Gwq+6fUs305T5WQiD5iSGJw+j/4w/HGmk4sHDAcy+rp9zU5eaxB7nOyz5/I/nkNAuKPqfp6uIbiUBXkBCw==
|
||||||
|
|
||||||
|
"@tauri-apps/cli-linux-x64-gnu@2.11.1":
|
||||||
|
version "2.11.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.11.1.tgz#c59b7d54aeb8d3d0975e99eaee121d6ac51fd898"
|
||||||
|
integrity sha512-XFxGxOvHM7jjeD6ozCKdGfhzJ7lERYDGZl1/Kb4fsvchaJsfLJ981TlyTG8Qy/gFq+f5GitH3bfrX9JAkjPEyw==
|
||||||
|
|
||||||
|
"@tauri-apps/cli-linux-x64-musl@2.11.1":
|
||||||
|
version "2.11.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.11.1.tgz#1df5392521893d199b49b31466ebf7d36bb262a0"
|
||||||
|
integrity sha512-d5C2/Zm+68v7R9wTuTCjRQEVrWjcdMkJBZ1+rXse+QdMMlTB9+u9PDNDLw9PQflWxYLaYZ7tjxxL9Nb9II6PbA==
|
||||||
|
|
||||||
|
"@tauri-apps/cli-win32-arm64-msvc@2.11.1":
|
||||||
|
version "2.11.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.11.1.tgz#f28fccdaabc63d76d820a4b46173f387069c5851"
|
||||||
|
integrity sha512-YdeVWFAR1pTXzUU6NLstPq4G6OLxuDrXCXEBdmBH+5EZIDXUx0D2kJlz3+YjpazkKvAzYpgziTsyRagls0OfRQ==
|
||||||
|
|
||||||
|
"@tauri-apps/cli-win32-ia32-msvc@2.11.1":
|
||||||
|
version "2.11.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.11.1.tgz#85d0261420ed790fef3f344ca935a743dc43977e"
|
||||||
|
integrity sha512-VBGkuH0eB9K9LLSMv361Gzr5Ou72sCS4+ztpmkWEQ+wd/amhcYOsf3X6qn1RJZDzIhiOYHJEOysZUC3baD01rA==
|
||||||
|
|
||||||
|
"@tauri-apps/cli-win32-x64-msvc@2.11.1":
|
||||||
|
version "2.11.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.11.1.tgz#78e631ef50dd47f992eb2a4ae83b9bf8781b251f"
|
||||||
|
integrity sha512-b3ORhIAKgp9ZYY+zBt7b7r0kLU2kjvyGF0+MS2SBym3emsweGPybEqocJcmtMuxyBhkOKHP4CiuEJEDuAlTx6A==
|
||||||
|
|
||||||
|
"@tauri-apps/cli@^2":
|
||||||
|
version "2.11.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@tauri-apps/cli/-/cli-2.11.1.tgz#46493afee700baadf0209bc879069485aa9525f3"
|
||||||
|
integrity sha512-rpEbaJ/HzNb6fwsquwoAbq29/Vt4gADhS423A8fdkwL4edJ0wZmoB8ar7O6JPDL834MUKOCm/rrJ7c9oAaEaYQ==
|
||||||
|
optionalDependencies:
|
||||||
|
"@tauri-apps/cli-darwin-arm64" "2.11.1"
|
||||||
|
"@tauri-apps/cli-darwin-x64" "2.11.1"
|
||||||
|
"@tauri-apps/cli-linux-arm-gnueabihf" "2.11.1"
|
||||||
|
"@tauri-apps/cli-linux-arm64-gnu" "2.11.1"
|
||||||
|
"@tauri-apps/cli-linux-arm64-musl" "2.11.1"
|
||||||
|
"@tauri-apps/cli-linux-riscv64-gnu" "2.11.1"
|
||||||
|
"@tauri-apps/cli-linux-x64-gnu" "2.11.1"
|
||||||
|
"@tauri-apps/cli-linux-x64-musl" "2.11.1"
|
||||||
|
"@tauri-apps/cli-win32-arm64-msvc" "2.11.1"
|
||||||
|
"@tauri-apps/cli-win32-ia32-msvc" "2.11.1"
|
||||||
|
"@tauri-apps/cli-win32-x64-msvc" "2.11.1"
|
||||||
|
|
||||||
|
"@tauri-apps/plugin-opener@^2":
|
||||||
|
version "2.5.4"
|
||||||
|
resolved "https://registry.npmmirror.com/@tauri-apps/plugin-opener/-/plugin-opener-2.5.4.tgz#b37883e4d36125b8c5a0c74f683395958a65bd7d"
|
||||||
|
integrity sha512-1HnPkb+AmgO29HBazm4uPLKB+r7zzcTBW1d0fyYp1uP+jwtpoiNDGKMMzz58SFp49nOIrxdE3aUJtT57lfO9CQ==
|
||||||
|
dependencies:
|
||||||
|
"@tauri-apps/api" "^2.11.0"
|
||||||
|
|
||||||
|
"@types/babel__core@^7.20.5":
|
||||||
|
version "7.20.5"
|
||||||
|
resolved "https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017"
|
||||||
|
integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/parser" "^7.20.7"
|
||||||
|
"@babel/types" "^7.20.7"
|
||||||
|
"@types/babel__generator" "*"
|
||||||
|
"@types/babel__template" "*"
|
||||||
|
"@types/babel__traverse" "*"
|
||||||
|
|
||||||
|
"@types/babel__generator@*":
|
||||||
|
version "7.27.0"
|
||||||
|
resolved "https://registry.npmmirror.com/@types/babel__generator/-/babel__generator-7.27.0.tgz#b5819294c51179957afaec341442f9341e4108a9"
|
||||||
|
integrity sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/types" "^7.0.0"
|
||||||
|
|
||||||
|
"@types/babel__template@*":
|
||||||
|
version "7.4.4"
|
||||||
|
resolved "https://registry.npmmirror.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f"
|
||||||
|
integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==
|
||||||
|
dependencies:
|
||||||
|
"@babel/parser" "^7.1.0"
|
||||||
|
"@babel/types" "^7.0.0"
|
||||||
|
|
||||||
|
"@types/babel__traverse@*":
|
||||||
|
version "7.28.0"
|
||||||
|
resolved "https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.28.0.tgz#07d713d6cce0d265c9849db0cbe62d3f61f36f74"
|
||||||
|
integrity sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==
|
||||||
|
dependencies:
|
||||||
|
"@babel/types" "^7.28.2"
|
||||||
|
|
||||||
|
"@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-react@^4.6.0":
|
||||||
|
version "4.7.0"
|
||||||
|
resolved "https://registry.npmmirror.com/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz#647af4e7bb75ad3add578e762ad984b90f4a24b9"
|
||||||
|
integrity sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/core" "^7.28.0"
|
||||||
|
"@babel/plugin-transform-react-jsx-self" "^7.27.1"
|
||||||
|
"@babel/plugin-transform-react-jsx-source" "^7.27.1"
|
||||||
|
"@rolldown/pluginutils" "1.0.0-beta.27"
|
||||||
|
"@types/babel__core" "^7.20.5"
|
||||||
|
react-refresh "^0.17.0"
|
||||||
|
|
||||||
|
baseline-browser-mapping@^2.10.12:
|
||||||
|
version "2.10.29"
|
||||||
|
resolved "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.29.tgz#47bdc13027af28d341f367a4f35a07ce872e27b4"
|
||||||
|
integrity sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==
|
||||||
|
|
||||||
|
browserslist@^4.24.0:
|
||||||
|
version "4.28.2"
|
||||||
|
resolved "https://registry.npmmirror.com/browserslist/-/browserslist-4.28.2.tgz#f50b65362ef48974ca9f50b3680566d786b811d2"
|
||||||
|
integrity sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==
|
||||||
|
dependencies:
|
||||||
|
baseline-browser-mapping "^2.10.12"
|
||||||
|
caniuse-lite "^1.0.30001782"
|
||||||
|
electron-to-chromium "^1.5.328"
|
||||||
|
node-releases "^2.0.36"
|
||||||
|
update-browserslist-db "^1.2.3"
|
||||||
|
|
||||||
|
caniuse-lite@^1.0.30001782:
|
||||||
|
version "1.0.30001792"
|
||||||
|
resolved "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz#ca8bb9be244835a335e2018272ce7223691873c5"
|
||||||
|
integrity sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==
|
||||||
|
|
||||||
|
convert-source-map@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a"
|
||||||
|
integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==
|
||||||
|
|
||||||
|
debug@^4.1.0, debug@^4.3.1:
|
||||||
|
version "4.4.3"
|
||||||
|
resolved "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a"
|
||||||
|
integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
|
||||||
|
dependencies:
|
||||||
|
ms "^2.1.3"
|
||||||
|
|
||||||
|
electron-to-chromium@^1.5.328:
|
||||||
|
version "1.5.353"
|
||||||
|
resolved "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.353.tgz#01e8a8e25a0bf13e631106045f177d0568ca91c2"
|
||||||
|
integrity sha512-kOrWphBi8TOZyiJZqsgqIle0lw+tzmnQK83pV9dZUd01Nm2POECSyFQMAuarzZdYqQW7FH9RaYOuaRo3h+bQ3w==
|
||||||
|
|
||||||
|
esbuild@^0.27.0:
|
||||||
|
version "0.27.7"
|
||||||
|
resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.27.7.tgz#bcadce22b2f3fd76f257e3a64f83a64986fea11f"
|
||||||
|
integrity sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==
|
||||||
|
optionalDependencies:
|
||||||
|
"@esbuild/aix-ppc64" "0.27.7"
|
||||||
|
"@esbuild/android-arm" "0.27.7"
|
||||||
|
"@esbuild/android-arm64" "0.27.7"
|
||||||
|
"@esbuild/android-x64" "0.27.7"
|
||||||
|
"@esbuild/darwin-arm64" "0.27.7"
|
||||||
|
"@esbuild/darwin-x64" "0.27.7"
|
||||||
|
"@esbuild/freebsd-arm64" "0.27.7"
|
||||||
|
"@esbuild/freebsd-x64" "0.27.7"
|
||||||
|
"@esbuild/linux-arm" "0.27.7"
|
||||||
|
"@esbuild/linux-arm64" "0.27.7"
|
||||||
|
"@esbuild/linux-ia32" "0.27.7"
|
||||||
|
"@esbuild/linux-loong64" "0.27.7"
|
||||||
|
"@esbuild/linux-mips64el" "0.27.7"
|
||||||
|
"@esbuild/linux-ppc64" "0.27.7"
|
||||||
|
"@esbuild/linux-riscv64" "0.27.7"
|
||||||
|
"@esbuild/linux-s390x" "0.27.7"
|
||||||
|
"@esbuild/linux-x64" "0.27.7"
|
||||||
|
"@esbuild/netbsd-arm64" "0.27.7"
|
||||||
|
"@esbuild/netbsd-x64" "0.27.7"
|
||||||
|
"@esbuild/openbsd-arm64" "0.27.7"
|
||||||
|
"@esbuild/openbsd-x64" "0.27.7"
|
||||||
|
"@esbuild/openharmony-arm64" "0.27.7"
|
||||||
|
"@esbuild/sunos-x64" "0.27.7"
|
||||||
|
"@esbuild/win32-arm64" "0.27.7"
|
||||||
|
"@esbuild/win32-ia32" "0.27.7"
|
||||||
|
"@esbuild/win32-x64" "0.27.7"
|
||||||
|
|
||||||
|
escalade@^3.2.0:
|
||||||
|
version "3.2.0"
|
||||||
|
resolved "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"
|
||||||
|
integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
|
||||||
|
|
||||||
|
fdir@^6.5.0:
|
||||||
|
version "6.5.0"
|
||||||
|
resolved "https://registry.npmmirror.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350"
|
||||||
|
integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==
|
||||||
|
|
||||||
|
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==
|
||||||
|
|
||||||
|
gensync@^1.0.0-beta.2:
|
||||||
|
version "1.0.0-beta.2"
|
||||||
|
resolved "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
|
||||||
|
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
|
||||||
|
|
||||||
|
js-tokens@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||||
|
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||||
|
|
||||||
|
jsesc@^3.0.2:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d"
|
||||||
|
integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==
|
||||||
|
|
||||||
|
json5@^2.2.3:
|
||||||
|
version "2.2.3"
|
||||||
|
resolved "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
|
||||||
|
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
|
||||||
|
|
||||||
|
lru-cache@^5.1.1:
|
||||||
|
version "5.1.1"
|
||||||
|
resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
|
||||||
|
integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
|
||||||
|
dependencies:
|
||||||
|
yallist "^3.0.2"
|
||||||
|
|
||||||
|
ms@^2.1.3:
|
||||||
|
version "2.1.3"
|
||||||
|
resolved "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||||
|
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||||
|
|
||||||
|
nanoid@^3.3.11:
|
||||||
|
version "3.3.12"
|
||||||
|
resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.12.tgz#ab3d912e217a6d0a514f00a72a16543a28982c05"
|
||||||
|
integrity sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==
|
||||||
|
|
||||||
|
node-releases@^2.0.36:
|
||||||
|
version "2.0.44"
|
||||||
|
resolved "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.44.tgz#212c9b983f5bb70d311dd68c27d55dd0e65d1ca7"
|
||||||
|
integrity sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==
|
||||||
|
|
||||||
|
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==
|
||||||
|
|
||||||
|
picomatch@^4.0.3, picomatch@^4.0.4:
|
||||||
|
version "4.0.4"
|
||||||
|
resolved "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.4.tgz#fd6f5e00a143086e074dffe4c924b8fb293b0589"
|
||||||
|
integrity sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==
|
||||||
|
|
||||||
|
postcss@^8.5.6:
|
||||||
|
version "8.5.14"
|
||||||
|
resolved "https://registry.npmmirror.com/postcss/-/postcss-8.5.14.tgz#a66c2d7808fadf69ebb5b84a03f8bafd76c4919c"
|
||||||
|
integrity sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==
|
||||||
|
dependencies:
|
||||||
|
nanoid "^3.3.11"
|
||||||
|
picocolors "^1.1.1"
|
||||||
|
source-map-js "^1.2.1"
|
||||||
|
|
||||||
|
react-dom@^19.1.0:
|
||||||
|
version "19.2.6"
|
||||||
|
resolved "https://registry.npmmirror.com/react-dom/-/react-dom-19.2.6.tgz#44a81b0bcca22da814c00847d09d01c8615529b7"
|
||||||
|
integrity sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==
|
||||||
|
dependencies:
|
||||||
|
scheduler "^0.27.0"
|
||||||
|
|
||||||
|
react-refresh@^0.17.0:
|
||||||
|
version "0.17.0"
|
||||||
|
resolved "https://registry.npmmirror.com/react-refresh/-/react-refresh-0.17.0.tgz#b7e579c3657f23d04eccbe4ad2e58a8ed51e7e53"
|
||||||
|
integrity sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==
|
||||||
|
|
||||||
|
react@^19.1.0:
|
||||||
|
version "19.2.6"
|
||||||
|
resolved "https://registry.npmmirror.com/react/-/react-19.2.6.tgz#3dadb8e12b2a7934c1d5317973e5dce1301f9a4d"
|
||||||
|
integrity sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==
|
||||||
|
|
||||||
|
rollup@^4.43.0:
|
||||||
|
version "4.60.3"
|
||||||
|
resolved "https://registry.npmmirror.com/rollup/-/rollup-4.60.3.tgz#789258d41d090687d0ca7e80e8583d733711ddd3"
|
||||||
|
integrity sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==
|
||||||
|
dependencies:
|
||||||
|
"@types/estree" "1.0.8"
|
||||||
|
optionalDependencies:
|
||||||
|
"@rollup/rollup-android-arm-eabi" "4.60.3"
|
||||||
|
"@rollup/rollup-android-arm64" "4.60.3"
|
||||||
|
"@rollup/rollup-darwin-arm64" "4.60.3"
|
||||||
|
"@rollup/rollup-darwin-x64" "4.60.3"
|
||||||
|
"@rollup/rollup-freebsd-arm64" "4.60.3"
|
||||||
|
"@rollup/rollup-freebsd-x64" "4.60.3"
|
||||||
|
"@rollup/rollup-linux-arm-gnueabihf" "4.60.3"
|
||||||
|
"@rollup/rollup-linux-arm-musleabihf" "4.60.3"
|
||||||
|
"@rollup/rollup-linux-arm64-gnu" "4.60.3"
|
||||||
|
"@rollup/rollup-linux-arm64-musl" "4.60.3"
|
||||||
|
"@rollup/rollup-linux-loong64-gnu" "4.60.3"
|
||||||
|
"@rollup/rollup-linux-loong64-musl" "4.60.3"
|
||||||
|
"@rollup/rollup-linux-ppc64-gnu" "4.60.3"
|
||||||
|
"@rollup/rollup-linux-ppc64-musl" "4.60.3"
|
||||||
|
"@rollup/rollup-linux-riscv64-gnu" "4.60.3"
|
||||||
|
"@rollup/rollup-linux-riscv64-musl" "4.60.3"
|
||||||
|
"@rollup/rollup-linux-s390x-gnu" "4.60.3"
|
||||||
|
"@rollup/rollup-linux-x64-gnu" "4.60.3"
|
||||||
|
"@rollup/rollup-linux-x64-musl" "4.60.3"
|
||||||
|
"@rollup/rollup-openbsd-x64" "4.60.3"
|
||||||
|
"@rollup/rollup-openharmony-arm64" "4.60.3"
|
||||||
|
"@rollup/rollup-win32-arm64-msvc" "4.60.3"
|
||||||
|
"@rollup/rollup-win32-ia32-msvc" "4.60.3"
|
||||||
|
"@rollup/rollup-win32-x64-gnu" "4.60.3"
|
||||||
|
"@rollup/rollup-win32-x64-msvc" "4.60.3"
|
||||||
|
fsevents "~2.3.2"
|
||||||
|
|
||||||
|
scheduler@^0.27.0:
|
||||||
|
version "0.27.0"
|
||||||
|
resolved "https://registry.npmmirror.com/scheduler/-/scheduler-0.27.0.tgz#0c4ef82d67d1e5c1e359e8fc76d3a87f045fe5bd"
|
||||||
|
integrity sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==
|
||||||
|
|
||||||
|
semver@^6.3.1:
|
||||||
|
version "6.3.1"
|
||||||
|
resolved "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
|
||||||
|
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
|
||||||
|
|
||||||
|
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==
|
||||||
|
|
||||||
|
tinyglobby@^0.2.15:
|
||||||
|
version "0.2.16"
|
||||||
|
resolved "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.16.tgz#1c3b7eb953fce42b226bc5a1ee06428281aff3d6"
|
||||||
|
integrity sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==
|
||||||
|
dependencies:
|
||||||
|
fdir "^6.5.0"
|
||||||
|
picomatch "^4.0.4"
|
||||||
|
|
||||||
|
update-browserslist-db@^1.2.3:
|
||||||
|
version "1.2.3"
|
||||||
|
resolved "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d"
|
||||||
|
integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==
|
||||||
|
dependencies:
|
||||||
|
escalade "^3.2.0"
|
||||||
|
picocolors "^1.1.1"
|
||||||
|
|
||||||
|
vite@^7.0.4:
|
||||||
|
version "7.3.3"
|
||||||
|
resolved "https://registry.npmmirror.com/vite/-/vite-7.3.3.tgz#d7e07a52b5873fb86f902a3f4b3d17410337450f"
|
||||||
|
integrity sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==
|
||||||
|
dependencies:
|
||||||
|
esbuild "^0.27.0"
|
||||||
|
fdir "^6.5.0"
|
||||||
|
picomatch "^4.0.3"
|
||||||
|
postcss "^8.5.6"
|
||||||
|
rollup "^4.43.0"
|
||||||
|
tinyglobby "^0.2.15"
|
||||||
|
optionalDependencies:
|
||||||
|
fsevents "~2.3.3"
|
||||||
|
|
||||||
|
yallist@^3.0.2:
|
||||||
|
version "3.1.1"
|
||||||
|
resolved "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
|
||||||
|
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
|
||||||