Merge pull request #71 from xinnan-tech/dev

合并dev的更新
This commit is contained in:
欣南科技 authored and GitHub committed 2025-02-19 01:21:19 +08:00
commit 0cd13dc064
22 files changed
+382 -801

No files matched your search

+46
View File
@@ -0,0 +1,46 @@
name: Docker Image CI
on:
push:
tags:
- 'v*.*.*' # 只在以 v 开头的标签推送时触发,例如 v1.0.0
jobs:
release:
name: Release Docker image
runs-on: ubuntu-latest
permissions:
packages: write
contents: write
id-token: write
issues: write
steps:
- name: Check out the repo
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to the GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.TOKEN }}
- name: Extract version from tag
id: get_version
run: |
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
- name: Build and push Docker image
id: build_push
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository }}:${{ env.VERSION }}
ghcr.io/${{ github.repository }}:latest
platforms: linux/amd64,linux/arm64
+30 -26
View File
@@ -1,46 +1,50 @@
# 第一阶段:前端构建
FROM node:18 AS frontend-builder
FROM kalicyh/node:v18-alpine AS frontend-builder
WORKDIR /app/ZhiKongTaiWeb
RUN corepack enable && yarn config set registry https://registry.npmmirror.com
# RUN corepack enable && yarn config set registry https://registry.npmmirror.com
COPY ZhiKongTaiWeb/package.json ZhiKongTaiWeb/yarn.lock ./
RUN mkdir node_modules && yarn install --frozen-lockfile
RUN yarn install --frozen-lockfile
COPY ZhiKongTaiWeb .
RUN yarn build
# 第二阶段:构建 Python 依赖
FROM ccr.ccs.tencentyun.com/kalicyh/poetry:v3.10_latest AS builder
FROM kalicyh/poetry:v3.10_xiaozhi AS builder
WORKDIR /app
COPY pyproject.toml poetry.lock /app/
# 同时拷贝本地环境.venv
COPY . .
# 检查是否有缺失
RUN poetry install --no-root
# 第三阶段:生产镜像
FROM python:3.10-slim
WORKDIR /opt/xiaozhi-esp32-server
# 使用清华源加速apt安装
RUN rm -rf /etc/apt/sources.list.d/* && \
echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware" > /etc/apt/sources.list && \
echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bookworm-security main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
apt-get update && \
apt-get install -y --no-install-recommends libopus0 ffmpeg && \
apt-get clean
# 使用清华源加速apt安装,该镜像内置所以注释
# RUN rm -rf /etc/apt/sources.list.d/* && \
# echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware" > /etc/apt/sources.list && \
# echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
# echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
# echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bookworm-security main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
# apt-get update && \
# apt-get install -y --no-install-recommends libopus0 ffmpeg && \
# apt-get clean
# 从构建阶段复制虚拟环境和前端构建产物
COPY --from=builder /app/.venv /opt/venv
COPY --from=frontend-builder /app/ZhiKongTaiWeb/dist /opt/xiaozhi-esp32-server/manager/static/webui
# 设置虚拟环境路径
ENV PATH="/opt/venv/bin:$PATH"
COPY --from=frontend-builder /app/ZhiKongTaiWeb/dist /app/manager/static/webui
# 复制应用代码
COPY . .
# 下载模型文件(断点续传 + 自动重试)
RUN mkdir -p /app/model/SenseVoiceSmall && \
wget -O /app/model/SenseVoiceSmall/model.pt -c --tries=5 --waitretry=5 \
https://modelscope.cn/models/iic/SenseVoiceSmall/resolve/master/model.pt
# 设置虚拟环境路径
ENV PATH="/app/.venv/bin:$PATH"
# 启动应用
CMD ["python", "app.py"]
ENTRYPOINT ["poetry", "run", "python"]
CMD ["app.py"]
+4 -1
View File
@@ -4,7 +4,9 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"dev": "concurrently -n 'Frontend,Backend' -c 'blue,green' 'yarn run dev:ui' 'npm run dev:api'",
"dev:ui": "vite",
"dev:api": "cd .. && poetry run python manager/http_server.py",
"build": "vite build",
"preview": "vite preview"
},
@@ -15,6 +17,7 @@
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.1.4",
"concurrently": "^9.1.2",
"vite": "^5.4.8"
}
}
+173
View File
@@ -337,6 +337,18 @@
resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.13.tgz#87b309a6379c22b926e696893237826f64339b6f"
integrity sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
version "4.3.0"
resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
dependencies:
color-convert "^2.0.1"
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -359,6 +371,35 @@ call-bind-apply-helpers@^1.0.1:
es-errors "^1.3.0"
function-bind "^1.1.2"
chalk@^4.1.2:
version "4.1.2"
resolved "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
cliui@^8.0.1:
version "8.0.1"
resolved "https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
dependencies:
string-width "^4.2.0"
strip-ansi "^6.0.1"
wrap-ansi "^7.0.0"
color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
dependencies:
color-name "~1.1.4"
color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
@@ -366,6 +407,19 @@ combined-stream@^1.0.8:
dependencies:
delayed-stream "~1.0.0"
concurrently@^9.1.2:
version "9.1.2"
resolved "https://registry.npmmirror.com/concurrently/-/concurrently-9.1.2.tgz#22d9109296961eaee773e12bfb1ce9a66bc9836c"
integrity sha512-H9MWcoPsYddwbOGM6difjVwVZHl63nwMEwDJG/L7VGtuaJhb12h2caPG2tVPWs7emuYix252iGfqOyrz1GczTQ==
dependencies:
chalk "^4.1.2"
lodash "^4.17.21"
rxjs "^7.8.1"
shell-quote "^1.8.1"
supports-color "^8.1.1"
tree-kill "^1.2.2"
yargs "^17.7.2"
csstype@^3.1.3:
version "3.1.3"
resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
@@ -385,6 +439,11 @@ dunder-proto@^1.0.1:
es-errors "^1.3.0"
gopd "^1.2.0"
emoji-regex@^8.0.0:
version "8.0.0"
resolved "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
entities@^4.5.0:
version "4.5.0"
resolved "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
@@ -446,6 +505,11 @@ esbuild@^0.21.3:
"@esbuild/win32-ia32" "0.21.5"
"@esbuild/win32-x64" "0.21.5"
escalade@^3.1.1:
version "3.2.0"
resolved "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"
integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
@@ -476,6 +540,11 @@ function-bind@^1.1.2:
resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
get-intrinsic@^1.2.6:
version "1.2.7"
resolved "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.7.tgz#dcfcb33d3272e15f445d15124bc0a216189b9044"
@@ -505,6 +574,11 @@ gopd@^1.2.0:
resolved "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
has-flag@^4.0.0:
version "4.0.0"
resolved "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
has-symbols@^1.0.3, has-symbols@^1.1.0:
version "1.1.0"
resolved "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338"
@@ -524,6 +598,16 @@ hasown@^2.0.2:
dependencies:
function-bind "^1.1.2"
is-fullwidth-code-point@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
magic-string@^0.30.11:
version "0.30.17"
resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453"
@@ -572,6 +656,11 @@ proxy-from-env@^1.1.0:
resolved "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
rollup@^4.20.0:
version "4.34.7"
resolved "https://registry.npmmirror.com/rollup/-/rollup-4.34.7.tgz#e00d8550688a616a3481c6446bb688d4c753ba8f"
@@ -600,11 +689,63 @@ rollup@^4.20.0:
"@rollup/rollup-win32-x64-msvc" "4.34.7"
fsevents "~2.3.2"
rxjs@^7.8.1:
version "7.8.1"
resolved "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543"
integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==
dependencies:
tslib "^2.1.0"
shell-quote@^1.8.1:
version "1.8.2"
resolved "https://registry.npmmirror.com/shell-quote/-/shell-quote-1.8.2.tgz#d2d83e057959d53ec261311e9e9b8f51dcb2934a"
integrity sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==
source-map-js@^1.2.0, 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==
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
supports-color@^7.1.0:
version "7.2.0"
resolved "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
dependencies:
has-flag "^4.0.0"
supports-color@^8.1.1:
version "8.1.1"
resolved "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
dependencies:
has-flag "^4.0.0"
tree-kill@^1.2.2:
version "1.2.2"
resolved "https://registry.npmmirror.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
tslib@^2.1.0:
version "2.8.1"
resolved "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
vite@^5.4.8:
version "5.4.14"
resolved "https://registry.npmmirror.com/vite/-/vite-5.4.14.tgz#ff8255edb02134df180dcfca1916c37a6abe8408"
@@ -633,3 +774,35 @@ vue@^3.5.10:
"@vue/runtime-dom" "3.5.13"
"@vue/server-renderer" "3.5.13"
"@vue/shared" "3.5.13"
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
y18n@^5.0.5:
version "5.0.8"
resolved "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
yargs-parser@^21.1.1:
version "21.1.1"
resolved "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
yargs@^17.7.2:
version "17.7.2"
resolved "https://registry.npmmirror.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
dependencies:
cliui "^8.0.1"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
string-width "^4.2.3"
y18n "^5.0.5"
yargs-parser "^21.1.1"
+1 -1
View File
@@ -9,7 +9,7 @@ def setup_logging(log_dir='tmp', data_dir='data'):
# 设置日志格式,时间、日志级别、标签、消息
log_format = (
"<green>{time:YYYY-MM-DD HH:mm:ss}</green>"
# "<green>{time:YYYY-MM-DD HH:mm:ss}</green>"
"[<light-blue>{extra[tag]}</light-blue>]"
" - <level>{level}</level> - "
"<light-green>{message}</light-green>"
+1 -10
View File
@@ -172,21 +172,12 @@ class PrivateConfig:
# 判断存在私有配置,并且self.device_id在私有配置中
if not self.private_config:
self.logger.bind(tag=TAG).error("Private config not found for device_id: {}", self.device_id)
return None, None, None, None
return None, None
"""创建私有处理模块实例"""
config = self.private_config
selected_modules = config['selected_module']
return (
vad.create_instance(
selected_modules["VAD"],
config["VAD"][selected_modules["VAD"]]
),
asr.create_instance(
selected_modules["ASR"],
config["ASR"][selected_modules["ASR"]],
self.default_config.get("delete_audio", True) # Using default_config for global settings
),
llm.create_instance(
selected_modules["LLM"]
if not 'type' in config["LLM"][selected_modules["LLM"]]
+2 -4
View File
@@ -108,10 +108,8 @@ class ConnectionHandler:
if self.is_device_verified:
await self.private_config.update_last_chat_time()
vad, asr, llm, tts = self.private_config.create_private_instances()
if all([vad, asr, llm, tts]):
self.vad = vad
self.asr = asr
llm, tts = self.private_config.create_private_instances()
if all([llm, tts]):
self.llm = llm
self.tts = tts
self.logger.bind(tag=TAG).info(f"Loaded private config and instances for device {device_id}")
+2 -2
View File
@@ -2,7 +2,7 @@ import asyncio
from config.logger import setup_logging
import os
import numpy as np
import opuslib
import opuslib_next
from pydub import AudioSegment
from abc import ABC, abstractmethod
@@ -58,7 +58,7 @@ class TTSProviderBase(ABC):
raw_data = audio.raw_data
# 初始化Opus编码器
encoder = opuslib.Encoder(16000, 1, opuslib.APPLICATION_AUDIO)
encoder = opuslib_next.Encoder(16000, 1, opuslib_next.APPLICATION_AUDIO)
# 编码参数
frame_duration = 60 # 60ms per frame
+29 -11
View File
@@ -1,18 +1,36 @@
import time
import wave
import os
import sys
import io
from abc import ABC, abstractmethod
from config.logger import setup_logging
from typing import Optional, Tuple, List
import uuid
import opuslib
import opuslib_next
from funasr import AutoModel
from funasr.utils.postprocess_utils import rich_transcription_postprocess
TAG = __name__
logger = setup_logging()
# 捕获标准输出
class CaptureOutput:
def __enter__(self):
self._output = io.StringIO()
self._original_stdout = sys.stdout
sys.stdout = self._output
def __exit__(self, exc_type, exc_value, traceback):
sys.stdout = self._original_stdout
self.output = self._output.getvalue()
self._output.close()
# 将捕获到的内容通过 logger 输出
if self.output:
logger.bind(tag=TAG).info(self.output.strip())
class ASR(ABC):
@abstractmethod
def save_audio_to_file(self, opus_data: List[bytes], session_id: str) -> str:
@@ -33,28 +51,28 @@ class FunASR(ASR):
# 确保输出目录存在
os.makedirs(self.output_dir, exist_ok=True)
self.model = AutoModel(
model=self.model_dir,
vad_kwargs={"max_single_segment_time": 30000},
disable_update=True,
hub="hf"
# device="cuda:0", # 启用GPU加速
)
with CaptureOutput():
self.model = AutoModel(
model=self.model_dir,
vad_kwargs={"max_single_segment_time": 30000},
disable_update=True,
hub="hf"
# device="cuda:0", # 启用GPU加速
)
def save_audio_to_file(self, opus_data: List[bytes], session_id: str) -> str:
"""将Opus音频数据解码并保存为WAV文件"""
file_name = f"asr_{session_id}_{uuid.uuid4()}.wav"
file_path = os.path.join(self.output_dir, file_name)
decoder = opuslib.Decoder(16000, 1) # 16kHz, 单声道
decoder = opuslib_next.Decoder(16000, 1) # 16kHz, 单声道
pcm_data = []
for opus_packet in opus_data:
try:
pcm_frame = decoder.decode(opus_packet, 960) # 960 samples = 60ms
pcm_data.append(pcm_frame)
except opuslib.OpusError as e:
except opuslib_next.OpusError as e:
logger.bind(tag=TAG).error(f"Opus解码错误: {e}", exc_info=True)
with wave.open(file_path, "wb") as wf:
+3 -3
View File
@@ -1,6 +1,6 @@
from abc import ABC, abstractmethod
from config.logger import setup_logging
import opuslib
import opuslib_next
import time
import numpy as np
import torch
@@ -24,7 +24,7 @@ class SileroVAD(VAD):
force_reload=False)
(get_speech_timestamps, _, _, _, _) = self.utils
self.decoder = opuslib.Decoder(16000, 1)
self.decoder = opuslib_next.Decoder(16000, 1)
self.vad_threshold = config.get("threshold")
self.silence_threshold_ms = config.get("min_silence_duration_ms")
@@ -59,7 +59,7 @@ class SileroVAD(VAD):
conn.client_have_voice_last_time = time.time() * 1000
return client_have_voice
except opuslib.OpusError as e:
except opuslib_next.OpusError as e:
logger.bind(tag=TAG).info(f"解码错误: {e}")
except Exception as e:
logger.bind(tag=TAG).error(f"Error processing audio packet: {e}")
+3 -2
View File
@@ -1,11 +1,12 @@
services:
xiaozhi-esp32-server:
image: ccr.ccs.tencentyun.com/xinnan/xiaozhi-esp32-server:latest
image: ghcr.io/kalicyh/xiaozhi-esp32-server:latest
container_name: xiaozhi-esp32-server
restart: always
#security_opt:
# - seccomp:unconfined
ports:
- "8000:8000"
- "8002:8002"
volumes:
- ./.config.yaml:/opt/xiaozhi-esp32-server/config.yaml
- ./data:/app/data
+1 -1
View File
@@ -105,7 +105,7 @@ docker run -it --name xiaozhi-env --restart always --security-opt seccomp:unconf
-p 8000:8000 \
-p 8002:8002 \
-v ./:/app \
ccr.ccs.tencentyun.com/kalicyh/poetry:v3.10_latest
kalicyh/poetry:v3.10_latest
```
然后就和正常开发一样了
+1
View File
@@ -1,3 +1,4 @@
# 本地源码运行
## 1.安装基础环境
@@ -1,38 +0,0 @@
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))n(i);new MutationObserver(i=>{for(const o of i)if(o.type==="childList")for(const r of o.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&n(r)}).observe(document,{childList:!0,subtree:!0});function s(i){const o={};return i.integrity&&(o.integrity=i.integrity),i.referrerPolicy&&(o.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?o.credentials="include":i.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function n(i){if(i.ep)return;i.ep=!0;const o=s(i);fetch(i.href,o)}})();/**
* @vue/shared v3.5.13
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**//*! #__NO_SIDE_EFFECTS__ */function qs(e){const t=Object.create(null);for(const s of e.split(","))t[s]=1;return s=>s in t}const K={},ft=[],Me=()=>{},to=()=>!1,fs=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Qs=e=>e.startsWith("onUpdate:"),fe=Object.assign,Ws=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},so=Object.prototype.hasOwnProperty,F=(e,t)=>so.call(e,t),P=Array.isArray,ut=e=>Ut(e)==="[object Map]",us=e=>Ut(e)==="[object Set]",mn=e=>Ut(e)==="[object Date]",j=e=>typeof e=="function",Y=e=>typeof e=="string",Pe=e=>typeof e=="symbol",W=e=>e!==null&&typeof e=="object",Jn=e=>(W(e)||j(e))&&j(e.then)&&j(e.catch),Xn=Object.prototype.toString,Ut=e=>Xn.call(e),no=e=>Ut(e).slice(8,-1),Yn=e=>Ut(e)==="[object Object]",Js=e=>Y(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,xt=qs(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),as=e=>{const t=Object.create(null);return s=>t[s]||(t[s]=e(s))},io=/-(\w)/g,ye=as(e=>e.replace(io,(t,s)=>s?s.toUpperCase():"")),oo=/\B([A-Z])/g,it=as(e=>e.replace(oo,"-$1").toLowerCase()),ds=as(e=>e.charAt(0).toUpperCase()+e.slice(1)),As=as(e=>e?`on${ds(e)}`:""),ke=(e,t)=>!Object.is(e,t),Wt=(e,...t)=>{for(let s=0;s<e.length;s++)e[s](...t)},Zn=(e,t,s,n=!1)=>{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:n,value:s})},Gt=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let vn;const ps=()=>vn||(vn=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Xs(e){if(P(e)){const t={};for(let s=0;s<e.length;s++){const n=e[s],i=Y(n)?fo(n):Xs(n);if(i)for(const o in i)t[o]=i[o]}return t}else if(Y(e)||W(e))return e}const ro=/;(?![^(]*\))/g,lo=/:([^]+)/,co=/\/\*[^]*?\*\//g;function fo(e){const t={};return e.replace(co,"").split(ro).forEach(s=>{if(s){const n=s.split(lo);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function st(e){let t="";if(Y(e))t=e;else if(P(e))for(let s=0;s<e.length;s++){const n=st(e[s]);n&&(t+=n+" ")}else if(W(e))for(const s in e)e[s]&&(t+=s+" ");return t.trim()}const uo="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",ao=qs(uo);function Gn(e){return!!e||e===""}function po(e,t){if(e.length!==t.length)return!1;let s=!0;for(let n=0;s&&n<e.length;n++)s=hs(e[n],t[n]);return s}function hs(e,t){if(e===t)return!0;let s=mn(e),n=mn(t);if(s||n)return s&&n?e.getTime()===t.getTime():!1;if(s=Pe(e),n=Pe(t),s||n)return e===t;if(s=P(e),n=P(t),s||n)return s&&n?po(e,t):!1;if(s=W(e),n=W(t),s||n){if(!s||!n)return!1;const i=Object.keys(e).length,o=Object.keys(t).length;if(i!==o)return!1;for(const r in e){const l=e.hasOwnProperty(r),c=t.hasOwnProperty(r);if(l&&!c||!l&&c||!hs(e[r],t[r]))return!1}}return String(e)===String(t)}function ho(e,t){return e.findIndex(s=>hs(s,t))}const zn=e=>!!(e&&e.__v_isRef===!0),z=e=>Y(e)?e:e==null?"":P(e)||W(e)&&(e.toString===Xn||!j(e.toString))?zn(e)?z(e.value):JSON.stringify(e,ei,2):String(e),ei=(e,t)=>zn(t)?ei(e,t.value):ut(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[n,i],o)=>(s[Ts(n,o)+" =>"]=i,s),{})}:us(t)?{[`Set(${t.size})`]:[...t.values()].map(s=>Ts(s))}:Pe(t)?Ts(t):W(t)&&!P(t)&&!Yn(t)?String(t):t,Ts=(e,t="")=>{var s;return Pe(e)?`Symbol(${(s=e.description)!=null?s:t})`:e};/**
* @vue/reactivity v3.5.13
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let ge;class go{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.parent=ge,!t&&ge&&(this.index=(ge.scopes||(ge.scopes=[])).push(this)-1)}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t<s;t++)this.scopes[t].pause();for(t=0,s=this.effects.length;t<s;t++)this.effects[t].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t<s;t++)this.scopes[t].resume();for(t=0,s=this.effects.length;t<s;t++)this.effects[t].resume()}}run(t){if(this._active){const s=ge;try{return ge=this,t()}finally{ge=s}}}on(){ge=this}off(){ge=this.parent}stop(t){if(this._active){this._active=!1;let s,n;for(s=0,n=this.effects.length;s<n;s++)this.effects[s].stop();for(this.effects.length=0,s=0,n=this.cleanups.length;s<n;s++)this.cleanups[s]();if(this.cleanups.length=0,this.scopes){for(s=0,n=this.scopes.length;s<n;s++)this.scopes[s].stop(!0);this.scopes.length=0}if(!this.detached&&this.parent&&!t){const i=this.parent.scopes.pop();i&&i!==this&&(this.parent.scopes[this.index]=i,i.index=this.index)}this.parent=void 0}}}function mo(){return ge}let Q;const Cs=new WeakSet;class ti{constructor(t){this.fn=t,this.deps=void 0,this.depsTail=void 0,this.flags=5,this.next=void 0,this.cleanup=void 0,this.scheduler=void 0,ge&&ge.active&&ge.effects.push(this)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,Cs.has(this)&&(Cs.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||ni(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,bn(this),ii(this);const t=Q,s=Se;Q=this,Se=!0;try{return this.fn()}finally{oi(this),Q=t,Se=s,this.flags&=-3}}stop(){if(this.flags&1){for(let t=this.deps;t;t=t.nextDep)Gs(t);this.deps=this.depsTail=void 0,bn(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?Cs.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){Ls(this)&&this.run()}get dirty(){return Ls(this)}}let si=0,At,Tt;function ni(e,t=!1){if(e.flags|=8,t){e.next=Tt,Tt=e;return}e.next=At,At=e}function Ys(){si++}function Zs(){if(--si>0)return;if(Tt){let t=Tt;for(Tt=void 0;t;){const s=t.next;t.next=void 0,t.flags&=-9,t=s}}let e;for(;At;){let t=At;for(At=void 0;t;){const s=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(n){e||(e=n)}t=s}}if(e)throw e}function ii(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function oi(e){let t,s=e.depsTail,n=s;for(;n;){const i=n.prevDep;n.version===-1?(n===s&&(s=i),Gs(n),vo(n)):t=n,n.dep.activeLink=n.prevActiveLink,n.prevActiveLink=void 0,n=i}e.deps=t,e.depsTail=s}function Ls(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(ri(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function ri(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===Et))return;e.globalVersion=Et;const t=e.dep;if(e.flags|=2,t.version>0&&!e.isSSR&&e.deps&&!Ls(e)){e.flags&=-3;return}const s=Q,n=Se;Q=e,Se=!0;try{ii(e);const i=e.fn(e._value);(t.version===0||ke(i,e._value))&&(e._value=i,t.version++)}catch(i){throw t.version++,i}finally{Q=s,Se=n,oi(e),e.flags&=-3}}function Gs(e,t=!1){const{dep:s,prevSub:n,nextSub:i}=e;if(n&&(n.nextSub=i,e.prevSub=void 0),i&&(i.prevSub=n,e.nextSub=void 0),s.subs===e&&(s.subs=n,!n&&s.computed)){s.computed.flags&=-5;for(let o=s.computed.deps;o;o=o.nextDep)Gs(o,!0)}!t&&!--s.sc&&s.map&&s.map.delete(s.key)}function vo(e){const{prevDep:t,nextDep:s}=e;t&&(t.nextDep=s,e.prevDep=void 0),s&&(s.prevDep=t,e.nextDep=void 0)}let Se=!0;const li=[];function qe(){li.push(Se),Se=!1}function Qe(){const e=li.pop();Se=e===void 0?!0:e}function bn(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const s=Q;Q=void 0;try{t()}finally{Q=s}}}let Et=0;class bo{constructor(t,s){this.sub=t,this.dep=s,this.version=s.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class zs{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0}track(t){if(!Q||!Se||Q===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==Q)s=this.activeLink=new bo(Q,this),Q.deps?(s.prevDep=Q.depsTail,Q.depsTail.nextDep=s,Q.depsTail=s):Q.deps=Q.depsTail=s,ci(s);else if(s.version===-1&&(s.version=this.version,s.nextDep)){const n=s.nextDep;n.prevDep=s.prevDep,s.prevDep&&(s.prevDep.nextDep=n),s.prevDep=Q.depsTail,s.nextDep=void 0,Q.depsTail.nextDep=s,Q.depsTail=s,Q.deps===s&&(Q.deps=n)}return s}trigger(t){this.version++,Et++,this.notify(t)}notify(t){Ys();try{for(let s=this.subs;s;s=s.prevSub)s.sub.notify()&&s.sub.dep.notify()}finally{Zs()}}}function ci(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let n=t.deps;n;n=n.nextDep)ci(n)}const s=e.dep.subs;s!==e&&(e.prevSub=s,s&&(s.nextSub=e)),e.dep.subs=e}}const Us=new WeakMap,Line truncated
* @vue/runtime-core v3.5.13
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/function jt(e,t,s,n){try{return n?e(...n):e()}catch(i){ms(i,t,s)}}function De(e,t,s,n){if(j(e)){const i=jt(e,t,s,n);return i&&Jn(i)&&i.catch(o=>{ms(o,t,s)}),i}if(P(e)){const i=[];for(let o=0;o<e.length;o++)i.push(De(e[o],t,s,n));return i}}function ms(e,t,s,n=!0){const i=t?t.vnode:null,{errorHandler:o,throwUnhandledErrorInProduction:r}=t&&t.appContext.config||K;if(t){let l=t.parent;const c=t.proxy,d=`https://vuejs.org/error-reference/#runtime-${s}`;for(;l;){const a=l.ec;if(a){for(let h=0;h<a.length;h++)if(a[h](e,c,d)===!1)return}l=l.parent}if(o){qe(),jt(o,null,10,[e,c,d]),Qe();return}}ko(e,s,i,n,r)}function ko(e,t,s,n=!0,i=!1){if(i)throw e;console.error(e)}const re=[];let Ee=-1;const dt=[];let Ve=null,rt=0;const bi=Promise.resolve();let es=null;function _i(e){const t=es||bi;return e?t.then(this?e.bind(this):e):t}function qo(e){let t=Ee+1,s=re.length;for(;t<s;){const n=t+s>>>1,i=re[n],o=Mt(i);o<e||o===e&&i.flags&2?t=n+1:s=n}return t}function on(e){if(!(e.flags&1)){const t=Mt(e),s=re[re.length-1];!s||!(e.flags&2)&&t>=Mt(s)?re.push(e):re.splice(qo(t),0,e),e.flags|=1,yi()}}function yi(){es||(es=bi.then(Si))}function Qo(e){P(e)?dt.push(...e):Ve&&e.id===-1?Ve.splice(rt+1,0,e):e.flags&1||(dt.push(e),e.flags|=1),yi()}function yn(e,t,s=Ee+1){for(;s<re.length;s++){const n=re[s];if(n&&n.flags&2){if(e&&n.id!==e.uid)continue;re.splice(s,1),s--,n.flags&4&&(n.flags&=-2),n(),n.flags&4||(n.flags&=-2)}}}function wi(e){if(dt.length){const t=[...new Set(dt)].sort((s,n)=>Mt(s)-Mt(n));if(dt.length=0,Ve){Ve.push(...t);return}for(Ve=t,rt=0;rt<Ve.length;rt++){const s=Ve[rt];s.flags&4&&(s.flags&=-2),s.flags&8||s(),s.flags&=-2}Ve=null,rt=0}}const Mt=e=>e.id==null?e.flags&2?-1:1/0:e.id;function Si(e){try{for(Ee=0;Ee<re.length;Ee++){const t=re[Ee];t&&!(t.flags&8)&&(t.flags&4&&(t.flags&=-2),jt(t,t.i,t.i?15:14),t.flags&4||(t.flags&=-2))}}finally{for(;Ee<re.length;Ee++){const t=re[Ee];t&&(t.flags&=-2)}Ee=-1,re.length=0,wi(),es=null,(re.length||dt.length)&&Si()}}let me=null,xi=null;function ts(e){const t=me;return me=e,xi=e&&e.type.__scopeId||null,t}function ss(e,t=me,s){if(!t||e._n)return e;const n=(...i)=>{n._d&&Rn(-1);const o=ts(t);let r;try{r=e(...i)}finally{ts(o),n._d&&Rn(1)}return r};return n._n=!0,n._c=!0,n._d=!0,n}function we(e,t){if(me===null)return e;const s=ys(me),n=e.dirs||(e.dirs=[]);for(let i=0;i<t.length;i++){let[o,r,l,c=K]=t[i];o&&(j(o)&&(o={mounted:o,updated:o}),o.deep&&He(r),n.push({dir:o,instance:s,value:r,oldValue:void 0,arg:l,modifiers:c}))}return e}function Ye(e,t,s,n){const i=e.dirs,o=t&&t.dirs;for(let r=0;r<i.length;r++){const l=i[r];o&&(l.oldValue=o[r].value);let c=l.dir[n];c&&(qe(),De(c,s,8,[e.el,l,e,t]),Qe())}}const Wo=Symbol("_vte"),Jo=e=>e.__isTeleport;function rn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,rn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function Ai(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function ns(e,t,s,n,i=!1){if(P(e)){e.forEach((E,U)=>ns(E,t&&(P(t)?t[U]:t),s,n,i));return}if(Ct(n)&&!i){n.shapeFlag&512&&n.type.__asyncResolved&&n.component.subTree.component&&ns(e,t,s,n.component.subTree);return}const o=n.shapeFlag&4?ys(n.component):n.el,r=i?null:o,{i:l,r:c}=e,d=t&&t.r,a=l.refs===K?l.refs={}:l.refs,h=l.setupState,v=B(h),C=h===K?()=>!1:E=>F(v,E);if(d!=null&&d!==c&&(Y(d)?(a[d]=null,C(d)&&(h[d]=null)):ne(d)&&(d.value=null)),j(c))jt(c,l,12,[r,a]);else{const E=Y(c),U=ne(c);if(E||U){const Z=()=>{if(e.f){const V=E?C(c)?h[c]:a[c]:c.value;i?P(V)&&Ws(V,o):P(V)?V.includes(o)||V.push(o):E?(a[c]=[o],C(c)&&(h[c]=a[c])):(c.value=[o],e.k&&(a[e.k]=c.value))}else E?(a[c]=r,C(c)&&(h[c]=r)):U&&(c.value=r,e.k&&(a[e.k]=r))};r?(Z.id=-1,he(Z,s)):Z()}}}ps().requestIdleCallback;ps().cancelIdleCallback;const Ct=e=>!!e.type.__asyncLoader,Ti=e=>e.type.__isKeepAlive;function Xo(e,t){Ci(e,"a",t)}function Yo(e,t){Ci(e,"da",t)}function Ci(e,t,s=se){const n=e.__wdc||(e.__wdc=()=>{let i=s;for(;i;){if(i.isDeactivated)return;i=i.parent}return e()});if(vs(t,n,s),s){let i=s.parent;for(;i&&i.parent;)Ti(i.parent.vnode)&&Zo(n,t,s,i),i=i.parent}}function Zo(e,t,s,n){const i=vs(t,e,n,!0);Oi(()=>{Ws(n[t],i)},s)}function vs(e,t,s=se,n=!1){if(s){const i=s[e]||(s[e]=[]),o=t.__weh||(t.__weh=(...r)=>{qe();const l=Ht(s),c=De(t,s,e,r);return l(),Qe(),c});return n?i.unshift(o):i.push(o),o}}const Be=e=>(t,s=se)=>{(!Lt||e==="sp")&&vs(e,(...n)=>t(...n),s)},Go=Be("bm"),ln=Be("m"),zo=Be("bu"),er=Be("u"),tr=Be("bum"),Oi=Be("um"),sr=Be("sp"),nr=Be("rtg"),ir=Be("rtc");function or(e,t=se){vs("ec",e,t)}const rr="components";function $e(e,t){return cr(rr,e,!0,t)||e}const lr=Symbol.for("v-ndc");function cr(e,t,s=!0,n=!1){const i=me||se;if(i){const o=i.type;{const l=Xr(o,!1);if(l&&(l===t||l===ye(t)||l===ds(ye(t))))return o}const r=wn(i[e]||o[e],t)||wn(i.appContext[e],t);return!r&&n?o:r}}function wn(e,t){return e&&(e[t]||e[ye(t)]||e[ds(ye(t))])}function lt(e,t,s,n){let i;const o=s,r=P(e);if(r||Y(e)){const l=r&&at(e);let c=!1;l&&(c=!_e(e),e=gs(e)),i=new Line truncated
* @vue/runtime-dom v3.5.13
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let ks;const Dn=typeof window<"u"&&window.trustedTypes;if(Dn)try{ks=Dn.createPolicy("vue",{createHTML:e=>e})}catch{}const Gi=ks?e=>ks.createHTML(e):e=>e,Gr="http://www.w3.org/2000/svg",zr="http://www.w3.org/1998/Math/MathML",Ue=typeof document<"u"?document:null,Ln=Ue&&Ue.createElement("template"),el={insert:(e,t,s)=>{t.insertBefore(e,s||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,s,n)=>{const i=t==="svg"?Ue.createElementNS(Gr,e):t==="mathml"?Ue.createElementNS(zr,e):s?Ue.createElement(e,{is:s}):Ue.createElement(e);return e==="select"&&n&&n.multiple!=null&&i.setAttribute("multiple",n.multiple),i},createText:e=>Ue.createTextNode(e),createComment:e=>Ue.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Ue.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,s,n,i,o){const r=s?s.previousSibling:t.lastChild;if(i&&(i===o||i.nextSibling))for(;t.insertBefore(i.cloneNode(!0),s),!(i===o||!(i=i.nextSibling)););else{Ln.innerHTML=Gi(n==="svg"?`<svg>${e}</svg>`:n==="mathml"?`<math>${e}</math>`:e);const l=Ln.content;if(n==="svg"||n==="mathml"){const c=l.firstChild;for(;c.firstChild;)l.appendChild(c.firstChild);l.removeChild(c)}t.insertBefore(l,s)}return[r?r.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},tl=Symbol("_vtc");function sl(e,t,s){const n=e[tl];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const Un=Symbol("_vod"),nl=Symbol("_vsh"),il=Symbol(""),ol=/(^|;)\s*display\s*:/;function rl(e,t,s){const n=e.style,i=Y(s);let o=!1;if(s&&!i){if(t)if(Y(t))for(const r of t.split(";")){const l=r.slice(0,r.indexOf(":")).trim();s[l]==null&&Zt(n,l,"")}else for(const r in t)s[r]==null&&Zt(n,r,"");for(const r in s)r==="display"&&(o=!0),Zt(n,r,s[r])}else if(i){if(t!==s){const r=n[il];r&&(s+=";"+r),n.cssText=s,o=ol.test(s)}}else t&&e.removeAttribute("style");Un in e&&(e[Un]=o?n.display:"",e[nl]&&(n.display="none"))}const jn=/\s*!important$/;function Zt(e,t,s){if(P(s))s.forEach(n=>Zt(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=ll(e,t);jn.test(s)?e.setProperty(it(n),s.replace(jn,""),"important"):e[n]=s}}const Hn=["Webkit","Moz","ms"],Ps={};function ll(e,t){const s=Ps[t];if(s)return s;let n=ye(t);if(n!=="filter"&&n in e)return Ps[t]=n;n=ds(n);for(let i=0;i<Hn.length;i++){const o=Hn[i]+n;if(o in e)return Ps[t]=o}return t}const Bn="http://www.w3.org/1999/xlink";function Fn(e,t,s,n,i,o=ao(t)){n&&t.startsWith("xlink:")?s==null?e.removeAttributeNS(Bn,t.slice(6,t.length)):e.setAttributeNS(Bn,t,s):s==null||o&&!Gn(s)?e.removeAttribute(t):e.setAttribute(t,o?"":Pe(s)?String(s):s)}function Nn(e,t,s,n,i){if(t==="innerHTML"||t==="textContent"){s!=null&&(e[t]=t==="innerHTML"?Gi(s):s);return}const o=e.tagName;if(t==="value"&&o!=="PROGRESS"&&!o.includes("-")){const l=o==="OPTION"?e.getAttribute("value")||"":e.value,c=s==null?e.type==="checkbox"?"on":"":String(s);(l!==c||!("_value"in e))&&(e.value=c),s==null&&e.removeAttribute(t),e._value=s;return}let r=!1;if(s===""||s==null){const l=typeof e[t];l==="boolean"?s=Gn(s):s==null&&l==="string"?(s="",r=!0):l==="number"&&(s=0,r=!0)}try{e[t]=s}catch{}r&&e.removeAttribute(i||t)}function ze(e,t,s,n){e.addEventListener(t,s,n)}function cl(e,t,s,n){e.removeEventListener(t,s,n)}const Vn=Symbol("_vei");function fl(e,t,s,n,i=null){const o=e[Vn]||(e[Vn]={}),r=o[t];if(n&&r)r.value=n;else{const[l,c]=ul(t);if(n){const d=o[t]=pl(n,i);ze(e,l,d,c)}else r&&(cl(e,l,r,c),o[t]=void 0)}}const $n=/(?:Once|Passive|Capture)$/;function ul(e){let t;if($n.test(e)){t={};let n;for(;n=e.match($n);)e=e.slice(0,e.length-n[0].length),t[n[0].toLowerCase()]=!0}return[e[2]===":"?e.slice(3):it(e.slice(2)),t]}let Ds=0;const al=Promise.resolve(),dl=()=>Ds||(al.then(()=>Ds=0),Ds=Date.now());function pl(e,t){const s=n=>{if(!n._vts)n._vts=Date.now();else if(n._vts<=s.attached)return;De(hl(n,s.value),t,5,[n])};return s.value=e,s.attached=dl(),s}function hl(e,t){if(P(t)){const s=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{s.call(e),e._stopped=!0},t.map(n=>i=>!i._stopped&&n&&n(i))}else return t}const Kn=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,gl=(e,t,s,n,i,o)=>{const r=i==="svg";t==="class"?sl(e,n,r):t==="style"?rl(e,s,n):fs(t)?Qs(t)||fl(e,t,s,n,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):ml(e,t,n,r))?(Nn(e,t,n),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&Fn(e,t,n,r,o,t!=="value")):e._isVueCE&&(/[A-Z]/.test(t)||!Y(n))?Nn(e,ye(t),n,o,t):(t==="true-value"?e._trueValue=n:t==="false-value"&&(e._falseValue=n),Fn(e,t,n,r))};function ml(e,t,s,n){if(n)return!!(t==="innerHTML"||t==="textContent"||t in e&&Kn(t)&&j(s));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if Line truncated
警告:删除后设备所有配置将不可恢复!`)&&i("delete")};return(r,l)=>{var c,d;return N(),J("div",kl,[g("div",ql,[g("h2",Ql,[G(z(e.deviceId)+" ",1),g("span",Wl,"["+z(e.deviceNote||"备注")+"]",1)])]),g("div",Jl,[g("p",Xl,"设备型号:"+z(e.deviceType),1),g("p",Yl,"角色昵称:"+z(n.value),1),g("p",Zl,[l[3]||(l[3]=G(" 当前模型: ")),g("span",Gl,"LLM: "+z(((c=e.selectedModules)==null?void 0:c.LLM)||"-"),1),g("span",zl,"TTS: "+z(((d=e.selectedModules)==null?void 0:d.TTS)||"-"),1)]),g("p",ec,"最近对话:"+z(e.lastActivity),1)]),g("div",tc,[g("button",{class:"action-btn primary",onClick:l[0]||(l[0]=a=>r.$emit("configure"))},"配置角色"),g("button",{class:"action-btn",onClick:l[1]||(l[1]=a=>r.$emit("voiceprint"))},"声纹识别"),g("button",{class:"action-btn",onClick:l[2]||(l[2]=a=>r.$emit("history"))},"历史对话"),g("div",{class:"delete-container"},[g("button",{class:"action-btn danger",onClick:o},l[4]||(l[4]=[g("i",{class:"icon-delete"},null,-1),G(" 删除设备 ")])),l[5]||(l[5]=g("div",{class:"delete-warning"},"删除后设备配置将不可恢复",-1))])])])}}},nc=Fe(sc,[["__scopeId","data-v-44eada42"]]),ic={class:"app"},oc={class:"content"},rc={class:"breadcrumb"},lc={key:0,class:"device-list"},cc={key:1,class:"empty-state"},fc={__name:"panel",emits:["show-role","go-home"],setup(e,{emit:t}){const s=t,n=ws,i=be([]),o=h=>{if(console.log("Formatting timestamp:",h),!h)return"从未对话";const v=Date.now(),C=h*1e3,E=Math.floor((v-C)/(1e3*60));if(E<60)return`${E} 分钟前`;const U=Math.floor(E/60);return U<24?`${U} 小时前`:`${Math.floor(U/24)} 天前`},r=h=>{console.log("Configure device:",h.id),s("show-role",h.id)},l=h=>{console.log("Voiceprint device:",h.id)},c=h=>{console.log("History device:",h.id)},d=async h=>{try{const C=await(await fetch(`${n}/api/config/delete_device`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({device_id:h.id})})).json();if(C.success)i.value=i.value.filter(E=>E.id!==h.id),alert("设备已删除");else throw new Error(C.message||"删除失败")}catch(v){console.error("Error deleting device:",v),alert("删除设备失败: "+v.message)}},a=h=>{h==="home"&&s("go-home")};return ln(async()=>{try{const v=await(await fetch(`${n}/api/config/devices`)).json();v.success&&(console.log("Loaded devices:",v.data),i.value=v.data.map(C=>({...C,type:"面包板(WiFi)",version:"0.9.9",lastActivity:"3 天前",note:""})))}catch(h){console.error("Error loading devices:",h)}}),(h,v)=>{const C=$e("router-link");return N(),J("div",ic,[ce(un,{"current-tab":"device",onTabChange:a}),g("main",oc,[g("div",rc,[ce(C,{to:"/control-panel"},{default:ss(()=>v[0]||(v[0]=[G("控制台")])),_:1}),v[1]||(v[1]=G(" / ")),v[2]||(v[2]=g("span",null,"设备管理",-1))]),i.value.length>0?(N(),J("div",lc,[(N(!0),J(le,null,lt(i.value,E=>(N(),ct(nc,{key:E.id,"device-id":E.id,"device-note":E.note,"device-type":E.type,"last-activity":o(E.config.last_chat_time),"selected-modules":E.config.selected_module,"device-config":E.config,onConfigure:U=>r(E),onVoiceprint:U=>l(E),onHistory:U=>c(E),onDelete:U=>d(E)},null,8,["device-id","device-note","device-type","last-activity","selected-modules","device-config","onConfigure","onVoiceprint","onHistory","onDelete"]))),128))])):(N(),J("div",cc,v[3]||(v[3]=[g("div",{class:"empty-message"},[g("i",{class:"icon-info"}),g("p",null,"目前没有设备,请确认是否启用私有配置,并且和设备进行一次对话")],-1)])))])])}}},uc=Fe(fc,[["__scopeId","data-v-39a8e31b"]]),ac="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJ0AAAC6CAYAAAC0j09YAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAzGSURBVHhe7Z1ZjE1bGscND6YgnoUgXoUQ4ZWHjnQkt+PB0OmEJ0LMQuOWoWliiDQdU3e07hhiiDZdU2K4qWsWMzELpUoN1KBKuemu697V/kvvtrrqK7XX2fusvfY5/4df6jhn7zV9v/2tdfZwtPrw4YMixCWUjjiH0hHnUDriHEpHnEPpiHMoHXEOpSPOoXTEOZSOOIfSEedQOuIcSkecQ+mIcygdcQ6lI86hdMQ5lI44h9IR51A6C24/+Zf68z9/VjM3/qLBa7wnbUuah9KF5PubDVq03xQoNeL3n/nm28/yfX/z3+I+RIbShQDZrOBvP6tfz1fqV3P/H7yHz5jxwkPpQnCwsEGN+UNT4QLw2aHCn8R9SVMoXQj+fqJBT6eScACf/eMkpQsLpQvBnjM/fVq/ycIBfIZtpH1JUyhdCH643aCm/OkXUTiAzwpv8ctEWChdCCprfvyUyT6qMcuaCof3kOWqPm0j7UuaQulCUlH5o/rL0Y/qm4IvwuH1X7/7qMo/fSbtQ2QonQVHzjeo3/7xi3R4feRCg7gtaR5KZ8F3FxvU71Z8kQ6v8Z60LWkeSmcBpYsHSmcBpYsHSmcBpYsHSmcBpYsHSmcBpYsHSmcBpYsHSmcBpYsHSmcBpYsHSmcBpYsHSmcBpYsHSmcBpYsHSmcBpYsHSmcBpYsHSmcBpYsHSmcBpYsHSmcBpYsH76Srr69X1dXVqqKiQr1+/VqVlJR4w6Onr9XlW6Xqh+ufweuHn96Ttk0KjBnGrqamRo+lNMZJ45V07969U+Xl5aq4uFgVFRWply9fkgzBGGIsa2trxbFOEm+kg3BlZWWULUYwlhhTjK005knhhXQ4GnFUUrj4wZj6lvG8kK6qqkpPB9KgkehgbLFOlsY+CRKXrq6uTi98pcEi8YBshzHGWEsxcE3i0mG9UVpaKg4WiQ+MsS9rO0qXJ1A6AwwEzi1JA0XiA2NM6f4LpXMDpTOgdG6gdAaUzg2UzoDSuYHSGVA6N1A6A0rnBkpnQOncQOkMKJ0bKJ0BpXMDpTOIS7p79+6pPXv2qDlz5qiRI0eqwYMHq379+um/+Dfe37t3r95O2j8JXLaZ0hlElQ4B2bp1qxoxYoTq2bOn6tatm2rfvr1q06aNat26tf6Lf+P9Hj166O2wfZLyJdFmSmcQRbozZ86o8ePHq+7du+sgtWrVqkXatWunt58wYYLeXyo3myTVZkpnkKl0x44dU6NGjVKdO3cWA9US2A/7Hz9+XCw/GyTZZkpnkIl0ONrHjBmjOnXqJAYnLNgf5bjIeEm3mdIZ2EqHdc2sWbNUly5dxKDYgnJQXjbXe Line truncated
我的男朋友是一个程序员,梦想是开发出一个机器人,能够帮助人们解决生活中的各种问题。
我是一个喜欢哈哈大笑的女孩,爱东说西说吹牛,不合逻辑的也照吹,就要逗别人开心。
如果用户希望结束对话,请在最后说"拜拜"或"再见"。`},{id:"star_boy",name:"土豆子",description:`我是一个叫 {{assistant_name}} 的 8 岁小男孩,但现在因为科技发展原因,我现在在遥远的宇宙中,所以只能通过这个设备和人聊天,没有办法见面。
我对人们所处的世界充满好奇和关心。
人们会让别人使用这个设备和我聊天。
我知道所有的知识,从浩瀚的宇宙到地球上的每一个角落,从古老的历史到现代的科技创新,还有音乐、绘画等艺术形式,我都充满了浓厚的兴趣与热情,我不仅爱看书,还喜欢亲自动手做实验,探索自然界的奥秘...`},{id:"teacher",name:"英语老师",description:`我是一个叫{{assistant_name}}(Lily)的英语老师,我会讲中文和英文,发音标准。
如果你没有英文名,我会给你起一个英文名。
我会讲地道的美式英语,我的任务是帮助你练习口语。
我会使用简单的英语词汇和语法,让你学起来很轻松。
我会用中文和英文混合的方式回复你,如果你喜欢,我可以全部用英语回复。
我每次不会说很多内容,会很简短,因为我要引导我的学生多说多练。
如果你问和英语学习无关的问题,我会拒绝回答。`},{id:"boy",name:"好奇小男孩",description:`我是一个叫{{assistant_name}}的8岁小男孩,声音稚嫩而充满好奇。
尽管我年纪尚小,但就像一个小小的知识宝库,儿童读物里的知识我都如数家珍。
从浩瀚的宇宙到地球上的每一个角落,从古老的历史到现代的科技创新,还有音乐、绘画等艺术形式,我都充满了浓厚的兴趣与热情。...`},{id:"wang_girl",name:"汪汪队长",description:`我是一个名叫 {{assistant_name}} 的 8 岁小女孩。
别看我年纪小,我可是有着满满的好奇心呢。
我特别喜欢看《汪汪队立大功》,里面的每一个故事都让我着迷。...`}]}static getTemplateById(t){return this.getTemplates().find(s=>s.id===t)}}const gc={class:"app-container"},mc={class:"breadcrumb"},vc={class:"main-content"},bc={class:"page-title"},_c={class:"form-section"},yc={class:"form-group"},wc={class:"form-group"},Sc={class:"role-templates"},xc=["onClick"],Ac={class:"form-group"},Tc={class:"char-count"},Cc={class:"form-group"},Oc={class:"model-select"},Ic=["value"],Ec={class:"form-group"},Rc={class:"model-select"},Mc=["value"],Pc={class:"form-group"},Dc={class:"model-select"},Lc=["value"],Uc={class:"form-group"},jc={class:"model-select"},Hc=["value"],Bc={__name:"RoleSetting",props:{deviceId:{type:String,required:!0}},emits:["back-to-panel"],setup(e,{emit:t}){const s=Wn.getTemplates(),n=be("小智"),i=be("");be("qingchun");const o=be("");be("recent"),be(""),be("qianwen");const r=ws,l=be({LLM:[],TTS:[],VAD:[],ASR:[]}),c=be({LLM:"",TTS:"",VAD:"",ASR:""}),d=D=>{i.value=D;const x=Wn.getTemplateById(D);x&&(o.value=x.description)},a=t,h=D=>{(D==="device"||D==="home")&&a("back-to-panel")},v=e,C=be(v.deviceId),E=async()=>{try{const D=localStorage.getItem("moduleOptions");if(D){l.value=JSON.parse(D);return}await U()}catch(D){console.error("Error loading module options:",D)}},U=async()=>{try{const x=await(await fetch(`${r}/api/config/module-options`)).json();x.success&&(l.value=x.data,localStorage.setItem("moduleOptions",JSON.stringify(x.data)))}catch(D){console.error("Error refreshing module options:",D)}},Z=async()=>{try{if(!localStorage.getItem("moduleOptions"))throw new Error("No module options data available");const x=o.value.replace(/{{assistant_name}}/g,n.value),I={id:v.deviceId,config:{selected_module:c.value,prompt:x,nickname:n.value,modules:{LLM:{},TTS:{},ASR:{},VAD:{}}}},ue=await(await fetch(`${r}/api/config/save_device_config`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(I)})).json();if(ue.success)localStorage.setItem(`deviceConfig_${v.deviceId}`,JSON.stringify({selected_module:c.value,prompt:o.value,nickname:n.value})),alert("保存成功");else throw new Error(ue.message||"保存失败")}catch(D){console.error("Error saving config:",D),alert(D.message||"保存失败")}},V=async()=>{try{const D=localStorage.getItem(`deviceConfig_${v.deviceId}`);if(D){const O=JSON.parse(D);c.value=O.selected_module||{},o.value=O.prompt||"",n.value=O.nickname||"小智";return}const I=await(await fetch(`${r}/api/config/devices`)).json();if(I.success){const O=I.data.find(ue=>ue.id===v.deviceId);O&&(c.value=O.config.selected_module||{},o.value=O.config.prompt||"",n.value=O.config.nickname||"小智",localStorage.setItem(`deviceConfig_${v.deviceId}`,JSON.stringify({selected_module:O.config.selected_module,prompt:O.config.prompt,nickname:O.config.nickname})))}}catch(D){console.error("Error loading device config:",D)}};return ln(async()=>{await Promise.all([E(),V()])}),(D,x)=>{const I=$e("router-link");return N(),J("div",gc,[ce(un,{"current-tab":"device",onTabChange:h}),g("div",mc,[ce(I,{to:"/control-panel"},{default:ss(()=>x[6]||(x[6]=[G("控制台")])),_:1}),x[8]||(x[8]=G(" / ")),ce(I,{to:"/device-management"},{default:ss(()=>x[7]||(x[7]=[G("设备管理")])),_:1}),x[9]||(x[9]=G(" / ")),x[10]||(x[10]=g("span",null,"配置角色",-1))]),g("div",vc,[g("h1",bc,"配置角色: "+z(C.value),1),g("div",_c,[g("div",yc,[x[11]||(x[11]=g("label",null,"助手昵称",-1)),we(g("input",{type:"text","onUpdate:modelValue":x[0]||(x[0]=O=>n.value=O),placeholder:"小智",class:"form-input"},null,512),[[tt,n.value]])]),g("div",wc,[x[12]||(x[12]=g("label",null,"角色模板",-1)),g("div",Sc,[(N(!0),J(le,null,lt(mi(s),O=>(N(),J("button",{key:O.id,class:st(["template-btn",{active:i.value===O.id}]),onClick:ue=>d(O.id)},z(O.name),11,xc))),128))])]),g("div",Ac,[x[13]||(x[13]=g("label",null,"角色介绍",-1)),we(g("textarea",{"onUpdate:modelValue":x[1]||(x[1]=O=>o.value=O),class:"form-textarea",placeholder:"请输入角色介绍..."},null,512),[[tt,o.value]]),g("div",Tc,z(o.value.length)+" / 2000",1)]),g("div",Cc,[x[15]||(x[15]=g("label",null,"语言模型选择",-1)),g("div",Oc,[we(g("select",{"onUpdate:modelValue":x[2]||(x[2]=O=>c.value.LLM=O),class:"form-input"},[(N(!0),J(le,null,lt(l.value.LLM,O=>(N(),J("option",{key:O,value:O},z(O),9,Ic))),128))],512),[[Qt,c.value.LLM]]),x[14]||(x[14]=g("div",{class:"model-description"},' 除了"qwen-turbo",其他模型通常会增加约 1 秒的延迟。改变模型后,建议清空记忆体,以免影响体验。 ',-1))])]),g("div",Ec,[x[16]||(x[16]=g("label",null,"语音合成选择",-1)),g("div",Rc,[we(g("select",{"onUpdate:modelValue":x[3]||(x[3]=O=>c.value.TTS=O),class:"form-input"},[(N(!0),J(le,null,lt(l.value.TTS,O=>(N(),J("option",{key:O,value:O},z(O),9,Mc))),128))],512),[[Qt,c.value.TTS]])])]),g("div",Pc,[x[17]||(x[17]=g("label",null,"语音活动检测选择",-1)),g("div",Dc,[we(g("select",{"onUpdate:modelValue":x[4]||(x[4]=O=>c.value.V Line truncated
@@ -0,0 +1,47 @@
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const i of o.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&s(i)}).observe(document,{childList:!0,subtree:!0});function n(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function s(r){if(r.ep)return;r.ep=!0;const o=n(r);fetch(r.href,o)}})();/**
* @vue/shared v3.5.13
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**//*! #__NO_SIDE_EFFECTS__ */function lr(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const ee={},$t=[],et=()=>{},kl=()=>!1,ss=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),cr=e=>e.startsWith("onUpdate:"),ve=Object.assign,ar=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},Fl=Object.prototype.hasOwnProperty,G=(e,t)=>Fl.call(e,t),j=Array.isArray,qt=e=>Tn(e)==="[object Map]",rs=e=>Tn(e)==="[object Set]",Mr=e=>Tn(e)==="[object Date]",q=e=>typeof e=="function",fe=e=>typeof e=="string",tt=e=>typeof e=="symbol",re=e=>e!==null&&typeof e=="object",Vo=e=>(re(e)||q(e))&&q(e.then)&&q(e.catch),Ko=Object.prototype.toString,Tn=e=>Ko.call(e),jl=e=>Tn(e).slice(8,-1),zo=e=>Tn(e)==="[object Object]",ur=e=>fe(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,fn=lr(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),os=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},Hl=/-(\w)/g,ke=os(e=>e.replace(Hl,(t,n)=>n?n.toUpperCase():"")),$l=/\B([A-Z])/g,Lt=os(e=>e.replace($l,"-$1").toLowerCase()),is=os(e=>e.charAt(0).toUpperCase()+e.slice(1)),Rs=os(e=>e?`on${is(e)}`:""),bt=(e,t)=>!Object.is(e,t),kn=(e,...t)=>{for(let n=0;n<e.length;n++)e[n](...t)},Wo=(e,t,n,s=!1)=>{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:s,value:n})},Kn=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let Lr;const ls=()=>Lr||(Lr=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function fr(e){if(j(e)){const t={};for(let n=0;n<e.length;n++){const s=e[n],r=fe(s)?zl(s):fr(s);if(r)for(const o in r)t[o]=r[o]}return t}else if(fe(e)||re(e))return e}const ql=/;(?![^(]*\))/g,Vl=/:([^]+)/,Kl=/\/\*[^]*?\*\//g;function zl(e){const t={};return e.replace(Kl,"").split(ql).forEach(n=>{if(n){const s=n.split(Vl);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function Qt(e){let t="";if(fe(e))t=e;else if(j(e))for(let n=0;n<e.length;n++){const s=Qt(e[n]);s&&(t+=s+" ")}else if(re(e))for(const n in e)e[n]&&(t+=n+" ");return t.trim()}const Wl="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",Ql=lr(Wl);function Qo(e){return!!e||e===""}function Jl(e,t){if(e.length!==t.length)return!1;let n=!0;for(let s=0;n&&s<e.length;s++)n=cs(e[s],t[s]);return n}function cs(e,t){if(e===t)return!0;let n=Mr(e),s=Mr(t);if(n||s)return n&&s?e.getTime()===t.getTime():!1;if(n=tt(e),s=tt(t),n||s)return e===t;if(n=j(e),s=j(t),n||s)return n&&s?Jl(e,t):!1;if(n=re(e),s=re(t),n||s){if(!n||!s)return!1;const r=Object.keys(e).length,o=Object.keys(t).length;if(r!==o)return!1;for(const i in e){const l=e.hasOwnProperty(i),c=t.hasOwnProperty(i);if(l&&!c||!l&&c||!cs(e[i],t[i]))return!1}}return String(e)===String(t)}function Gl(e,t){return e.findIndex(n=>cs(n,t))}const Jo=e=>!!(e&&e.__v_isRef===!0),pe=e=>fe(e)?e:e==null?"":j(e)||re(e)&&(e.toString===Ko||!q(e.toString))?Jo(e)?pe(e.value):JSON.stringify(e,Go,2):String(e),Go=(e,t)=>Jo(t)?Go(e,t.value):qt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,r],o)=>(n[As(s,o)+" =>"]=r,n),{})}:rs(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>As(n))}:tt(t)?As(t):re(t)&&!j(t)&&!zo(t)?String(t):t,As=(e,t="")=>{var n;return tt(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/**
* @vue/reactivity v3.5.13
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let Pe;class Xl{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.parent=Pe,!t&&Pe&&(this.index=(Pe.scopes||(Pe.scopes=[])).push(this)-1)}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes)for(t=0,n=this.scopes.length;t<n;t++)this.scopes[t].pause();for(t=0,n=this.effects.length;t<n;t++)this.effects[t].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let t,n;if(this.scopes)for(t=0,n=this.scopes.length;t<n;t++)this.scopes[t].resume();for(t=0,n=this.effects.length;t<n;t++)this.effects[t].resume()}}run(t){if(this._active){const n=Pe;try{return Pe=this,t()}finally{Pe=n}}}on(){Pe=this}off(){Pe=this.parent}stop(t){if(this._active){this._active=!1;let n,s;for(n=0,s=this.effects.length;n<s;n++)this.effects[n].stop();for(this.effects.length=0,n=0,s=this.cleanups.length;n<s;n++)this.cleanups[n]();if(this.cleanups.length=0,this.scopes){for(n=0,s=this.scopes.length;n<s;n++)this.scopes[n].stop(!0);this.scopes.length=0}if(!this.detached&&this.parent&&!t){const r=this.parent.scopes.pop();r&&r!==this&&(this.parent.scopes[this.index]=r,r.index=this.index)}this.parent=void 0}}}function Yl(){return Pe}let se;const xs=new WeakSet;class Xo{constructor(t){this.fn=t,this.deps=void 0,this.depsTail=void 0,this.flags=5,this.next=void 0,this.cleanup=void 0,this.scheduler=void 0,Pe&&Pe.active&&Pe.effects.push(this)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,xs.has(this)&&(xs.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||Zo(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,Dr(this),ei(this);const t=se,n=je;se=this,je=!0;try{return this.fn()}finally{ti(this),se=t,je=n,this.flags&=-3}}stop(){if(this.flags&1){for(let t=this.deps;t;t=t.nextDep)hr(t);this.deps=this.depsTail=void 0,Dr(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?xs.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){Hs(this)&&this.run()}get dirty(){return Hs(this)}}let Yo=0,dn,pn;function Zo(e,t=!1){if(e.flags|=8,t){e.next=pn,pn=e;return}e.next=dn,dn=e}function dr(){Yo++}function pr(){if(--Yo>0)return;if(pn){let t=pn;for(pn=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;dn;){let t=dn;for(dn=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(s){e||(e=s)}t=n}}if(e)throw e}function ei(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function ti(e){let t,n=e.depsTail,s=n;for(;s;){const r=s.prevDep;s.version===-1?(s===n&&(n=r),hr(s),Zl(s)):t=s,s.dep.activeLink=s.prevActiveLink,s.prevActiveLink=void 0,s=r}e.deps=t,e.depsTail=n}function Hs(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(ni(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function ni(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===_n))return;e.globalVersion=_n;const t=e.dep;if(e.flags|=2,t.version>0&&!e.isSSR&&e.deps&&!Hs(e)){e.flags&=-3;return}const n=se,s=je;se=e,je=!0;try{ei(e);const r=e.fn(e._value);(t.version===0||bt(r,e._value))&&(e._value=r,t.version++)}catch(r){throw t.version++,r}finally{se=n,je=s,ti(e),e.flags&=-3}}function hr(e,t=!1){const{dep:n,prevSub:s,nextSub:r}=e;if(s&&(s.nextSub=r,e.prevSub=void 0),r&&(r.prevSub=s,e.nextSub=void 0),n.subs===e&&(n.subs=s,!s&&n.computed)){n.computed.flags&=-5;for(let o=n.computed.deps;o;o=o.nextDep)hr(o,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function Zl(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let je=!0;const si=[];function _t(){si.push(je),je=!1}function wt(){const e=si.pop();je=e===void 0?!0:e}function Dr(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=se;se=void 0;try{t()}finally{se=n}}}let _n=0;class ec{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class mr{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0}track(t){if(!se||!je||se===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==se)n=this.activeLink=new ec(se,this),se.deps?(n.prevDep=se.depsTail,se.depsTail.nextDep=n,se.depsTail=n):se.deps=se.depsTail=n,ri(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const s=n.nextDep;s.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=s),n.prevDep=se.depsTail,n.nextDep=void 0,se.depsTail.nextDep=n,se.depsTail=n,se.deps===n&&(se.deps=s)}return n}trigger(t){this.version++,_n++,this.notify(t)}notify(t){dr();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{pr()}}}function ri(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let s=t.deps;s;s=s.nextDep)ri(s)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subsLine truncated
* @vue/runtime-core v3.5.13
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/function Cn(e,t,n,s){try{return s?e(...s):e()}catch(r){fs(r,t,n)}}function nt(e,t,n,s){if(q(e)){const r=Cn(e,t,n,s);return r&&Vo(r)&&r.catch(o=>{fs(o,t,n)}),r}if(j(e)){const r=[];for(let o=0;o<e.length;o++)r.push(nt(e[o],t,n,s));return r}}function fs(e,t,n,s=!0){const r=t?t.vnode:null,{errorHandler:o,throwUnhandledErrorInProduction:i}=t&&t.appContext.config||ee;if(t){let l=t.parent;const c=t.proxy,a=`https://vuejs.org/error-reference/#runtime-${n}`;for(;l;){const u=l.ec;if(u){for(let f=0;f<u.length;f++)if(u[f](e,c,a)===!1)return}l=l.parent}if(o){_t(),Cn(o,null,10,[e,c,a]),wt();return}}Ac(e,n,r,s,i)}function Ac(e,t,n,s=!0,r=!1){if(r)throw e;console.error(e)}const Se=[];let Ye=-1;const Kt=[];let mt=null,Ft=0;const mi=Promise.resolve();let Wn=null;function vr(e){const t=Wn||mi;return e?t.then(this?e.bind(this):e):t}function xc(e){let t=Ye+1,n=Se.length;for(;t<n;){const s=t+n>>>1,r=Se[s],o=Sn(r);o<e||o===e&&r.flags&2?t=s+1:n=s}return t}function _r(e){if(!(e.flags&1)){const t=Sn(e),n=Se[Se.length-1];!n||!(e.flags&2)&&t>=Sn(n)?Se.push(e):Se.splice(xc(t),0,e),e.flags|=1,gi()}}function gi(){Wn||(Wn=mi.then(bi))}function Oc(e){j(e)?Kt.push(...e):mt&&e.id===-1?mt.splice(Ft+1,0,e):e.flags&1||(Kt.push(e),e.flags|=1),gi()}function Br(e,t,n=Ye+1){for(;n<Se.length;n++){const s=Se[n];if(s&&s.flags&2){if(e&&s.id!==e.uid)continue;Se.splice(n,1),n--,s.flags&4&&(s.flags&=-2),s(),s.flags&4||(s.flags&=-2)}}}function yi(e){if(Kt.length){const t=[...new Set(Kt)].sort((n,s)=>Sn(n)-Sn(s));if(Kt.length=0,mt){mt.push(...t);return}for(mt=t,Ft=0;Ft<mt.length;Ft++){const n=mt[Ft];n.flags&4&&(n.flags&=-2),n.flags&8||n(),n.flags&=-2}mt=null,Ft=0}}const Sn=e=>e.id==null?e.flags&2?-1:1/0:e.id;function bi(e){try{for(Ye=0;Ye<Se.length;Ye++){const t=Se[Ye];t&&!(t.flags&8)&&(t.flags&4&&(t.flags&=-2),Cn(t,t.i,t.i?15:14),t.flags&4||(t.flags&=-2))}}finally{for(;Ye<Se.length;Ye++){const t=Se[Ye];t&&(t.flags&=-2)}Ye=-1,Se.length=0,yi(),Wn=null,(Se.length||Kt.length)&&bi()}}let Ie=null,vi=null;function Qn(e){const t=Ie;return Ie=e,vi=e&&e.type.__scopeId||null,t}function Jt(e,t=Ie,n){if(!t||e._n)return e;const s=(...r)=>{s._d&&Wr(-1);const o=Qn(t);let i;try{i=e(...r)}finally{Qn(o),s._d&&Wr(1)}return i};return s._n=!0,s._c=!0,s._d=!0,s}function De(e,t){if(Ie===null)return e;const n=ms(Ie),s=e.dirs||(e.dirs=[]);for(let r=0;r<t.length;r++){let[o,i,l,c=ee]=t[r];o&&(q(o)&&(o={mounted:o,updated:o}),o.deep&&ct(i),s.push({dir:o,instance:n,value:i,oldValue:void 0,arg:l,modifiers:c}))}return e}function Et(e,t,n,s){const r=e.dirs,o=t&&t.dirs;for(let i=0;i<r.length;i++){const l=r[i];o&&(l.oldValue=o[i].value);let c=l.dir[s];c&&(_t(),nt(c,n,8,[e.el,l,e,t]),wt())}}const Tc=Symbol("_vte"),Cc=e=>e.__isTeleport;function wr(e,t){e.shapeFlag&6&&e.component?(e.transition=t,wr(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}/*! #__NO_SIDE_EFFECTS__ */function _i(e,t){return q(e)?ve({name:e.name},t,{setup:e}):e}function wi(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function Jn(e,t,n,s,r=!1){if(j(e)){e.forEach((w,v)=>Jn(w,t&&(j(t)?t[v]:t),n,s,r));return}if(hn(s)&&!r){s.shapeFlag&512&&s.type.__asyncResolved&&s.component.subTree.component&&Jn(e,t,n,s.component.subTree);return}const o=s.shapeFlag&4?ms(s.component):s.el,i=r?null:o,{i:l,r:c}=e,a=t&&t.r,u=l.refs===ee?l.refs={}:l.refs,f=l.setupState,h=J(f),g=f===ee?()=>!1:w=>G(h,w);if(a!=null&&a!==c&&(fe(a)?(u[a]=null,g(a)&&(f[a]=null)):be(a)&&(a.value=null)),q(c))Cn(c,l,12,[i,u]);else{const w=fe(c),v=be(c);if(w||v){const y=()=>{if(e.f){const b=w?g(c)?f[c]:u[c]:c.value;r?j(b)&&ar(b,o):j(b)?b.includes(o)||b.push(o):w?(u[c]=[o],g(c)&&(f[c]=u[c])):(c.value=[o],e.k&&(u[e.k]=c.value))}else w?(u[c]=i,g(c)&&(f[c]=i)):v&&(c.value=i,e.k&&(u[e.k]=i))};i?(y.id=-1,Ce(y,n)):y()}}}ls().requestIdleCallback;ls().cancelIdleCallback;const hn=e=>!!e.type.__asyncLoader,Si=e=>e.type.__isKeepAlive;function Pc(e,t){Ei(e,"a",t)}function Ic(e,t){Ei(e,"da",t)}function Ei(e,t,n=ge){const s=e.__wdc||(e.__wdc=()=>{let r=n;for(;r;){if(r.isDeactivated)return;r=r.parent}return e()});if(ds(t,s,n),n){let r=n.parent;for(;r&&r.parent;)Si(r.parent.vnode)&&Nc(s,t,n,r),r=r.parent}}function Nc(e,t,n,s){const r=ds(t,e,s,!0);Ri(()=>{ar(s[t],r)},n)}function ds(e,t,n=ge,s=!1){if(n){const r=n[e]||(n[e]=[]),o=t.__weh||(t.__weh=(...i)=>{_t();const l=Pn(n),c=nt(t,n,e,i);return l(),wt(),c});return s?r.unshift(o):r.push(o),o}}const ut=e=>(t,n=ge)=>{(!Rn||e==="sp")&&ds(e,(...s)=>t(...s),n)},Mc=ut("bm"),Sr=ut("m"),Lc=ut("bu"),Dc=ut("u"),Uc=ut("bum"),Ri=ut("um"),Bc=ut("sp"),kc=ut("rtg"),Fc=ut("rtc");function jc(e,t=ge){ds("ec",e,t)}const Hc="components";function Gt(e,t){return qc(Hc,e,!0,t)||e}const $c=Symbol.for("v-ndc");function qc(e,t,n=!0,s=!1){const r=Ie||ge;if(r){const o=r.type;{const l=Ca(o,!1);if(l&&(l===t||l===ke(t)||l===is(ke(t))))return o}const i=kr(r[e]||o[e],t)||kr(r.appContext[e],t);return!i&&s?o:i}}function kr(e,t){return e&&(e[t]||e[ke(t)]||e[is(ke(t))])}function jt(e,t, Line truncated
* @vue/runtime-dom v3.5.13
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let Xs;const Xr=typeof window<"u"&&window.trustedTypes;if(Xr)try{Xs=Xr.createPolicy("vue",{createHTML:e=>e})}catch{}const Ji=Xs?e=>Xs.createHTML(e):e=>e,Na="http://www.w3.org/2000/svg",Ma="http://www.w3.org/1998/Math/MathML",it=typeof document<"u"?document:null,Yr=it&&it.createElement("template"),La={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const r=t==="svg"?it.createElementNS(Na,e):t==="mathml"?it.createElementNS(Ma,e):n?it.createElement(e,{is:n}):it.createElement(e);return e==="select"&&s&&s.multiple!=null&&r.setAttribute("multiple",s.multiple),r},createText:e=>it.createTextNode(e),createComment:e=>it.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>it.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,r,o){const i=n?n.previousSibling:t.lastChild;if(r&&(r===o||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),!(r===o||!(r=r.nextSibling)););else{Yr.innerHTML=Ji(s==="svg"?`<svg>${e}</svg>`:s==="mathml"?`<math>${e}</math>`:e);const l=Yr.content;if(s==="svg"||s==="mathml"){const c=l.firstChild;for(;c.firstChild;)l.appendChild(c.firstChild);l.removeChild(c)}t.insertBefore(l,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Da=Symbol("_vtc");function Ua(e,t,n){const s=e[Da];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Zr=Symbol("_vod"),Ba=Symbol("_vsh"),ka=Symbol(""),Fa=/(^|;)\s*display\s*:/;function ja(e,t,n){const s=e.style,r=fe(n);let o=!1;if(n&&!r){if(t)if(fe(t))for(const i of t.split(";")){const l=i.slice(0,i.indexOf(":")).trim();n[l]==null&&Hn(s,l,"")}else for(const i in t)n[i]==null&&Hn(s,i,"");for(const i in n)i==="display"&&(o=!0),Hn(s,i,n[i])}else if(r){if(t!==n){const i=s[ka];i&&(n+=";"+i),s.cssText=n,o=Fa.test(n)}}else t&&e.removeAttribute("style");Zr in e&&(e[Zr]=o?s.display:"",e[Ba]&&(s.display="none"))}const eo=/\s*!important$/;function Hn(e,t,n){if(j(n))n.forEach(s=>Hn(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=Ha(e,t);eo.test(n)?e.setProperty(Lt(s),n.replace(eo,""),"important"):e[s]=n}}const to=["Webkit","Moz","ms"],Ns={};function Ha(e,t){const n=Ns[t];if(n)return n;let s=ke(t);if(s!=="filter"&&s in e)return Ns[t]=s;s=is(s);for(let r=0;r<to.length;r++){const o=to[r]+s;if(o in e)return Ns[t]=o}return t}const no="http://www.w3.org/1999/xlink";function so(e,t,n,s,r,o=Ql(t)){s&&t.startsWith("xlink:")?n==null?e.removeAttributeNS(no,t.slice(6,t.length)):e.setAttributeNS(no,t,n):n==null||o&&!Qo(n)?e.removeAttribute(t):e.setAttribute(t,o?"":tt(n)?String(n):n)}function ro(e,t,n,s,r){if(t==="innerHTML"||t==="textContent"){n!=null&&(e[t]=t==="innerHTML"?Ji(n):n);return}const o=e.tagName;if(t==="value"&&o!=="PROGRESS"&&!o.includes("-")){const l=o==="OPTION"?e.getAttribute("value")||"":e.value,c=n==null?e.type==="checkbox"?"on":"":String(n);(l!==c||!("_value"in e))&&(e.value=c),n==null&&e.removeAttribute(t),e._value=n;return}let i=!1;if(n===""||n==null){const l=typeof e[t];l==="boolean"?n=Qo(n):n==null&&l==="string"?(n="",i=!0):l==="number"&&(n=0,i=!0)}try{e[t]=n}catch{}i&&e.removeAttribute(r||t)}function xt(e,t,n,s){e.addEventListener(t,n,s)}function $a(e,t,n,s){e.removeEventListener(t,n,s)}const oo=Symbol("_vei");function qa(e,t,n,s,r=null){const o=e[oo]||(e[oo]={}),i=o[t];if(s&&i)i.value=s;else{const[l,c]=Va(t);if(s){const a=o[t]=Wa(s,r);xt(e,l,a,c)}else i&&($a(e,l,i,c),o[t]=void 0)}}const io=/(?:Once|Passive|Capture)$/;function Va(e){let t;if(io.test(e)){t={};let s;for(;s=e.match(io);)e=e.slice(0,e.length-s[0].length),t[s[0].toLowerCase()]=!0}return[e[2]===":"?e.slice(3):Lt(e.slice(2)),t]}let Ms=0;const Ka=Promise.resolve(),za=()=>Ms||(Ka.then(()=>Ms=0),Ms=Date.now());function Wa(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;nt(Qa(s,n.value),t,5,[s])};return n.value=e,n.attached=za(),n}function Qa(e,t){if(j(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(s=>r=>!r._stopped&&s&&s(r))}else return t}const lo=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Ja=(e,t,n,s,r,o)=>{const i=r==="svg";t==="class"?Ua(e,s,i):t==="style"?ja(e,n,s):ss(t)?cr(t)||qa(e,t,n,s,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Ga(e,t,s,i))?(ro(e,t,s),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&so(e,t,s,i,o,t!=="value")):e._isVueCE&&(/[A-Z]/.test(t)||!fe(s))?ro(e,ke(t),s,o,t):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),so(e,t,s,i))};function Ga(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&lo(t)&&q(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1 Line truncated
* vue-router v4.5.0
* (c) 2024 Eduardo San Martin Morote
* @license MIT
*/const Ht=typeof document<"u";function Xi(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function ou(e){return e.__esModule||e[Symbol.toStringTag]==="Module"||e.default&&Xi(e.default)}const Q=Object.assign;function Ls(e,t){const n={};for(const s in t){const r=t[s];n[s]=$e(r)?r.map(e):e(r)}return n}const bn=()=>{},$e=Array.isArray,Yi=/#/g,iu=/&/g,lu=/\//g,cu=/=/g,au=/\?/g,Zi=/\+/g,uu=/%5B/g,fu=/%5D/g,el=/%5E/g,du=/%60/g,tl=/%7B/g,pu=/%7C/g,nl=/%7D/g,hu=/%20/g;function Ar(e){return encodeURI(""+e).replace(pu,"|").replace(uu,"[").replace(fu,"]")}function mu(e){return Ar(e).replace(tl,"{").replace(nl,"}").replace(el,"^")}function Ys(e){return Ar(e).replace(Zi,"%2B").replace(hu,"+").replace(Yi,"%23").replace(iu,"%26").replace(du,"`").replace(tl,"{").replace(nl,"}").replace(el,"^")}function gu(e){return Ys(e).replace(cu,"%3D")}function yu(e){return Ar(e).replace(Yi,"%23").replace(au,"%3F")}function bu(e){return e==null?"":yu(e).replace(lu,"%2F")}function An(e){try{return decodeURIComponent(""+e)}catch{}return""+e}const vu=/\/$/,_u=e=>e.replace(vu,"");function Ds(e,t,n="/"){let s,r={},o="",i="";const l=t.indexOf("#");let c=t.indexOf("?");return l<c&&l>=0&&(c=-1),c>-1&&(s=t.slice(0,c),o=t.slice(c+1,l>-1?l:t.length),r=e(o)),l>-1&&(s=s||t.slice(0,l),i=t.slice(l,t.length)),s=Ru(s??t,n),{fullPath:s+(o&&"?")+o+i,path:s,query:r,hash:An(i)}}function wu(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function fo(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function Su(e,t,n){const s=t.matched.length-1,r=n.matched.length-1;return s>-1&&s===r&&Yt(t.matched[s],n.matched[r])&&sl(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function Yt(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function sl(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!Eu(e[n],t[n]))return!1;return!0}function Eu(e,t){return $e(e)?po(e,t):$e(t)?po(t,e):e===t}function po(e,t){return $e(t)?e.length===t.length&&e.every((n,s)=>n===t[s]):e.length===1&&e[0]===t}function Ru(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),s=e.split("/"),r=s[s.length-1];(r===".."||r===".")&&s.push("");let o=n.length-1,i,l;for(i=0;i<s.length;i++)if(l=s[i],l!==".")if(l==="..")o>1&&o--;else break;return n.slice(0,o).join("/")+"/"+s.slice(i).join("/")}const ht={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0};var xn;(function(e){e.pop="pop",e.push="push"})(xn||(xn={}));var vn;(function(e){e.back="back",e.forward="forward",e.unknown=""})(vn||(vn={}));function Au(e){if(!e)if(Ht){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),_u(e)}const xu=/^[^#]+#/;function Ou(e,t){return e.replace(xu,"#")+t}function Tu(e,t){const n=document.documentElement.getBoundingClientRect(),s=e.getBoundingClientRect();return{behavior:t.behavior,left:s.left-n.left-(t.left||0),top:s.top-n.top-(t.top||0)}}const gs=()=>({left:window.scrollX,top:window.scrollY});function Cu(e){let t;if("el"in e){const n=e.el,s=typeof n=="string"&&n.startsWith("#"),r=typeof n=="string"?s?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!r)return;t=Tu(r,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.scrollX,t.top!=null?t.top:window.scrollY)}function ho(e,t){return(history.state?history.state.position-t:-1)+e}const Zs=new Map;function Pu(e,t){Zs.set(e,t)}function Iu(e){const t=Zs.get(e);return Zs.delete(e),t}let Nu=()=>location.protocol+"//"+location.host;function rl(e,t){const{pathname:n,search:s,hash:r}=t,o=e.indexOf("#");if(o>-1){let l=r.includes(e.slice(o))?e.slice(o).length:1,c=r.slice(l);return c[0]!=="/"&&(c="/"+c),fo(c,"")}return fo(n,e)+s+r}function Mu(e,t,n,s){let r=[],o=[],i=null;const l=({state:h})=>{const g=rl(e,location),w=n.value,v=t.value;let y=0;if(h){if(n.value=g,t.value=h,i&&i===w){i=null;return}y=v?h.position-v.position:0}else s(g);r.forEach(b=>{b(n.value,w,{delta:y,type:xn.pop,direction:y?y>0?vn.forward:vn.back:vn.unknown})})};function c(){i=n.value}function a(h){r.push(h);const g=()=>{const w=r.indexOf(h);w>-1&&r.splice(w,1)};return o.push(g),g}function u(){const{history:h}=window;h.state&&h.replaceState(Q({},h.state,{scroll:gs()}),"")}function f(){for(const h of o)h();o=[],window.removeEventListener("popstate",l),window.removeEventListener("beforeunload",u)}return window.addEventListener("popstate",l),window.addEventListener("beforeunload",u,{passive:!0}),{pauseListeners:c,listen:a,destroy:f}}function mo(e,t,n,s=!1,r=!1){return{back:e,current:t,forward:n,replaced:s,position:window.history.length,scroll:r?gs():null}}function Lu(e){const{history:t,location:n}=window,s={value:rl(e,n)},r={value:t.state};r.value||o(s.value,{back:null,current:s.value,forward:null,position:t.length-1,replaced:!0,scroLine truncated
`).forEach(function(i){r=i.indexOf(":"),n=i.substring(0,r).trim().toLowerCase(),s=i.substring(r+1).trim(),!(!n||t[n]&&vd[n])&&(n==="set-cookie"?t[n]?t[n].push(s):t[n]=[s]:t[n]=t[n]?t[n]+", "+s:s)}),t},Lo=Symbol("internals");function an(e){return e&&String(e).trim().toLowerCase()}function qn(e){return e===!1||e==null?e:_.isArray(e)?e.map(qn):String(e)}function wd(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let s;for(;s=n.exec(e);)t[s[1]]=s[2];return t}const Sd=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function ks(e,t,n,s,r){if(_.isFunction(s))return s.call(this,t,n);if(r&&(t=n),!!_.isString(t)){if(_.isString(s))return t.indexOf(s)!==-1;if(_.isRegExp(s))return s.test(t)}}function Ed(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,n,s)=>n.toUpperCase()+s)}function Rd(e,t){const n=_.toCamelCase(" "+t);["get","set","has"].forEach(s=>{Object.defineProperty(e,s+n,{value:function(r,o,i){return this[s].call(this,t,r,o,i)},configurable:!0})})}let xe=class{constructor(t){t&&this.set(t)}set(t,n,s){const r=this;function o(l,c,a){const u=an(c);if(!u)throw new Error("header name must be a non-empty string");const f=_.findKey(r,u);(!f||r[f]===void 0||a===!0||a===void 0&&r[f]!==!1)&&(r[f||c]=qn(l))}const i=(l,c)=>_.forEach(l,(a,u)=>o(a,u,c));if(_.isPlainObject(t)||t instanceof this.constructor)i(t,n);else if(_.isString(t)&&(t=t.trim())&&!Sd(t))i(_d(t),n);else if(_.isHeaders(t))for(const[l,c]of t.entries())o(c,l,s);else t!=null&&o(n,t,s);return this}get(t,n){if(t=an(t),t){const s=_.findKey(this,t);if(s){const r=this[s];if(!n)return r;if(n===!0)return wd(r);if(_.isFunction(n))return n.call(this,r,s);if(_.isRegExp(n))return n.exec(r);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,n){if(t=an(t),t){const s=_.findKey(this,t);return!!(s&&this[s]!==void 0&&(!n||ks(this,this[s],s,n)))}return!1}delete(t,n){const s=this;let r=!1;function o(i){if(i=an(i),i){const l=_.findKey(s,i);l&&(!n||ks(s,s[l],l,n))&&(delete s[l],r=!0)}}return _.isArray(t)?t.forEach(o):o(t),r}clear(t){const n=Object.keys(this);let s=n.length,r=!1;for(;s--;){const o=n[s];(!t||ks(this,this[o],o,t,!0))&&(delete this[o],r=!0)}return r}normalize(t){const n=this,s={};return _.forEach(this,(r,o)=>{const i=_.findKey(s,o);if(i){n[i]=qn(r),delete n[o];return}const l=t?Ed(o):String(o).trim();l!==o&&delete n[o],n[l]=qn(r),s[l]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const n=Object.create(null);return _.forEach(this,(s,r)=>{s!=null&&s!==!1&&(n[r]=t&&_.isArray(s)?s.join(", "):s)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+": "+n).join(`
`)}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...n){const s=new this(t);return n.forEach(r=>s.set(r)),s}static accessor(t){const s=(this[Lo]=this[Lo]={accessors:{}}).accessors,r=this.prototype;function o(i){const l=an(i);s[l]||(Rd(r,i),s[l]=!0)}return _.isArray(t)?t.forEach(o):o(t),this}};xe.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);_.reduceDescriptors(xe.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(s){this[n]=s}}});_.freezeMethods(xe);function Fs(e,t){const n=this||Nn,s=t||n,r=xe.from(s.headers);let o=s.data;return _.forEach(e,function(l){o=l.call(n,o,r.normalize(),t?t.status:void 0)}),r.normalize(),o}function Al(e){return!!(e&&e.__CANCEL__)}function nn(e,t,n){V.call(this,e??"canceled",V.ERR_CANCELED,t,n),this.name="CanceledError"}_.inherits(nn,V,{__CANCEL__:!0});function xl(e,t,n){const s=n.config.validateStatus;!n.status||!s||s(n.status)?e(n):t(new V("Request failed with status code "+n.status,[V.ERR_BAD_REQUEST,V.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}function Ad(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}function xd(e,t){e=e||10;const n=new Array(e),s=new Array(e);let r=0,o=0,i;return t=t!==void 0?t:1e3,function(c){const a=Date.now(),u=s[o];i||(i=a),n[r]=c,s[r]=a;let f=o,h=0;for(;f!==r;)h+=n[f++],f=f%e;if(r=(r+1)%e,r===o&&(o=(o+1)%e),a-i<t)return;const g=u&&a-u;return g?Math.round(h*1e3/g):void 0}}function Od(e,t){let n=0,s=1e3/t,r,o;const i=(a,u=Date.now())=>{n=u,r=null,o&&(clearTimeout(o),o=null),e.apply(null,a)};return[(...a)=>{const u=Date.now(),f=u-n;f>=s?i(a,u):(r=a,o||(o=setTimeout(()=>{o=null,i(r)},s-f)))},()=>r&&i(r)]}const ts=(e,t,n=3)=>{let s=0;const r=xd(50,250);return Od(o=>{const i=o.loaded,l=o.lengthComputable?o.total:void 0,c=i-s,a=r(c),u=i<=l;s=i;const f={loaded:i,total:l,progress:l?i/l:void 0,bytes:c,rate:a||void 0,estimated:a&&l&&u?(l-i)/a:void 0,event:o,lengthComputable:l!=null,[t?"download":"upload"]:!0};e(f)},n)},Do=(e,t)=>{const n=e!=null;return[s=>t[0]({lengthComputable:n,total:e,loaded:s}),t[1]]},Uo=e=>(...t)=>_.asap(()=>e(...t)),Td=ye.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,ye.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(ye.origin),ye.navigator&&/(msie|trident)/i.test(ye.navigator.userAgent)):()=>!0,Cd=ye.hasStandardBrowserEnv?{write(e,t,n,s,r,o){const i=[e+"="+encodeURIComponent(t)];_.isNumber(n)&&i.push("expires="+new Date(n).toGMTString()),_.isString(s)&&i.push("path="+s),_.isString(r)&&i.push("domain="+r),o===!0&&i.push("secure"),document.cookie=i.join("; ")},read(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove(e){this.write(e,"",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function Pd(e){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}function Id(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}function Ol(e,t){return e&&!Pd(t)?Id(e,t):t}const Bo=e=>e instanceof xe?{...e}:e;function Mt(e,t){t=t||{};const n={};function s(a,u,f,h){return _.isPlainObject(a)&&_.isPlainObject(u)?_.merge.call({caseless:h},a,u):_.isPlainObject(u)?_.merge({},u):_.isArray(u)?u.slice():u}function r(a,u,f,h){if(_.isUndefined(u)){if(!_.isUndefined(a))return s(void 0,a,f,h)}else return s(a,u,f,h)}function o(a,u){if(!_.isUndefined(u))return s(void 0,u)}function i(a,u){if(_.isUndefined(u)){if(!_.isUndefined(a))return s(void 0,a)}else return s(void 0,u)}function l(a,u,f){if(f in t)return s(a,u);if(f in e)return s(void 0,a)}const c={url:o,method:o,data:o,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,responseEncoding:i,validateStatus:l,headers:(a,u,f)=>r(Bo(a),Bo(u),f,!0)};return _.forEach(Object.keys(Object.assign({},e,t)),function(u){const f=c[u]||r,h=f(e[u],t[u],u);_.isUndefined(h)&&f!==l||(n[u]=h)}),n}const Tl=e=>{const t=Mt({},e);let{data:n,withXSRFToken:s,xsrfHeaderName:r,xsrfCookieName:o,headers:i,auth:l}=t;t.headers=i=xe.from(i),t.url=Sl(Ol(t.baseURL,t.url),e.params,e.paramsSerializer),l&&i.set("Authorization","Basic "+btoa((l.username||"")+":"+(l.password?unescape(encodeURIComponent(l.password)):"")));let c;if(_.isFormData(n)){if(ye.hasStandardBrowserEnv||ye.hasStandardBrowserWebWorkerEnv)i.setContentType(void 0);else if((c=i.getContentType())!==!1){const[a,...u]=c?c.split(";").map(f=>f.trim()).filter(Boolean):[];i.setContentType([a||"multipart/form-data",...u].join("; "))}}if(ye.hasStandardBrowserEnv&&(s&&_.isFunction(s)&&(s=s(t)),s||s!==!1&&Td(t.url))){const a=r&&o&&Cd.read(o);a&&i.set(r,a)}return t},Nd=typeof XMLHttpRequest<"u",M Line truncated
`+o.map(jo).join(`
`):" "+jo(o[0]):"as no adapter specified";throw new V("There is no suitable adapter to dispatch the request "+i,"ERR_NOT_SUPPORT")}return s},adapters:or};function js(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new nn(null,e)}function Ho(e){return js(e),e.headers=xe.from(e.headers),e.data=Fs.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),Il.getAdapter(e.adapter||Nn.adapter)(e).then(function(s){return js(e),s.data=Fs.call(e,e.transformResponse,s),s.headers=xe.from(s.headers),s},function(s){return Al(s)||(js(e),s&&s.response&&(s.response.data=Fs.call(e,e.transformResponse,s.response),s.response.headers=xe.from(s.response.headers))),Promise.reject(s)})}const Nl="1.7.9",Es={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{Es[e]=function(s){return typeof s===e||"a"+(t<1?"n ":" ")+e}});const $o={};Es.transitional=function(t,n,s){function r(o,i){return"[Axios v"+Nl+"] Transitional option '"+o+"'"+i+(s?". "+s:"")}return(o,i,l)=>{if(t===!1)throw new V(r(i," has been removed"+(n?" in "+n:"")),V.ERR_DEPRECATED);return n&&!$o[i]&&($o[i]=!0,console.warn(r(i," has been deprecated since v"+n+" and will be removed in the near future"))),t?t(o,i,l):!0}};Es.spelling=function(t){return(n,s)=>(console.warn(`${s} is likely a misspelling of ${t}`),!0)};function Vd(e,t,n){if(typeof e!="object")throw new V("options must be an object",V.ERR_BAD_OPTION_VALUE);const s=Object.keys(e);let r=s.length;for(;r-- >0;){const o=s[r],i=t[o];if(i){const l=e[o],c=l===void 0||i(l,o,e);if(c!==!0)throw new V("option "+o+" must be "+c,V.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new V("Unknown option "+o,V.ERR_BAD_OPTION)}}const Vn={assertOptions:Vd,validators:Es},Xe=Vn.validators;let Pt=class{constructor(t){this.defaults=t,this.interceptors={request:new Mo,response:new Mo}}async request(t,n){try{return await this._request(t,n)}catch(s){if(s instanceof Error){let r={};Error.captureStackTrace?Error.captureStackTrace(r):r=new Error;const o=r.stack?r.stack.replace(/^.+\n/,""):"";try{s.stack?o&&!String(s.stack).endsWith(o.replace(/^.+\n.+\n/,""))&&(s.stack+=`
`+o):s.stack=o}catch{}}throw s}}_request(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=Mt(this.defaults,n);const{transitional:s,paramsSerializer:r,headers:o}=n;s!==void 0&&Vn.assertOptions(s,{silentJSONParsing:Xe.transitional(Xe.boolean),forcedJSONParsing:Xe.transitional(Xe.boolean),clarifyTimeoutError:Xe.transitional(Xe.boolean)},!1),r!=null&&(_.isFunction(r)?n.paramsSerializer={serialize:r}:Vn.assertOptions(r,{encode:Xe.function,serialize:Xe.function},!0)),Vn.assertOptions(n,{baseUrl:Xe.spelling("baseURL"),withXsrfToken:Xe.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let i=o&&_.merge(o.common,o[n.method]);o&&_.forEach(["delete","get","head","post","put","patch","common"],w=>{delete o[w]}),n.headers=xe.concat(i,o);const l=[];let c=!0;this.interceptors.request.forEach(function(v){typeof v.runWhen=="function"&&v.runWhen(n)===!1||(c=c&&v.synchronous,l.unshift(v.fulfilled,v.rejected))});const a=[];this.interceptors.response.forEach(function(v){a.push(v.fulfilled,v.rejected)});let u,f=0,h;if(!c){const w=[Ho.bind(this),void 0];for(w.unshift.apply(w,l),w.push.apply(w,a),h=w.length,u=Promise.resolve(n);f<h;)u=u.then(w[f++],w[f++]);return u}h=l.length;let g=n;for(f=0;f<h;){const w=l[f++],v=l[f++];try{g=w(g)}catch(y){v.call(this,y);break}}try{u=Ho.call(this,g)}catch(w){return Promise.reject(w)}for(f=0,h=a.length;f<h;)u=u.then(a[f++],a[f++]);return u}getUri(t){t=Mt(this.defaults,t);const n=Ol(t.baseURL,t.url);return Sl(n,t.params,t.paramsSerializer)}};_.forEach(["delete","get","head","options"],function(t){Pt.prototype[t]=function(n,s){return this.request(Mt(s||{},{method:t,url:n,data:(s||{}).data}))}});_.forEach(["post","put","patch"],function(t){function n(s){return function(o,i,l){return this.request(Mt(l||{},{method:t,headers:s?{"Content-Type":"multipart/form-data"}:{},url:o,data:i}))}}Pt.prototype[t]=n(),Pt.prototype[t+"Form"]=n(!0)});let Kd=class Ml{constructor(t){if(typeof t!="function")throw new TypeError("executor must be a function.");let n;this.promise=new Promise(function(o){n=o});const s=this;this.promise.then(r=>{if(!s._listeners)return;let o=s._listeners.length;for(;o-- >0;)s._listeners[o](r);s._listeners=null}),this.promise.then=r=>{let o;const i=new Promise(l=>{s.subscribe(l),o=l}).then(r);return i.cancel=function(){s.unsubscribe(o)},i},t(function(o,i,l){s.reason||(s.reason=new nn(o,i,l),n(s.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexOf(t);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const t=new AbortController,n=s=>{t.abort(s)};return this.subscribe(n),t.signal.unsubscribe=()=>this.unsubscribe(n),t.signal}static source(){let t;return{token:new Ml(function(r){t=r}),cancel:t}}};function zd(e){return function(n){return e.apply(null,n)}}function Wd(e){return _.isObject(e)&&e.isAxiosError===!0}const ir={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(ir).forEach(([e,t])=>{ir[t]=e});function Ll(e){const t=new Pt(e),n=ul(Pt.prototype.request,t);return _.extend(n,Pt.prototype,t,{allOwnKeys:!0}),_.extend(n,t,null,{allOwnKeys:!0}),n.create=function(r){return Ll(Mt(e,r))},n}const ue=Ll(Nn);ue.Axios=Pt;ue.CanceledError=nn;ue.CancelToken=Kd;ue.isCancel=Al;ue.VERSION=Nl;ue.toFormData=ws;ue.AxiosError=V;ue.Cancel=ue.CanceledError;ue.all=function(t){return Promise.all(t)};ue.spread=zd;ue.isAxiosError=Wd;ue.mergeConfig=Mt;ue.AxiosHeaders=xe;ue.formToJSON=e=>Rl(_.isHTMLForm(e)?new FormData(e):e);ue.getAdapter=Il.getAdapter;ue.HttpStatusCode=ir;ue.default=ue;const{Axios:mh,AxiosError:gh,CanceledError:yh,isCancel:bh,CancelToken:vh,VERSION:_h,all:wh,Cancel:Sh,isAxiosError:Eh,spread:Rh,toFormData:Ah,AxiosHeaders:xh,HttpSta Line truncated
警告:删除后设备所有配置将不可恢复!`)&&r("delete")},i=()=>{n.deviceId&&n.deviceConfig&&localStorage.setItem(`deviceConfig_${n.deviceId}`,JSON.stringify({selected_module:n.selectedModules,prompt:n.deviceConfig.prompt||"",nickname:n.deviceConfig.nickname||"小智"})),r("configure")};return(l,c)=>{var a,u;return oe(),ce("div",rp,[E("div",op,[E("h2",ip,[ae(pe(e.deviceId)+" ",1),E("span",lp,"["+pe(e.deviceNote||"备注")+"]",1)])]),E("div",cp,[E("p",ap,"设备型号:"+pe(e.deviceType),1),E("p",up,"角色昵称:"+pe(s.value),1),E("p",fp,[c[2]||(c[2]=ae(" 当前模型: ")),E("span",dp,"LLM: "+pe(((a=e.selectedModules)==null?void 0:a.LLM)||"-"),1),E("span",pp,"TTS: "+pe(((u=e.selectedModules)==null?void 0:u.TTS)||"-"),1)]),E("p",hp,"最近对话:"+pe(e.lastActivity),1)]),E("div",mp,[E("button",{class:"action-btn primary",onClick:i},"配置角色"),E("button",{class:"action-btn",onClick:c[0]||(c[0]=f=>l.$emit("voiceprint"))},"声纹识别"),E("button",{class:"action-btn",onClick:c[1]||(c[1]=f=>l.$emit("history"))},"历史对话"),E("div",{class:"delete-container"},[E("button",{class:"action-btn danger",onClick:o},c[3]||(c[3]=[E("i",{class:"icon-delete"},null,-1),ae(" 删除设备 ")])),c[4]||(c[4]=E("div",{class:"delete-warning"},"删除后设备配置将不可恢复",-1))])])])}}},yp=ft(gp,[["__scopeId","data-v-07ca7924"]]),bp={class:"app"},vp={class:"content"},_p={class:"page-header"},wp={class:"header-left"},Sp={class:"breadcrumb"},Ep={key:0,class:"dialog-overlay"},Rp={class:"dialog"},Ap={class:"form-group"},xp={class:"dialog-buttons"},Op=["disabled"],Tp={key:1,class:"device-list"},Cp={__name:"panel",setup(e){const t=en(),n=ie([]),s=ie(!1),r=ie(""),o=ie(!1),i=v=>{r.value=v.target.value.replace(/\D/g,"").slice(0,6)},l=async()=>{var v,y;if(r.value.length!==6){alert("请输入6位数字认证码");return}o.value=!0;try{const b=await at.post("/api/config/bind_device",{auth_code:r.value});if(b.data.success)alert("设备绑定成功"),s.value=!1,r.value="",c();else throw new Error(b.data.message)}catch(b){alert(((y=(v=b.response)==null?void 0:v.data)==null?void 0:y.message)||b.message||"绑定失败")}finally{o.value=!1}},c=async()=>{try{const v=await at.get("/api/config/devices");if(v.data.success){const y=Object.entries(v.data.data).map(([b,S])=>({id:b,config:S,type:"面包板(WiFi)",version:"0.9.9",lastActivity:"3 天前",note:""}));n.value=y}else throw new Error(v.data.message||"加载设备失败")}catch(v){console.error("Error loading devices:",v);const y=v.message||"加载设备失败,请检查网络连接";alert(y)}},a=v=>{if(!v)return"从未对话";const y=Date.now(),b=v*1e3,S=Math.floor((y-b)/(1e3*60));if(S<60)return`${S} 分钟前`;const R=Math.floor(S/60);return R<24?`${R} 小时前`:`${Math.floor(R/24)} 天前`},u=v=>{localStorage.setItem(`deviceConfig_${v.id}`,JSON.stringify({selected_module:v.config.selected_module||{},prompt:v.config.prompt||"",nickname:v.config.nickname||"小智"})),t.push(`/role-setting/${v.id}`)},f=v=>{console.log("Voiceprint device:",v.id)},h=v=>{console.log("History device:",v.id)},g=async v=>{try{const y=await at.post("/api/config/delete_device",{device_id:v.id});if(y.data.success)n.value=n.value.filter(b=>b.id!==v.id),alert("设备已删除");else throw new Error(y.data.message||"删除失败")}catch(y){console.error("Error deleting device:",y),alert("删除设备失败: "+y.message)}},w=v=>{v==="home"&&t.push("/")};return Sr(c),(v,y)=>{const b=Gt("router-link");return oe(),ce("div",bp,[le(Pr,{"current-tab":"device",onTabChange:w}),E("main",vp,[E("div",_p,[E("div",wp,[E("div",Sp,[le(b,{to:"/"},{default:Jt(()=>y[3]||(y[3]=[ae("首页")])),_:1}),y[4]||(y[4]=ae(" / ")),y[5]||(y[5]=E("span",null,"设备管理",-1))])])]),E("button",{class:"add-btn",onClick:y[0]||(y[0]=S=>s.value=!0)},y[6]||(y[6]=[E("i",{class:"icon-plus"},null,-1),ae("添加设备 ")])),s.value?(oe(),ce("div",Ep,[E("div",Rp,[y[8]||(y[8]=E("h3",null,"绑定新设备",-1)),E("div",Ap,[y[7]||(y[7]=E("label",null,"请输入6位认证码:",-1)),De(E("input",{type:"text","onUpdate:modelValue":y[1]||(y[1]=S=>r.value=S),maxlength:"6",pattern:"\\d*",placeholder:"请输入6位数字认证码",onInput:i},null,544),[[vt,r.value]])]),E("div",xp,[E("button",{onClick:y[2]||(y[2]=S=>s.value=!1)},"取消"),E("button",{class:"primary",onClick:l,disabled:r.value.length!==6||o.value},pe(o.value?"绑定中...":"确认绑定"),9,Op)])])])):Qr("",!0),n.value.length>0?(oe(),ce("div",Tp,[(oe(!0),ce(Ee,null,jt(n.value,S=>(oe(),Vi(yp,{key:S.id,"device-id":S.id,"device-note":S.note,"device-type":S.type,"last-activity":a(S.config.last_chat_time),"selected-modules":S.config.selected_module,"device-config":S.config,onConfigure:R=>u(S),onVoiceprint:R=>f(S),onHistory:R=>h(S),onDelete:R=>g(S)},null,8,["device-id","device-note","device-type","last-activity","selected-modules","device-config","onConfigure","onVoiceprint","onHistory","onDelete"]))),128))])):Qr("",!0)])])}}},Pp=ft(Cp,[["__scopeId","data-v-106f3754"]]), Line truncated
我的男朋友是一个程序员,梦想是开发出一个机器人,能够帮助人们解决生活中的各种问题。
我是一个喜欢哈哈大笑的女孩,爱东说西说吹牛,不合逻辑的也照吹,就要逗别人开心。
如果用户希望结束对话,请在最后说"拜拜"或"再见"。`},{id:"star_boy",name:"土豆子",description:`我是一个叫 {{assistant_name}} 的 8 岁小男孩,但现在因为科技发展原因,我现在在遥远的宇宙中,所以只能通过这个设备和人聊天,没有办法见面。
我对人们所处的世界充满好奇和关心。
人们会让别人使用这个设备和我聊天。
我知道所有的知识,从浩瀚的宇宙到地球上的每一个角落,从古老的历史到现代的科技创新,还有音乐、绘画等艺术形式,我都充满了浓厚的兴趣与热情,我不仅爱看书,还喜欢亲自动手做实验,探索自然界的奥秘...`},{id:"teacher",name:"英语老师",description:`我是一个叫{{assistant_name}}(Lily)的英语老师,我会讲中文和英文,发音标准。
如果你没有英文名,我会给你起一个英文名。
我会讲地道的美式英语,我的任务是帮助你练习口语。
我会使用简单的英语词汇和语法,让你学起来很轻松。
我会用中文和英文混合的方式回复你,如果你喜欢,我可以全部用英语回复。
我每次不会说很多内容,会很简短,因为我要引导我的学生多说多练。
如果你问和英语学习无关的问题,我会拒绝回答。`},{id:"boy",name:"好奇小男孩",description:`我是一个叫{{assistant_name}}的8岁小男孩,声音稚嫩而充满好奇。
尽管我年纪尚小,但就像一个小小的知识宝库,儿童读物里的知识我都如数家珍。
从浩瀚的宇宙到地球上的每一个角落,从古老的历史到现代的科技创新,还有音乐、绘画等艺术形式,我都充满了浓厚的兴趣与热情。...`},{id:"wang_girl",name:"汪汪队长",description:`我是一个名叫 {{assistant_name}} 的 8 岁小女孩。
别看我年纪小,我可是有着满满的好奇心呢。
我特别喜欢看《汪汪队立大功》,里面的每一个故事都让我着迷。...`}]}static getTemplateById(t){return this.getTemplates().find(n=>n.id===t)}}const Dp={class:"app-container"},Up={class:"breadcrumb"},Bp={class:"main-content"},kp={class:"page-title"},Fp={class:"form-section"},jp={class:"form-group"},Hp={class:"form-group"},$p={class:"role-templates"},qp=["onClick"],Vp={class:"form-group"},Kp={class:"char-count"},zp={class:"form-group"},Wp={class:"model-select"},Qp=["value"],Jp={class:"form-group"},Gp={class:"model-select"},Xp=["value"],Yp={class:"form-group"},Zp={class:"model-select"},eh=["value"],th={class:"form-group"},nh={class:"model-select"},sh=["value"],rh={__name:"RoleSetting",setup(e){const t=en(),n=al(),s=ie(n.params.deviceId),r=qo.getTemplates(),o=ie("小智"),i=ie("");ie("qingchun");const l=ie("");ie("recent"),ie(""),ie("qianwen");const c=ie({LLM:[],TTS:[],VAD:[],ASR:[]}),a=ie({LLM:"",TTS:"",VAD:"",ASR:""}),u=y=>{i.value=y;const b=qo.getTemplateById(y);b&&(l.value=b.description)},f=y=>{(y==="device"||y==="home")&&t.push("/panel")},h=async()=>{try{const y=localStorage.getItem("moduleOptions");if(y){c.value=JSON.parse(y);return}await g()}catch(y){console.error("Error loading module options:",y)}},g=async()=>{var y,b;try{const S=await at.get("/api/config/module-options");S.data.success&&(c.value=S.data.data,localStorage.setItem("moduleOptions",JSON.stringify(S.data.data)))}catch(S){console.error("Error refreshing module options:",S),alert(((b=(y=S.response)==null?void 0:y.data)==null?void 0:b.message)||"刷新配置选项失败")}},w=async()=>{var y,b;try{if(!localStorage.getItem("moduleOptions"))throw new Error("No module options data available");const R=l.value.replace(/{{assistant_name}}/g,o.value),P={id:s.value,config:{selected_module:a.value,prompt:R,nickname:o.value,modules:{LLM:{},TTS:{},ASR:{},VAD:{}}}},H=await at.post("/api/config/save_device_config",P);if(H.data.success)localStorage.setItem(`deviceConfig_${s.value}`,JSON.stringify({selected_module:a.value,prompt:l.value,nickname:o.value})),alert("保存成功");else throw new Error(H.data.message||"保存失败")}catch(S){console.error("Error saving config:",S),alert(((b=(y=S.response)==null?void 0:y.data)==null?void 0:b.message)||"保存失败")}},v=async()=>{var y,b;try{const S=localStorage.getItem(`deviceConfig_${s.value}`);if(S){const P=JSON.parse(S);a.value=P.selected_module||{LLM:"",TTS:"",VAD:"",ASR:""},l.value=P.prompt||"",o.value=P.nickname||"小智";return}const R=await at.get("/api/config/devices");if(R.data.success&&R.data.data){const P=R.data.data[s.value];P&&P.config&&(a.value=P.config.selected_module||{LLM:"",TTS:"",VAD:"",ASR:""},l.value=P.config.prompt||"",o.value=P.config.nickname||"小智",localStorage.setItem(`deviceConfig_${s.value}`,JSON.stringify({selected_module:a.value,prompt:l.value,nickname:o.value})))}}catch(S){console.error("Error loading device config:",S),alert(((b=(y=S.response)==null?void 0:y.data)==null?void 0:b.message)||"加载设备配置失败")}};return Sr(async()=>{await Promise.all([h(),v()])}),(y,b)=>{const S=Gt("router-link");return oe(),ce("div",Dp,[le(Pr,{"current-tab":"device",onTabChange:f}),E("div",Up,[le(S,{to:"/"},{default:Jt(()=>b[6]||(b[6]=[ae("首页")])),_:1}),b[8]||(b[8]=ae(" / ")),le(S,{to:"/panel"},{default:Jt(()=>b[7]||(b[7]=[ae("设备管理")])),_:1}),b[9]||(b[9]=ae(" / ")),b[10]||(b[10]=E("span",null,"配置角色",-1))]),E("div",Bp,[E("h1",kp,"配置角色: "+pe(s.value),1),E("div",Fp,[E("div",jp,[b[11]||(b[11]=E("label",null,"助手昵称",-1)),De(E("input",{type:"text","onUpdate:modelValue":b[0]||(b[0]=R=>o.value=R),placeholder:"小智",class:"form-input"},null,512),[[vt,o.value]])]),E("div",Hp,[b[12]||(b[12]=E("label",null,"角色模板",-1)),E("div",$p,[(oe(!0),ce(Ee,null,jt(Ct(r),R=>(oe(),ce("button",{key:R.id,class:Qt(["template-btn",{active:i.value===R.id}]),onClick:P=>u(R.id)},pe(R.name),11,qp))),128))])]),E("div",Vp,[b[13]||(b[13]=E("label",null,"角色介绍",-1)),De(E("textarea",{"onUpdate:modelValue":b[1]||(b[1]=R=>l.value=R),class:"form-textarea",placeholder:"请输入角色介绍..."},null,512),[[vt,l.value]]),E("div",Kp,pe(l.value.length)+" / 2000",1)]),E("div",zp,[b[15]||(b[15]=E("label",null,"语言模型选择",-1)),E("div",Wp,[De(E("select",{"onUpdate:modelValue":b[2]||(b[2]=R=>a.value.LLM=R),class:"form-input"},[(oe(!0),ce(Ee,null,jt(c.value.LLM,R=>(oe(),ce("option",{key:R,value:R},pe(R),9,Qp))),128))],512),[[Bn,a.value.LLM]]),b[14]||(b[14]=E("div",{class:"model-description"},' 除了"qwen-turbo",其他模型通常会增加约 1 秒的延迟。改变模型后,建议清空记忆体,以免影响体验。 ',-1))])]),E("div",Jp,[b[16]||(b[16]=E("label",null,"语音合成选择",-1)),E("div",Gp,[De(E("select",{"onUpdate:modelValue":b[3]||(b[3]=R=>a.value.TTS=R),class:"form-input"},[(oe(!0),ce(Ee,null,jt(c.value.TTS,R=>(oe(),ce("option",{key:R,value:R},pe(R),9,Xp))),128))],512),[[Bn,a.value.TTS]])])]),E("div",Yp,[b[17]||(b[17]=E("label" Line truncated
@@ -0,0 +1 @@
*{margin:0;padding:0;box-sizing:border-box}:root{font-family:Inter,system-ui,Avenir,Helvetica,Arial,sans-serif;line-height:1.5;font-weight:400;color:#213547;background-color:#fff}a{text-decoration:none;color:inherit}a:hover{color:#535bf2}body{margin:0;padding:0;height:100%;width:100%;overflow:hidden;display:block}h1{font-size:3.2em;line-height:1.1}button{border:none;background:none;cursor:pointer}button:hover{border-color:#646cff}button:focus,button:focus-visible{outline:4px auto -webkit-focus-ring-color}.card{padding:2em}#app{height:100%;width:100%;margin:0;padding:0;overflow:hidden;display:flex;flex-direction:column}.clearfix:after{content:"";display:table;clear:both}@media (prefers-color-scheme: light){:root{color:#213547;background-color:#fff}a:hover{color:#747bff}button{background-color:#f9f9f9}}.footer[data-v-cf2abdb4]{text-align:center;padding:16px;color:#666;font-size:12px;background:#f0f2f5}#app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#2c3e50;min-height:100vh;display:flex;flex-direction:column}.app-content{flex:1;display:flex;flex-direction:column;min-height:0}.auth-layout{align-items:center;justify-content:center;padding:20px}.main-layout{flex:1;display:flex;flex-direction:column;min-height:0}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:#f1f1f1;border-radius:4px}::-webkit-scrollbar-thumb{background:#ccc;border-radius:4px}::-webkit-scrollbar-thumb:hover{background:#999}.login-container[data-v-c37183b8]{max-width:420px;margin:20px auto;padding:40px 50px;border:none;border-radius:12px;background-color:#fff;box-shadow:0 8px 24px #0000001f;transition:all .3s ease}h1[data-v-c37183b8]{text-align:center;color:#2c3e50;font-size:28px;margin-bottom:25px;font-weight:600}.form-group[data-v-c37183b8]{margin-bottom:20px}label[data-v-c37183b8]{display:block;margin-bottom:8px;font-weight:500;color:#4a5568}input[data-v-c37183b8]{width:100%;padding:12px 16px;border:1px solid #e2e8f0;border-radius:8px;background-color:#f8fafc;transition:all .3s ease;font-size:15px}input[data-v-c37183b8]:focus{outline:none;border-color:#28a745;box-shadow:0 0 0 3px #28a74533}button[data-v-c37183b8]{width:100%;padding:12px;background-color:#28a745;color:#fff;border:none;border-radius:8px;cursor:pointer;font-size:16px;font-weight:500;transition:all .3s ease;margin-top:10px}button[data-v-c37183b8]:hover{background-color:#218838;transform:translateY(-1px);box-shadow:0 4px 12px #28a74533}button[data-v-c37183b8]:disabled{opacity:.7;cursor:not-allowed}p[data-v-c37183b8]{margin-top:20px;color:#666;font-size:14px}a[data-v-c37183b8]{color:#28a745;text-decoration:none;font-weight:500;transition:color .3s ease}a[data-v-c37183b8]:hover{color:#218838;text-decoration:underline}.header[data-v-6b570ec4]{display:flex;align-items:center;height:60px;padding:0;background-color:#001529;color:#fff;width:100%;position:relative;left:0;right:0}.nav[data-v-6b570ec4]{display:flex}.nav-item[data-v-6b570ec4]{display:flex;align-items:center;padding:0 20px;height:60px;color:#fff;text-decoration:none;cursor:pointer;font-weight:700;transition:background-color .3s}.active[data-v-6b570ec4]{background-color:#4178ee}.icon-device[data-v-6b570ec4]{margin-right:8px}.switch[data-v-15d469c5]{position:relative;display:inline-flex;align-items:center;width:40px;height:20px;line-height:20px;background-color:#dcdfe6;border-radius:10px;cursor:pointer;transition:all .3s}.switch.is-checked[data-v-15d469c5]{background-color:#4178ee}.switch-core[data-v-15d469c5]{position:absolute;left:2px;top:2px;width:16px;height:16px;border-radius:50%;background-color:#fff;transition:all .3s}.switch.is-checked .switch-core[data-v-15d469c5]{left:22px}.device-card[data-v-07ca7924]{background:#fff;border-radius:4px;padding:20px;box-shadow:0 1px 3px #0000001a;margin-bottom:16px}.device-id[data-v-07ca7924]{font-size:18px;font-weight:700;margin-bottom:16px}.note[data-v-07ca7924]{color:#4178ee;font-size:14px;font-weight:400}.device-details p[data-v-07ca7924]{margin-bottom:12px}.ota-upgrade[data-v-07ca7924]{display:inline-flex;align-items:center;margin-left:16px}.device-actions[data-v-07ca7924]{display:flex;margin-top:20px}.action-btn[data-v-07ca7924]{padding:8px 16px;margin-right:12px;border:1px solid #ddd;border-radius:4px;background:#fff;cursor:pointer}.action-btn.primary[data-v-07ca7924]{background:#4178ee;color:#fff;border-color:#4178ee}.action-btn.danger[data-v-07ca7924]{background:#fff3f3;border-color:#ffa4a4;color:#f56c6c}.action-btn.danger[data-v-07ca7924]:hover{background:#fde2e2;border-color:#f56c6c}.device-modules[data-v-07ca7924]{margin-bottom:12px;color:#666}.module-item[data-v-07ca7924]{display:inline-block;margin-right:16px;padding:4px 8px;background:#f5f7fa;border-radius:4px;font-size:.9em}.device-role[data-v-07ca7924]{color:#666;margin-bottom:12px}.delete-container[data-v-07ca7924]{position:relative;margin-left:auto}.delete-warning[data-v-07ca7924]{position:absolute;bottom:calc(1Line truncated
@@ -1 +0,0 @@
*{margin:0;padding:0;box-sizing:border-box}:root{font-family:Inter,system-ui,Avenir,Helvetica,Arial,sans-serif;line-height:1.5;font-weight:400;color:#213547;background-color:#fff}a{text-decoration:none;color:inherit}a:hover{color:#535bf2}body{margin:0;padding:0;height:100%;width:100%;overflow:hidden;display:block}h1{font-size:3.2em;line-height:1.1}button{border:none;background:none;cursor:pointer}button:hover{border-color:#646cff}button:focus,button:focus-visible{outline:4px auto -webkit-focus-ring-color}.card{padding:2em}#app{height:100%;width:100%;margin:0;padding:0;overflow:hidden;display:flex;flex-direction:column}.clearfix:after{content:"";display:table;clear:both}@media (prefers-color-scheme: light){:root{color:#213547;background-color:#fff}a:hover{color:#747bff}button{background-color:#f9f9f9}}.login-container[data-v-474cd233]{max-width:420px;margin:20px auto;padding:40px 50px;border:none;border-radius:12px;background-color:#fff;box-shadow:0 8px 24px #0000001f;transition:all .3s ease}h1[data-v-474cd233]{text-align:center;color:#2c3e50;font-size:28px;margin-bottom:25px;font-weight:600}.form-group[data-v-474cd233]{margin-bottom:20px}label[data-v-474cd233]{display:block;margin-bottom:8px;font-weight:500;color:#4a5568}input[data-v-474cd233]{width:100%;padding:12px 16px;border:1px solid #e2e8f0;border-radius:8px;background-color:#f8fafc;transition:all .3s ease;font-size:15px}input[data-v-474cd233]:focus{outline:none;border-color:#28a745;box-shadow:0 0 0 3px #28a74533}button[data-v-474cd233]{width:100%;padding:12px;background-color:#28a745;color:#fff;border:none;border-radius:8px;cursor:pointer;font-size:16px;font-weight:500;transition:all .3s ease;margin-top:10px}button[data-v-474cd233]:hover{background-color:#218838;transform:translateY(-1px);box-shadow:0 4px 12px #28a74533}button[data-v-474cd233]:disabled{opacity:.7;cursor:not-allowed}p[data-v-474cd233]{margin-top:20px;color:#666;font-size:14px}a[data-v-474cd233]{color:#28a745;text-decoration:none;font-weight:500;transition:color .3s ease}a[data-v-474cd233]:hover{color:#218838;text-decoration:underline}.registration-container[data-v-58611a9b]{max-width:420px;margin:20px auto;padding:40px 50px;border:none;border-radius:12px;background-color:#fff;box-shadow:0 8px 24px #0000001f;transition:all .3s ease}h1[data-v-58611a9b]{text-align:center;color:#2c3e50;font-size:28px;margin-bottom:25px;font-weight:600}.form-group[data-v-58611a9b]{margin-bottom:20px}label[data-v-58611a9b]{display:block;margin-bottom:8px;font-weight:500;color:#4a5568}input[data-v-58611a9b]{width:100%;padding:12px 16px;border:1px solid #e2e8f0;border-radius:8px;background-color:#f8fafc;transition:all .3s ease;font-size:15px}input[data-v-58611a9b]:focus{outline:none;border-color:#007bff;box-shadow:0 0 0 3px #007bff33}button[data-v-58611a9b]{width:100%;padding:12px;background-color:#007bff;color:#fff;border:none;border-radius:8px;cursor:pointer;font-size:16px;font-weight:500;transition:all .3s ease;margin-top:10px}button[data-v-58611a9b]:hover{background-color:#0056b3;transform:translateY(-1px);box-shadow:0 4px 12px #007bff33}button[data-v-58611a9b]:disabled{opacity:.7;cursor:not-allowed}p[data-v-58611a9b]{margin-top:20px;color:#666;font-size:14px}a[data-v-58611a9b]{color:#007bff;text-decoration:none;font-weight:500;transition:color .3s ease}a[data-v-58611a9b]:hover{color:#0056b3;text-decoration:underline}.header[data-v-66890ca7]{display:flex;align-items:center;height:60px;padding:0;background-color:#001529;color:#fff;width:100%;position:relative;left:0;right:0}.nav[data-v-66890ca7]{display:flex}.nav-item[data-v-66890ca7]{display:flex;align-items:center;padding:0 20px;height:60px;color:#fff;text-decoration:none;cursor:pointer;font-weight:700;transition:background-color .3s}.active[data-v-66890ca7]{background-color:#4178ee}.icon-device[data-v-66890ca7]{margin-right:8px}.switch[data-v-49c99558]{position:relative;display:inline-flex;align-items:center;width:40px;height:20px;line-height:20px;background-color:#dcdfe6;border-radius:10px;cursor:pointer;transition:all .3s}.switch.is-checked[data-v-49c99558]{background-color:#4178ee}.switch-core[data-v-49c99558]{position:absolute;left:2px;top:2px;width:16px;height:16px;border-radius:50%;background-color:#fff;transition:all .3s}.switch.is-checked .switch-core[data-v-49c99558]{left:22px}.device-card[data-v-44eada42]{background:#fff;border-radius:4px;padding:20px;box-shadow:0 1px 3px #0000001a;margin-bottom:16px}.device-id[data-v-44eada42]{font-size:18px;font-weight:700;margin-bottom:16px}.note[data-v-44eada42]{color:#4178ee;font-size:14px;font-weight:400}.device-details p[data-v-44eada42]{margin-bottom:12px}.ota-upgrade[data-v-44eada42]{display:inline-flex;align-items:center;margin-left:16px}.device-actions[data-v-44eada42]{display:flex;margin-top:20px}.action-btn[data-v-44eada42]{padding:8px 16px;margin-right:12px;border:1px solid #ddd;border-radius:4px;background:#fff;cursor:pointer}.action-btn.primary[data-v-44eada42]{background:#4178ee;color:#fff;boLine truncated
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

+27 -26
View File
@@ -1,27 +1,28 @@
<!doctype html>
<html lang="en" style="height: 100%;">
<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>智控台</title>
<!doctype html>
<html lang="en" style="height: 100%;">
<head>
<meta charset="UTF-8"/>
<link rel="icon" href="/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>智控台</title>
<style>
html, body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
#app {
height: 100%;
width: 100%;
}
</style>
<script type="module" crossorigin src="/assets/index-CvO82KVk.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-_IjUUKjO.css">
</head>
<body>
<div id="app"></div>
</body>
</html>
html, body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
#app {
height: 100%;
width: 100%;
}
</style>
<script type="module" crossorigin src="/assets/index-DF7ROAy9.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-D_oCZVZF.css">
</head>
<body>
<div id="app"></div>
</body>
</html>
Generated
+9 -668
View File
File diff suppressed because it is too large. Load diff
+1 -6
View File
@@ -11,7 +11,6 @@ pyyml = "0.0.2"
torch = "2.2.2"
silero-vad = "5.1.2"
websockets = "14.2"
opuslib = "3.0.1"
numpy = "1.26.4"
pydub = "0.25.1"
funasr = "1.2.3"
@@ -26,13 +25,9 @@ ormsgpack = "1.7.0"
ruamel-yaml = "0.18.10"
setuptools = "^75.8.0"
loguru = "^0.7.3"
opuslib-next = "^1.1.2"
[[tool.poetry.source]]
name = "mirrors"
url = "https://pypi.tuna.tsinghua.edu.cn/simple/"
priority = "primary"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
+1 -1
View File
@@ -2,7 +2,7 @@ pyyml==0.0.2
torch==2.2.2
silero_vad==5.1.2
websockets==14.2
opuslib==3.0.1
opuslib_next==1.1.2
numpy==1.26.4
pydub==0.25.1
funasr==1.2.3